ICMP Covert Channels & Protocol Misuse
Decode hidden data payloads embedded in ICMP ping echo request/reply data fields and IP header ID fields using Wireshark and TShark.
// prerequisite reading
ICMP Protocol Overview
ICMP (Internet Control Message Protocol) is used for diagnostic error reporting (e.g., ping echo requests/replies, destination unreachable).
Standard ping packets contain an ICMP header followed by an arbitrary data payload (by default, 32 bytes on Windows or 56 bytes on Linux containing repeated pattern sequences like abcd... or timestamp data).
+----------------+----------------+-------------------------------------+
| IP Header (20B)| ICMP Header(8B)| Payload / Data Field (Variable B) |
+----------------+----------------+-------------------------------------+
^ Attacker conceals exfiltrated bytes
1. Extracting ICMP Data Payloads with TShark
When malware or CTF challenges exfiltrate data via ICMP echo requests (Type 8):
# Filter ICMP Echo Request packets (icmp.type == 8) and print data payload field
tshark -r capture.pcap -Y "icmp.type == 8" -T fields -e data
Sample output (hex encoded bytes):
464c41477b
69636d705f
737465676f
7d0a
Concatenating & Decoding in Linux CLI
tshark -r capture.pcap -Y "icmp.type == 8" -T fields -e data | tr -d '\n' | xxd -r -p
Output exposes the extracted flag: FLAG{icmp_stego}.
2. IP Header Identification (ip.id) Covert Channel
Covert data can also be hidden inside standard IP header fields rather than the ICMP payload body:
ip.id(16-bit Identification field): Contains ASCII character codes or 16-bit integers sent in sequential packets.ip.ttl(Time to Live field): Variations in TTL values encode secret bits.
Extracting ip.id Field Values
# Extract IP ID field values in hexadecimal
tshark -r capture.pcap -Y "icmp" -T fields -e ip.id
Python Reassembly Script
import pyshark
cap = pyshark.FileCapture('icmp_id.pcap', display_filter='icmp.type == 8')
chars = []
for pkt in cap:
try:
# Extract IP ID integer and convert to ASCII character
ip_id = int(pkt.ip.id, 0)
chars.append(chr(ip_id))
except (AttributeError, ValueError):
continue
print("Extracted Message:", "".join(chars))