Loading

记一次反序列化(运用preg_replace去吞掉字符串构造payload)——UNCTF2021-easy_serialize

查看代码,可以知道当一个post的变量action=1时可以看到function.php里的内容,我们post一下看下

 

 

 我们从index.php开始进行分析

 

 

 这里是一个过滤器,将$file变量里出现的flag,php,fl1g给替换成空白

 

 

 

这里是通过get方法得到一个变量a和b的值

然后给$u变量new一个UNCTF的对象

变量$s为变量$u序列化后的结果

 

这里是一个常见的md5绕过

可以参考:https://blog.csdn.net/iczfy585/article/details/106081299

 

 

所以给$a赋值QNKCDZO,给$b赋值240610708,发现网页不一样了,说明绕过成功了

 

 说明这个地方是把变量$u序列化后的结果$s进行过滤,之后在进行反序列化得到一个对象

分析完index.php后,我们再对function.php进行分析

 

 有一个me7eorite类,里面有两个属性safe和class,还有一个构造函数,给safe赋了一个初值,给class属性new了一个UNCTF的对象,

这里还有一个__toString()魔术方法,调用class属性的getShell()函数

最后就是getShell()函数,读取safe属性内容指代的文件

 

 最后是UNCTF类,存在三个变量$pass,$email,$name,构造函数,一个getShell()函数(没啥用),和一个析构函数

这里的析构函数是拼接$name变量和一个字符串,并将其echo

这里我们就可以联想到跟上面那个类的__toString()魔术方法进行联动,如果我们一个UNCTF的对象$name里的内容是一个me7eorite对象,然后这个对象里的$class里的内容又是一个me7eorite对象,而在这个对象中的$safe变量的值是flag,是不是就可以读取flag文件中的内容了呢

因为我们不能通过网页中post方法给变量赋值一个对象,因为我们输入的内容会被当作字符串,所以我们需要去利用之前的preg_replace去吞掉一些字符,然后构造出类似于

 

 这样的效果

 所以构造payload

email=";s:5:"email";s:1:"2";s:4:"name";O:9:"me7eorite":2:{s:4:"safe";s:11:"/etc/passwd";s:5:"class";O:9:"me7eorite":2:{s:4:"safe";s:5:"/flflagag";s:5:"class";i:1;}}}
&name=3
&pass=phpphpphpphpphpphpphp

 

 

 

 

可以把标蓝的字符全部吞掉,后面的“;把前面的”闭合了

然后在后面将被吞掉的$emal变量补充完整,还有$name里,构造一个me7eorite对象,然后这个对象的$class又是一个me7eorite对象,这个对象里的$safe的值为/flflagag,因为中间的flag也会因为过滤而被吞掉,最后用}"闭合前面,忽略后面的值

 

 

 于是得到flag

 

posted @ 2021-12-01 21:56  Nanne1ess  阅读(192)  评论(0编辑  收藏  举报