CSRF with Flash

flash功能丰富,当然也有向任意站点发送请求的API,而且发送的请求会继承是当前浏览器的会话—也就是说可以利用flash而不是js来控制浏览器向目标URL发送请求,这就实现CSRF了。比如flash8中的loadVariablesflash9中的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发起请求可以绕过IE隐私策略,携带cookie>

    0×02 超越JavaScript Hijacking

    JavaScript Hijacking其实也是一种CSRF,不过它着重在利用当前会话身份会拿到以JS形式返回的内容,进而得到JS中出现的敏感数据。一个典型的漏洞场景是,一些为ajax提供JS接口的Web程序,可能会把当前用户的资料输出到JS中。
    有了flash问题就简单了很多,因为flash9的URLLoader可以发送请求并得到返回的数据(flash8也有类似的API)。
    用以下as<actionScript>代码来演示加载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加载目标站点的其他文件作为跨域策略文件。如果没有跨域策略文件许可,那么flash就不能加载该站点的内容。

    0×04 绕过flash的跨域策略

    要进行CSRF,可能需要获取目标站点某些页面中的内容,这个时候就得想办法绕过flash的跨域策略。
    1、目标站点本身没有安全意识,允许任意flash加载内容(allow-access-from domain=”*”)。
    2、目标站点根目录没有crossdomain.xml,那就找到上传文件的地方传一个同样格式的文件上去然后用 Security.loadPolicyFile加载这个文件,这里貌似flash有通过Content-Type来判断,所以要文本类型的才有效
    3、有crossdomain.xml,而且配置得很好。这个时候就要稍微麻烦一点,那么就去找它允许flash加载的站点是否可以上传文 件,上传精心构造的flash就好了。后缀倒无所谓:如果是以object标签调用flash的话任意后缀就可以;以embed调用的话除了jpg、 jpeg、gif等少数后缀不支持外其他都可以

    0×05 flash的限制措施

    flash的网络功能太强大,所以它本身也有一套限制措施。那就是在启用flash的标签<object>和<embed>中设置allowNetworking参数。
    allowNetworking 参数有3个值供选择:allinternalnone

    1. ·all —— 允许所有的网络 API
    2. ·internal —— 不能调用浏览器导航或浏览器交互 API。例如 getURL(flash8) navigateToURL 等。仍然可以向外发请求和加载内容
    3. ·none —— 禁止任何网络APIflash的功能会被削弱,比如一个flashMP3播放器就不能用了

    每个选项具体禁止哪些函数请参考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 防范措施

    了解了威胁之后再来看防御手段就再简单不过。

    1. 1Web程序中可以通过请求的来源进行判断:通过正常页面过来的referer我们已知的,flash过来的请求referer为空或者是swf文件地址 (直接发请求的API不带referer,加载页面的API发出的refererflash文件地址)。
    2. 2flash发送请求的时候也会在HTTP 头中带上x-flash-version标识版本。
    3. 3、在配置方面需要注意:用户可以控制flash地址的地方根据业务特性设置allowNetworking值;尽量不要使用Windows Media Player,开发一套flash播放器;
    4. 4、站点根目录的crossdomain.xml文件要配置好,尽量精确到子域,缩小被攻击面。
    5. 5、不考虑用户体验的话,特别敏感的地方用图形验证码是最好的。