Hello monks! :) I am currently working on a WPA implementation in Perl, - just as a way for me to learn about not only the protocol, but Perl too, because that's what life's all about!

Anyways, I have read loads of documentation and source code, including that from Aircrack-NG. Across the board, the docs don't really match up really and are very vague, at best. So this is what I came up with. I used Net::Pcap with WiFi to capture a perfect EAPOL and beacon with which I passed to Aircrack-NG with a word list and my password inside that list. For those unfamiliar with aircrack-ng, it produces the PTK transient Key, EAPOL, and PMK. I can do the PMK, that's incredibly easy, and you will see from my simple code below. The PTK part is where I am having trouble it seems. I have hard-coded the Anonce, Snonce, AP-MAC (BSSID), and Station MAC into the code as well.

The way it seems to work in practice is that the PMK is used to create the PTK, using a function like so (taken directly from Aircrack-NG):
/* pre-compute the key expansion buffer */ memcpy( pke, "Pairwise key expansion", 23 ); if( memcmp( ap->wpa.stmac, ap->bssid, 6 ) < 0 ) { memcpy( pke + 23, ap->wpa.stmac, 6 ); memcpy( pke + 29, ap->bssid, 6 ); } else { memcpy( pke + 23, ap->bssid, 6 ); memcpy( pke + 29, ap->wpa.stmac, 6 ); } if( memcmp( ap->wpa.snonce, ap->wpa.anonce, 32 ) < 0 ) { memcpy( pke + 35, ap->wpa.snonce, 32 ); memcpy( pke + 67, ap->wpa.anonce, 32 ); } else { memcpy( pke + 35, ap->wpa.anonce, 32 ); memcpy( pke + 67, ap->wpa.snonce, 32 ); } // then to get the PTK, they used the string above, like so: /* compute the pairwise transient key and the frame MIC */ for (i = 0; i < 4; i++) { pke[99] = i; HMAC(EVP_sha1(), pmk[j], 32, pke, 100, ptk[j] + i * 20 +, NULL); /* unsigned char *HMAC(const EVP_MD *evp_md, const vo +id *key, int key_len, const unsigned char *d, int n, unsigned char *md, unsigned int *md_len); */ }


I have placed in comments a definition of that simple HMAC() function. I tried to make my code mimic, as closely as I could, this function (and as I said, I have hard coded my PMK (which I know is correct)) but simply fall short and cannot replicate the correct PTK given to me from Aircrack-NG or CowPatty :( Below is my code:

#!/usr/bin/perl -w use strict; use Crypt::PBKDF2; use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); use List::Util qw( min max ); my $usage = "Usage: perl wpa2hex <ESSID> <PASSPHRASE>\n"; my $essid = shift || die $usage; my $passwd = shift || die $usage; # pack the next few registers up my $smac = pack("H*","489d2477179a"); # station MAC (RIM) my $amac = pack("H*","001dd0f694b0"); # AP MAC (Arris) my $snonce = pack("H*","143fbb4333341f36e17667f88aa02c5230ab82c508cc4b +d5947dd7e50475ad36"); my $anonce = pack("H*","87f2718bad169e4987c94255395e054bcaf77c8d791698 +bf03dc85ed3c90832a"); my $pbkdf2 = Crypt::PBKDF2->new( hash_class => 'HMACSHA1', # HMAC-SHA1 hash_args => { sha_size => 512, },iterations => 4096, salt_len => length($essid), output_len => 32 ); my $pmk = uc($pbkdf2->PBKDF2($essid, $passwd)); my $pbkdf2b = Crypt::PBKDF2->new( hash_class => 'HMACSHA1', # HMAC-SHA1 hash_args => { sha_size => 512, },iterations => 4096, salt_len => length($pmk), output_len => 20 ); print "Master Key: ",uc(unpack("H*",$pmk)),"\n"; prf512(); sub prf512{ my $a = "Pairwise key expansion"; # application-specific data my $b = $amac.$smac.$snonce.$anonce; my $r = ""; for(my $i=0;$i<4;$i++){ my $data = $a."\x00".$b.$i; $r .= $pbkdf2b->PBKDF2($pmk,$data); } print "Transient Key: ",uc(unpack("H*",$r)),"\n"; return; }

I simply used Wikipedia and this site: http goo.gl UVXhGi as a reference. That site, however states that you need to use a "0 byte" between the "Pairwise key expansion" string and the first MAC address in the data passed to the function. Aircrack-NG's source code, as you see above, does not! Anyways, I am not trying to re-invent the wheel here, I am just a student of 802.11, Perl, C and life.

If anyone has any idea as to where I am wrong, please, the help would be greatly appreciated. Thank you in advance, and peace be with you monks <3

In reply to [SOLVED] HMAC_SHA1 Implementation for WPA by return0

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.