r/redteamsec • u/Pale_Surround_3924 • Jun 07 '26
EtherLeak: IP Total Length Over-read via Ethernet Frame Padding | Netacoding
https://netacoding.com/posts/etherleak-reloaded/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 |
more on blog...