Sunday 10 November 2013

Unmasking a Spoofed MAC Address (CVE-2013-4579)

Update: This vulnerability has been fixed in kernel 3.8.13.16 and above.

Certain Atheros wireless drivers do not properly update the MAC address when changed (spoofed) by a user. This allows an active attacker to retrieve the original MAC address. In short, spoofing your MAC address does not always hide the original MAC address.


Background

While working on the ath9k_htc driver (used by Atheros USB WiFi donglesI noticed the driver did not properly set a spoofed MAC address. Though the device appears to use the newly assigned MAC address correctly, the flaw allows an attacker capable of injecting packets towards the target to uncover the original MAC address.

The cause of the problem lies in how the driver and hardware implement Multiple Virtual Interface (VIF) support. Using this technology a single wireless chip can listen on multiple MAC addresses. Because sending an acknowledgement to correctly received packets is done in hardware, a question that arises is how the wireless chip can quickly determine whether a wireless packet was destined for it. At first you'd think there must be some method to give the hardware a (possibly fixed length) list of MAC addresses to listen on. However, some devices uses a different strategy (and in particular Atheros devices uses this method). Their strategy is the following: the wireless chip has a register which contains the "main" hardware MAC address (mainmac), and a register containing a mask (macmask). Given an incoming frame destined for a particular mac (incmac), it sends an ACK and accepts the frame if and only if: (mainmac & macmask) == (incmac & macmask). You can see that macmask determines which bits of incmask (MAC of the packet being received) have to match those of mainmac. Essentially the macmask represents the locations where the bits of all the virtual MAC addresses are identical to the "main" hardware MAC address (mainmac).

To clarify, consider a device having two virtual interfaces, one with MAC address 72:40:a2:3f:65:5a and another one with address 8e:8e:95:cd:90:4e. In binary these MAC addresses are:
01110010 : 01000000 : 10100010 : 00111111 : 01100101 : 01011010
10001110 : 10001110 : 10010101 : 11001101 : 10010000 : 01001110
Now, macmask should consist of the bits where both these MAC addresses are the same (mathematically that's the negation of the XOR). In our example the mask would be:
00000011 : 00110001 : 11001000 : 00001101 : 00001010 : 11101011
So the wireless chip can pick either 72:40:a2:3f:65:5a or 8e:8e:95:cd:90:4e as its main MAC address, and then set the mask to 03:31:c8:0d:0a:eb. Frames sent to either of these MAC addresses will now be accepted and acknowledged. For more details see the comments in the atheros driver source file. Unfortunately this technique has the side effect that the wireless chipset now listens on more MAC addresses then we really want, as not all bits of incoming frames are checked!

Vulnerability Details

When a MAC address is spoofed the driver does not simply update the mainmac register. Instead the mainmac register will still contain the original MAC address, and macmask will contain the bits where the original and spoofed MAC agree (see previous section). The wireless chip will acknowledge frames sent to the spoofed MAC addresses, and the operating system will include the spoofed MAC address in all packets, so everything will seem to work properly. Unfortunately this method allows an attacker to uncover the original MAC address bit by bit (given the spoofed MAC address). Specifically we can determine the value of any bit of the original MAC address as follows:
  1. Flip the bit in the spoofed MAC address and send a packet to the modified MAC address.
  2. We now have two cases:
    • The device replies with an ACK: This means the mask for this bit is zero, thus the bit in the spoofed MAC address was different than the original MAC address.
    • Device doesn't reply: This means the mask for this bit is one, so the bit we are guessing was identical to the bit in the spoofed MAC
By doing this for each bit, we eventually learn the complete original MAC address.

The vulnerability has been successfully exploited against AR7010 and AR9271 chipsets (which use the ath9k_htc driver) under following operating systems:
  • Debian 7.2.0 amd64 and i386
  • Kali 1.0.5 amd64 and i386
  • Ubuntu 13.10 amd64 and i386
The ath9k driver is not vulnerable (see comments below). The ath5k and ath10k were not tested and/or investigated. Other drivers also capable of creating multiple virtual interfaces with different MAC addresses, on a single device, might also be susceptible to the same vulnerability (so feel free test your device and post results).

Exploit

A proof of concept has been implemented in python using scapy. Given a MAC address that you suspect to be spoofed the tool will attempt to uncover the original MAC address. In case the tool returns the same MAC address as you entered, it means the target is not susceptible to the attack, or that the target is using the default MAC address of the device.

Patch

Update: I have made a patch and submitted it to the linux-wireless@vger.kernel.org mailing list (before this patch I also notified the ath9k-devel mailing list of the bug and filed a bug report for debian). The CVE ID of this bug is CVE-2013-4579.

Final Remarks

Though spoofing a MAC address can be done securely by simply updating mainmac, an attacker can use the same technique to learn that two virtual MAC addresses actually belong to the same user. So if you put up several virtual interfaces (possibly with random MAC addresses) they can be easily linked back together (again, that's if your device uses a method similar to the one described above). This flaw is inherent to usage of macmask and, at first sight, seems difficult to fix.