Browse CTFs New CTF Sign in

Detecting ICMP Covert Channels via Payload Anomaly Identification and Hidden Data Extraction

network_forensics_pcap Difficulty 1–5 30 min certifiable

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

  1. Apply display filter icmp in 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.
  2. 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.
  3. 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.
  4. Use tshark to extract data.data fields and concatenate across packets ordered by sequence number. Run bytes.fromhex() in Python to decode. Look for ASCII text (shell commands, file contents), PKZIP magic bytes, or other structured content.
  5. Check ICMP identifier consistency: icmp.ident should 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.
  6. 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.
  7. 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 > 0 to 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.seq before 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.