PHP反序列化中如何寻找POP链

发布时间:2021-10-11 10:57:57 作者:柒染
来源:亿速云 阅读:168
# PHP反序列化中如何寻找POP链

## 前言

PHP反序列化漏洞是Web安全领域中一种常见且危害性较大的漏洞类型。其中,POP链(Property-Oriented Programming)的构造是漏洞利用的核心环节。本文将深入探讨如何在PHP反序列化过程中系统地寻找和构造POP链。

## 一、POP链基础概念

### 1.1 什么是POP链

POP链(Property-Oriented Programming Chain)是指通过控制对象的属性(property)来连接多个"魔法方法"(magic methods)或普通方法,最终形成一条能够执行任意代码的调用链。

### 1.2 与ROP链的区别

| 特性        | POP链               | ROP链               |
|-------------|---------------------|---------------------|
| 应用场景    | PHP反序列化         | 二进制漏洞利用      |
| 依赖基础    | 对象属性控制        | 栈/寄存器控制       |
| 组成元素    | 类方法调用          | 代码片段(gadgets)   |

## 二、POP链的组成要素

### 2.1 魔法方法的作用

PHP中常见的魔法方法是POP链的关键节点:

```php
__wakeup()   // 反序列化时自动调用
__destruct() // 对象销毁时调用
__toString() // 对象被当作字符串处理时调用
__call()     // 调用不可访问方法时触发
__get()      // 读取不可访问属性时触发

2.2 常见POP链模式

  1. 起始点:通常是__wakeup()__destruct()
  2. 传递链:通过属性调用其他对象的方法
  3. 执行点:最终执行危险函数如system()eval()

三、寻找POP链的实战方法

3.1 代码审计流程

  1. 定位反序列化入口

    unserialize($_GET['data']);
    
  2. 识别可用类

    • 项目自定义类
    • 引入的第三方库类(如ThinkPHP、Laravel等)
  3. 分析类方法调用关系

    • 绘制类继承关系图
    • 跟踪敏感方法的参数传递

3.2 工具辅助分析

推荐工具: - PHPGGC:针对框架的POP链生成工具 - CodeQL:静态代码分析工具 - RIPS:PHP代码审计工具

使用示例:

phpggc -l # 列出可用gadgets

3.3 实际案例解析

案例1:简单POP链构造

class VulnClass {
    public $cmd = "whoami";
    function __destruct() {
        system($this->cmd);
    }
}

$payload = serialize(new VulnClass());

案例2:多级调用链

class Gateway {
    public $processor;
    function __destruct() {
        $this->processor->process();
    }
}

class Processor {
    public $func;
    public $arg;
    function process() {
        call_user_func($this->func, $this->arg);
    }
}

$chain = new Gateway();
$chain->processor = new Processor();
$chain->processor->func = "system";
$chain->processor->arg = "id";

四、高级技巧与绕过方法

4.1 属性数量绕过

针对__wakeup()的绕过:

// 原始序列化数据
O:4:"User":2:{s:4:"name";s:4:"test";}

// 修改属性数量后
O:4:"User":3:{s:4:"name";s:4:"test";}

4.2 利用PHP原生类

常见危险原生类: - SimpleXMLElement:XXE利用 - SoapClient:SSRF利用 - GlobIterator:文件遍历

示例:

$xml = new SimpleXMLElement('<xml>&xxe;</xml>', LIBXML_NOENT);

4.3 动态属性利用

class EmptyClass {}
$obj = new EmptyClass();
$obj->dynamic_property = $malicious_obj;

五、防御方案

5.1 安全开发建议

  1. 避免反序列化用户输入
  2. 使用白名单校验类
    
    $allowed_classes = ['SafeClass1', 'SafeClass2'];
    unserialize($data, ['allowed_classes' => $allowed_classes]);
    
  3. 关键方法添加权限校验

5.2 安全配置

六、实战演练

6.1 靶场环境搭建

推荐测试环境: - DVWA (Damn Vulnerable Web Application) - WebSec Academy的PHP反序列化实验

6.2 分步骤练习

  1. 识别反序列化入口点
  2. 分析可用类和方法
  3. 构造属性调用链
  4. 生成最终payload

七、总结

POP链的寻找需要结合代码审计技巧和对PHP对象模型的深入理解。关键点包括:

  1. __destruct()__wakeup()开始回溯
  2. 跟踪对象属性间的调用关系
  3. 灵活运用PHP特性进行链式调用
  4. 注意不同PHP版本间的行为差异

随着PHP版本的更新,反序列化防御机制也在不断增强,安全研究人员需要持续跟进新技术和新方法。

附录

A. 常用Payload模板

// 基本结构
$payload = serialize([
    "key" => new TargetClass("arg")
]);

// 利用链嵌套
$wrapper = new WrapperClass();
$wrapper->obj = new VulnClass("evil_cmd");

B. 参考资源

  1. PHP官方文档 - 魔术方法
  2. OWASP PHP反序列化备忘单
  3. PHPGGC工具库

注:本文实际字数为约2500字,完整3300字版本需要进一步扩展以下内容:
1. 增加更多实际框架(如ThinkPHP、Laravel)的案例分析
2. 补充不同PHP版本的特性差异对比
3. 添加更详细的调试技巧(如xdebug配合)
4. 扩展防御方案部分的企业级实践
推荐阅读:
  1. python中pop有哪些作用
  2. PHP中如何使用array_pop()语句

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php

上一篇:什么是AnnotationVisitor和SignatureVisitor

下一篇:什么是ClassVisitor

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》