手工编写简化版CommonsCollections6,带你实现Java8全版本反序列化利用

这是代码审计知识星球中《Java安全漫谈》的第十二篇文章。

本文带大家编写一个简化版的CommonsCollections6利用链,代码量相比于ysoserial减少50%,能够让大家更好理解。

上一篇文章我们详细分析了CommonsCollections1这个利用链和其中的LazyMap原理。但是我们说到,在Java 8u71以后,这个利用链不能再利用了,主要原因是sun.reflect.annotation.AnnotationInvocationHandler#readObject的逻辑变化了。

在ysoserial中,CommonsCollections6可以说是commons-collections这个库中相对比较通用的利用链,为了解决高版本Java的利用问题,我们先来看看这个利用链。

不过,本文我不会按照ysoserial中的代码进行讲解,原因是ysoserial的代码过于复杂了,而且其实用到了一些没必要的类。

我们先看下我这条简化版利用链:

/*
	Gadget chain:
	    java.io.ObjectInputStream.readObject()
            java.util.HashMap.readObject()
                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()
*/

我们需要看的主要是从最开始到org.apache.commons.collections.map.LazyMap.get()的那一部分,因为LazyMap#get后面的部分在上一篇文章里已经说了。所以简单来说,解决Java高版本利用问题,实际上就是在找上下文中是否还有其他调用LazyMap#get()的地方

我们找到的类是org.apache.commons.collections.keyvalue.TiedMapEntry,在其getValue方法中调用了this.map.get,而其hashCode方法调用了getValue方法:

package org.apache.commons.collections.keyvalue;


import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.collections.KeyValue;


public class TiedMapEntry implements Entry, KeyValue, Serializable {
private static final long serialVersionUID = -8453869361373831205L;
private final Map map;
private final Object key;


public TiedMapEntry(Map map, Object key) {
this.map = map;
this.key = key;
    }


public Object getKey() {
return this.key;
    }


public Object getValue() {
return this.map.get(this.key);
    }


// ...


public int hashCode() {
        Object value = this.getValue();
return (this.getKey() 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值