Stateful handshake-parsing

About two weeks ago the update to Pyrit 0.3.1-svn r226 made Pyrit more picky about how it parsed the information from a capture-file and reconstruct the fourway-handshake. This change solved some cases where Pyrit would combine packets from overlapping or incomplete handshakes which made the task of finding the correct PMK impossible. Being more strict solved some cases of non-working capture-files but opened a whole can of worms on the other end: Pyrit would sometimes pick up packets from an incomplete handshake, look for the remaining parts and ignore other, more valuable packet-combinations.

The latest development-revision Pyrit 0.3.1-svn r231 brings relief to this problem and solves a to-do that had been marked as such since the packet-handling code was first checked in. Pyrit now has the ability to analyse, parse and work with multiple authentications and rate their quality. This brings a huge increase to Pyrit’s ability of working with packet-captures-files.

Here is an example of how the result of analysing a capture-file may look like from now on:

#1: AccessPoint 00:0b:86:c2:a4:85 (‘linksys’):

#1: Station 00:13:ce:55:98:ef, 3 handshake(s):

#1: Good quality (HMAC_SHA1_AES)
#2: Good quality (HMAC_SHA1_AES)
#3: Good quality (HMAC_SHA1_AES)

As you can see, Pyrit has detected three possible handshakes (WPA2-PSK in this case) and rated them as being of good quality. The quality of a handshakes is (currently) determined like this:

  • good” handshakes include the challenge from the AccessPoint, the response from the Station and the confirmation from the AccessPoint.
  • workable” handshakes include only the response from the Station and the confirmation from the AccessPoint.
  • bad” handshakes include only the challenge from the AccessPoint and the response from the Station (but not the confirmation).

Multiple handshakes of the same quality (like in the example above) are rated by how close to each other the packets resembling the handshake are. That way, vaguely related packets that accidentally resemble to a complete handshake are not completely ignored, but of little priority.

To pursue with the original behaviour, Pyrit picks the single most valuable handshake by itself and works only with this single handshake. The attack-modes therefore now understand a new option “–all-handshakes“. When this option is passed:

  • attack_passthrough attacks all workable handshakes at the same time. This does not affect performance as the bottleneck is computing the PMK.
  • attack_batch and attack_db work down the list of possible handshakes one after the other.
  • attack_cowpatty attacks all workable handshakes at the same time. This impacts performance (e.g. 2 handshakes == 50% throughput)

Additionally, the behaviour of strip and stripLive has changed: Pyrit no longer places the (selected) packets from a single authentication but all authentication-related packets into the new file.

Bad SQL-Storage performance fixed

Please notice that Pyrit used to create an index on a table in an unprofitable column-order. This causes a full table scan for operations like “eval” and “delete_essid” which may take a very long time for large (hundreds of millions of entries) databases.

This problem is about to get fixed for 0.3.1-svn so Pyrit creates new databases with their indexes in in proper column-order. Older databases can be fixed by creating a new index like this (use the database-server’s sql-console):

CREATE INDEX myrescueidx ON results (essid_id, _key);

People using the on-disk (“file://”) storage backend are not affected.

New tutorial

The most basic steps with Pyrit are now explained in a new tutorial as part of the wiki.

Pyrit 0.3.0 released

Pyrit 0.3.0 was just tagged and is now the currently stable version. Enjoy.

Due to the numerous changes after 0.2.4, I’ve advanced Pyrit’s “major-minor” revision number to 0.3. Highlights from the changelog include:

  • SSE2-support for the EAPOLCracker, making all attack-modes roughly 3x faster
  • Much improved lazy-loading of files, giving another 20% to 30% performance to all attack-modes
  • Support for using SQL-databases as a storage backend
  • Support for sharing GPUs and databases over the network

You can get the new version right here.

ATI Catalyst 10.2

Word of advice: Do not update to ATI’s 10.2 drivers. After the usual ~1 hour to get my system working again after the update, i had to find out that the new driver produces random segfaults in libaticaldd.so.

More on this on AMD’s Praise-And-Glory blog where the announcement is completed by (as the time of writing) 52 comments mostly about bugs and crashes…

Oh the irony

Using Pyrit in shell scripts

Pyrit 0.2.5-svn r216 now understands the option ‘-o’ (output-filename) in all attack-commands. The password – if found at all – is written to the given filename, which can be “-” to indicate stdout. This makes it very easy to integrate Pyrit into your own shell scripts.

Also note that Pyrit sets it’s process exit code depending on the result of the command. This behaviour has been integrated some time ago but seems to be pretty unknown. Pyrit signals failure in case…

  • the attack-commands do not find the password
  • the command verify stumbles upon a corrupted workunit
  • analyze can’t find at least one handshake in the capture-file
  • any runtime-error occurs

When combined, you can do things like:

# Save the password to a file (file is not touched if password is never found)
pyrit -r wpa2psk-linksys.dump.gz -i linksys.cow.gz -b 00:0b:86:c2:a4:85 -o 000b86c2a485_linksys.txt attack_cowpatty

# Send password by eMail via mailx
pyrit -r wpa2psk-linksys.dump.gz -i dict.gz -b 00:0b:86:c2:a4:85 -o – attack_passthrough | mailx -s “Password found” “myemail@mydomain”

# Batchprocess the database and then shutdown the computer
pyrit batch && shutdown -h now

We’ll have to go right to… Ludicrous Speed!

A recent update brought a SSE2-based execution path for Pyrit’s HMAC-SHA1 implementation and thereby a very compelling performance improvement for attack_db or attack_cowpatty when used with handshakes based on WPA2-PSK. The older WPA-PSK however utilises MD5 instead of SHA1 so that case could not equally benefit.

I’ve taken yesterday’s and today’s evening and the latest “Pyrit 0.2.5-svn r215” has shiny SSE2-code for MD5 now too. The numbers speak for themselves: Crunching a 2gb, 50 million entries cowpatty-file against a WPA-PSK handshake on my MacBook Pro 2×2.5Ghz took 1 minute and 27 seconds with r213 (575.000 passwords per second). The new r215 walks through the same file in just over 33 seconds (1.5 million passwords per second).

GC object already fucking tracked

I recently had a problem with the python interpreter crashing within it’s garbage-collector after changing some code in Pyrit’s C-extensions. More specifically, the interpreter sometimes crashed with the following error:

Fatal Python error: GC object already tracked

Crashes that involve referencing counting are hard to debug because the cause of the error (e.g. deallocating an object although there are still references to it) and the effect (assertion errors, random segfault) are usually temporal- and location-independent from each other. Searching for other cases of the error shown above via google revealed almost no valuable information for me.

I’ve found the problem and now write this blog-enry for google to bring it up to other people looking for an answer. The solution is found within the last sentence of CPython’s documentation about the PyTypeObject.tp_free-field. When an object’s type is subclassed, the object may suddenly become a target of CPython’s cyclic garbage collection. In that case, the default PyObject_Del that is usually found in your object’s PyTypeObject.tp_free becomes PyObject_GC_Del. My fault was to call PyObject_Del directly within PyTypeObject.tp_dealloc, ripping the object from the loving hands of the garbage collector.

Long story short:

PyObject_Del((PyObject*)self);
self->ob_type->tp_free((PyObject*)self);

Remember kids: Always use the slots of self->ob_type. Crash fixed.

Even better numbers…

… come with “Pyrit 0.2.5-dev r213” which improves performance of attacking WPA2 via precomputed (cowpatty-like) tables by about 30% to 40% for my little MacBook Pro. The new version does a 50 million entries, 2GB cowpatty file in about 37 seconds (1.3 million keys per seconds).

WPA-PSK will not benefit as much as WPA2-PSK as it partly uses MD5 instead of SHA1 for which we don’t have a SSE2-path yet.

Parsing bug fixed

Please notice that Pyrit 0.2.5-svn r210 fixes a quite serious bug that caused Pyrit to sometimes pick the wrong KeyScheme (e.g. HMAC_MD5_RC4 instead of HMAC_SHA1_AES) when parsing packet data. This in turn caused Pyrit to miss the correct passphrase even if it was supplied.

This does not affect computation of Pairwise Master Keys so databases/cowpatty-files created by Pyrit are not affected by this.

  • RSS Unknown Feed

    • An error has occurred; the feed is probably down. Try again later.