Tuesday, June 4, 2013

Decrypting WEP/WPA2 traffic on the fly

This is the first application I've developed using libtins, a packet crafting and sniffing library I've been developing for a while. In the latest release of that library, I've added support for WPA2 decryption, so this application does very few things and does not handle encription at all; the library does so.

The decryption of WEP and WPA2 traffic has been available for a while now. Applications such as wireshark, tshark and airdecap have supported this for quite some time. However, after adding this decryption feature to libtins, I wondered why there were no applications that let you decrypt the traffic directly from a network interface and make it available, decrypted, for any other application. This is where dot11decrypt was born.



The application sniffs a network interface looking for WEP and WPA2 encrypted traffic. It also analyzes EAPOL(802.1X) handshakes in order to track the nonces shared by peers, which will later be necessary while decrypting WPA2.

Once a packet is decrypted successfully, the 802.11 frame is replaced by an Ethernet header, and the whole packet is written to a tap interface. You now can read those decrypted packets using any other tool, such as Wireshark or ngrep, and perform any kind of analysis.

What is required for decryption

dot11decrypt does not crack any of the above mentioned encryption algorithms. So if you're looking for a wireless cracking tool, then this is not one of them.

In order to crack WEP encrypted traffic, you need to provide the access point's BSSID and the WEP key. The syntax required to indicate that decryption data is the following:
For example:
Indicates that the access point whose BSSID is "00:01:02:03:04:05" uses WEP encryption and the WEP key is "mypassword".

On the other hand, WPA2 traffic is a little bit more complex. In order to generate the first set of keys required to decrypt the traffic(the Pairwise Master Key or PMK), both the pre-shared key and the network SSID(you network's "name") are required.

In order to specify both of this attributes, the following syntax is used:
As an example:
Indicates that any access point which broadcast the SSID "MyAccessPoint" will be decrypted, assuming the PSK is "MySecretKey".

How it works


Decrypting WEP frames is fairly simple, given the WEP key, it's just using RC4 over the encrypted data.

Decrypting WPA2, however, is a little bit trickier. In order to decrypt a WPA2 encrypted frame, the following is required:

  • The PMK(mentioned a few lines above).
  • The association SSID -> BSSID.
  • A valid 4-way handshake between the client which sends or is about to receive that frame.
The application initially computes the PMK. Since you only provide the network SSID, then the application will look for beacon frames so as to know which BSSID is broadcasting the given SSID.

After that, when a client performs a handshake against those BSSIDs, a Pairwise Transient Key(PTK) is computed and stored. At that point, any packet sent from or to the associated client will be decrypted using that PTK. If any client is deauthenticated and then authenticated again, that new handshake will be taken into account and used to decrypt its packets.

Luckily for us, all of the above mentioned is already implemented and performed automatically by libtins: inspecting beacon frames looking for the SSID, capturing 4-way handshakes and decrypting the traffic. If you want to have a look at that code, have a look at the WPA2Decrypter class.

Note that WPA2 decryption works for both AES(CCMP) and TKIP encrypted frames, so this works for WPA as well(since this uses TKIP).

Compiling the application


In order to compile dot11decrypt, the latest version of libtins is required(version 1.1 at the moment of writing). You can download it from the project's github entry. The library must be compiled using support for WPA2 decryption(this is enabled by default).

Since the application uses some C++11 features, a fairly recent C++ compiler is needed as well. g++ 4.6 is enough. g++ 4.5 might do.

dot11decrypt's source code can be downloaded from github. After you've got these, just go ahead and do the usual:

Using it


The application takes as its first argument, the interface in which to listen for packets. This must be a wireless interface in monitor mode. The rest of the arguments specify the data which will be used to decrypt the data, using the syntax mentioned near the beginning of this post:
./dot11decrypt wlan0 wpa:MyAccessPoint:some_password
./dot11decrypt mon0 wep:00:01:02:03:04:05:blahbleehh
After running it, you'll get an output similar to the following:
Using device: tap0
Device is up.
The tap0 interface will now be used to output the decrypted traffic. tcpdump or any other network sniffing tool can be used to process the data. Note that the 802.11(and possibly the RadioTap encapsulation used) and LLC+SNAP frames will be removed and replaced by an Ethernet header.

Note that you require either root privileges or the CAP_NET_ADMIN capability on the executable to run this application successfully.


In this example, I'm going to sniff and decrypt the traffic sent from my phone.

The mon0 interface, the one I'll be using, is in monitor mode. This is the output of running tcpdump on that interface, filtering only IEEE 802.11 data frames for which the second address in that frame is the access point's BSSID:

As you can see, there are several Dot11 QoS Data frames, all of them encrypted.

Now, I'm going to execute dot11decrypt providing the SSID and the WPA2 PSK:

A new tap interface has been created, named tap0. Every decrypted packet will be written to it.

At this point, I connected my phone to the access point. The application captures the 802.1X handshake and it will start decrypting the traffic. In the image below, you can see how the traffic sniffed from the tap0 interface is no longed encrypted:

I hope you find this application useful!


  1. Great stuff! Just used it with my little script and it works like a charm!

  2. This comment has been removed by the author.

  3. this works ok on my wlan0 interface but thats not set to monitor mode and thus only shows my trafic. When i forward the decryted traffic to tcpfump from my monitor interface(mon0) it only shows ipv6 traffic .....good work bro. i think it may be overloaded? and the traffic passes thru too quickly. anyway keep it up

  4. sorry works perfectly now.adapter issue

    1. Can you tell me how you solved it? I have the exact same problem, only ICMPv6 showing up.

  5. Thanks for posting this neat program. Unfortunately, I have encountered a problem where the decrypting interface tap0 does not output anything.

    Here is my setup:

    I am running 2 laptops: a test laptop that connects to the AP TestNet and the sniffing laptop that runs dot11decrypt

    0. sudo su
    1. airmon-ng start wlan1
    2. dot11decrypt mon0 wpa:TestNet:wireless
    3. tcpdump -i tap0
    4. turn off, then turn on the WiFi adapter of the test laptop (this is to let the sniffing laptop captures the handsakes)

    After all these steps, I still see nothing from the tcpdump.

    I wonder if you could point out some possible problem that I should look into.

  6. I have been trying to use this on a raspberry pi to capture traffic on my wireless network. However I am getting the same result as Steven William.

    I get the same kind of QoS Data packets reported when I sniff the mon0 device however when I try to sniff the tap0 device I don't get anything at all.

    What I am trying to do long term is to monitor my Wireless network to see what kind of websites my kids are visiting without having to stand over their shoulders.

    Any suggestions or advice would be appreciated.

    1. Maybe the handshake is not being sniffed, and therefore no traffic can be decrypted.

      If you run tcpdump on the wireless interface mon0, do you see the WPA handshakes?

    2. to be honest I' not sure what a handshake packet should look like but here is an extract from a dump I just did.

      pi@raspberrypi ~ $ sudo tcpdump -i wlan0 -c10 -n "wlan type data"
      tcpdump: WARNING: wlan0: no IPv4 address assigned
      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
      listening on wlan0, link-type IEEE802_11_RADIO (802.11 plus radiotap header), capture size 65535 bytes
      07:00:14.680085 48.0 Mb/s 2412 MHz 11g -51dB signal antenna 1 CF +QoS Data IV:f1ac Pad 20 KeyID 0
      07:00:14.680693 1.0 Mb/s 2412 MHz 11b -77dB signal antenna 1
      07:00:14.681221 48.0 Mb/s 2412 MHz 11g -51dB signal antenna 1 CF +QoS Data IV:f198 Pad 20 KeyID 0
      07:00:14.681580 2412 MHz 11g -51dB signal antenna 1 52.0 Mb/s MCS 5 20 MHz lon GI CF +QoS Data IV:3fe Pad 20 KeyID 0
      07:00:14.884024 1.0 Mb/s 2412 MHz 11b -79dB signal antenna 1
      07:00:15.066769 1.0 Mb/s 2412 MHz 11b -49dB signal antenna 1 Data IV:7f2080 Pad 20 KeyID 1
      07:00:15.253354 48.0 Mb/s 2412 MHz 11g -51dB signal antenna 1 CF +QoS Data IV:f1ad Pad 20 KeyID 0
      07:00:15.253504 48.0 Mb/s 2412 MHz 11g -51dB signal antenna 1 CF +QoS Data IV:f199 Pad 20 KeyID 0
      07:00:15.271510 1.0 Mb/s 2412 MHz 11b -47dB signal antenna 1 Data IV:802080 Pad 20 KeyID 1
      07:00:15.272774 1.0 Mb/s 2412 MHz 11b -49dB signal antenna 1 Data IV:812080 Pad 20 KeyID 1
      10 packets captured
      10 packets received by filter
      0 packets dropped by kernel
      1 packet dropped by interface

    3. is there a particular filter I can put on tcpdump to show if I am getting the handshakes?

    4. It looks like there are no handshakes in the output you provided. You could use the filter "ether proto 0x888e" to filter them.

      Just to check out, are you disconnecting and connecting again to the access point after you start dot11decrypt? If you don't do this, then it just won't work.

    5. This comment has been removed by the author.

    6. ok I didn't realize about the disconnect and reconnect bit. I did another trace with the filter you suggested and got the following:

      14:53:54.595962 1.0 Mb/s 2412 MHz 11b -47dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 95
      14:53:54.606470 1.0 Mb/s 2412 MHz 11b -41dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 117
      14:53:54.611642 1.0 Mb/s 2412 MHz 11b -49dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 175
      14:53:54.613688 1.0 Mb/s 2412 MHz 11b -41dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 95
      14:54:14.871153 1.0 Mb/s 2412 MHz 11b -45dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 95
      14:54:14.883475 1.0 Mb/s 2412 MHz 11b -43dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 117
      14:54:14.888214 1.0 Mb/s 2412 MHz 11b -47dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 175
      14:54:14.890671 1.0 Mb/s 2412 MHz 11b -43dB signal antenna 1 CF +QoS EAPOL key (3) v1, len 95

      It looks like I am getting handshakes. So i tried the sniff again with a disconnect and reconnect.

      sudo tcpdump -i tap0 -c10
      tcpdump: WARNING: tap0: no IPv4 address assigned
      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
      listening on tap0, link-type EN10MB (Ethernet), capture size 65535 bytes
      tcpdump: pcap_loop: The interface went down

      At the same time in the other console where I ran dot11decrypt it exists at exactly the same time. (obviously i've change the ssid and password for the purposes of this post)

      pi@raspberrypi ~ $ sudo dot11decrypt wlan0 'wpa:myssid:mypassword'
      Using device: tap0
      Device is up.
      pi@raspberrypi ~ $

      I've tried this quite a few times now and get the same result. Every time I reconnect the dot11decrypt application exits.

      I was wondering is having the wlan0 in monitor mode and decrypting the wpa packets the only way get all the tcp packets from WIFI or is there any other method similar to a wired network where you just connect the cable and put the interface in promiscuous mode.

    7. Mmm that's strange. It would be great if you could give me a pcap that included the handshake, and gave me the access point's passphrase(change it before doing so, of course), so I could fix the bug. Wasn't the interface in monitor mode named "mon0"? That's what you posted at the beginning.

      If I were you, I'd just install DD-WRT in your home router and redirect all the traffic to one of your hosts. You can do this by using iptables, just look it up.

    8. It was in in mon0 earlier however I put the whole wlan0 into monitor so it really didn't matter which I chose. I have tried on mon0 and wlan0. I don't mind providing you with a pcap and the keys for you to have a look at. but would like to send them privately rather than via the blog.

      The idea of install custom firmware on my router is a bit daunting as any support I'd get from my ISP would just go out the window, But it is a consideration. However I am mainly interested in the WIFI only traffic at the moment and not all internet traffic as my kids have got tablets for Christmas and I wanted to just get a list of http request they are making so I can see if they are visiting any worrying websites.

      if you provide me with the commands you'd like me to run to do the capture you require I will do it now.

  7. Oh, I see. Okay then, if you give me a pcap capture, the SSID and the passphrase, I could be fixing this in a couple of hours, luckily.

    If you want to do this, please do the following:
    - tcpdump -i mon0 -w capture.pcap
    - Disconnect some PC from the access point, reconnect again and just do some ping, or get into any website, just so that there is some traffic to decrypt.

    You could send me the information to my e-mail address: matias [dot] fontanini [at] gmail [dot] com

    Thank you very much!

    1. Done that, you should have the pcap file any time now.

      Thanks for the help.

    2. Neil and Matias, I am looking to do the same thing with an rPi2b I just purchased and kismet running. I'd like to monitor specific MAC's and decrypt the websites being visited. I recognize this is an older post (1year+) but if either of you are interested, I'd like to know how this project turned out and Neil, if you were able to get it up and running and was it successful?

    3. Neil and Matias, I am looking to do the same thing with an rPi2b I just purchased and kismet running. I'd like to monitor specific MAC's and decrypt the websites being visited. I recognize this is an older post (1year+) but if either of you are interested, I'd like to know how this project turned out and Neil, if you were able to get it up and running and was it successful?

  8. This looks awesome. Unfortunately I've not got out of the starting blocks with it yet. Am getting errors running ./configure (as root):

    checking tins/handshake_capturer.h presence... yes
    configure: WARNING: tins/handshake_capturer.h: present but cannot be compiled
    configure: WARNING: tins/handshake_capturer.h: check for missing prerequisite headers?
    configure: WARNING: tins/handshake_capturer.h: see the Autoconf documentation
    configure: WARNING: tins/handshake_capturer.h: section "Present But Cannot Be Compiled"
    configure: WARNING: tins/handshake_capturer.h: proceeding with the compiler's result
    configure: WARNING: ## ----------------------------------------- ##
    configure: WARNING: ## Report this to matias.fontanini@gmail.com ##
    configure: WARNING: ## ----------------------------------------- ##
    checking for tins/handshake_capturer.h... no
    checking for libtins... configure: error: libtins is either missing or an old version is installed!

    Libtins went on fine and the handshake_capturer.h header file is present

    Any ideas?

    1. Have you downloaded the latest libtins source code and you don't have any other previous version installed in your system?

  9. The version of libtins I downloaded was 2.0.0. It installed OK when I ran ./configure make and make install

    Library is present under /usr/local/lib and headers (including dot11 headers) are all under /usr/local/include/tins.

    Incidentally I get errors when I try to run make against the tins example apps eg arpmonitor. Getting errors about expecting semi-colons in the header files by the looks of things.

    This is on RHEL6.1 32bit btw and there were no other versions of libtin installed previously

    Many thanks

    1. Can you try compiling this short snippet?


      Remeber to link it with libtins using -ltins.

      The problem you're facing is described here: http://www.gnu.org/software/autoconf/manual/autoconf-2.68/html_node/Present-But-Cannot-Be-Compiled.html. But I don't think that situation is occuring in handshake_capturer.h, so I don't really know what's the problem.

  10. That compiles OK using g++ -c capturetest.cpp -o capturetest -ltins. Then I run ldconfig and ./capturetest. It returns without any errors.

    Running make against the libtins examples I'm getting:

    [root@localhost examples]# make
    g++ arpspoofing.cpp -o arpspoofing -Wall -g -O2 -ltins
    g++ arpmonitor.cpp -o arpmonitor -std=c++0x -Wall -g -O2 -ltins
    In file included from /usr/local/include/tins/dns.h:40,
    from /usr/local/include/tins/tins.h:33,
    from arpmonitor.cpp:1:
    /usr/local/include/tins/pdu.h:152: error: expected â;â before ânoexceptâ
    /usr/local/include/tins/pdu.h:163: error: expected â;â before âPDUâ
    /usr/local/include/tins/pdu.h:163: error: expected â;â before ânoexceptâ
    /usr/local/include/tins/pdu.h:175: error: expected â;â before âvirtualâ
    In file included from /usr/local/include/tins/tins.h:48,
    from arpmonitor.cpp:1:
    /usr/local/include/tins/packet_sender.h:90: error: expected â;â before ânoexceptâ
    /usr/local/include/tins/packet_sender.h:98: error: expected â;â before âPacketSenderâ
    /usr/local/include/tins/packet_sender.h:98: error: expected â;â before ânoexceptâ
    /usr/local/include/tins/packet_sender.h:122: error: expected â;â before â~â token
    In file included from /usr/local/include/tins/tins.h:49,
    from arpmonitor.cpp:1:
    /usr/local/include/tins/packet_writer.h:79: error: expected â;â before ânoexceptâ

    Not sure if this is related

    1. Which gcc version are you using? It seems like it doesn't have support for C++11's noexcept keyword, which was added in gcc 4.6, so the compilation errors on the examples are caused by that. I don't know if it's the cause for the other problem though.

    2. I forgot that dot11decrypt uses C++11 features. In fact, the requirements(https://github.com/mfontanini/dot11decrypt#requirements) state that you need at least gcc 4.6. So that's actually the problem.

  11. You're right I'm using 4.4.5. I'll see if I can get gcc updated and give it another try

    Thanks for your help

  12. I've got a similar problem on the Raspberry Pi. I've got tap0 setup, but it never receives any packets, even though wlan0 can be monitored with Wireshark, and the packets can be decrypted. I've simultaneously been capturing from my Macbook wifi in monitor mode with Wireshark and can decrypt the traffic and see everything as well. I'm happy to provide whatever you need to get it fixed.

    1. I also seem to have reproduced the same behavior with Centos 6.4.

  13. Hi,

    I've tried this software in my laptop, and works perfectly. However, I've tried exactly the same steps (installation and usage) in my server, and does not work. I can compile, install and use it, but only captures a few ipv6 packets. There is no difference regarding libtins version between the laptop and server. It is almost the same linux distro (mint). I'm also using the same wifi adaptor (usb) in both computers. I'm running out of ideas. Any help please?


    1. Hi,

      the following URL contains some tips on how to fix a possibly similar problem on aircrack:


      You might just be missing a few packets, including some of those which are part of the 4-way WPA handshake. Try tuning the wireless card, change the channel using "iwconfig" and see if that works.

    2. Thanks for the response. I forgot to mention that effectively the adapter is in the same channel that the ap. In fact, otherwise I cannot capture obsolutely anything. I've reading the link. I've to do some tests, but the most feasible option is that the adaptor is too close to the AP. I also would like to ask to you if it's possible to tell to dot11decrypt to read the handshake from a pcap (tcpdump) file (I can do it with the laptop) and start the capture immediately. Is it possible to modify the program to allow this? Is it a good idea?

  14. Everytime a handshake occurs tap0 shuts down and the message "segmentation fault" appears. Any suggestions on how to fix this would be very much appreciated.

    1. I have the same issue as Jerry and Joe. Running KaliLinux on Raspbery.

  15. thanks! your great programmer!

  16. guys, i have a problem kali for rassberypy shutdown this program. temp resolve modify source.