技术分析之PHP的反序列化漏洞


By 团队成员——PM2.5

最近在研究php的反序列化漏洞,整理一下笔记心得。
一、首先,什么是序列化?
简单来说就是把对象变成字符串,而反序列化就是把字符串变成对象。
相关函数有,serialize()和unserialize()。
前者在执行前会检测有没有_sleep(),后者会检测有没有_wakeup()(有时候绕过用的到,比如flag)。
如果php代码中并没有在反序列化前检测恶意代码(条件1),并且恶意代码可以由客户端控制(条件2),反序列化的对象有使用魔术方法(条件3),就可以构成反序列化漏洞。

二、魔术方法是什么?
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(),__invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。

常见魔术方法的自动调用情景:__construst() 方法在每次创建新对象时会被自动调用,__destruct() 方法在使用 exit() 终止脚本运行时会被自动调用
关于序列化的格式(避免每次都需要本地生成),我们可以看一下。

例子O:1:"A":1:{s:4:"name";s:3:"hhh";}
O代表对象 因为我们序列化的是一个对象 序列化数组则用A来表示
1 代表类名字占三个字符 
A 类名
1 代表一个属性
s代表字符串
4代表属性名长度
name属性名
s:3:"hhh" 字符串 属性值

三、如何利用反序列化漏洞?
如果反序列化对象中存在魔术函数,使用unserialize()函数同时也会触发。
那么我可以构造这样的魔术函数调用eval来达到getshell的目的。
如果运气好看到这个(其实魔术方法在也是对象的情况下,此时就可以构造魔术方法内容一键getshell了)
function __destruct(){
@eval($this->test);
}
那利用序列化可以直接替换test,变成隐蔽的小马。
总结:实际上反序列化的利用主要是围绕魔术方法进行的,魔术方法的具体内容查看php官网。
By 团队成员——PM2.5
本博客所有文章如无特别注明均为原创。作者:渊龙Sec团队复制或转载请以超链接形式注明转自 渊龙Sec安全团队博客
原文地址《技术分析之PHP的反序列化漏洞
分享到:更多

相关推荐

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交

网友评论(0)