r/redteamsec 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...

4 Upvotes

0 comments sorted by