PHP反序列化与WordPress一些意外BUG的有趣结合
字数 1345 2025-08-18 11:37:07
PHP反序列化漏洞与WordPress安全研究
0x00 前言
本文详细分析PHP反序列化漏洞在WordPress环境中的实际应用,通过真实案例展示如何发现、利用这类漏洞,并探讨其安全影响。
0x01 PHP反序列化漏洞基础
1.1 反序列化漏洞原理
当攻击者能够控制传递给unserialize()函数的数据时,就可能存在反序列化漏洞。关键点在于:
- 攻击者可以控制反序列化后对象的属性
- 通过操纵对象属性可以影响代码执行流程
- 这种技术称为面向属性编程(POP)
1.2 PHP中的关键魔术方法
PHP的魔术方法在反序列化攻击中扮演重要角色:
__wakeup(): 对象反序列化时自动调用__destruct(): 对象销毁时自动调用__get(): 访问不存在的属性时调用__call(): 调用不存在的方法时调用- 其他魔术方法如
__set(),__isset()等也可能被利用
0x02 通用PHP POP小工具
2.1 UniversalPOPGadget类
为简化漏洞发现过程,作者创建了一个通用POP小工具类,记录所有魔术方法的调用:
class UniversalPOPGadget {
private function logEvent($event) {
file_put_contents('UniversalPOPGadget.txt', $event . "\r\n", FILE_APPEND);
}
public function __construct() { $this->logEvent('UniversalPOPGadget::__construct()'); }
public function __destruct() { $this->logEvent('UniversalPOPGadget::__destruct()'); }
public function __call($name, $args) { $this->logEvent('UniversalPOPGadget::__call(' . $name . implode(',', $args)); }
public static function __callStatic($name, $args) { $this->logEvent('UniversalPOPGadget::__callStatic(' . $name . implode(',', $args)); }
public function __get($name) { $this->logEvent('UniversalPOPGadget::__get(' . $name); }
public function __set($name, $value) { $this->logEvent('UniversalPOPGadget::__set(' . $name . ',' . $value); }
public function __isset($name) { $this->logEvent('UniversalPOPGadget::__isset(' . $name); }
public function __unset($name) { $this->logEvent('UniversalPOPGadget::__unset(' . $name); }
public function __sleep() { $this->logEvent('UniversalPOPGadget::__sleep()'); return array(); }
public function __wakeup() {
$this->logEvent('UniversalPOPGadget::__wakeup()');
$this->logEvent(" [!] Defined classes:");
foreach(get_declared_classes() as $c) {
$this->logEvent($c);
}
}
// 其他魔术方法...
}
2.2 小工具注入脚本
使用Python脚本自动将小工具注入到PHP文件中:
import os
import sys
GADGET_PATH = "/path/to/UniversalPOPGadget.php"
FILE_EXTENSIONS = [".php", ".php3", ".php4", ".php5", ".phtml", ".inc"]
for root, dirs, files in os.walk(sys.argv[1]):
for filename in files:
for ext in FILE_EXTENSIONS:
if filename.lower().endswith(ext):
fIn = open(os.path.join(root, filename), "rb")
phpCode = fIn.read()
fIn.close()
fOut = open(os.path.join(root, filename), "wb")
fOut.write("<?php include '" + GADGET_PATH + "'; ?>" + phpCode)
fOut.close()
break
0x03 WordPress中的反序列化漏洞
3.1 漏洞发现过程
- 通过grep查找WordPress插件中调用
unserialize()的代码 - 发现插件通过HTTP请求获取数据并反序列化:
$url = 'http://api.wordpress.org/plugins/info/1.0/';
$response = wp_remote_post($url, array('body' => $request));
$plugin_info = @unserialize($response['body']);
if (isset($plugin_info->ratings)) {
3.2 漏洞利用步骤
- 设置伪造的api.wordpress.org端点,返回序列化的UniversalPOPGadget对象
- 观察WordPress如何与反序列化后的对象交互
- 日志显示WordPress尝试访问多个属性:
UniversalPOPGadget::__wakeup()
UniversalPOPGadget::__get(sections)
UniversalPOPGadget::__isset(version)
UniversalPOPGadget::__isset(author)
...
3.3 实际攻击向量
- 管理员界面XSS:通过控制某些属性值注入恶意JavaScript
- 虚假更新诱导:伪造更新通知诱导管理员点击
- 远程代码执行:通过虚假插件更新植入后门
0x04 WordPress自动更新机制的安全问题
4.1 更新检查机制
WordPress默认每天两次检查更新:
function wp_schedule_update_checks() {
if (!wp_next_scheduled('wp_version_check') && !wp_installing())
wp_schedule_event(time(), 'twicedaily', 'wp_version_check');
if (!wp_next_scheduled('wp_update_plugins') && !wp_installing())
wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');
if (!wp_next_scheduled('wp_update_themes') && !wp_installing())
wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
}
4.2 HTTPS降级问题
WordPress更新机制存在严重安全问题:
- 首先尝试HTTPS连接
- 如果HTTPS失败,自动降级为不安全的HTTP
- 这使得MITM攻击成为可能
4.3 零交互攻击
攻击者可以通过DNS欺骗或MITM攻击:
- 劫持api.wordpress.org的HTTP响应
- 伪造更新信息
- 诱导WordPress下载恶意更新包
- 自动解压执行恶意代码
0x05 防御措施
5.1 开发者建议
- 避免反序列化不可信数据
- 使用JSON等安全格式替代序列化
- 对反序列化操作实施严格的白名单控制
5.2 WordPress管理员建议
- 强制使用HTTPS连接
- 禁用自动更新或严格监控更新行为
- 使用文件系统权限限制WordPress的写入能力
- 定期审计服务器上的异常文件
0x06 总结
PHP反序列化漏洞在复杂系统如WordPress中可能产生深远影响。通过精心构造的POP链,攻击者可以实现从XSS到RCE的多层次攻击。WordPress的更新机制设计缺陷放大了这类漏洞的风险,开发者和管理员都应提高警惕,采取适当防护措施。