Sunday, 30 September 2012

Compat-Wireless Injection Patch for Aircrack-ng

Update: Compat-Drivers Patch

28 may 2013: My previous patch for compat-drivers was incomplete. The new patch for compat-drivers works for both the 3.8 and 3.9 versions. It will make monitor mode, injecting, changes channels, and fragmentation working properly. Before continuing make sure you have the linux header installed. If not, execute:
apt-get install linux-headers-$(uname -r)
Once the headers are installed, the following commands will download the latest compat-drivers version and apply the updated patch:

Quickstart: Compat-Wireless Patch

To get monitor mode, injecting, changing channels, and fragmentation properly working I recommend downloading the latest stable compat-wireless 3.6 package and applying my patch. This can all be accomplished by executing these commands and then rebooting:

The issue where you aren't able to change channels should be fixed for all drivers, and the ability to inject QoS headers is also fixed for all drivers. An issue specific to the RTL8187 driver used by AWUS036H and AWUS036NH that prevents a successful fragmentation attack is also fixed by my patch.

Background Behind the Patch

Normally when working with the aircrack-ng tool suite or other wireless network tools under linux, it's recommended you use the latest compat-wireless package to get access to the latest drivers. Generally the thought is: the newer the drivers, the better they work. Unfortunately this isn't always true.

First it's good to have a basic understanding of what compat-wireless and compat-drivers offers. Essentially you can think of compat-wireless (in fact, you should) as a sized-down version of the kernel tree, one that contains only the sources of the wireless drivers and the wireless stack. Therefore, you can apply any wireless-related patches to it and recompile them without having to recompile the whole kernel [quoted aircrack-ng docs]. So really it's a backport of the latest drivers so they can be used in older kernels. To make your life more difficult [1] the compat-wireless project has recently been renamed to compat-drivers, and now again seems to be renamed to "backports".

My own problems started when I was working on a few vulnerabilities I found in WPA-TKIP (I found a few bugs that prevented from packets being injected properly). To fix these I first looked at some of the existing patches available from the aircrack-ng directory. But no luck there, and nothing posted on the forum helped either. After messing around I managed to patch the driver myself. But what wasn't working? Well there were three main bugs I encountered:
  1. Unable to change the channel of the monitor interface with the error message "SET failed on device mon0 ; Device or resource busy.".
  2. When injecting packets the Quality of Service (QoS) header was being overwritten by the driver.
  3. Injecting fragments was not working properly. Only the first fragment was being transmitted.
I played around with various configurations and version to see if some of them didn't have these problems. Unfortunately with everything I had problems. In particular I tried the following three things:
  • Backtrack 5 R3: Changing channels worked, but the Quality of Service (QoS) header was overwritten, and when using fragmentation only the first fragment was transmitted.
  • Compat-wireless 3.6 stable: All three problems were present (can't change channel, QoS overwritten, fragmentation not working).
  • Latest snapshot of compat-drivers: All three problems were present.
At one point I also tried using Backtrack 4 with an older release of compat-wireless. But that one also had bugs. Bugs, fucking bugs everywhere. I gave up finding a decent configuration and decided to patch the drivers myself.

Changing Channel

I fixed this bug by commenting out two lines in the function cfg80211_set_monitor_channel of ./net/wireless/chan.c file:
//if (!cfg80211_has_monitors_only(rdev))
//        return -EBUSY;
It appears we couldn't change the channel when "normal" virtual interfaces are also using the device. Looking at the commit history I found the specific commit mentioning this: "having .set_monitor_channel work with non-monitor interfaces running would make interface combinations accounting ambiguous". So the new drivers prevent you from changing the channel if the device is also being used "normally". Practically this means that (if you don't apply my patch) you need to disable them by executing "ifconfig wlanX down" until you only have monitor interfaces over.

However disabling them all the time is annoying, and not many people know this! That's why I decided to remove this check in my patch. Most of the time if you're playing with monitor mode you're not using the device in a normal mode anyway, so this shouldn't be a problem. For the compat-drivers the file ./net/mac80211/cfg.c in function ieee80211_set_monitor_channel also needs to be changed:
} else /*if (local->open_count == local->monitors)*/ {
This again disables the check that only monitor interfaces are allowed to be present. I also found a post on the aircrack-ng wiki explaining how to install the latest compat-wireless and compat-drivers packages. That post discusses an older problem and its solution. So if you tried that one and it failed, try my patch again.

Sending Raw QoS Header

The QoS header is modified in the function ieee80211_set_qos_hdr of ./net/mac80211/wme.c and is called from ieee80211_xmit in ./net/mac80211/tx.c. We simply have to prevent this call from happening in monitor mode.
// Don't overwrite QoS header in monitor mode
if (likely(info->control.vif->type != NL80211_IFTYPE_MONITOR)) {
        ieee80211_set_qos_hdr(sdata, skb);
This kills the bug. As a side node the "likely" macro is used for branch optimization by the compiler.

Patching Fragmentation

This one turned out to be specific to some devices. My patch is for the AWUS036H and AWUS036NH using the RTL8187 driver. The problem is that it will only transmit the first fragment. I did a simple test to further isolate the issue by instructing to driver to send the following frames (from a userland program):
  1. Send the first fragment
  2. Send an ARP request packet
  3. Send the second fragment, which is the last one
It turned out the device actually transmits the ARP request packet first, and only then sends the first fragment! So the hypothesis was that it's first waiting for ALL the fragments before it begins sending them. Furthermore it would only send the next fragment once the previous one has been acknowledged (which isn't detected in monitor mode, hence only the first fragment is transmitted).

Luckily this can easily be fixed by removing the RTL818X_TX_DESC_FLAG_MOREFRAG flag that is being passed to the device (firmware). It will then immediately transmit the fragment. So the patch is at ./drivers/net/wireless/rtl818x/rtl8187/dev.c in the function rtl8187_tx:
// When this flag is set the firmware waits until ALL fragments have
// reached the USB device. Then it sends the first fragments and waits
// for ACK's. Of course in monitor mode it won't receive these ACK's.
if (ieee80211_has_morefrags(tx_hdr->frame_control))
      // If info->control.vif is NULL it's mostly likely in monitor mode
      if (info->control.vif != NULL && info->control.vif->type != NL80211_IFTYPE_MONITOR) {
            flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
And hurray, that fixed the last bug =)

[1] It's annoying because most tutorials will reference older compat-wireless releases. Also finding the proper links on the new compat-drivers website is annoying.


  1. I do like very much your posts. I have never written anything here, but thanks for sharing, and please delight us more often! ;) Greetings from Spain.

  2. Thanks for the comment! =) Only time will tell whether more blog posts are possible time-wise though.

  3. I appreciate your post. I've tried a lot to understand all those stuffs before reading a lot of wikis, docs and how to, but looks like all of then are outdated. So I started like you trying to patch the rtl8187 by myself looking old patches from aircrack, but I had only a partial success because I can use the monitor mode, but normal mode doesn't work correctly.
    I'll try your way right now and I hope it can helps me.
    I would like to thank you very much for your work, that I really know that weren't easy!
    Thks very much and keep on going. :)
    Best Regards from Brazil (Rio)

  4. Funciona para la AWUS036NH en Linux Mint 13

  5. All three hunks already fail on 3.6.2-1. Bad practice but add the --ignore-whitespace option to patch and it all should succeed. great work. thanks for the update, I'm gonna test it out now.

  6. @Mike I tested the 3.6.2-1 versions and patching went without any problems (on Backtrack 5 R3). Now I'm wondering why it works for me but not for you. Anyway links in the blog post have been updated to 3.6.2-1.

  7. The commands to download & update the driver contained a few errors (wrong filenames). It has been fixed and works again.

  8. Hello,

    Nice Article! I was able to patch the current compat-wireless (2012-12-02) with your patch and the patches for zd1211rw from

    patch -Np0 < ../wireless-patches/zd1211rw-inject+dbi-fix-2.6.26.patch
    patch -Np0 < ../wireless-patches/zd1211rw.patch

    This two patches were needed to get Injection to work with my Sitecom WL-113 Stick.

    Now it works on Ubuntu 12.10 without any trouble at all. WEP cracked using ARP Mehtod in under 5 minutes!

    Thanks again!

  9. Hi, with my AWUS036NHR (genuine) I can't get any wpa handshake; I can deauth without any problems but all wifi clients show up in airodump-ng as being 'not associated' .

    I tried using beini 1.2.3 and the drivers included don't exhibit this behavior, however I'm unable to reproduce the results; every compat-wireless/compat-drivers snapshot/stable release I tried has this bug.

    I read somewhere that it could be related to some unicast packets being filtered out from the driver, however I can't wrap my head around this; I'll try to ask to beini maintainers but have little faith.... could you please test it out/help in any way ?

    Thank you in advance!

  10. I have a similar problem with AWUS036H on Linux Mint 14. deauth works but can't capture handshake.

  11. Hi, I have in VMware Backtrack 5r3 running. My AWUS036H is not working with mdk3 as expected. It shuts the network down while it was sending packets (mdk3 mon0 b -n Pwned). Therefore I was looking for way to update the driver. Reading I found your blog and decided to follow your instructions.

    I get errors during make. Can you please help me?

    [email protected]:~/compat-wireless-3.6.2-1-snp# patch -p1 < compatwireless_chan_qos_frag.patch
    patching file drivers/net/wireless/rtl818x/rtl8187/dev.c
    patching file net/mac80211/tx.c
    patching file net/wireless/chan.c
    [email protected]:~/compat-wireless-3.6.2-1-snp# make
    ./scripts/ /root/compat-wireless-3.6.2-1-snp/.config /root/compat-wireless-3.6.2-1-snp/ > include/linux/compat_autoconf.h
    make -C /lib/modules/3.2.6/build M=/root/compat-wireless-3.6.2-1-snp modules
    make[1]: Entering directory `/usr/src/linux-source-3.2.6'

    WARNING: Symbol version dump /usr/src/linux-source-3.2.6/Module.symvers
    is missing; modules will have no dependencies and modversions.

    /lib/modules/3.2.6/build/.config:1: *** missing separator. Stop.
    make[1]: *** [_module_/root/compat-wireless-3.6.2-1-snp] Error 2
    make[1]: Leaving directory `/usr/src/linux-source-3.2.6'
    make: *** [modules] Error 2

    1. I found the way to get it running (sorry).

      [email protected]:~# cat /proc/version
      Linux version 3.2.6 ([email protected]) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #1 SMP Fri Feb 17 10:40:05 EST 2012
      [email protected]:~# prepare-kernel-sources
      [*] Kernel source seems to be available
      scripts/kconfig/conf --silentoldconfig Kconfig
      CHK include/linux/version.h
      CHK include/generated/utsrelease.h
      CALL scripts/
      [*] tada!
      [email protected]:~# cd /usr/src/linux
      [email protected]:/usr/src/linux# cp -rf include/generated/* include/linux/

      [email protected]:/usr/src/linux# cd ~/compat-wireless-3.6.2-1-snp
      [email protected]:~/compat-wireless-3.6.2-1-snp# make
      make -C /lib/modules/3.2.6/build M=/root/compat-wireless-3.6.2-1-snp modules
      make[1]: Entering directory `/usr/src/linux-source-3.2.6'

      WARNING: Symbol version dump /usr/src/linux-source-3.2.6/Module.symvers
      is missing; modules will have no dependencies and modversions.

      CC [M] /root/compat-wireless-3.6.2-1-snp/compat/main.o
      CC [M] /root/compat-wireless-3.6.2-1-snp/compat/compat-3.3.o
      CC [M] /root/compat-wireless-3.6.2-1-snp/compat/compat-3.4.o
      CC [M] /root/compat-wireless-3.6.2-1-snp/compat/compat-3.7.o
      /root/compat-wireless-3.6.2-1-snp/compat/compat-3.7.c: In function ‘pcie_flags_reg’:
      /root/compat-wireless-3.6.2-1-snp/compat/compat-3.7.c:37: warning: passing argument 1 of ‘pci_find_capability’ discards qualifiers from pointer target type

  12. On Arch Linux, latest stable kernel (3.8.4) it's not working with any dompat-drivers-3.8* package with your patch. (Patching ending with success) After all (driver-select iwlwifi, make install && reboot) sitll got fixed chan -1. Do you have any solution ?

  13. Much thanks for your work, but still one question...

    Is the compat-drivers-3.8-1-u.tar.bz2 file with the related patch compatible with any 3.8 kernel versions, or specific to a 3.8 kernel, and hypothetically with kernel 3.9-rcx kernel ???

    I'm asking because at the moment I use a kernel 3.9-rc3 which works fine with my Terratec 2400I DT PCIe double tuners TV TNT. Kernel below 3.9-rc2 won't work with it.

    I'm working on a custom 3.8.2 kernel (from Ubuntu) for it to work with my Terratec... ^^


    make-C / lib/modules/3.8.2-030802-generic/build M = / home/alex751/Desktop/123 modules
    make: *** / lib/modules/3.8.2-030802-generic/build: No such file or directory. Stop.
    make: *** [modules] Error 2

    I'm trying to do it in 3 days

  15. Hi, how can i uninstall your patch? i try with "sudo make uninstall" but it doesn't work. please help.

  16. make-C / lib/modules/3.8.2-030802-generic/build M = / home/alex751/Desktop/123 modules
    make: *** / lib/modules/3.8.2-030802-generic/build: No such file or directory. Stop.
    make: *** [modules] Error 2

    cd /usr/src/linux
    cp -rf include/generated/* include/linux/
    ln -s /usr/src/linux /lib/modules/
    apt-get install linux-headers
    ln -s /usr/src/linux-headers- /usr/src/linux-source-

    (change to your kernel version)

  17. Great post... I was despairing using rtl8187 from compat-wireless and the adapter being stuck on channel 1... any attempt to change channel gave the dreaded device busy error (now I know: return -EBUSY!!!) This patch helped, now I can change channels! Thanks a lot!!!

  18. Hi Mathy,

    Great post!.
    I've been using the AWUS036NH on BT5R3 for a while now, it works out of the box with the default drivers, however it feels like im not getting the most out of the adapter.
    Ive been tuning and tweaking different things but not to much avail.

    I'm also curious on your opinion on recompiling an edited db.txt in to a new regulatory.bin, my findings up until now are that it doesnt make ANY difference weither it uses the EU default 20dbm or 33dbm from the new regulatory.bin results are the same and seem to be actually determined by the hardware, the change thus, seems to be purely cosmetic!.

    Furthermore i found that pwr rqx etc where rather on the low side for an AP that was sitting 1 room away, ive also encountered the clients not associated to any app bug. in short, its all rather buggy and flakey.

    Google led me to your page and your patch, which made me jump up in joy, as it seems to fix the things i was looking for.
    But alass, i can not seem to get it to work. As some people stated above already, i always encounter the "Fixed Channel -1" issue.

    I've compiled the compat-drivers 3.8 package, without your patch. with your patch, with your patch but with the channel part stripped off, older compat-drivers version, and a newer one, yet they all result in Channel Fixed -1.

    Downloaded Kali linux 1.0.3 to see how that would go, and seems to work fine there, yet i dont think they changed much on the drivers side. Any insight on what is going on or hints and tips on a possible sollution would be very much appreciated!..

    Kind regards,

  19. I am no luck with this patch, not working on fixed channel -1.

  20. hey .

    this patch have problem with 3.9 and 3.10.
    i do update your patch's offsets .

    diff -rupN old/drivers/net/wireless/rtl818x/rtl8187/dev.c new/drivers/net/wireless/rtl818x/rtl8187/dev.c
    --- old/drivers/net/wireless/rtl818x/rtl8187/dev.c 2013-05-20 01:36:52.000000000 +0430
    +++ new/drivers/net/wireless/rtl818x/rtl8187/dev.c 2013-05-24 21:53:06.683112630 +0430
    @@ -252,8 +252,18 @@ static void rtl8187_tx(struct ieee80211_
    flags |= RTL818X_TX_DESC_FLAG_NO_ENC;

    flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
    + // When this flag is set the firmware waits untill ALL fragments have
    + // reached the USB device. Then it sends the first fragment and waits
    + // for ACKS's. Of course in monitor mode it won't detect these ACK's.
    if (ieee80211_has_morefrags(tx_hdr->frame_control))
    - flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
    + {
    + // If info->control.vif is NULL it's most likely in monitor mode
    + if (info->control.vif != NULL && info->control.vif->type != NL80211_IFTYPE_MONITOR) {
    + flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
    + }
    + }
    if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
    flags |= RTL818X_TX_DESC_FLAG_RTS;
    flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
    diff -rupN old/net/mac80211/tx.c new/net/mac80211/tx.c
    --- old/net/mac80211/tx.c 2013-05-20 01:36:54.000000000 +0430
    +++ new/net/mac80211/tx.c 2013-05-24 21:53:26.787212320 +0430
    @@ -1458,7 +1458,11 @@ void ieee80211_xmit(struct ieee80211_sub
    /* Older kernels do not have the select_queue callback */
    skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
    - ieee80211_set_qos_hdr(sdata, skb);
    + // ieee80211_set_qos_hdr(sdata, skb);
    + // Don't overwrite QoS header in monitor mode
    + if (likely(info->control.vif->type != NL80211_IFTYPE_MONITOR)) {
    + ieee80211_set_qos_hdr(sdata, skb);
    + }
    ieee80211_tx(sdata, skb, false, band);

    diff -rupN old/net/wireless/chan.c new/net/wireless/chan.c
    --- old/net/wireless/chan.c 2013-05-20 01:36:54.000000000 +0430
    +++ new/net/wireless/chan.c 2013-05-24 21:53:37.699266430 +0430
    @@ -439,8 +439,8 @@ int cfg80211_set_monitor_channel(struct
    if (!rdev->ops->set_monitor_channel)
    return -EOPNOTSUPP;
    - if (!cfg80211_has_monitors_only(rdev))
    - return -EBUSY;
    + //if (!cfg80211_has_monitors_only(rdev))
    + // return -EBUSY;

    return rdev_set_monitor_channel(rdev, chandef);

  21. I updated the post for compat-drivers 3.8 and 3.9. Both those versions should work. The "backports" version (3.10) is not yet supported (though if you're a bit familiar with the source code you can easily update the current patch for compat-drivers).

  22. Please create patch to fixed channel -1. Patch not works in compat-drivers-3.9-rc4-2-su. Thanks

  23. Hi , 1st sorry for my bad english.

    I test the patch , and works well when the interface is "down" ( the real wlanX )

    But the chipsets RALINK ,need interface "up" ( the real interface wlanX ) to inject pins on a wps , but if wlanX is up ,then got the channel -1 on airodump.

    Need all the time play whit ifconfig up or down , up for reaver and down for aircrack-ng.

    Can fix channel -1 when the interfaces are "up" ?


  24. Hi thank you very much for your patch, I tried on 3.9, make install ok.. but I got a problem with it.. after apply, the monitor mode in my rtl8187 behaves weird! I can not get anymore data frames! mon only shows acks,probes,beacons,broadcasts,req tosend.. only management frames! how can I fix that? thanks

  25. Someone Please Update this Patch, i am trying to apply it on Backported 3.13 but i am getting Hunk Failed error... :(

    "Machine backports-3.13-rc8-1 # patch -Np1 < compatdrivers_chan_qos_frag.patch
    patching file drivers/net/wireless/rtl818x/rtl8187/dev.c
    patching file net/mac80211/cfg.c
    Hunk #1 FAILED at 799.
    1 out of 1 hunk FAILED -- saving rejects to file net/mac80211/cfg.c.rej
    patching file net/mac80211/tx.c
    Hunk #1 succeeded at 1514 (offset 2 lines).
    patching file net/wireless/chan.c
    patch unexpectedly ends in middle of line
    Hunk #1 succeeded at 481 with fuzz 1 (offset 42 lines).

  26. thank you very much for the work done, but the patch does not work on usb ralink drivers: (airodump remains on channel -1. hope that a solution be found: (

  27. Thanks for the good work I was having problems with Reaver 1.4 and the Alfa Awus 036h it was only working in backtrack 5 R2. This has solved the problem in Ubuntu Precise.

    1. Which package did you use for Precise? As far as i understand one have to change the path in the patch to the correct kernel version or better to the correct version of this:
      Index of /pub/linux/kernel/projects/backports/stable?
      Am i right?

  28. Any updated technique to apply above patches to more recent kernels like 3.16 or 3.17 to provide kernel injection?

  29. Is there a similar tutorial for Kali v2.0 ?

  30. This comment has been removed by the author.