/****************************************************************************** * WeakCap, v.1.01 * * * * by * * * * L. Padilla (e-mail: padilla at domain "gae ucm es") * * * * Madrid, April 2005 - January 2006 * * * * Compile with: cc -O -lpcap -o weakcap weakcap.c * * Latest version at http://www.gae.ucm.es/~padilla/extrawork/weakcap.c * ******************************************************************************/ #include #include int main (int argc, char * argv[]) { char * data, errbuf[PCAP_ERRBUF_SIZE]; pcap_t * fd_pcap; pcap_dumper_t * pc_dump; struct pcap_pkthdr ph; struct bpf_program fp; int weak (unsigned char *); /* Process command line arguments */ if (argc != 4) { printf ("\nUsage: weakcap \n\n"); return 1; } /* Open net interface */ if ((fd_pcap = pcap_open_live (argv[1], 65535, 1, 0, errbuf)) == NULL) { perror ("pcap_open_live"); return -1; } /* Compile filter */ if (pcap_compile (fd_pcap, & fp, argv[3], 1, 0) == -1) { perror ("pcap_compile"); return -1; } /* Set filter */ if (pcap_setfilter (fd_pcap, & fp) == -1) { perror ("pcap_setfilter"); return -1; } /* Set nonblock mode */ if (pcap_setnonblock (fd_pcap, 0, errbuf) != 0) { perror ("pcap_setnonblock"); return -1; } /* Open output file */ if ((pc_dump = pcap_dump_open (fd_pcap, argv[2])) == NULL) { perror ("pcap_dump_open"); return -1; } while ((data = (char *) pcap_next (fd_pcap, & ph)) != NULL) /* Read loop */ if (weak ((unsigned char *) data + 24)) /* If weak IV packet */ { pcap_dump ((u_char *) pc_dump, & ph, (unsigned char *) data); /* Write packet */ pcap_dump_flush (pc_dump); /* Flush buffer to prevent loses if hanged */ } /* Close input and output sources */ pcap_close (fd_pcap); pcap_dump_close (pc_dump); return 0; } // Simplified version of airsnort's classify function int weak (unsigned char * p) { unsigned char sum, k; // Test for the FMS (A+3, N-1, X) form of IV if (p[1] == 255 && p[0] > 2 && p[0] < 16) return 1; // Test for other IVs for which it is known that // Si[1] < i and (Si[1] + Si[Si[1]]) = i + n (see FMS 7.1) sum = p[0] + p[1]; if (sum == 1 && (p[2] <= 0x0Au || p[2] == 0xFF)) return 1; k = 0xFEu - p[2]; if (sum == k && (p[2] >= 0xF2u && p[2] <= 0xFEu && p[2] != 0xFD)) return 1; return 0; }