CommonsCollections2

icfh / 2023-08-17 / 原文

环境搭建

  • Commons Collections 4.0
  • JDK8
  • ysoserial-master

基础知识

1.Java字节码加载过程

学习一下p神的文章:

image-20230816221641337

  • ClassLoader#loadClass:从已加载的类缓存,父加载器等位置寻找类,在前面没有找到的情况下,执行findClass

  • ClassLoader#findClass:根据基础URL指定的方式来加载类的字节码

    可能的来源:

    • 本地文件系统
    • jar包
    • 远程http服务器
  • ClassLoader#defineClass:处理字节码,转成真正的类

2.TemplatesImpl加载字节码

TemplatesImpl 是 Java 中用于处理 XSLT(Extensible Stylesheet Language Transformations)模板的类。XSLT 是一种用于将 XML 数据转换为其他格式的语言,例如 HTML 或文本。TemplatesImpl 类通常用于将 XSLT 模板编译成可重用的 Transformer 对象,以便在应用程序中进行 XML 转换操作

简单来说,TemplatesImpl中调用了defineClass,从而可以实现动态加载Java字节码

代码如下

public final class TemplatesImpl implements Templates, Serializable{
    ...
    static final class TransletClassLoader extends ClassLoader {
        TransletClassLoader(ClassLoader parent) {
            super(parent);
        }

        /**
         * Access to final protected superclass member from outer class.
         */
        Class defineClass(final byte[] b) {
            return defineClass(null, b, 0, b.length);
        }
    }
    ...
}

TemplatesImpl Gadget Chain

捋一下TemplatesImpl加载字节码的Gadget Chain

/*
	TemplatesImpl.newTransformer()
		TemplatesImpl.getTransletInstance()					
			TemplatesImpl.defineTransletClasses()			
				ClassLoader.defineClass()		=> 加载字节码
*/

重点贴一下defineTransletClasses()

    private void defineTransletClasses()
        throws TransformerConfigurationException {

        if (_bytecodes == null) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);
            throw new TransformerConfigurationException(err.toString());
        }

        TransletClassLoader loader = (TransletClassLoader)
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    return new TransletClassLoader(ObjectFactory.findClassLoader());		// find
                }
            });

        try {
            final int classCount = _bytecodes.length;
            _class = new Class[classCount];

            if (classCount > 1) {
                _auxClasses = new Hashtable();
            }

            for (int i = 0; i < classCount; i++) {
                _class[i] = loader.defineClass(_bytecodes[i]);				// 加载字节码
                final Class superClass = _class[i].getSuperclass();

                // Check if this is the main class
                if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
                    _transletIndex = i;
                }
                else {
                    _auxClasses.put(_class[i].getName(), _class[i]);
                }
            }

            if (_transletIndex < 0) {
                ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name);
                throw new TransformerConfigurationException(err.toString());
            }
        }
        catch (ClassFormatError e) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name);
            throw new TransformerConfigurationException(err.toString());
        }
        catch (LinkageError e) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
            throw new TransformerConfigurationException(err.toString());
        }
    }

CC2 Gadget Chain

/*
	Gadget chain:
		ObjectInputStream.readObject()
			PriorityQueue.readObject()
				{
				PriorityQueue.heapify()
					PriorityQueue.Siftdown()
						PriorityQueue.siftDownUsingComparator()
				}			
                        TransformingComparator.compare()
                            InvokerTransformer.transform()
                                Method.invoke()
                           			// TemplatesImpl加载字节码 
                                    Runtime.exec()
 */

调试分析

  • 反序列化,进入PriorityQueuereadObject函数

大致流程是取ObjectInputStream对象进行处理,跟进heapify()

image-20230816191905057

  • heapify()

image-20230816192253561

  • 再进入siftDown

image-20230816192537665

  • 由于comparator非空,进入siftDownUsingComparator()

看起来是个二分的过程,进入comparator.compare

image-20230816193916054

  • compare,可以发现有熟悉的transform函数

image-20230816200536954

  • 典,java反射执行类方法

    image-20230816200735645

  • 基于反射机制,使用TemplatesImpl动态加载恶意Java字节码