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.
Objective
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:
wep:[BSSID]:[KEY]
For example:
wep:00:01:02:03:04:05:mypassword
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:
wpa:[SSID]:[PSK]
As an example:
wpa:MyAccessPoint:MySecretKey
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:
./configure
make
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.
Example
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!