The problem: Earlier versions of pcap2ivs have a bug that generates broken files: aircrack (all versions) and aircrack-ng (=< 0.2.1).
Symptoms: When you open such .ivs file in aircrack you get much more bssid than what you had (quite slowing aircrack start), most of them are invalid.
If you have problems with this try and use original .cap files, and don't use old version of pcap2ivs. If you only have the corrupt .ivs file and you want to recover it you can try this tool.
Example:
If you had a packet with these values: BSSID: AA:BB:CC:DD:EE:FF, SOURCE: 00:11:22:33:44:55, DST: 66:77:88:99:66:77, you'd get a packet with BSSID: 66:77:88:99:66:77 (dst is taken instead of bssid).
Broadcast packets also de-synchronize file format and you start getting “random” macs.
/* This code is intended to address some issues in pcap2ivs that
affect (at least) aircrack-2.41 and aircrack-ng 0.2.1:
* Restriction in IVs file format design
* A check to detect broadcast frames was missing in pcap2ivs
* Bug in pcap2ivs, that saved dst-mac instead of bssid
As a result it was getting frequent broadcast mac, which did not filter, and messed up file format.
Usage:
fixivs [FromMac1 ToMac1] [FromMac2 ToMac2]... < broken.ivs > fixed.ivs
(do NOT use same filename for input and output!).
It will replace occurrences of FromMac for ToMac, because bssid got replaced with dst-mac of packets.
Author: LatinSuD
*/
#include <stdio.h>
#define IVSONLY_MAGIC "\xBF\xCA\x84\xD4"
#define M 1
#define IVD 2
/* States (s):
* IVD, if next is FF:FF:FF:FF:FF:FF -> Read it as a mac. s=MAC
* else if next is FF -> Read IV and Data. s=IVD
* else next is a mac -> Read it. s=MAC
* MAC, read IV and Data. s=IVD
*/
#define BCAST "\xff\xff\xff\xff\xff\xff"
void usage() {
fprintf(stderr, "Fixes IVs files generated by broken pcap2ivs, replacing mac's as desired\n");
fprintf(stderr, "\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\tfixivs [FromMac1 ToMac1] [FromMac2 ToMac2]... < broken.ivs > fixed.ivs\n");
fprintf(stderr, "\t (do NOT use same file for input and output!)\n");
}
int atoh(char c) {
if (c>= '0' && c<='9')
return c-'0';
if (c>='a' && c<='f')
return c-'a'+0xa;
if (c>='A' && c<='F')
return c-'A'+0xa;
usage();
fprintf(stderr, "ERROR: Invalid character in mac address '%c'\n", c);
exit(1);
}
void strtomac(unsigned char *mac, char * str) {
int i,c;
i=0;
while (*str) {
if (i>=12) {
usage();
fprintf(stderr, "ERROR: Mac address too long\n");
exit(1);
}
if ((i%2)==0) {
mac[i/2]=atoh(*str)<<4;
} else {
mac[i/2]+=atoh(*str);
}
i++;
do { // skip junk
str++;
} while (*str==':' || *str=='-') ;
}
if (i!=12) {
usage();
fprintf(stderr, "ERROR: Mac address too short\n");
exit(1);
}
}
main (int argc, char **argv) {
int s=IVD;
unsigned char buf[6];
char *frommac,*tomac;
int i,ntr;
if (argc%2 != 1) {
usage();
exit(1);
} else {
ntr=(argc-1)/2;
}
// initialize user custom mac replacement
frommac=(char*)malloc(6*ntr);
tomac=(char*)malloc(6*ntr);
for (i=0; i<ntr; i++) {
strtomac(&frommac[i*6],argv[i*2+1]);
strtomac(&tomac[i*6],argv[i*2+2]);
}
// read, check and write magic
if (fread(buf,4,1,stdin)!=1) {
fprintf(stderr, "Error reading input");
exit(1);
}
if( memcmp( buf, IVSONLY_MAGIC, 4 ) != 0 ) {
fprintf(stderr, "Error: Input is not an .ivs file\n" );
exit(1);
}
fwrite(buf,4,1,stdout);
while (1) {
// s = state representing what we read just before
switch(s) {
case IVD:
// read 6 bytes, either: mac address or ff+iv+data
if(fread(buf,6,1,stdin)!=1) // detect eof
exit(0);
// Fix buggy bcast for 7F:FF:FF:FF:FF:FF
if (memcmp(buf,BCAST,6)==0) {
buf[0]=0x7F;
}
// User custom replaces
for (i=0; i<ntr; i++) {
if (memcmp(buf, &frommac[i*6], 6)==0) {
memcpy(buf, &tomac[i*6], 6);
}
}
// Detect next
if (buf[0] != (unsigned char)'\xff') { // next will be a mac
s=M;
} else { // next will be an iv and data
s=IVD;
}
// Write the 6 bytes, either FF+IV+data or mac
fwrite(buf,6,1,stdout);
break;
case M:
if(fread(buf,5,1,stdin)!=1) // detect eof
exit(0);
s=IVD;
// write the 5 bytes of the iv+data
fwrite(buf,5,1,stdout);
break;
}
}
return 0;
}