CVE-2020-16898: Windows ICMPv6 Router Advertisement RRDNS Option Remote Code Execution Vulnerability
Last Updated: 2020-10-15 18:53:05 UTC
by Johannes Ullrich (Version: 1)
- Do not disable IPv6 entirely unless you want to break Windows in interesting ways.
- This can only be exploited from the local subnet.
- But it may lead to remote code execution / BSOD
- PoC exploit is easy, but actual RCE is hard.
For more details, see also the YouTube video I just published:
One vulnerability that got defenders' (including mine) attention this week was CVE-2020-16898. The vulnerability, sometimes called "Bad Neighbor," can be used to execute arbitrary code on a Windows system. To exploit the vulnerability, an attacker has to send a crafted ICMPv6 router advertisement.
What Are Router Advertisements?
I (and probably others) have called them sometimes "DHCP Lite." IPv6 relies less on DHCP to manage IP addresses. After all, we got plenty of them, and the need to "recycle" IP addresses pretty much went away. A router will send router advertisements periodically or in response to a router solicitation sent by a host that just joined the network. All hosts that "speak" IPv6 will listen for router advertisements to learn about the network configuration. Even if you use DHCPv6, you still need router advertisements to know about the default gateway.
One more recently added option includes a list of recursive DNS servers. This "completes" the DHCP-Lite analogy by offering a gateway, IP address(es), and DNS servers. The same data usually found in DHCP servers.
How are recursive DNS servers (RDNSS) encoded in router advertisements?
Router advertisement options follow the standard "Type/Length/Value" format. They start with a byte indicating the type (25 = RDNSS), followed by a byte indicating the length, two reserved bytes, and a 4-byte "lifetime." Plus, of course, the DNS server IP addresses.
As typical for IPv6, the length is indicated in 8-byte increments. So a length of "1" indicates that our option is 8 bytes long. The initial fields (Type, Length, Reserved, Lifetime) are exactly 8 bytes long. Each IP address is 16 bytes long.
For one IP address, our length would be "3". Each additional IP address adds another "2" (2 x 8 Bytes). As a result, the length has to be always odd.
The vulnerability is triggered if the length is even, and larger then 3. For example, consider this packet with a length of "4":
The last eight bytes of the second IP address are no longer included in the length. And this is exactly where Windows gets confused. Wireshark gets a bit confusing, as well:
Wireshark still displays both IP addresses but also recognizes that there is data beyond the option length.
How bad is it?
It is bad in that this allows arbitrary code execution. But an attacker has to be able to send the packet from the victim's network. Even an exposed host can not be attacked from "across the internet," only within a subnet. An attacker will also have to overcome anti-exploit features in Windows 10 (address layout randomization and such), requiring a second information leakage, vulnerability, and exploit.
What can I do?
Patching is probably the simplest, most straightforward solution, which is least likely to cause problems. Other options:
- Microsoft offers the ability to turn off the RDNSS feature as an option. This could, of course, come back to haunt you later as you start using the option.
- Various IDSs have released signatures to detect the attack.
- Some switches offer a "Router Advertisement Guard" feature that can limit router advertisements. Maybe it will help.
- Did I mention that you should get it over with and patch?