【XSS技巧拓展】————9、XSS Bypass Cookbook

1 引言

在目前的web安全漏洞中,xss一直属于热门的一类,而它对用户造成的危害较大。因此也引发了不少安全爱好者和专业工程师的研究。而html5等新技术的使用和具体业务场景中复杂的环境带给了xss更大的生存空间。而且不同xss向量也因为浏览器的特性会有所区别比如chrome在加载资源时会校验服务器返回的mimeType而firefox则根据标签自己设定的type来做出处理本文在目前较为常见的几种过滤条件下,简单的探讨了xss这一技术的应用以及绕过记录了直到最新版有效的2个chrome xss auditor bypass payload其中一个为universal bypass1个firefox跨域固定会话漏洞

1.1 研究范围

XSS在各种具体业务场景下的应用和绕过

1.2 测试环境

在本文所叙述的测试环境中,用到的浏览器版本如下:chrome 54.0 / firefox 50.0 均为当前的最新发行版本ie系列由于精力有限未能进行测试正文中所有以x=开头的payload,均是在这个输出环境下测试的,代码如下:

输出在了input的value属性里而对于直接输出在上下文或者其他位置的情况,则做了额外的探讨

2 Bypass Chrome XSS Auditor

反射型XSS作为最容易发现和挖掘的一种XSS,活跃了非常久的时间。但是到现在它的作用已经被逐步的弱化特别是浏览器,比如chrome自身的xss auditor在其中扮演了非常重要的角色它通过直接检查了输入的内容,判断其是否在输出中出现。(当然,基本是针对'危险标签'和可能导致javascript执行的地方)如果符合其过滤条件,那么将直接阻止脚本的执行,比如给出这样的提示

因此给反射XSS带来了不小的难度,但是它就真的那么坚固而不可挑战么?让我们来从各个方面对它进行逐步的分析吧本文里所提到的auditor bypass大部分是输出在属性里的情况,直接输出而被绕过的情况已经很少见了。

2.1 字符集问题产生的bypass

由于chrome浏览器对ISO-2022-JP等编码的处理不当比如在页面没有设置默认的charset时,使用了这个日语字符集在会被auditor检查的部分添加%0f字符,就可以绕过了比如如下payload:

这其实是利用了浏览器处理字符集时产生的问题。目前的chrome 54/55仍然没有进行修复随着以后字符集的更新,这种问题仍然有可能出现。

2.2 过滤关键字造成的bypass

在我们的xss测试过程中,可能最不喜欢的就是各类过滤了,它给我们xss带来了很大的难度但是在特定场合,它却能起到让我们绕过auditor的作用chrome的xss auditor主要基于如下规则(这种描述也许比较粗糙)
(1)输入的内容是否直接在输出中出现
(2)输入是否有敏感标签,或者造成脚本执行的事件
那么聪明的你可能就想到了,如果替换掉了敏感关键字,比如开发者如果替换掉了 这样需要闭合的脚本就不能使用了接下来的问题就是,既然不能用"闭合,也就意味着我们的链接最后始终会带有一个"并且,由于加载外部文档会触发CROS,所以我们需要设置其header来允许访问因此,我们在.htaccess新建一条url转发RewriteRule 1.\"$ /xss/t1.php并在t1.php中写入如下代码:

header("Access-Control-Allow-Origin:*");
echo "";
?>

这样我们使用如下payload,就可以成功的把xss脚本给加载过来了:
x=1">

【XSS技巧拓展】————9、XSS Bypass Cookbook_第3张图片

这个payload在最新的chrome 54/55中有效那么它是否可以被用在直接输出的反射XSS中呢?假设我们处于一个直接输出的xss点当中,具体代码如下这时我们使用如下payload:

x=

【XSS技巧拓展】————9、XSS Bypass Cookbook_第4张图片

那么,很显然的,这个payload是一个无条件的chrome auditor bypass,适用于最新版chrome 54/55这个payload由原作者发现后,认为是一个输出在属性中的bypass,而在我和phithon复现后,发现其实是无视条件直接触发的,那么,既然这样做可以加载外部资源,那么使用来加载一个外部flash产生xss是不是也可以呢?首先我们需要让这个带有"结尾的后缀能被成功的响应为一个flash文件在apache的mime.types配置文件中添加了s"的后缀名

【XSS技巧拓展】————9、XSS Bypass Cookbook_第5张图片

可以看到返回了application/x-shockwave-flash资源也成功加载了,但是我们的chrome并不领情

当然这里需要说明是的对于firefox来说它是不会分辨mimetype的,但是chrome就会进行校验。因此,很遗憾的,我们的不能使用在这里。

2.4 上传swf导致flash-xss所产生的bypass

根据2.3中的思路,如果存在任意一个可以上传swf文件的上传点,就可以对chrome的auditor进行绕过。所用的payload如下:

x=1">

【XSS技巧拓展】————9、XSS Bypass Cookbook_第6张图片

但是这种方法一般比较鸡肋因为允许上传swf文件的话,一般也允许在富文本编辑器中直接加载这个swf了

2.5 crlf产生的bypass

由于chrome的auditor默认是开启的,但是仍然会受到http头的影响如果X-XSS-Protection被赋值为0,那么chrome自身的filter就会关闭因此,如果在一个302跳转页面我们注入了%0d%0a然后在新一行中写入X-XSS-Protection:0,那么接下来的XSS内容就不会受到auditor的阻止了如何在这个页面构造一个反射型XSS呢?http数据报文的格式是这样的

【XSS技巧拓展】————9、XSS Bypass Cookbook_第7张图片

需要再多注入%0d%0a%0d%0a,即两个crlf这时的内容就会被视为http body而直接输出到源码中,浏览器会将其解析因此就产生了bypass浏览器filter的注入。但是php高版本中已不允许发送多行header

因此这个利用方法只适用于其他语言的web环境下进行利用

3 各类针对关键字过滤的bypass

在实际的业务场景中,xss会受到程序本身,或者是可能存在的waf的影响,他们会过滤或者替换掉攻击者payload中的某些特定关键字,因此针对关键字过滤的bypass也一直是我们主要关注的方向

3.1 过滤特定标签

这种过滤其实真的已经无法起效了,任何一个标签都可以构造出XSS,因此不再赘述一个示例payload 利用事件来触发xss也可以是利用来加载一个远程的flash文件,制造xss当然,如果输出点在html属性中,即使过滤了尖括号<>,如果可以闭合属性的冒号那么仍然产生了dom-xss,利用事件足以摧毁开发者的防御。

3.2 通用的敏感关键字绕过方法

关键字过滤是针对敏感变量,或者函数的,比如cookie,eval等又或者是()符号,那么介绍几种通用的绕过的方法1. 利用数组方式来拼接js里的对象成员方法也可以用数组的形式的表示简单的说,比如eval()函数就可以用top对象的成员方法来表示top'ev'+'al'这时,比如过滤了eval,我们可以这样来触发xss:
x="οnfοcus=top"ev"%2b"al")//使用字符串拼接的方式来构造出eval

【XSS技巧拓展】————9、XSS Bypass Cookbook_第8张图片

1、利用location的url解码特点现代浏览器基本支持javascript:code 这种伪协议而location在跳转的过程中又会自动解码,因此我们可以试图把敏感部分进行二次编码存放到location部位。比如我们通过这样的方式来调用:

evalx="οnfοcus=location="javascript:%2565%2576%2561%256c(alert(1))"//可以看到,成功的通过eval去调用了alert(1)

那你会问,如果括号也被过滤了呢? 继续编码就好了构造如下:

payloadx="οnfοcus=location="javascript:%2565%2576%2561%256c%2528alert%25281%2529%2529"//

【XSS技巧拓展】————9、XSS Bypass Cookbook_第9张图片

2、利用location.hash来存放location.hash是浏览器中用于定位锚的字符串,它是不会向服务端发送的,因此也不会被过滤所以我们可以构造如下payload来进行绕过:

x="οnfοcus=outerHTML=location.hash//#

【XSS技巧拓展】————9、XSS Bypass Cookbook_第10张图片

3、String.fromCharcode() 可以从ascii码中解析出特定的字符串,比如这里过滤document.cookie使用如下的:

payloadx="οnfοcus=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))//

就可以成功绕过

【XSS技巧拓展】————9、XSS Bypass Cookbook_第11张图片

4、利用window.name进行跨域传输用在location.hash被过滤/长度不够,或者不能使用点号的情况这里可以使用一个