Using the new CCMP-attack in Pyrit

The last post described some of the background details of how the new CCMP-attack works. Using this feature in Pyrit is quite easy:

As the Temporal Key is not used during the authentication but only in the following data-stream, Pyrit needs more than just the fourway-handshake. The ‘analyze‘-command from now on indicates if an encrypted packet can be associated with an authentication and sufficiently constrained to actually “belong” to this authentication (encrypted with the Temporal Key from that authentication). A simply asterisk shows that:

>pyrit -r wpa2psk-linksys.dump.gz analyze
Pyrit 0.4.1-dev (svn r304) (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com
This code is distributed under the GNU General Public License v3+

Parsing file ‘wpa2psk-linksys.dump.gz’ (1/1)…
Parsed 499 packets (499 802.11-packets), got 1 AP(s)

#1: AccessPoint 00:0b:86:c2:a4:85 (‘linksys’):
#1: Station 00:13:ce:55:98:ef, 3 handshake(s):
#1: HMAC_SHA1_AES, good*, spread 1
#2: HMAC_SHA1_AES, good*, spread 1
#3: HMAC_SHA1_AES, good*, spread 1

All “attack“-commands from now on understand the new switch “–aes“. This switch tells Pyrit to attack an authentication using the new CCMP-approach if possible. You can, in fact, apply this switch all the time. Pyrit will figure out if the CCMP-path is actually possible. The switch will be removed (or reversed) in the future.

>pyrit -r wpa2psk-linksys.dump.gz -i dict.gz –aes attack_passthrough
Pyrit 0.4.1-dev (svn r304) (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com
This code is distributed under the GNU General Public License v3+

Parsing file ‘wpa2psk-linksys.dump.gz’ (1/1)…
Parsed 499 packets (499 802.11-packets), got 1 AP(s)

Picked AccessPoint 00:0b:86:c2:a4:85 (‘linksys’) automatically.
Tried 4094 PMKs so far; 1049 PMKs per second.

The password is ‘dictionary’.

Pyrit can use the new AES-NI instruction-set found in recent processors (e.g. Intel Sandy Bridge) to boost performance. The “list-cores“-command shows if the local processor supports this instruction-set:

> pyrit list_cores
Pyrit 0.4.1-dev (svn r304) (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com
This code is distributed under the GNU General Public License v3+

The following cores seem available…
#1:  ‘CPU-Core (SSE2/AES)’
#2:  ‘CPU-Core (SSE2/AES)’
#3:  ‘CPU-Core (SSE2/AES)’
#4:  ‘CPU-Core (SSE2/AES)’

Note that a recent version of GCC 4.4+ is required to compile the intrinsics for the new AES-NI instructions. Pyrit‘s module will not be able to use the hardware-based AES-acceleration if it was compiled with a previous version of GCC.

Please also note that this feature is currently only the the svn-codebase and not found in a released stable version. Your help is required to make this process faster. Please submit cases where Pyrit is able to successfully attack a handshake using the original approach but fails to do so when the –aes switch is applied. Such regressions need to be sorted out before we can make the new CCMP-approach a default and get a new stable version 0.4.1 out onto the road. Please open a bug on Pyrit’s bugtracker for these cases (including all necessary information).

Known-plaintext attack against CCMP

A new feature now completely implemented in Pyrit can boost the performance of database-driven attacks against WPA2-PSK by about fifty percent. As far as I know, Pyrit is the first and only tool that implements this new approach of attacking WPA2-PSK.

The idea, originally pitched to me by Domonkos Tomcsányi, is to leverage the knowledge of the plaintext for the first few bytes of an encrypted packet to find the correct Temporal Key. This is the key which is used by WPA2 in conjunction with CCMP and AES to encrypt and authenticate the data-stream. The performance-gain comes from the fact that computing the Temporal Key and one encryption-round via AES to prove it’s validity is faster than the classic approach of computing the Key Confirmation Key and HMAC-SHA1 over one entire packet.

The first important insight is that we know what the first six bytes of an encrypted message should be as there is always a LLC- and a SNAP-header. There is only a minuscule chance that a guessed key was incorrect after we try a possible CCMP-key and the first six bytes of the decrypted plaintext turn out to read AAAA03000000. After the Temporal Key has been computed, this check can be done with just one AES key-setup and one encryption-round.

The Temporal Key is a part of the Pairwise Transient Key which in turn is derived from the Pairwise Master Key using PRF-384. Technically spoken, PRF-384 is HMAC-SHA1 computed over the Pairwise Key Expansion and keyed by the Pairwise Master Key. As the function’s output is always 20 bytes per iteration (the length of a SHA1-digest) and the Temporal Key is 32 bytes into the function’s stream, we need the last eight bytes of the second and the first eight bytes of the third iteration. At first sight this makes it actually more difficult to compute the Temporal Key compared to the Key Confirmation Key which only requires one iteration of PRF-384. While implementing Domonkos’ idea I came to realize that there are two important (and afaik not previously discussed) weaknesses in the design of PRF-384 that we can exploit in order to lessen this disadvantage:

The PRF-384 function is – in essence – like a stream-cipher that produces a large number of output bits using a smaller number of secret input bits. Real stream-ciphers or strong PRNG feed the output of iteration N back as an input to iteration N+1; this makes it impossible to compute the state of the algorithm at iteration N without knowing it’s state at iteration N-1. However, PRF-384 does not do that: We can compute the second iteration (for the first eight bytes of the Temporal Key) without having to compute the first iteration. Second, the counter used in every iteration is placed at the end of the Pairwise Key Expansion instead of the beginning. We can therefor re-use the state of the SHA1-algorithm between iteration two and three as the HMAC-key and the first block of the message are the same.

Combining these two completely unnecessary weaknesses allows us to reduce the number of SHA1-rounds required to compute the Temporal Key from fifteen to seven. This is still more than the five rounds of SHA1 required to compute the Key Confirmation Key but in fact is more than fast enough: The one key-setup plus one AES-round required to confirm the Temporal Key can be done much faster than the four to six rounds of SHA1 required to check the Key Confirmation Key. This is especially true as we can utilize hardware-based implementations of AES with the new AES-NI instruction-set found in recent processors.

Putting this all together, the number of passwords Pyrit can check on my Intel i7 4×3.4Ghz increases from 5.4 million to 7.9 million per second, a straight 50% increase. I will post more details about how to use this new feature in the next blog-entry.

Follow

Get every new post delivered to your Inbox.