Concepts / Denial of service

Denial of service

DHCP starvation

Also called DHCP exhaustion, pool exhaustion, DHCP flooding

Claiming every address in a DHCP pool under forged MAC addresses so no real device can get one.

A DHCP server leases by MAC address and cannot tell a forged one from a real one. An attacker requests a lease again and again, each under a new made-up MAC, until the pool is empty; from then on any device that relies on DHCP joins and gets nothing — a quiet denial of service. Hosts with static addresses are untouched. The lease table fills with unfamiliar MACs in seconds, the tell-tale sign. The real cure is on the switch: port security caps the MACs one port may present and rate-limits DHCP from it, so one port cannot impersonate a hundred clients.

How a DHCP starvation attack works, step by step

A DHCP server (RFC 2131) owns a finite pool of addresses and leases one to each MAC address that asks. It cannot tell a forged MAC from a real one. Starvation drains the pool by asking for lease after lease, each under a fresh made-up MAC, until nothing is left. In the DHCP starvation lab the server leases from 10.0.1.0/27, a pool of nine addresses (10.0.1.22–10.0.1.30); the attacker and the laptops share the LAN.

  1. The attacker forges a MAC. It sets its card to 02:00:00:00:ab:01 and runs the DORA exchange (Discover, Offer, Request, ACK) to claim one lease.
  2. It repeats under new MACs. 02:00:00:00:ab:02, ...:03, and on, each a new identity the server treats as a new device. Every round takes one address out of the pool.
  3. The pool empties. After enough rounds all nine addresses are leased to MACs that do not exist. The server has nothing left to offer.
  4. Real clients are locked out. A genuine laptop sends a Discover, gets no Offer, retries and gives up with no address. With no address it reaches nothing: a quiet denial of service.
  5. Static hosts ride it out. A printer whose address is set by hand never asked for a lease, so the drained pool never touches it, and devices that already hold a lease keep working until it expires.

Starvation is often step one of a bigger attack: drain the real server, then answer as a rogue DHCP server so only the attacker's offers remain.

What it looks like on a Linux machine

The attacker loops, changing its MAC each round and asking for a lease with udhcpc:

$ for i in $(seq 1 16); do
    M=$(printf '02:00:00:00:ab:%02x' $i)
    ip link set eth0 down; ip link set eth0 address $M; ip link set eth0 up
    udhcpc -i eth0 -n -q -t 2 -T 1
  done

On the server the lease table fills with the forged MACs. It is dnsmasq, so the leases live in a file:

$ awk '{print $2, $3}' /var/lib/netlab/dhcp.leases | head -4
02:00:00:00:ab:01 10.0.1.22
02:00:00:00:ab:02 10.0.1.23
02:00:00:00:ab:03 10.0.1.24
02:00:00:00:ab:04 10.0.1.25

A genuine laptop now gets nothing. BusyBox udhcpc prints the failure and the card stays empty:

$ udhcpc -i eth0 -n -q -t 4 -T 2
udhcpc: no lease, failing
$ ip -4 -o addr show eth0 | awk '{print $4}'

The static printer, whose address never came from DHCP, still answers:

$ curl -s http://10.0.1.14/
printer ready

What goes wrong, and how you see it

New devices cannot join, old ones are fine. The signature failure: machines that already hold a lease keep working, while anything new gets no lease, failing and an empty card. The pool is exhausted, not the wire.

A burst of unfamiliar MACs in the lease table. Dozens of leases to addresses like 02:00:00:00:ab:xx, all appearing within seconds and all learned from one switch port, is the tell. grep -c '^02:00:00:00:ab' over the leases counts them.

A link-local 169.254 address appears. A host that gives up on DHCP may self-assign from 169.254.0.0/16 (RFC 3927). That address reaches nothing beyond the wire and marks a DHCP failure.

The switch stops it at the port. Port security caps how many MAC addresses one access port may present and err-disables a port that breaks the limit, so one port cannot pose as a hundred clients; DHCP snooping also rate-limits DHCP per port. The layer 2 security lab shows a port shut for exactly this.

Questions people ask

DHCP starvation vs a rogue DHCP server? Starvation is denial of service: it empties the pool so nobody gets an address. A rogue server hands out poisoned addresses. They combine: starve the real server, then answer in its place.

How many addresses can an attacker take? As many as the pool holds; a /24 has about 254, a /27 only 30. Smaller pools empty in seconds, which is why the lab uses a /27.

Does giving everything a static address fix it? It protects those hosts, as the lab's printer shows, but it does not scale to a whole network. The real fix is on the switch. See DHCP and MAC flooding, its layer 2 cousin.

See it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Open this lab