ICMP Backdoor
Introduction
These past few days, I’ve been researching some communication protocols used by remote control Trojans, such as TCP, UDP, ICMP, DNS, HTTP, etc. I won’t be elaborating on TCP and UDP because they’re too common.
You might not be very familiar with Trojans using ICMP and DNS. In fact, these two protocols are quite popular for Trojan communications due to their stealthiness, making them hard to block. The HTTP protocol is primarily used in scenarios where large websites serve as C&C servers—for example, there have been instances of using Twitter as a C&C server.
This time, we’ll analyze the ICMP protocol and use Python to develop an ICMP remote control backdoor. Before writing this article, I sensed that most people wouldn’t be very familiar with the ICMP protocol, so I’ve divided the implementation of the ICMP backdoor into several parts for explanation, gradually progressing. In this piece, we’ll explain the contents of the ICMP protocol and use Python to implement a simple ping.
>
Section One
What the heck is the ICMP protocol?
Have you ever pinged Baidu to test if your network is working smoothly, as shown in the image below?
>
The ping command uses the ICMP protocol. When pinging Baidu, we can use Wireshark to capture the packets, which provides a more intuitive view. As shown below, the ICMP protocol is a classic request-response model. The local machine sends an ICMP request packet to the Baidu server. If the request packet successfully reaches the destination, the Baidu server responds with an ICMP response packet.
Section Two
ICMP Protocol and Message Format
ICMP (Internet Control Message Protocol) is a subprotocol in the IPv4 protocol suite, used for transmitting control messages between IP hosts and routers. Control messages concern the network’s connectivity, whether a host is reachable, or if a route is available. ICMP messages are based on the IP protocol. Their format is shown below:
As illustrated, the data packet in ICMP protocol transmission includes: 20 bytes IP header + 8 bytes ICMP header + 1472 bytes 38 bytes. The ICMP header is further divided into 8-bit type, 8-bit code, 16-bit checksum, 16-bit identifier, and 16-bit sequence number. Among these, we are particularly interested in Request (value 8) and Reply (value 0).
Section Three
ping Implementation
We’ve briefly explained the ICMP message format above. Next, let’s use Python3 to implement a simple ping function based on the message format, mainly utilizing raw socket technology—i.e., raw sockets—and the struct pack method to package ICMP messages. Code implementation is as follows:
Initialization of raw socket, using the following code:
socket.socket(socket.AF_INET,socket.SOCK_RAW, socket.getprotobyname(‘icmp’))
The complex part is calculating the checksum, which is done as follows:
- Treat the entire ICMP header and data as a sequence of 16-bit integers (in network byte order),
- Compute the one’s complement for each integer, then add them up,
- Compute the one’s complement of the result to obtain the checksum.
Test ping Effect
Ensure to run the Python script with administrator privileges. Direct ping to Baidu’s address 220.181.112.244
Simultaneously, open Wireshark to capture packets.