CSRF with Flash
Author: lake2 [80sec]
EMail: lake2#80sec.com
Site: http://www.80sec.com
Date: 2008-10-04
From: http://www.80sec.com/release/csrf-with-flash.txt
———————————
[ 目录 ]
0×00 纯属扯淡
0×01 用flash发起CSRF攻击
0×02 超越JavaScript Hijacking
0×03 flash的跨域策略
0×04 绕过flash的跨域策略
0×05 flash的限制措施
0×06 Windows Media Player的隐患
0×07 防范措施
0×08 后记
——————————–
0×00 纯属扯淡
世界变化得太快,一不留神你就落后了。现在看来,CSRF也算老生常谈了,为了有点积极的意义,本文重点介绍一下利用flash进行CSRF攻击的一些手法,希望对你有点启发。
嗯,本期的扯淡话题是,我们老得太快,却明白得太迟。
0×01 用flash发起CSRF攻击
flash功能丰富,当然也有向任意站点发送请求的API,而且发送的请求会继承是当前浏览器的会话——也就是说我们可以利用flash而不是js来控制 浏览器向目标URL发送请求,这就实现CSRF了。比如flash8中的loadVariables,flash9中的sendToURL都是可以实现这 个功能的(编译的时候本地回放安全性一项要选择“只访问网络”)。
比如以下代码:
import flash.net.URLRequest;
import flash.system.Security;
var url = new URLRequest(“http://www.baidu.com/lake2”);
var lake = new URLVariables();
lake = “a=lake2”;
url.method = “POST”;
url.data = lake;
sendToURL(url);
stop();
编译好之后访问之,你会发现它会向百度POST数据哦,如果你的机器上有baidu.com的cookie,cookie也会发送出去的,这里就可以绕过 IE的隐私安全限制——如果你直接img或者iframe向baidu.com发送数据,呵呵,cookie是会被阻挡的。
我也写了个flash来实现这类攻击,可以参考之前CSRF的文章。
0×02 超越JavaScript Hijacking
JavaScript Hijacking其实也是一种CSRF,不过它着重在利用当前会话身份会拿到以JS形式返回的内容,进而得到JS中出现的敏感数据。一个典型的漏洞场景是,一些为ajax提供JS接口的Web程序,可能会把当前用户的资料输出到JS中。
有了flash问题就简单了很多,因为flash9的URLLoader可以发送请求并得到返回的数据(flash8也有类似的API)。
用以下as代码来演示加载http://www.0×54.org/lake2/flash/get.txt的页面:
import flash.net.*;
var myloader = new URLLoader(new URLRequest("http://www.0x54.org/lake2/flash/get.txt"));
myloader.addEventListener(Event.COMPLETE,test);
myloader.load();
function test(event:Event){
var ResponseText:String = myloader.data;
text1.text = ResponseText;
stop();
}
编译好的flash在这里:http://www.0×54.org/lake2/flash/flashgetdemo.swf,访问之,它会把get.txt的内容显示在flash中。
JavaScript Hijacking只能得到script,而flash这样可以得到整个网页,除了得到敏感信息,还可以绕过那些通过表单元素防御CSRF的策略。比如一 些网站把uid放在post的隐藏域中防御CSRF,用第三方的JS无法得到uid,但是却可以用flash来得到页面中的uid。
但是不要高兴得太早,对于这种加载其他页面的情况,flash受到跨域策略的限制。
0×03 flash的跨域策略
adobe为了限制flash加载任意页面,使用了一种跨域策略来进行限制。
所谓的flash跨域策略文件就是在站点根目录的crossdomain.xml,这个XML文件配置当前站点的资源允许来自哪些域的flash加载。当 flash加载一个站点的资源时,如果目标不跟自己一个站点,flash就会自动去访问目标站点跟目录下的crossdomain.xml文件,如果 crossdomain.xml中的allow-access-from domain标签包含flash所在网站,那么flash就可以加载该内容。
一个crossdomain.xml文件可能是这样的:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*.example.com" />
<allow-access-from domain="www.friendOfExample.com" />
<allow-access-from domain="192.0.34.166" />
</cross-domain-policy>
以上策略就是允许来自*.example.com、www.friendOfExample.com和192.0.34.166的flash加载资源。
在站点不存在crossdomain.xml文件的情况,允许flash主动加载目标站点的其他XML文件作为跨域策略文件。比如,flash9中可以使 用Security.loadPolicyFile加载目标站点的其他文件作为跨域策略文件。如果没有跨域策略文件许可,那么sorry,flash就不 能加载该站点的内容。
0×04 绕过flash的跨域策略
我们要进行CSRF,可能需要获取目标站点某些页面中的内容,这个时候就得想办法绕过flash的跨域策略。
最简单的情况是目标站点本身没有安全意识,允许任意flash加载内容那就没话说了(allow-access-from domain=”*”)。
还有就是目标站点根目录没有crossdomain.xml,那就看看能否找到上传文件的地方传一个同样格式的文件上去,然后用 Security.loadPolicyFile加载之。这里貌似flash有通过Content-Type来判断,所以要文本类型的才有效。
最后一种情况是有crossdomain.xml,而且配置得很好。这个时候就要稍微麻烦一点,那我们就去找它支持flash加载的站点是否可以上传文 件,上传我们精心构造的flash就好了。后缀倒无所谓:如果是以object标签调用flash的话任意后缀就可以;以embed调用的话除了jpg、 jpeg、gif等少数后缀不支持外其他都可以。
0×05 flash的限制措施
flash的网络功能太强大,所以它本身也有一套限制措施。那就是在启用flash的标签<object>和<embed>中设置allowNetworking参数。
allowNetworking 参数有3个值供选择:all、internal、none
·all —— 允许所有的网络 API
·internal —— 不能调用浏览器导航或浏览器交互 API。例如 getURL(flash8) 和 navigateToURL 等。仍然可以向外发请求和加载内容
·none —— 禁止任何网络API。世界清静了,但是flash的功能会被削弱,比如一个flash的MP3播放器就不能用了
每个选项具体禁止哪些函数请参考ActionScript手册。这里要说明的是如果不设置 allowNetworking,默认为all;不通过网页调用而直接访问swf文件,allowNetworking也为all。
0×06 Windows Media Player的隐患
我们可以在网页调用Windows Media Player来播放视频,呃,如果你安装了flash控件,那么Windows Media Player也会播放flash。如果flash中包含向外发送数据的脚本,那么,它也会被执行——大概就类似allowNetworking被设置成了 internal。这是一个绝佳的CSRF载体。
有点麻烦的是,allowNetworking参数限制不住在Windows Media Player中调用的flash——似乎没有什么可以限制到它,对Web程序来说,这个隐患简直是太可怕了。
0×07 防范措施
了解了威胁之后再来看防御手段就再简单不过。
Web程序中可以通过请求的来源进行判断:通过正常页面过来的referer我们已知的,flash过来的请求referer为空或者是swf文件地址 (直接发请求的API不带referer,加载页面的API发出的referer是flash文件地址)。另外,flash发送请求的时候也会在HTTP 头中带上x-flash-version标识版本。
在配置方面需要注意:用户可以控制flash地址的地方根据业务特性设置allowNetworking值;尽量不要使用Windows Media Player,开发一套flash播放器吧;站点根目录的crossdomain.xml文件要配置好,尽量精确到子域,缩小被攻击面。
不考虑用户体验的话,特别敏感的地方用图形验证码是最好的。
0×08 后记
有什么意见可以和我交流,请发邮件到lake2#80sec.com。BTW,CSDN那个邮箱已经废了-_-!!
以前研究过,但不是CSRF,是可以直接挂马的.