Adding OpenWrt support for Netgear WNR1000v2

I’ve this router for the sole reason that it is a recommended piece of equipment for doing WiFu, but as as I previously mentioned, it fails to do its job.

In the mean time, I discovered that Netgear released some GPL firmwares which sit at the base of their firmwares. Basically you get a heavily modified OpenWrt Kamikaze (7.09) without a web interface and you need an ancient buildroot. You do have a command line utility for configuring it, but it is painful to do it so. I was unable to configure the WEP support in 1.0.0.5 GPL by using the same config as the 1.0.1.1 is using. Also, moving around the GPL firmware is difficult since there’s no vi support in busybox, but there’s a tftp client and cat.

The device itself is EOL, therefore the idea of using OpenWrt came up. I tried the generic AP81 build, as described here, but it corrupts the rootfs. The device boots in failsafe mode where you may flash a good firmware by using a TFTP client, therefore on the recovery side is good.

On the WikiDevi page for WNR1000v2 it is stated that it is using the same hardware as WNR612v2, but the WNR612v2 router has only two LAN ports, while WNR1000v2 uses four. WNR612v2 itself uses hardware close to WNR2000v3 and both of these are supported by OpenWrt.

Flashing a WNR612v2 firmware, both factory and OpenWrt is impossible with the default images. The Netgear flashing support checks for the presence of a “magic number” in the firmware file. The procedure for finding that “magic number” is totally undocumented, therefore I made a lot of wrong turns. I used the WNR612v2 “magic number” which is declared in OpenWrt, 0x32303631, and started to examine the firmware file. A quick grep confirmed that the byte sequence is present. Dumping the header of the file also confirmed it.

I repeated the procedure with the GPL firmware which I built for WNR1000v2 and with a factory firmware. It turns out that the magic number is: 0x31303031.

wnr1000v2-magic-number

The rest of the work for adding WNR1000v2 support to OpenWrt was fairly straightforward after that as I used WNR2000v3 and WNR612v2 as template.

The rfkill and the WPS buttons don’t work at all. I don’t use WPS anyway, therefore for me is a non-issue. The lack of rfkill support may be a mild annoyance, but since this is my first router that actually has a button for toggling the wireless, doing it the usual way isn’t a big deal for me. I think the buttons may be controlled by GPIO, but I’m not sure and probably I’ll check this when my schedule allows it.

The patch and images are available into this Gist. The patch was made against the Barrier Breaker branch, r43617. The procedure for building your image if you don’t want to use my own image is described into the README.

I guess the next step is to add this support into the OpenWrt trunk, but I need to see if somebody is willing to merge the changes for supporting this device. I’ll need to test the patch and build more since the first merge with quilt wasn’t without issues. The purpose is to obtain a clean build in a single run.

wnr1000v2-openwrt

Forging an 802.11 beacon frame

Let’s assume the following use case: you’ve gathered enough frames containing a valid WPA handshake, but you missed the mgt frame containing the ESSID. If it happens to know the ESSID, but the AP doesn’t broadcast it, and you don’t have the patience to wait for another frame (assuming the attack is fully passive), you may forge a mgt frame. I picked a beacon frame as the structure is simple and it’s easy to please aircrack-ng and Hashcat with it.

As the file used by the above mentioned brute-forcing tools is a capture file, you need to forge:

  • A radiotap header
  • A 802.11 MAC header
  • The frame body containing the ESSID information
  • Optionally: the FCS (frame check sequence)

I haven’t found an easy method for computing the FCS and the cracking tools don’t require a valid FCS.

For creating a capture file from the byte representation itself, you need a tool which is part of the Wireshark suite: text2pcap. Also you need the od and xxd tools for manipulating the hex representation of the bytes in order to please text2pcap.

Any radiotap header may be used. Here’s a forged one:

00 00 27 00 2b 40 08 a0 20 08 00 00 00 00 00 00
00 00 00 00 00 00 00 00 10 00 6c 09 80 04 FF 00
00 00 00 00 00 FF 00

It translates to the following information:

forged-radiotap-header

The next part is the 802.11 MAC header:

80 00 00 00 FF FF FF FF FF FF AA BB CC DD EE FF
AA BB CC DD EE FF 10 00

This image explains the structure of the 802.11 frame:

802.11-frame

Address 4 is in use only in WDS, therefore not present in this header. The DS status is 00 in the frame control field, therefore the Address 1 field is the DA (ff:ff:ff:ff:ff:ff – the beacon frames are broadcasted), the Address 2 field is the SA, and Address 3 field is the BSSID (aa:bb:cc:dd:ee:ff -a forged MAC address for the purpose of demonstrating the concept). In this particular case, SA and BSSID is the same for obvious reasons. The last field is the sequence control which in this case indicates the fragment number 0 and the sequence number 1.

The frame body needs to contain the minimum information for the ESSID to be picked up by aircrack-ng.

You need 12 bytes for the fixed parameters field:

00 00 00 00 00 00 00 00 60 EA 11 04

Which translates to the following information:

frame-body-fixed-parameters

The next (and last) field is required for indicating the ESSID. It requires a variable number of bytes:

  • 1 byte for the tag number. 0 = SSID parameter set
  • 1 byte for the tag length. 0x00 – 0x20 range
  • 0 – 32 bytes for the SSID field – the number of bytes indicated by the previous field, encoding the ESSID string

An easy method for generating this field is to use echo and hexdump:

echo -n "foobar" | hexdump
0000000 66 6f 6f 62 61 72
0000006

You get in the output the encoded bytes for the ESSID and the length on the second line, which means that the tagged parameters field of the frame body is:

00 06 66 6f 6f 62 61 72

Putting all of the above knowledge into practice:

cat forged-beacon.txt
00 00 27 00 2b 40 08 a0 20 08 00 00 00 00 00 00
00 00 00 00 00 00 00 00 10 00 6c 09 80 04 FF 00
00 00 00 00 00 FF 00 80 00 00 00 FF FF FF FF FF
FF AA BB CC DD EE FF AA BB CC DD EE FF 10 00 00
00 00 00 00 00 00 00 60 EA 11 04 00 06 66 6f 6f
62 61 72
cat forged-beacon.txt | xxd -r -p | od -Ax -tx1 -v | \
text2pcap -l 127 - forged-beacon.cap
Input from: Standard input
Output to: forged-beacon.cap
Output format: PCAP
Wrote packet of 83 bytes.
Read 1 potential packet, wrote 1 packet (123 bytes).

You may check the capture with Wireshark. It should complain about the fact that the packet is malformed. You may ignore this error, or copy the computed FCS (0x954d6a59) and append the bytes to the forged-beacon.txt file.

Merging the capture with a previous capture containing the EAPOL messages is as simple as:

mergecap -a -F pcap -w handshake.cap forged-beacon.cap no-essid-eapol.cap

Capturing WPA handshakes with OS X

Fortunately, the wireless card from Apple’s hardware supports the monitor mode. Unfortunately, the aircrack-ng suite has only partial OS X support. That means: placing the card in monitor mode requires other methods as airmon-ng doesn’t know how to do it, you can’t capture wireless traffic with airodump-ng, most probably the drivers don’t support packet injection. No packet injection means no deauthentication, therefore you need to be patient as this attack is fully passive. However, you can use aircrack-ng to test that a capture has all the needed bits and pieces.

It requires arcane methods, getting out of the comfort zone, and going the extra mile you usually don’t find in courses talking about wireless security. Yes, you need to go MacGyver on this with tcpdump. This article is more about the research done in order to figure out the internals than actually doing pen testing with a Mac. But if the situation requires it and if you need to peek at 802.11ac traffic (the newer models, mid 2013+, have ac enabled hardware), this is valuable knowledge.

The first tool you need is aiport, which is a small utility hidden in Apple80211 private framework. I made a symlink in /usr/local/bin for easier invocation. In 10.9 it can be found here: /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport

While airport itself can sniff traffic, it dumps all of the captured traffic. As I found out, parsing a 100 megs capture takes a while, and this capture size isn’t uncommon for a busy network. Therefore, for the purpose of capturing WPA handshakes its usage is restricted to disassociation from the network and setting an arbitrary channel for the wireless interface. You need to disassociate from the AP as taking en0 out of monitor mode reconnects the network and resets the channel setting.

# disassociate from the AP
sudo airport -z
# set an arbitrary channel, notice the lack of space between the flag and the value
sudo airport -c10
# check the channel
airport -c
channel: 10

You need a tool for capturing traffic. An up to date tcpdump or tshark may fill that role. The tcpdump that comes with OS X is too old to play nice. It is recommended to install tcpdump and mandatory to install wireshark. Both are available as brew recipes.

Either of the above tools have the -I (that’s capital I not l) flag for placing the wireless interface into the monitor mode. The functionality is actually part of libpcap. In order to keep the captures to minimum, you need two runs for gathering the required information.

# capture a beacon frame from the AP
tcpdump "type mgt subtype beacon and ether src $BSSID" -I -c 1 -i en0 -w beacon.cap
# wait for the WPA handshake
tcpdump "ether proto 0x888e and ether host $BSSID" -I -U -vvv -i en0 -w eapol.cap

$BSSID = The MAC address of the AP. tcpdump may be replaced with tshark -f in the above lines if you take out -U -vvv and use -V instead. tcpdump’s -U is tshark’s -l. Read the corresponding manuals for more information.

Usually you have to wait until the 0 from the tcpdump output changes to 4, but you don’t need all the frames of a four-way handshake in order to pass the capture to aircrack-ng. If there are captured packets, you may want to inspect them with Wireshark. Sometimes the frames aren’t captured as they are missed by the wireless interface. For cracking the passphrase you need two frames at minimum: either “Message 1 of 4″ and “Message 2 of 4″, or “Message 2 of 4″ and “Message 3 of 4″, as shown in the Info column in Wireshark. You may need to export specific packets from Wireshark in another capture. Mark the packets, then File > Export Specified Packets.

If the correct frames are captured, you may terminate the tcpdump process with Ctrl+C.

aircrack-ng needs a management frame containing the ESSID (beacon, probe response, association request, or reassociation request) and two data frames containing the EAPOL messages as mentioned above. The EAPOL messages are encapsulated in qos-data frames (a subtype of the data frames). You need to merge the beacon.cap and the eapol.cap captures.

mergecap -a -F pcap -w handshake.cap beacon.cap eapol.cap
aircrack-ng -w /path/to/wordlist handshake.cap

You need a probe response (subtype proberesp) for the networks that don’t broadcast their ESSID in beacon frames. You may combine this as a single capturing filter for getting both type of frames in a single run when the WPA handshake occurs. This won’t work for AP’s that broadcast their ESSID as the capture will contain a lot of useless packets. Of course, you may use either this method or the beacon method, but the capture parsing is slowed by the sheer size of the capture in this case.

tcpdump "(type mgt subtype proberesp or ether proto 0x888e) and ether host $BSSID" \
-I -U -vvv -i en0 -w hidden-handshake.cap

It may capture more than one probe response when the handshake happens. You may need to investigate with Wireshark or do an aircrack-ng test run against the capture to check that the capture is usable.

Another source for the ESSID value is to listen for association request frames (subtype assocreq) or reassociation request frames (subtype reassocreq) in order to fetch the ESSID. You may wait for a reassociation request if you got the handshake of a network with hidden ESSID, but you’ve missed the relevant mgt frame.

Waiting however for an association request is a method for combining all of the above knowledge in one capturing filter that works for both hidden and non-hidden networks. It also contains the minimum number of captured frames by using a single filter.

tcpdump "(type mgt subtype assocreq or ether proto 0x888e) and ether host $BSSID" \
-U -vvv -i en0 -w handshake.cap

I also tested that the captures work with Hashcat by converting them to the HCCAP format with cap2hccap. Building cap2hccap under OS X requires a small patch for MAX_BUFF. You need to change this:

#define MAX_BUFF (PATH_MAX)

into this:

#define MAX_BUFF (1024)

How to create a wireless pen testing lab

In my previous rant I was telling how notoriously difficult is to get the right hardware. If you get an AP for this reason, chances are it wont work as expected. Finding information about various models is next to impossible.

My solution is: get a bunch of USB adapters, then use virtual machines. You need a hypervisor with proper USB passthrough support though. Unfortunately, VirtualBox won’t cut it.

Hypervisor recommendations: VMware Player (Windows, Linux), KVM (Linux, untested for this particular setup), VMware Fusion (OS X), Parallels Desktop (OS X, untested for this particular setup). Unfortunately, for OS X there’s no free/freeware product with proper USB passthrough support. Bear in mind that virt-manager makes things easier for KVM under Linux. This brings KVM close to the usual desktop solutions.

I use three virtual machines with three USB adapters, but at minimum you need two VM’s and two adapters if you don’t need remote connectivity to your lab. The wireless client might be any device if you’re near the machine (phone, tablet, etc). The adapters that you need to use for monitor mode and wireless client may need to have removable antennas.

The AP VM

I found out that an adapter with AR9271 proved to be the best choice for the AP VM. That is, from my collection of USB adapters. For example, I use a TP-LINK TL-WN722N. It is inexpensive and easily available. I mounted the antenna on the AP adapter.

For the VM itself, I use Ubuntu 14.04 with hostapd and dnsmasq. I removed the network-manager package and configured the wired interface by editing the /etc/network/interfaces file.

I placed the hostapd configuration in /etc/hostapd/hostapd.conf:

interface=wlan0
driver=nl80211
ssid=wifu
hw_mode=g
channel=3
macaddr_acl=0
ignore_broadcast_ssid=0

# WEP config
# 1 = open
# 2 = psk
# 3 = both
auth_algs=1
wep_default_key=0
wep_key0=AABBCCDDEE

# WPA config
# 1 = WPA
# 2 = WPA2
# 3 = both
#wpa=2
# TKIP = WPA
# CCMP = WPA2
# TKIP CCMP = both
#wpa_pairwise=CCMP
#wpa_passphrase=password

This configuration is for WEP with open authentication. The comments help you to use this as a template for configuring WEP with PSK, WPA, or WPA2. If you comment the WEP config and uncomment the WPA config, it will default to WPA2.

The dnsmasq config was placed in /etc/dnsmasq.conf:

# disables dnsmasq reading any other files like /etc/resolv.conf
no-resolv
# Interface to bind to
interface=wlan0
# Specify starting_range,end_range,lease_time
dhcp-range=10.0.0.3,10.0.0.27,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

For starting the AP, I use this script:

#!/bin/bash
#Initial wifi interface configuration
ifconfig $1 up 10.0.0.1 netmask 255.255.255.0
sleep 2
 
###########Start dnsmasq, modify if required##########
if [ -z "$(ps -e | grep dnsmasq)" ]
then
 dnsmasq
fi
###########
 
#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $2 -j MASQUERADE
iptables --append FORWARD --in-interface $1 -j ACCEPT
 
sysctl -w net.ipv4.ip_forward=1
 
#start hostapd
hostapd /etc/hostapd/hostapd.conf
killall dnsmasq

I placed it into a $PATH directory. Invoke it with:

sudo initSoftAp wlan0 eth0

The script runs in foreground. It can be easily killed with Ctrl+C. You may easily observe the hostapd log messages for debugging reasons. The subnet for this lab AP is different than the subnet used by the eth0 interface of the VM. It’s irrelevant if the VM itself uses NAT or bridge for its “wired” interface.

The monitor mode VM

I use an ALFA AWUS036H simply because I have it. It uses the RTL8187L chipset which is old, but well supported. You may pick any adapter that properly supports packet injection. I started a project to document this. I call it aircrack-db as I use the aircrack-ng suite for testing the wireless interfaces capabilities.

I took down the antenna of this adapter because of the receiver saturation. It is too close to the AP and using long USB cables isn’t feasible in my case. Taking the antenna down and placing the cards apart at about half a metre provides the best results. The aircrack-ng FAQ explains this: Why do I have bad speeds when i’m too close to the access point? If you keep the antenna, you may see good quality signal (PWR -19 or so), but the RXQ shows that something is wrong. Most of the time, this setup is going to be useless, therefore only the AP or the attacking card needs to have the antenna, or place them far away from each other.

For the VM itself I use Kali 1.0.9a (aka the latest, up to date, version). You may also remove network-manager from this machine and configure eth0 via /etc/network/interfaces. The network-manager usually is troublesome together with the aircrack-ng suite. In my case, “airmon-ng check” returns nothing.

The STA VM

This is optional if you don’t need remote connectivity to the wireless pen testing lab. If you do, this is my setup.

I use an ALFA AWUS051NH simply because I have it. I also use a Netis WF2190 from time to time. This adapter doesn’t need to support monitor mode. It just needs to act as a wireless client in order to test various scenarios where an associated STA to the AP is required, or if you target an unassociated client with airbase-ng.

I use Ubuntu 14.04 and that’s pretty much it. It doesn’t need any modifications as the network-manager is actually useful in this case. Sometimes, the AP disappears after repeated deauth attacks. If this happens, you need to uncheck “Enable WiFi” from the network manager menu, and then enable back the WiFi.

If the AP adapter has its antenna, then take down the antenna of the wireless client adapter. The receiver saturation in this case means really erratic behaviour such as connections timeouts to the AP or really slow association.

Reproducing KoreK’s ChopChop attack is a pain in the ass

Well, getting a Netgear WNR1000v2, one of the recommended access points by WiFu, was also a pain in the ass since the product is EOL. Imagine my surprise when I couldn’t reproduce this particular attack as the AP was not dropping properly the packets with invalid ICV.

I started to dig for some information. The product that I got was so old that basically was one of those unsold units. It came with the only firmware still available on Netgear’s support site that features WEP support. Actually, the only one who mentions this product in relation to WiFu is Samiux. WNR1000v2h2 is basically a WNR1000v2, but with internal antenna.

The things that I tried, but utterly failed

I tried the Netgear WNR1000v2 AP with firmware versions 1.0.1.1 (the version that was installed on it), 1.0.1.1NA (basically the same as previous, but region locked to USA, so it would stick to FCC’s emission regulations), and 1.1.2.28 (does not feature WEP support).

I dug up my retired ASUS WL-500g Premium. Tried the attack with the following firmwares: OpenWrt 12.09 (built the attitude_adjustment branch myself few months ago due to unstable b43 driver at the time of the 12.09 release), OpenWrt 10.03 brcm-2.4 (Linux 2.4.40, Broadcom STA / wl driver), and the first available factory firmware on ASUS’ support site, v1.9.6.9. Neither of them worked. OpenWrt 12.09 and the factory firmware created the illusion that it works, only to fail few seconds later.

I also tried to create a basic soft AP using hostapd. In reality, not all the drivers and hardware are the same. While it theoretically supports the nl80211 library in order to talk to devices that use mac80211 drivers, only some of the chips that support master mode can actual create a working AP.

My first try was a proof of concept on a piece of Raspberry Pi, but it didn’t work as I was using my portable stuff instead of the toys that stay at home in my proper Wi-Fi lab. I tried to create an AP using Unex DNUA-93F, powered by AR9271, but I had nothing to test it with. While Kali works on VirtualBox / OS X, the USB support is spotty at best and this card is the only one that can be used with a certain degree of reliability. So I had to switch to an ALFA AWUS051NH, powered by RT2770. I could get reliable packet injection starting from a fragmentation attack, but no dice with ChopChop.

In my home lab I tried to create a proper soft AP on a machine which runs Kali, but as previously mentioned, not all the hardware is the same. I tried to create an AP with the legendary ALFA AWUS036H, powered by RTL8187. For some reason, hostapd won’t start with this card if WEP is in use. Running hostapd with -dd added more confusion, hence I switched to the built in wireless interface, an AirForce One 54g, powered by BCM4318. The AP was created successfully, but every connected client wouldn’t finish the authentication and the log was flooded with “wlan0: STA […] did not acknowledge authentication response”. Which was odd as WL-500gP has the same Mini PCI card in it.

What finally worked

I created a soft AP using a TP-LINK TL-WN722N, powered by AR9271 (same as Unex DNUA-93F). For the internet connectivity I used the built in AirForce One 54g to connect to my actual AP.

For the configuration I used the information posted by nims11’s article about how to create a soft AP, but I used dnsmasq as DHCP server because dhcpd was being a pain in the ass (you can see a pattern here).

The hostapd config in /etc/hostapd/hostapd.conf:

interface=wlan2
driver=nl80211
ssid=wifu
hw_mode=g
channel=3
macaddr_acl=0
ignore_broadcast_ssid=0
auth_algs=1
wep_default_key=0
wep_key0=AABBCCDDEE

The dnsmasq config in /etc/dnsmasq.conf:

# disables dnsmasq reading any other files like /etc/resolv.conf
no-resolv
# Interface to bind to
interface=wlan2
# Specify starting_range,end_range,lease_time
dhcp-range=10.0.0.3,10.0.0.20,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

The initSoftAP for starting up the stuff:

#!/bin/bash
#Initial wifi interface configuration
ifconfig $1 up 10.0.0.1 netmask 255.255.255.0
sleep 2
 
###########Start dnsmasq, modify if required##########
if [ -z "$(ps -e | grep dnsmasq)" ]
then
 dnsmasq
fi
###########
 
#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $2 -j MASQUERADE
iptables --append FORWARD --in-interface $1 -j ACCEPT
 
sysctl -w net.ipv4.ip_forward=1
 
#start hostapd
hostapd /etc/hostapd/hostapd.conf
killall dnsmasq

Started it with ./initSoftAp wlan2 wlan0 (under root, obviously). I did the double-NAT over Wi-Fi because I was too lazy to add another patch cable over the already crowded desktop. Otherwise, it would be ./initSoftAp wlan2 eth0.

I booted up my desktop machine, started Kali in a VirtualBox VM, and made the ALFA AWUS036H to be available inside the VM. Did the usual drill (airmon-ng, airodump-ng, etc). I had to keep the antennas about 1.5 meters apart due to their radiation pattern.

I used my phone as testing client. I could browse the ‘net and I got the 10.0.0.3 IP via DHCP, as instructed by dnsmasq. The ChopChop attack was running in unauthenticated mode, but the packets fetched from the phone as client were not usable. In fact, I don’t recall getting usable packets in unauthenticated mode.

I fired up another instance of aireplay-ng running fake auth and retried the ChopChop attack in authenticated mode. The first captured packet was a winner. Bam! I got the plaintext capture and the PRGA / xor file. Few minutes later, after creating an ARP packet with packetforge-ng and injecting it via interactive packet injection, I managed to crack the WEP key, therefore successfully completing the ChopChop challenge.

The end

It took me two long days, but I did learn a lot. I think the WiFu lab can be reduced to my desktop machine, running a couple of VirtualBox VMs (one for Kali, one for a soft AP), two Wi-Fi USB adapters, and a wireless client to play the victim role. This can be either a phone, a tablet, a notebook (this may be the host machine for VirtualBox and the victim), or another VM plus another USB adapter. I think hunting for old hardware for this course is a flawed idea. Sure, ALFA AWUS036H may be used after finishing this course, but the AP is going to be virtually useless.