用途限制声明,本文仅用于网络安全技术研究、教育与知识分享。文中涉及的渗透测试方法与工具,严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果,作者及发布平台不承担任何责任。渗透测试涉及复杂技术操作,可能对目标系统造成数据损坏、服务中断等风险。读者需充分评估技术能力与潜在后果,在合法合规前提下谨慎实践。
这次我们主要介绍反序列化漏洞,其中两种比较常见的反序列化漏洞,Java反序列化漏洞和php反序列化漏洞,接下来着重介绍这两种反序列化漏洞。
一 、Java 反序列化漏洞
Java 作为面向对象的编译型语言,其序列化格式为二进制流(不可直接阅读),漏洞触发依赖readObject()方法(反序列化核心方法),且通常需要构造 "利用链(Gadget Chain)"------ 串联多个类的方法,最终触发恶意代码执行,比 PHP 反序列化更复杂但危害范围更广。
1. 漏洞核心原理
(1)Java 序列化机制
Java 通过java.io.Serializable接口标记可序列化类,序列化由ObjectOutputStream.writeObject()完成(生成二进制流),反序列化由ObjectInputStream.readObject()完成(恢复对象)。
关键特性:若类重写了readObject()方法,反序列化时会优先执行该方法中的逻辑------ 这是漏洞的核心触发点。
(2)利用链(Gadget Chain)的必要性
Java 的安全设计较严谨,单个类的readObject()通常无法直接执行命令(如无Runtime.getRuntime().exec()这类危险代码)。因此,攻击者需要 "串联多个合法类的方法",形成一条 "利用链":从readObject()出发,通过调用链触发反射(Java 的反射机制可动态调用任意类的任意方法),最终执行恶意命令。
简单理解:利用链 = readObject() → 类 A 方法 → 类 B 方法 → ... → 反射执行命令。
(3)漏洞触发流程
攻击者分析目标 Java 程序依赖的第三方库(如 Apache Commons Collections、Jackson)或框架(如 Struts2、WebLogic),寻找可串联成利用链的类;
构造恶意对象:基于利用链,创建包含恶意逻辑的序列化对象(如通过反射执行calc.exe的对象);
将恶意二进制流通过请求(如 HTTP POST、T3 协议)传入目标程序;
目标程序调用readObject()反序列化该流,触发利用链,执行恶意代码。
2. 典型代表案例
(1)里程碑漏洞:Apache Commons Collections 反序列化漏洞(CVE-2015-7501)
漏洞背景:2015 年披露,影响 Apache Commons Collections 3.1~3.2.1 版本(该库是 Java 生态中最常用的工具库之一,几乎所有企业级 Java 项目都会依赖),是 Java 反序列化漏洞的 "开山之作",直接推动了后续所有 Java 反序列化漏洞的研究。
漏洞原理(核心利用链):
关键类:TransformedMap( Commons Collections 中的映射类)、InvokerTransformer(实现Transformer接口,可通过反射调用方法)。
TransformedMap在反序列化时,会调用其transformValue()方法,而该方法会执行Transformer接口的transform()方法;
攻击者将TransformedMap的Transformer设置为InvokerTransformer,并指定InvokerTransformer通过反射调用Runtime.getRuntime().exec()(执行系统命令);
当TransformedMap被反序列化时,transform()触发InvokerTransformer的反射逻辑,最终执行命令。
利用方式:
攻击者通过工具(如 ysoserial,专门生成 Java 反序列化利用链的工具)生成包含TransformedMap和InvokerTransformer的恶意二进制流,通过 HTTP 参数或协议(如 Struts2 的params参数)传入目标程序,触发readObject()后执行命令。
危害:覆盖全球数百万依赖 Commons Collections 的 Java 应用(如 Struts2、WebLogic、JBoss),导致大规模 RCE 攻击,至今仍是渗透测试中的 "必测漏洞"。
(2)企业级漏洞:WebLogic T3 协议反序列化漏洞(CVE-2017-10271)
漏洞背景:影响 Oracle WebLogic Server 10.3.6.0、12.1.3.0、12.2.1.1、12.2.1.2 版本(WebLogic 是 Oracle 推出的企业级应用服务器,广泛用于金融、政府、大型企业)。
漏洞原理:WebLogic 的T3协议(用于 WebLogic 服务器与客户端 / 其他服务器通信)在处理序列化数据时,会调用readObject()反序列化数据。攻击者可利用 WebLogic 内部的wls9_async_response组件,构造包含恶意利用链(如基于 Commons Collections 或 WebLogic 自身类的链)的序列化数据,通过 T3 协议发送给服务器。
利用方式:
攻击者无需认证,直接向 WebLogic 的 T3 端口(默认 7001)发送恶意二进制流,服务器反序列化时触发利用链,执行命令(如nc反弹 shell)。
危害:企业级服务器直接被远程控制,可能导致核心业务数据泄露、业务中断,甚至内网横向渗透(因为 WebLogic 通常部署在企业内网)。
一、PHP 反序列化漏洞
PHP 作为脚本语言,其序列化格式为明文可阅读的字符串,漏洞触发高度依赖 PHP 的 "魔术方法"(具有特殊功能的预定义方法,通常以__开头),本质是 "可控输入触发危险魔术方法"。
1. 漏洞核心原理
(1)PHP 序列化格式
PHP 对象序列化后会生成类似如下的字符串,结构清晰(便于攻击者构造恶意数据):
php
// 格式:O:类名长度:"类名":属性个数:{属性1类型:属性1值;属性2类型:属性2值;...}O:5:"User":2:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";}// 含义:类名User(长度5),2个属性:username(字符串,值admin)、password(字符串,值123456)
(2)关键触发点:魔术方法
PHP 在反序列化过程中会自动触发特定魔术方法,若这些方法中包含 "危险操作"(如eval()、system()、文件写入等),且方法依赖的属性值可由攻击者控制,则漏洞成立。常见危险魔术方法:
__wakeup():反序列化之前触发(最核心的触发点之一);
__destruct():对象被销毁时触发(反序列化后若对象无引用,会自动触发);
__toString():对象被当作字符串使用时触发(如echo $obj、字符串拼接);
__call():调用不存在的方法时触发;
__get():访问不存在的属性时触发。
(3)漏洞触发流程
攻击者分析目标 PHP 程序,找到包含 "危险魔术方法" 的类(如存在__wakeup()调用eval($this->cmd)的类);
构造恶意对象:将危险方法依赖的属性(如$cmd)设为恶意代码(如system("whoami"));
将恶意对象序列化为字符串,通过请求参数(如 Cookie、POST 参数)传入目标程序;
目标程序接收该字符串并执行unserialize()(反序列化),触发魔术方法,执行恶意代码。
2. 典型代表案例
(1)PHP 原生漏洞:CVE-2016-7124
漏洞背景:影响 PHP 5.6.25 之前、7.0.10 之前的版本,源于 PHP 的Session反序列化机制缺陷。
漏洞原理:
PHP 的Session存储依赖session.serialize_handler(序列化处理器),默认值为php(格式:键名|序列化数据),而若配置为php_serialize(格式:序列化数据),且session.save_handler为自定义处理器(如user),则Session数据的反序列化过程可控。
利用方式:
攻击者通过 Cookie 设置PHPSESSID对应的Session数据,构造包含恶意对象的序列化字符串(如触发__wakeup()执行命令的对象)。当 PHP 读取Session并反序列化时,直接触发漏洞,实现 RCE。
危害:直接攻击 PHP 解释器本身,无需依赖第三方框架,影响所有使用存在漏洞版本 PHP 的网站。
(2)框架漏洞:ThinkPHP 5.x 反序列化漏洞(如 CNVD-2018-24942)
漏洞背景:影响 ThinkPHP 5.0.0~5.0.23、5.1.0~5.1.30 版本,是 PHP 框架中最典型的反序列化漏洞之一(ThinkPHP 是国内使用最广泛的 PHP 框架)。
漏洞原理:
ThinkPHP 框架的Request类(处理 HTTP 请求)中存在__destruct()魔术方法,该方法会调用filterValue(),而filterValue()会执行call_user_func()(调用指定函数)。攻击者可通过控制filter属性(指定要调用的函数)和params属性(函数参数),构造恶意序列化数据。
利用方式:
攻击者通过cookie或GET/POST参数传入恶意序列化字符串(如O:10:"think\Request":2:{s:8:"filter";s:6:"system";s:6:"params";a:1:{i:0;s:6:"whoami";}}),当框架对该数据反序列化时,__destruct()触发call_user_func("system", "whoami"),执行系统命令。
危害:覆盖大量使用 ThinkPHP 的中小型网站,攻击者可直接获取服务器权限,植入后门或窃取数据。
二 、PHP 与 Java 反序列化漏洞的核心区别
|--------|--------------------------------------|--------------------------------|
| 对比维度 | PHP 反序列化漏洞 | Java 反序列化漏洞 |
| 序列化格式 | 明文字符串(易构造、易调试) | 二进制流(需工具生成,如 ysoserial) |
| 核心触发点 | 魔术方法(__wakeup()、__destruct()等) | 重写的readObject()方法 |
| 利用链复杂度 | 低(多为单个类的魔术方法直接触发) | 高(需串联多个类形成利用链,依赖第三方库) |
| 影响范围 | 主要影响 PHP 脚本 / 框架(如 ThinkPHP、Laravel) | 影响所有 Java 应用(含企业级服务器、框架) |
| 典型依赖 | 自身语法特性(魔术方法) | 第三方库(Commons Collections)或框架组件 |
三 、两类漏洞的共同危害
无论 PHP 还是 Java 反序列化漏洞,其核心危害均为远程代码执行(RCE) ,攻击者可实现:
完全控制服务器:执行任意系统命令(如whoami、rm -rf /),获取服务器权限;
数据窃取 / 破坏:读取数据库配置、下载核心业务数据,或删除关键文件;
植入后门:上传 webshell(如 PHP 的一句话后门、Java 的jspx后门),长期控制服务器;
内网横向渗透:若服务器位于内网,攻击者可通过该服务器攻击内网其他机器,扩大攻击范围