Detecting ICMP Covert Channels via Payload Anomaly Identification and Hidden Data Extraction
Theory
Why This Matters
ICMP covert channels were among the first exfiltration techniques documented in academic literature, yet they remain effective because ICMP is almost universally permitted through firewalls — blocking ping breaks too many operational tools. The Loki tool published in 1996 demonstrated the concept; modern variants including icmpsh and PingTunnel implement full bidirectional shells over ICMP echo. During red team engagements in air-gapped environments where DNS and HTTP egress are blocked, ICMP often remains the last viable covert channel. Analysts who cannot recognise abnormal ICMP payloads miss an entire class of command-and-control traffic.
Core Concept
The ICMP Echo Request (type 8) and Echo Reply (type 0) messages include a variable-length data payload field. Standard operating system ping implementations populate this field with a predictable pattern: Windows uses the ASCII string abcdefghijklmnopqrstuvwxyz repeated to fill 32 bytes; Linux uses a incrementing byte sequence. Deviations from these patterns are the primary detection signal.
Covert channel indicators: - Payload size anomaly: standard ping payloads are 32 bytes (Windows) or 56 bytes (Linux). Covert tools frequently use larger payloads (up to 65,507 bytes — the maximum ICMP data length). - Non-standard payload content: instead of the expected repeating ASCII or incrementing byte pattern, payload contains high-entropy, non-printable, or cleartext data that is not a ping pattern. - Repeated sequences: legitimate ping sends a handful of requests; covert channels send hundreds or thousands of ICMP echo pairs at a regular interval. - Sequential ICMP identifier/sequence numbers: the ICMP identifier and sequence number fields are used by covert tools to encode fragmented messages. Anomalous identifier reuse or non-sequential sequence numbers indicate a custom implementation.
Technical Deep-Dive
# Show all ICMP packets with payload size and hex payload
tshark -r capture.pcap -Y "icmp"
-T fields
-e frame.number
-e frame.time_relative
-e ip.src
-e ip.dst
-e icmp.type
-e icmp.code
-e icmp.ident
-e icmp.seq
-e data.len
-e data.data
-E header=y -E separator=","
# Filter ICMP Echo requests with non-standard payload length (not 32 or 56 bytes)
tshark -r capture.pcap
-Y "icmp.type == 8 && data.len != 32 && data.len != 56"
# Count ICMP packets per (src, dst) pair — high counts indicate tunneling
tshark -r capture.pcap -Y "icmp.type == 8"
-T fields -e ip.src -e ip.dst
| sort | uniq -c | sort -rn | head -10
# Extract all ICMP payload bytes and concatenate for analysis
tshark -r capture.pcap
-Y "icmp.type == 8"
-T fields -e data.data
| tr -d '
' > icmp_payloads_hex.txt
# Decode concatenated hex payload
python3 -c "
import sys
data = open('icmp_payloads_hex.txt').read().strip()
raw = bytes.fromhex(data)
print(raw[:500])
"
from scapy.all import rdpcap, ICMP, Raw, IP
import string
WINDOWS_PING_PATTERN = bytes(range(ord('a'), ord('a') + 32))
LINUX_PING_PATTERN = bytes(range(8, 8 + 56)) # typical Linux ping data offset
def is_standard_payload(data: bytes) -> bool:
"""Return True if payload matches a known ping implementation pattern."""
# Windows: repeating lowercase alpha
expected_win = (string.ascii_lowercase * 3).encode()[:len(data)]
# Linux: incrementing bytes starting at 0x08
expected_lin = bytes((i + 8) % 256 for i in range(len(data)))
return data == expected_win or data == expected_lin
packets = rdpcap("capture.pcap")
covert_payloads: list[bytes] = []
for pkt in packets:
if pkt.haslayer(ICMP) and pkt[ICMP].type == 8: # Echo Request
if pkt.haslayer(Raw):
payload = bytes(pkt[Raw])
if payload and not is_standard_payload(payload):
print(
f"[COVERT] {pkt[IP].src} -> {pkt[IP].dst} "
f"seq={pkt[ICMP].seq} len={len(payload)} "
f"data={payload[:40]!r}"
)
covert_payloads.append(payload)
# Reassemble in sequence order and attempt decode
reconstructed = b"".join(covert_payloads)
print(f"
Total covert payload bytes: {len(reconstructed)}")
try:
print(f"As UTF-8: {reconstructed.decode('utf-8', errors='replace')[:200]}")
except Exception as e:
print(f"Decode error: {e}")
Analytical Methodology
- Apply display filter
icmpin Wireshark to isolate all ICMP traffic. Check Statistics → Endpoints to identify the top ICMP talkers. A host sending hundreds of ICMP echo requests to a single external IP is immediately suspicious. - Examine the data field in ICMP echo packets. In Wireshark, expand the ICMP section in the packet detail pane. Standard ping payloads show a recognisable repeating pattern. Covert payloads show binary data, printable non-alpha characters, or suspiciously uniform high-entropy bytes.
- Filter on payload length anomalies:
icmp.type == 8 && data.len > 64. Legitimate ping rarely exceeds 56 bytes of data; covert tools commonly use 100–1000 byte payloads to maximise throughput. - Use tshark to extract
data.datafields and concatenate across packets ordered by sequence number. Runbytes.fromhex()in Python to decode. Look for ASCII text (shell commands, file contents), PKZIP magic bytes, or other structured content. - Check ICMP identifier consistency:
icmp.identshould be the same value for all packets in one ping session. Multiple different identifier values from the same source IP may indicate different covert sessions running concurrently. - If the payload appears compressed or encrypted, attempt
zlib.decompress()and common ciphers with known weak keys (XOR 0x41, Caesar shifts). CTF covert channels frequently use trivial obfuscation. - Document: source and destination IPs, total packet count, total payload bytes, first and last packet timestamps, payload encoding scheme identified, and any recovered cleartext content.
Common Analytical Errors
- Dismissing all ICMP as benign connectivity checks: Network operators ping things; attackers tunnel through ping. ICMP must be included in every network forensic analysis — filtering it out as "noise" conceals a significant attack vector.
- Checking only Echo Requests: Some tools encode commands in Echo Replies and responses in Echo Requests, reversing the expected direction. Analyse both ICMP type 8 and type 0 payloads.
- Missing fragmented payloads: Large ICMP payloads trigger IP fragmentation. Filter
ip.frag_offset > 0to find fragmented ICMP packets; Wireshark reassembles them automatically, but tshark field extraction may miss reassembled content without-o ip.defragment:TRUE. - Ignoring ICMP types other than echo: ICMP Timestamp (type 13/14) and Information Request (type 15/16) messages are obscure and rarely inspected, making them attractive for covert data embedding. Include all ICMP types in an anomaly review.
- Sequence number ordering errors: Reconstructing the payload by packet arrival order rather than ICMP sequence number produces garbled output. Always sort by
icmp.seqbefore concatenating payload bytes.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0046 | Knowledge of intrusion detection systems and methodologies | Identifying ICMP covert channel signatures that network IDS rules target: payload length anomalies, high packet rates, non-standard data patterns |
| K0093 | Knowledge of network protocols | Understanding ICMP echo message structure, payload field semantics, identifier/sequence number usage, and operating system ping patterns |
| K0221 | Knowledge of OSI model and network layers | ICMP operates at layer 3; understanding how network-layer protocol fields are abused for application-layer data exfiltration |
| S0046 | Skill in performing packet-level analysis | Using tshark field extraction, Python payload analysis, sequence number ordering, and hex decoding to extract covert data from ICMP traffic |
| T0023 | Collect intrusion artifacts for use in forensic analysis | Recovering reassembled covert payload bytes, decoded content, and session metadata as forensic artifacts supporting incident attribution |
Further Reading
- "LOKI2: The Implementation" — Daemon9, Phrack Magazine Issue 51 (1997) — original ICMP covert channel paper
- Network Forensics: Tracking Hackers Through Cyberspace — Sherri Davidoff & Jonathan Ham, Chapter 5: ICMP and Layer-3 Anomalies (Prentice Hall)
- PingTunnel project documentation — modern ICMP tunnel implementation for reference
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.