1 /*
2 * This software is Copyright (c) 2013 Jim Fougeron jfoug AT cox dot net,
3 * Copyright (c) 2013 Dhiru Kholia <dhiru.kholia at gmail.com>
4 * and Copyright (c) 2014-2018 magnum, and it is hereby released
5 * to the general public under the following terms: Redistribution and use in
6 * source and binary forms, with or without modification, are permitted.
7 *
8 * Kudos to ZeroBeat for misc. help, and code snippets derived from hcxtools!
9 *
10 * MIC is 32-bit Message Integrity Code of DA, SA and payload.
11 * PTK is Pairwise Temporal Key, GTK is Group Temporal Key.
12 * IE are Information Elements (eg. supported or selected ciphers).
13 *
14 * AP picks random nonce (anonce).
15 * 1. AP -> STA Send anonce.
16 *
17 * STA picks random nonce (snonce) and derives PTK from
18 * PMK + anonce + snonce + AP MAC address + STA MAC address.
19 * 2. STA -> AP Send snonce, IE and encrypted MIC.
20 *
21 * AP derives PTK as above.
22 * 3. AP -> STA Send anonce, GTK, IE and encrypted MIC.
23 *
24 * 4 STA -> AP Send ACK with encrypted MIC (zeroed snonce).
25 *
26 * EAPOL addr3 is Destination (as opposed to Receiver, which is addr1).
27 */
28
29 #define __STDC_FORMAT_MACROS
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <inttypes.h>
35
36 #include "wpapcap2john.h"
37 #include "jumbo.h"
38
39 //#define WPADEBUG 1
40 #define IGNORE_MSG1 0
41 #define IGNORE_MSG2 0
42 #define IGNORE_MSG3 0
43
44 static size_t max_essid = 1024; /* Will grow automagically */
45 static size_t max_state = 1024; /* This too */
46
47 static uint64_t cur_ts64, abs_ts64, start_ts64;
48 static uint32_t pkt_num;
49 static uint8_t *full_packet;
50 static uint8_t *packet;
51 static uint8_t *packet_TA, *packet_RA, *packet_SA, *packet_DA, *bssid;
52 static uint8_t *new_p;
53 static size_t new_p_sz;
54 static int swap_needed;
55 static essid_t *essid_db; /* alloced/realloced to max_essid */
56 static int n_essid;
57 static WPA4way_t *apsta_db; /* alloced/realloced to max_state */
58 static int n_apsta;
59 static int n_handshakes, n_pmkids;
60 static int rctime = 2 * 1000000; /* 2 seconds (bumped with -r) */
61 static const char *filename;
62 static unsigned int show_unverified = 1, ignore_rc, force_fuzz;
63 static int warn_wpaclean;
64 static int warn_snaplen;
65 static int verbosity;
66 static char filter_mac[18];
67 static int filter_hit;
68 static int output_dupes;
69 static int opt_e_used;
70 static uint32_t orig_len, snap_len;
71
72 static const char cpItoa64[64] =
73 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
74 static const uint8_t bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
75 static const uint8_t l3mcast[3] = { 0x01, 0x00, 0x5e };
76
77 /*
78 * Fake 802.11 header. We use this when indata is Ethernet (not monitor mode)
79 * in order to fake a packet we can process
80 */
81 static uint8_t fake802_11[] = {
82 0x88, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x06, 0x00, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
86 };
87
88 /* Type 0 subtypes, for -vv display */
89 static const char* const ctl_subtype[16] = {
90 "Association request", "Association response", "Reassociation request",
91 "Reassociation response", "Probe request", "Probe response",
92 "Subtype 6", "Subtype 7", "Beacon", "ATIM", "Disassociation",
93 "Authentication", "Deauthentication", "Action", "Action no ack",
94 "Subtype 15"
95 };
96
97 #if HAVE___MINGW_ALIGNED_MALLOC
strdup_MSVC(const char * str)98 char *strdup_MSVC(const char *str)
99 {
100 char * s;
101 s = (char*)__mingw_aligned_malloc(strlen(str)+1, (sizeof(long long)));
102 if (s != NULL)
103 strcpy(s, str);
104 return s;
105 }
106 #endif
107
108 /*
109 * This function output data properly for JtR, in base-64 format.
110 * Original taken from hccap2john.c source, modified for this project.
111 */
code_block(unsigned char * in,unsigned char b,char * cp)112 static int code_block(unsigned char *in, unsigned char b, char *cp)
113 {
114 int cnt = 0;
115 *cp++ = cpItoa64[in[0] >> 2];
116 *cp++ = cpItoa64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
117 if (b) {
118 *cp++ = cpItoa64[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
119 *cp++ = cpItoa64[in[2] & 0x3f];
120 ++cnt;
121 } else
122 *cp++ = cpItoa64[((in[1] & 0x0f) << 2)];
123 *cp = 0;
124 return cnt+3;
125 }
126
to_mac_str(void * ptr)127 static char *to_mac_str(void *ptr)
128 {
129 static int rr;
130 static char out[4][18];
131 uint8_t *p = ptr;
132
133 if (ptr == NULL)
134 return " ";
135
136 sprintf(out[rr & 3], "%02X:%02X:%02X:%02X:%02X:%02X",
137 p[0],p[1],p[2],p[3],p[4],p[5]);
138 return out[rr++ & 3];
139 }
140
to_hex(void * ptr,int len)141 static char *to_hex(void *ptr, int len)
142 {
143 static int rr;
144 static char out[8][64];
145 uint8_t *p = ptr;
146 char *o = out[rr & 7];
147
148 while (len--) {
149 int ret = sprintf(o, "%02x", *p++);
150
151 if (ret < 0)
152 fprintf(stderr, "Error!");
153 else
154 o += ret;
155 }
156
157 return out[rr++ & 7];
158 }
159
get_essid_num(uint8_t * bssid)160 static int get_essid_num(uint8_t *bssid)
161 {
162 int i;
163
164 for (i = n_essid - 1; i >= 0; --i)
165 if (!memcmp(bssid, essid_db[i].bssid, 6))
166 return i;
167 return -1;
168 }
169
get_essid(uint8_t * bssid)170 static char *get_essid(uint8_t *bssid)
171 {
172 int ess = get_essid_num(bssid);
173
174 if (ess < 0) {
175 if (verbosity)
176 fprintf(stderr, "ESSID for %s not found\n", to_mac_str(bssid));
177 return "[NOTFOUND]";
178 }
179
180 if (essid_db[ess].essid_len == 0)
181 return to_mac_str(essid_db[ess].bssid);
182 else
183 return essid_db[ess].essid;
184 }
185
186 /*
187 * Dynamically allocate more memory for input data.
188 * Make sure newly allocated memory is initialized with zeros.
189 */
allocate_more_essid(void)190 static void allocate_more_essid(void)
191 {
192 size_t old_max = max_essid;
193
194 max_essid *= 2;
195 safe_realloc(essid_db, sizeof(essid_t) * max_essid);
196 memset(essid_db + old_max, 0, sizeof(essid_t) * old_max);
197 }
198
allocate_more_state(void)199 static void allocate_more_state(void)
200 {
201 size_t old_max = max_state;
202
203 max_state *= 2;
204 safe_realloc(apsta_db, sizeof(WPA4way_t) * max_state);
205 memset(apsta_db + old_max, 0, sizeof(WPA4way_t) * old_max);
206 }
207
208 /* Convert WPA handshakes from aircrack-ng (airodump-ng) IVS2 to JtR format */
convert_ivs2(FILE * f_in)209 static int convert_ivs2(FILE *f_in)
210 {
211 static char LastKey[2048];
212 char NewKey[2048];
213 char *cp = NewKey;
214 struct ivs2_filehdr fivs2;
215 struct ivs2_pkthdr ivs2;
216 struct ivs2_WPA_hdsk *wivs2;
217 hccap_t hccap;
218 uint8_t *ivs_buf;
219 int i;
220 size_t length, pos;
221 unsigned int pktlen;
222 unsigned char bssid[6];
223 int bssidFound = 0;
224 char essid[32 + 1];
225 unsigned char *p, *w;
226 int ess = -1;
227
228 fseek(f_in, 0, SEEK_END);
229 length = ftell(f_in);
230 fseek(f_in, 0, SEEK_SET);
231
232 safe_malloc(ivs_buf, length);
233
234 if (fread(ivs_buf, 1, 4, f_in) != 4) {
235 fprintf(stderr, "%s: fread file header failed\n", filename);
236 MEM_FREE(ivs_buf);
237 return 1;
238 }
239
240 if (memcmp(ivs_buf, IVSONLY_MAGIC, 4) == 0) {
241 fprintf(stderr, "%s: old version .ivs file, only WEP handshakes.\n",
242 filename);
243 MEM_FREE(ivs_buf);
244 return 1;
245 }
246
247 if (memcmp(ivs_buf, IVS2_MAGIC, 4) != 0) {
248 MEM_FREE(ivs_buf);
249 return 1;
250 }
251
252 if (fread(&fivs2, 1, sizeof(struct ivs2_filehdr), f_in) !=
253 (size_t) sizeof(struct ivs2_filehdr)) {
254 fprintf(stderr, "%s: fread ivs2 file header failed", filename);
255 MEM_FREE(ivs_buf);
256 return 1;
257 }
258
259 if (fivs2.version > IVS2_VERSION) {
260 fprintf(stderr,
261 "%s: wrong %s version: %d. Supported up to version %d.\n",
262 filename, IVS2_EXTENSION, fivs2.version, IVS2_VERSION);
263 MEM_FREE(ivs_buf);
264 return 1;
265 }
266
267 if (verbosity)
268 fprintf(stderr, "\n");
269 fprintf(stderr, "File %s: airodump-ng 'ivs' file (v2)\n", filename);
270
271 pos = ftell(f_in);
272
273 while (pos < length) {
274 if (fread(&ivs2, 1, sizeof(struct ivs2_pkthdr), f_in) !=
275 sizeof(struct ivs2_pkthdr)) {
276 fprintf(stderr,
277 "%s: Error reading ivs2 header at pos "Zu" of "Zu"\n",
278 filename, pos, length);
279 MEM_FREE(ivs_buf);
280 return 1;
281 }
282
283 pos += sizeof(struct ivs2_pkthdr);
284
285 pktlen = (unsigned int)ivs2.len;
286 if (pktlen+pos > length) {
287 fprintf(stderr, "%s: Invalid ivs2 packet length %u at "Zu"\n",
288 filename, pktlen, pos-sizeof(struct ivs2_pkthdr));
289 MEM_FREE(ivs_buf);
290 return 1;
291 }
292
293 if (fread(ivs_buf, 1, pktlen, f_in) != pktlen) {
294 fprintf(stderr,
295 "%s: Error reading ivs2 data (%u) at pos "Zu" of "Zu"\n",
296 filename, pktlen, pos, length);
297 MEM_FREE(ivs_buf);
298 return 1;
299 }
300
301 p = ivs_buf;
302 if (ivs2.flags & IVS2_BSSID) {
303 memcpy(bssid, p, 6);
304 p += 6;
305
306 if (verbosity >= 2)
307 fprintf(stderr, "ivs2 BSSID: %s\n", to_mac_str(bssid));
308 bssidFound = 1;
309 }
310 if (ivs2.flags & IVS2_ESSID) {
311 unsigned int ofs = (p - ivs_buf);
312 unsigned int len = pktlen - ofs;
313
314 if (len <= 0 || len > 32) {
315 fprintf(stderr, "ivs2 Invalid ESSID length (%d)\n", len);
316 continue;
317 }
318
319 memcpy(essid, p, len);
320 essid[len] = 0;
321
322 if (verbosity >= 2)
323 fprintf(stderr,"ivs2 ESSID: '%s' (%d bytes)\n", essid, len);
324 p += len;
325
326 /* Check if already in ESSID db */
327 for (i = n_essid - 1; i >= 0; --i) {
328 if (!memcmp(bssid, essid_db[i].bssid, 6) &&
329 !memcmp(essid, essid_db[i].essid, essid_db[i].essid_len)) {
330 ess = i;
331
332 break;
333 } else if (!memcmp(bssid, essid_db[i].bssid, 6)) {
334 if (verbosity >= 2)
335 fprintf(stderr, "ivs2 '%s' at %s (renamed, old '%s')\n",
336 essid, to_mac_str(essid_db[i].bssid),
337 essid_db[i].essid);
338 memcpy(essid_db[i].essid, essid, len);
339 essid_db[i].essid[len] = 0;
340 essid_db[i].essid_len = len;
341 ess = i;
342 break;
343 }
344 }
345
346 /* New entry in db */
347 if (ess < 0) {
348 ess = n_essid;
349 essid_db[n_essid].prio = 5;
350 memcpy(essid_db[n_essid].essid, essid, len);
351 essid_db[n_essid].essid[len] = 0;
352 memcpy(essid_db[n_essid].bssid, bssid, 6);
353
354 fprintf(stderr, "ivs2 '%s' at %s\n", essid, to_mac_str(bssid));
355
356 if (++n_essid >= max_state)
357 allocate_more_state();
358 }
359 } else if (bssidFound && ess < 0)
360 /* Check if already in db */
361 ess = get_essid_num(bssid);
362
363 if (ivs2.flags & IVS2_WPA) {
364 int ofs = (p - ivs_buf);
365 int len = pktlen - ofs;
366 char buf[8];
367 char anonce[9];
368 char snonce[9];
369
370 if (len != sizeof(struct ivs2_WPA_hdsk)) {
371 fprintf(stderr, "%s: Invalid WPA handshake length (%d vs %d)\n",
372 filename, len, (int)sizeof(struct ivs2_WPA_hdsk));
373 continue;
374 }
375
376 if (!bssidFound) {
377 fprintf(stderr,
378 "%s: Got WPA handshake but we don't have BSSID\n",
379 filename);
380 continue;
381 }
382
383 if (ess < 0) {
384 fprintf(stderr,
385 "%s: WPA handshake for %s but we don't have ESSID%s\n",
386 filename, to_mac_str(bssid),
387 opt_e_used ? "" : " (perhaps -e option needed?)");
388 continue;
389 }
390
391 wivs2 = (struct ivs2_WPA_hdsk*)p;
392
393 memset(&hccap, 0, sizeof(hccap_t));
394 hccap.keyver = wivs2->keyver;
395
396 memcpy(hccap.mac1, bssid, 6);
397 memcpy(hccap.mac2, wivs2->stmac, 6);
398
399 memcpy(hccap.nonce1, wivs2->snonce, 32);
400 memcpy(hccap.nonce2, wivs2->anonce, 32);
401 memcpy(hccap.keymic, wivs2->keymic, 16);
402 hccap.eapol_size = wivs2->eapol_size;
403
404 if (hccap.eapol_size > sizeof(((hccap_t*)(NULL))->eapol)) {
405 fprintf(stderr,
406 "%s: eapol size %u (too large), skipping packet\n",
407 filename, hccap.eapol_size);
408 continue;
409 }
410 if (hccap.eapol_size < 91) {
411 fprintf(stderr,
412 "%s: eapol size %u (too small), skipping packet\n",
413 filename, hccap.eapol_size);
414 continue;
415 }
416 memcpy(hccap.eapol, wivs2->eapol, wivs2->eapol_size);
417
418 /*
419 * These fields are duplicated in the hccap. We clear one of
420 * them in order to be compatible with hcxtools
421 */
422 //memset(hccap.eapol + offsetof(ieee802_1x_eapol_t, wpa_nonce), 0,
423 // sizeof(hccap.nonce1));
424 memset(hccap.eapol + offsetof(ieee802_1x_eapol_t, wpa_keymic), 0,
425 sizeof(hccap.keymic));
426
427 sprintf(anonce, "%02x%02x%02x%02x", wivs2->anonce[28],
428 wivs2->anonce[29], wivs2->anonce[30], wivs2->anonce[31]);
429 sprintf(snonce, "%02x%02x%02x%02x", wivs2->snonce[28],
430 wivs2->snonce[29], wivs2->snonce[30], wivs2->snonce[31]);
431
432 if (verbosity >= 2) {
433 fprintf(stderr,
434 "%s -> %s ivs2 WPA handshake ESSID '%s' anonce %s snonce %s state=%d keyver=%d eapolSize=%d%s%s\n",
435 to_mac_str(hccap.mac2), to_mac_str(hccap.mac1), essid,
436 anonce, snonce, wivs2->state, wivs2->keyver,
437 wivs2->eapol_size, hccap.keyver == 3 ?
438 " [AES-128-CMAC]" : "",
439 (apsta_db[ess].handshake_done) ?
440 " (4-way already seen)" : "");
441 }
442 if (output_dupes || !apsta_db[ess].handshake_done) {
443 cp = NewKey;
444 cp += sprintf(cp, "%s:$WPAPSK$%s#", essid, essid);
445
446 /* print struct in base64 format */
447 w = (unsigned char*)&hccap;
448 for (i=36; i+3 < sizeof(hccap_t); i += 3) {
449 code_block(&w[i], 1, buf);
450 cp += sprintf(cp, "%s", buf);
451 }
452 code_block(&w[i], 0, buf);
453 cp += sprintf(cp, "%s", buf);
454 cp += sprintf(cp, ":%s:%s:%s::WPA", to_hex(hccap.mac2, 6),
455 to_hex(hccap.mac1, 6),
456 to_hex(hccap.mac1, 6));
457 if (hccap.keyver > 1)
458 cp += sprintf(cp, "2");
459 if (hccap.keyver > 2)
460 cp += sprintf(cp, " CMAC");
461 if (hccap.keyver > 3)
462 cp += sprintf(cp, ", ver %d", hccap.keyver);
463 cp += sprintf(cp, ":%s", filename);
464 if (strcmp(LastKey, NewKey)) {
465 puts(NewKey);
466 fflush(stdout);
467 strcpy(LastKey, NewKey);
468 n_handshakes++;
469 }
470 /* State seems unreliable
471 if (wivs2->state == 7)
472 apsta_db[ess].handshake_done = 1;
473 */
474 }
475
476 p += len;
477 }
478
479 if (p < ivs_buf+pktlen) {
480 fprintf(stderr,
481 "%s: Unable to parse all data, unsupported flag? (%02x)\n",
482 filename, (int)ivs2.flags);
483 }
484
485 pos += pktlen;
486 }
487
488 MEM_FREE(ivs_buf);
489 return 0;
490 }
491
remove_handshake(int apsta,int handshake)492 static void remove_handshake(int apsta, int handshake)
493 {
494 MEM_FREE(apsta_db[apsta].M[handshake].eapol);
495 apsta_db[apsta].M[handshake].eapol_size = 0;
496 apsta_db[apsta].M[handshake].ts64 = 0;
497 return;
498 }
499
print_auth(int apsta,int ap_msg,int sta_msg,hccap_t hccap,int fuzz,int be)500 static void print_auth(int apsta, int ap_msg, int sta_msg,
501 hccap_t hccap, int fuzz, int be)
502 {
503 int i;
504 char TmpKey[2048], *cp = TmpKey;
505 uint8_t *w = (uint8_t *)&hccap;
506 int32_t *anonce_lsb = (int32_t*)&hccap.nonce2[28];
507 int latest = sta_msg;
508
509 if (fuzz) {
510 //fprintf(stderr, "anonce ...%08x -> ", (uint32_t)*anonce_lsb);
511 if (be == 1)
512 *anonce_lsb =
513 swap32u((uint32_t)(
514 (int32_t)swap32u((uint32_t)*anonce_lsb) + fuzz)
515 );
516 else /* LE */
517 *anonce_lsb += fuzz;
518 //fprintf(stderr, "%08x\n", (uint32_t)*anonce_lsb);
519 }
520
521 cp += sprintf(cp, "%s:$WPAPSK$%s#", get_essid(apsta_db[apsta].bssid),
522 get_essid(apsta_db[apsta].bssid));
523
524 for (i = 36; i + 3 < sizeof(hccap_t); i += 3)
525 cp += code_block(&w[i], 1, cp);
526 cp += code_block(&w[i], 0, cp);
527
528 cp += sprintf(cp, ":%s:%s:%s::WPA", to_hex(hccap.mac2, 6),
529 to_hex(hccap.mac1, 6), to_hex(hccap.mac1, 6));
530 if (hccap.keyver > 1)
531 cp += sprintf(cp, "2");
532 if (hccap.keyver > 2)
533 cp += sprintf(cp, " CMAC");
534 if (hccap.keyver > 3)
535 cp += sprintf(cp, ", ver %d", hccap.keyver);
536 cp += sprintf(cp, ", %sverified",
537 (ap_msg == 1 && sta_msg == 2) ? "not " : "");
538 if (fuzz)
539 cp += sprintf(cp, ", fuzz %d %s", fuzz, (be == 1) ? "BE" : "LE");
540 cp += sprintf(cp, ":%s", filename);
541
542 if (apsta_db[apsta].M[ap_msg].ts64 > apsta_db[apsta].M[sta_msg].ts64)
543 latest = ap_msg;
544 if (!fuzz)
545 fprintf(stderr,
546 "Dumping M%u/M%u at %u.%06u BSSID %s ESSID '%s' STA %s\n",
547 ap_msg, sta_msg,
548 (uint32_t)(apsta_db[apsta].M[latest].ts64 / 1000000),
549 (uint32_t)(apsta_db[apsta].M[latest].ts64 % 1000000),
550 to_mac_str(apsta_db[apsta].bssid),
551 get_essid(apsta_db[apsta].bssid),
552 to_mac_str(apsta_db[apsta].staid));
553 printf("%s\n", TmpKey);
554 fflush(stdout);
555 n_handshakes++;
556 }
557
558 /*
559 * We pick anonce from M1 or M3. Everything else should be from M2, or
560 * possibly from M4 unless it's zeroed out. In a pinch we can allegedly
561 * use EAPOL from M3 but then nonce fuzzing is impossible.
562 *
563 * hccapx "message pair value"
564 * val msgs EAPOL fuzzing possible rc match used here
565 * 0 M1/M2 M2 yes yes yes
566 * 1 M1/M4 M4 yes yes yes
567 * 2 M2/M3 M2 yes yes yes
568 * 3 M2/M3 M3 no yes no
569 * 4 M3/M4 M3 no yes no
570 * 5 M3/M4 M4 yes yes yes
571 * 128 M1/M2 M2 yes no yes*
572 * 129 M1/M4 M4 yes no yes*
573 * 130 M2/M3 M2 yes no yes*
574 * 131 M2/M3 M3 no no no
575 * 132 M3/M4 M3 no no no
576 * 133 M3/M4 M4 yes no yes*
577 */
dump_auth(int apsta,int ap_msg,int sta_msg,int force)578 static void dump_auth(int apsta, int ap_msg, int sta_msg, int force)
579 {
580 int i, j;
581 ieee802_1x_eapol_t *auth13 = apsta_db[apsta].M[ap_msg].eapol;
582 ieee802_1x_eapol_t *auth24 = apsta_db[apsta].M[sta_msg].eapol;
583 hccap_t hccap;
584 int this_fuzz = 0;
585 int endian = apsta_db[apsta].endian;
586 int fuzz = apsta_db[apsta].fuzz;
587 int have_pmkid = !(ap_msg || sta_msg);
588
589 if (have_pmkid)
590 apsta_db[apsta].pmkid_done = 1;
591
592 if (essid_db[get_essid_num(apsta_db[apsta].bssid)].essid_len == 0) {
593 if (essid_db[get_essid_num(apsta_db[apsta].bssid)].prio == 6) {
594 fprintf(stderr,
595 "%s: %s for %s but we don't have ESSID yet%s\n",
596 filename, have_pmkid ? "RSN IE PMKID" : "WPA handshake",
597 to_mac_str(apsta_db[apsta].bssid),
598 opt_e_used ? "" : " (perhaps -e option needed?)");
599 essid_db[get_essid_num(apsta_db[apsta].bssid)].prio = 10;
600 }
601 return;
602 }
603 if (ignore_rc && fuzz) {
604 if ((ap_msg == 1 && sta_msg == 2) || (ap_msg == 3 && sta_msg == 4))
605 this_fuzz = apsta_db[apsta].M[sta_msg].eapol->replay_cnt -
606 apsta_db[apsta].M[sta_msg].eapol->replay_cnt;
607 else
608 this_fuzz = MAX(apsta_db[apsta].M[ap_msg].eapol->replay_cnt, apsta_db[apsta].M[sta_msg].eapol->replay_cnt) - MIN(apsta_db[apsta].M[ap_msg].eapol->replay_cnt, apsta_db[apsta].M[sta_msg].eapol->replay_cnt) - 1;
609 }
610 this_fuzz = MAX(MAX(ABS(force_fuzz), ABS(this_fuzz)), fuzz);
611
612 if (fuzz < 0)
613 this_fuzz = 0 - this_fuzz;
614
615 if (verbosity && this_fuzz)
616 fprintf(stderr, "Outputting with fuzz: %d (%d seen) %s\n",
617 this_fuzz, fuzz,
618 endian ? (endian == 1 ? "BE" : "LE") : "LE/BE");
619
620 if (have_pmkid) {
621 char *essid = get_essid(apsta_db[apsta].bssid);
622
623 fprintf(stderr,
624 "Dumping RSN IE PMKID at %u.%06u BSSID %s ESSID '%s' STA %s\n",
625 (uint32_t)(apsta_db[apsta].M[0].ts64 / 1000000),
626 (uint32_t)(apsta_db[apsta].M[0].ts64 % 1000000),
627 to_mac_str(apsta_db[apsta].bssid),
628 get_essid(apsta_db[apsta].bssid),
629 to_mac_str(apsta_db[apsta].staid));
630 printf("%s:%s*%s*%s*%s:%s:%s:%s::PMKID:%s\n",
631 essid,
632 to_hex(apsta_db[apsta].M[0].eapol, 16),
633 to_hex(apsta_db[apsta].bssid, 6),
634 to_hex(apsta_db[apsta].staid, 6),
635 to_hex(essid, strlen(essid)),
636 to_hex(apsta_db[apsta].staid, 6), // uid
637 to_hex(apsta_db[apsta].bssid, 6), // gid
638 to_hex(apsta_db[apsta].bssid, 6), // gecos
639 filename);
640 fflush(stdout);
641
642 n_pmkids++;
643 remove_handshake(apsta, 0);
644 return;
645 }
646
647 if (!auth24) {
648 fprintf(stderr, "ERROR, M%u null\n", sta_msg);
649 return;
650 }
651
652 if (!auth13) {
653 fprintf(stderr, "ERROR, M%u null\n", ap_msg);
654 return;
655 }
656
657 memset(&hccap, 0, sizeof(hccap_t));
658 hccap.keyver = auth24->key_info.KeyDescr;
659 memcpy(hccap.mac1, apsta_db[apsta].bssid, 6);
660 memcpy(hccap.mac2, apsta_db[apsta].staid, 6);
661 memcpy(hccap.nonce1, auth24->wpa_nonce, 32);
662 memcpy(hccap.nonce2, auth13->wpa_nonce, 32);
663 memcpy(hccap.keymic, auth24->wpa_keymic, 16);
664
665 #if ARCH_LITTLE_ENDIAN
666 /* Endian-swap stuff back before storage */
667 auth24->length = swap16u(auth24->length);
668 auth24->key_info_u16 = swap16u(auth24->key_info_u16);
669 auth24->key_len = swap16u(auth24->key_len);
670 auth24->replay_cnt = swap64u(auth24->replay_cnt);
671 auth24->wpa_keydatlen = swap16u(auth24->wpa_keydatlen);
672 #endif
673
674 hccap.eapol_size = apsta_db[apsta].M[sta_msg].eapol_size;
675 memcpy(hccap.eapol, auth24, hccap.eapol_size);
676
677 /*
678 * These fields are duplicated in the hccap. We clear one of
679 * them in order to be compatible with hcxtools
680 */
681 //memset(hccap.eapol + offsetof(ieee802_1x_eapol_t, wpa_nonce), 0,
682 // sizeof(hccap.nonce1));
683 memset(hccap.eapol + offsetof(ieee802_1x_eapol_t, wpa_keymic), 0,
684 sizeof(hccap.keymic));
685
686 /* Non-fuzzed first */
687 print_auth(apsta, ap_msg, sta_msg, hccap, 0, 0);
688
689 /* If endianness unknown, we fuzz LE and BE */
690 for (j = (endian ? endian : 1); j <= (endian ? endian : 2); j++) {
691 /* Fuzz negative */
692 if (fuzz < 0 || force_fuzz)
693 for (i = -1; i >= (0 - this_fuzz); i--)
694 print_auth(apsta, ap_msg, sta_msg, hccap, i, j);
695
696 /* Fuzz positive */
697 if (fuzz > 0 || force_fuzz)
698 for (i = 1; i <= this_fuzz; i++)
699 print_auth(apsta, ap_msg, sta_msg, hccap, i, j);
700 }
701
702 if (MAX(ap_msg, sta_msg) > 2 || force) {
703 apsta_db[apsta].handshake_done = 1;
704 remove_handshake(apsta, 1);
705 remove_handshake(apsta, 2);
706 remove_handshake(apsta, 3);
707 remove_handshake(apsta, 4);
708 }
709 }
710
dump_late()711 static void dump_late() {
712 int printed = 0;
713 int i;
714
715 for (i = 0; i < n_apsta; i++)
716 if (apsta_db[i].M[0].eapol)
717 dump_auth(i, 0, 0, 1);
718
719 for (i = 0; i < n_apsta; i++) {
720 int ap_msg = 0, sta_msg = 0;
721
722 if (apsta_db[i].M[1].eapol)
723 ap_msg = 1;
724 if (apsta_db[i].M[2].eapol)
725 sta_msg = 2;
726 if (apsta_db[i].M[3].eapol)
727 ap_msg = 3;
728 if (apsta_db[i].M[4].eapol)
729 sta_msg = 4;
730
731 if (ap_msg && sta_msg) {
732 if (verbosity && !printed++)
733 fprintf(stderr, "Dumping unverified and/or post-poned data\n");
734 dump_auth(i, ap_msg, sta_msg, show_unverified);
735 }
736 }
737 }
738
learn_essid(uint16_t subtype,int has_ht,uint8_t * bssid)739 static void learn_essid(uint16_t subtype, int has_ht, uint8_t *bssid)
740 {
741 ieee802_1x_frame_hdr_t *pkt = (ieee802_1x_frame_hdr_t*)packet;
742 ieee802_1x_beacon_tag_t *tag;
743 uint8_t *pFinal = &packet[snap_len];
744 char essid[32 + 1];
745 int essid_len = 0;
746 int prio = 0;
747 int i;
748
749 if (subtype == 8 || subtype == 5) { /* beacon or probe response */
750 ieee802_1x_beacon_data_t *pDat = (ieee802_1x_beacon_data_t*)&packet[sizeof(ieee802_1x_frame_hdr_t) + (has_ht ? 4 : 0)];
751 tag = pDat->tags;
752 prio = (subtype == 8 ? 5 : 3);
753 } else if (subtype == 4) { /* probe request */
754 tag = (ieee802_1x_beacon_tag_t*)&packet[sizeof(ieee802_1x_frame_hdr_t) + (has_ht ? 4 : 0)];
755 prio = 4;
756 } else if (subtype == 0) { /* association request */
757 ieee802_1x_assocreq_t *pDat = (ieee802_1x_assocreq_t*)&packet[sizeof(ieee802_1x_frame_hdr_t) + (has_ht ? 4 : 0)];
758 tag = pDat->tags;
759 prio = 2;
760 } else if (subtype == 2) { /* re-association request */
761 ieee802_1x_reassocreq_t *pDat = (ieee802_1x_reassocreq_t*)&packet[sizeof(ieee802_1x_frame_hdr_t) + (has_ht ? 4 : 0)];
762 tag = pDat->tags;
763 prio = 1;
764 } else if (subtype == 11) {
765 ieee802_1x_auth_t *p = (ieee802_1x_auth_t*)&packet[sizeof(ieee802_1x_frame_hdr_t) + (has_ht ? 4 : 0)];
766 if (verbosity >= 2 && filter_hit) {
767 if (p->algo == 0)
768 fprintf(stderr, "WPA authentication, status %04x\n", p->status);
769 else if (p->algo == 1)
770 fprintf(stderr, "WEP authentication, status %04x\n", p->status);
771 else
772 fprintf(stderr, "Authentication %04x, status %04x\n",
773 p->algo, p->status);
774 }
775 return;
776 } else {
777 if (verbosity >= 2 && filter_hit)
778 fprintf(stderr, "%s\n", ctl_subtype[subtype]);
779 return;
780 }
781
782 /*
783 * addr1 (dst) should be broadcast for beacon, unicast for probe response
784 * addr2 (src) is source addr (should be same as BSSID for beacons)
785 * addr3 is BSSID (routers MAC)
786 *
787 * Walk the tags (actually tag 0 allegedly always come first, but WTH)
788 */
789 while (((uint8_t*)tag) < pFinal) {
790 char *x = (char*)tag;
791 if (x + 2 > (char*)pFinal || x + 2 + tag->taglen > (char*)pFinal)
792 break;
793 if (tag->tagtype == 0) {
794 if (tag->taglen == 0 || tag->taglen > 32) {
795 if (!filter_hit || !verbosity)
796 return;
797 fprintf(stderr, "%s %s ESSID", ctl_subtype[subtype],
798 tag->taglen ? "with invalid length" : "for any");
799 if (memcmp(pkt->addr1, pkt->addr3, 6))
800 fprintf(stderr, " (BSSID %s)\n", to_mac_str(bssid));
801 else
802 fprintf(stderr, "\n");
803 return;
804 }
805 essid_len = tag->taglen;
806 memcpy(essid, tag->tag, essid_len + 1);
807 essid[essid_len] = 0;
808 break;
809 }
810 x += tag->taglen + 2;
811 tag = (ieee802_1x_beacon_tag_t *)x;
812 }
813 if (strlen(essid) == 0) {
814 if (verbosity >= 2 && filter_hit)
815 fprintf(stderr, "%s with ESSID length 0\n", ctl_subtype[subtype]);
816 return;
817 }
818 if (pkt->addr3 + 6 > pFinal) {
819 if (verbosity >= 2 && filter_hit)
820 fprintf(stderr, "%s with malformed data\n", ctl_subtype[subtype]);
821 return;
822 }
823
824 if (!memcmp(pkt->addr3, bcast, 6)) {
825 if (verbosity >= 2 && filter_hit)
826 fprintf(stderr, "Broadcast %s '%s'\n",
827 ctl_subtype[subtype], essid);
828 return;
829 }
830
831 if (verbosity >= 2 && filter_hit && !memcmp(l3mcast, pkt->addr3, 3))
832 fprintf(stderr, "[IPv4 mcast BSSID] ");
833 else if (verbosity >= 2 && filter_hit && (pkt->addr3[0] & 0x03) == 0x03)
834 fprintf(stderr, "[LA mcast BSSID] ");
835 else if (verbosity >= 2 && filter_hit && pkt->addr3[0] & 0x01)
836 fprintf(stderr, "[mcast BSSID] ");
837 else if (verbosity >= 2 && filter_hit && pkt->addr3[0] & 0x02)
838 fprintf(stderr, "[LA BSSID] ");
839
840 /* Check if already in db, or older entry has worse prio */
841 for (i = n_essid - 1; i >= 0; --i) {
842 if (!memcmp(bssid, essid_db[i].bssid, 6) &&
843 essid_db[i].prio > 5) {
844 essid_db[i].essid_len = essid_len;
845 memcpy(essid_db[i].essid, essid, essid_len);
846 essid_db[i].essid[essid_len] = 0;
847 if (verbosity && filter_hit)
848 fprintf(stderr, "%s '%s' at %s (name found, prio %d -> %d)\n",
849 ctl_subtype[subtype], essid_db[i].essid,
850 to_mac_str(essid_db[i].bssid),
851 essid_db[i].prio, prio);
852 essid_db[i].prio = prio;
853 return;
854 } else if (!memcmp(bssid, essid_db[i].bssid, 6) &&
855 essid_len == essid_db[i].essid_len &&
856 !memcmp(essid, essid_db[i].essid, essid_len)) {
857 if (essid_db[i].prio > prio) {
858 if (verbosity && filter_hit)
859 fprintf(stderr, "%s '%s' at %s (prio %d -> %d)\n",
860 ctl_subtype[subtype], essid_db[i].essid,
861 to_mac_str(essid_db[i].bssid),
862 essid_db[i].prio, prio);
863 essid_db[i].prio = prio;
864 } else {
865 if (verbosity && filter_hit)
866 fprintf(stderr, "%s '%s' at %s\n", ctl_subtype[subtype],
867 essid_db[i].essid, to_mac_str(essid_db[i].bssid));
868 }
869 return;
870 } else if (!memcmp(bssid, essid_db[i].bssid, 6)) {
871 if (essid_db[i].prio >= prio) {
872 if (verbosity && filter_hit)
873 fprintf(stderr,
874 "%s '%s' at %s (renamed, old '%s' prio %d, new prio %d)\n",
875 ctl_subtype[subtype], essid,
876 to_mac_str(essid_db[i].bssid), essid_db[i].essid,
877 essid_db[i].prio, prio);
878 break;
879 }
880 }
881 }
882
883 essid_db[n_essid].prio = prio;
884 essid_db[n_essid].essid_len = essid_len;
885 memcpy(essid_db[n_essid].essid, essid, essid_len);
886 essid_db[n_essid].essid[essid_len] = 0;
887 memcpy(essid_db[n_essid].bssid, bssid, 6);
888
889 if (verbosity && filter_hit)
890 fprintf(stderr, "%s '%s' at %s\n",
891 ctl_subtype[subtype], essid, to_mac_str(bssid));
892
893 if (++n_essid >= max_essid)
894 allocate_more_essid();
895 }
896
is_zero(void * ptr,size_t len)897 static int is_zero(void *ptr, size_t len)
898 {
899 unsigned char *p = ptr;
900
901 while (len--)
902 if (*p++)
903 return 0;
904 return 1;
905 }
906
handle4way(ieee802_1x_eapol_t * auth,uint8_t * bssid)907 static void handle4way(ieee802_1x_eapol_t *auth, uint8_t *bssid)
908 {
909 uint8_t *end = packet + snap_len;
910 int i;
911 int apsta = -1, ess = -1;
912 int msg = 0;
913 uint8_t *staid;
914 uint32_t nonce_msb; /* First 32 bits of nonce */
915 uint32_t nonce_lsb; /* Last 32 bits of nonce */
916 uint64_t rc;
917 int eapol_sz;
918
919 if ((uint8_t*)auth + sizeof(ieee802_1x_eapol_t) > end) {
920 if (verbosity >= 2)
921 fprintf(stderr, "EAPOL truncated?\n");
922 return;
923 }
924
925 if (auth->length == 0) {
926 if (verbosity >= 2)
927 fprintf(stderr, "Zero length\n");
928 return;
929 }
930
931 #if ARCH_LITTLE_ENDIAN
932 /* Swap things from network order */
933 auth->length = swap16u(auth->length);
934 auth->key_info_u16 = swap16u(auth->key_info_u16);
935 auth->key_len = swap16u(auth->key_len);
936 auth->replay_cnt = swap64u(auth->replay_cnt);
937 auth->wpa_keydatlen = swap16u(auth->wpa_keydatlen);
938 #endif
939
940 nonce_msb = (uint32_t)auth->wpa_nonce[0] << 24 |
941 (uint32_t)auth->wpa_nonce[1] << 16 |
942 (uint32_t)auth->wpa_nonce[2] << 8 |
943 auth->wpa_nonce[3];
944 nonce_lsb = (uint32_t)auth->wpa_nonce[28] << 24 |
945 (uint32_t)auth->wpa_nonce[29] << 16 |
946 (uint32_t)auth->wpa_nonce[30] << 8 |
947 auth->wpa_nonce[31];
948 rc = auth->replay_cnt;
949
950 if (verbosity >= 3) {
951 fprintf(stderr,
952 "EAPOL breakdown:\n"
953 "\tver %02x type %02x length %d key_descr %02x",
954 auth->ver, auth->type, auth->length, auth->key_descr);
955 fprintf(stderr, " key_info %d %d %d %d %d %d %d %d %d\n",
956 auth->key_info.KeyDescr, auth->key_info.KeyType,
957 auth->key_info.KeyIdx, auth->key_info.Install,
958 auth->key_info.KeyACK,
959 auth->key_info.Secure, auth->key_info.Error,
960 auth->key_info.Reqst, auth->key_info.EncKeyDat);
961 fprintf(stderr, "\tkey_len %d replay_cnt %"PRIu64"\n",
962 auth->key_len, auth->replay_cnt);
963 dump_hex("\tnonce", auth->wpa_nonce, sizeof(auth->wpa_nonce));
964 dump_hex("\tkeyiv", auth->wpa_keyiv, sizeof(auth->wpa_keyiv));
965 dump_hex("\tkeyrsc", auth->wpa_keyrsc, sizeof(auth->wpa_keyrsc));
966 dump_hex("\tkeyid", auth->wpa_keyid, sizeof(auth->wpa_keyid));
967 if (auth->key_info.KeyMIC || !is_zero(auth->wpa_keymic,
968 sizeof(auth->wpa_keymic)))
969 dump_hex("\tmic", auth->wpa_keymic, sizeof(auth->wpa_keymic));
970 fprintf(stderr, "\tkeydatlen %d ", auth->wpa_keydatlen);
971 }
972
973 if (!auth->key_info.KeyACK) {
974 staid = packet_TA;
975 if (auth->key_info.Secure || auth->wpa_keydatlen == 0) {
976 msg = 4;
977 } else {
978 msg = 2;
979 }
980 } else {
981 staid = packet_RA;
982 if (auth->key_info.Install) {
983 msg = 3;
984 } else {
985 msg = 1;
986 }
987 }
988
989
990 /* Find the ESSID in our db. */
991 ess = get_essid_num(bssid);
992 if (ess == -1) {
993 ess = n_essid;
994 essid_db[ess].prio = 6;
995 essid_db[ess].essid_len = 0;
996 essid_db[ess].essid[0] = 0;
997 memcpy(essid_db[ess].bssid, bssid, 6);
998
999 if (++n_essid >= max_essid)
1000 allocate_more_essid();
1001 }
1002
1003 /* Find the AP/STA pair in our db. */
1004 for (i = n_apsta - 1; i >= 0; --i) {
1005 if (!memcmp(bssid, apsta_db[i].bssid, 6) &&
1006 !memcmp(staid, apsta_db[i].staid, 6) &&
1007 MAX(rc, apsta_db[i].rc) - MIN(rc, apsta_db[i].rc) <= 64) {
1008 apsta = i;
1009 break;
1010 }
1011 }
1012 if (apsta == -1) {
1013 apsta = n_apsta++;
1014 memcpy(apsta_db[apsta].bssid, bssid, 6);
1015 memcpy(apsta_db[apsta].staid, staid, 6);
1016 if (n_apsta >= max_state)
1017 allocate_more_state();
1018 }
1019 apsta_db[apsta].rc = rc;
1020
1021 if (auth->wpa_keydatlen == 22) {
1022 keydata_t *keydata = ((eapol_keydata_t*)auth)->tag;
1023
1024 if ((keydata->tagtype == 0xdd || keydata->tagtype == 0x14) &&
1025 !memcmp(keydata->oui, "\x00\x0f\xac", 3) &&
1026 keydata->oui_type == 0x04) {
1027 if (is_zero(keydata->data, 16)) {
1028 if (verbosity >= 2)
1029 fprintf(stderr, "RSN IE w/ all-zero PMKID\n");
1030 } else {
1031 if (verbosity >= 3)
1032 dump_hex("RSN IE PMKID", keydata->data, 16);
1033 if (apsta_db[apsta].pmkid_done) {
1034 if (verbosity >= 2)
1035 fprintf(stderr, "RSN IE PMKID (already seen)\n");
1036 } else if (!apsta_db[apsta].M[0].eapol) {
1037 /* PMKID is better than a handshake! */
1038 apsta_db[apsta].M[0].eapol_size = 16;
1039 apsta_db[apsta].M[0].ts64 = cur_ts64;
1040 safe_malloc(apsta_db[apsta].M[0].eapol, 16);
1041 memcpy(apsta_db[apsta].M[0].eapol, keydata->data, 16);
1042 if (verbosity >= 2)
1043 fprintf(stderr, "RSN IE PMKID\n");
1044 dump_auth(apsta, 0, 0, 0);
1045 }
1046 }
1047 return;
1048 }
1049 }
1050
1051 if (msg == 1 || msg == 3) {
1052 if (nonce_msb == apsta_db[apsta].anonce_msb &&
1053 nonce_lsb != apsta_db[apsta].anonce_lsb) {
1054 int8_t fuzz = apsta_db[apsta].fuzz;
1055 if ((nonce_lsb & 0x00ffffff) ==
1056 (apsta_db[apsta].anonce_lsb & 0x00ffffff)) {
1057 uint32_t nonce1 = swap32u(apsta_db[apsta].anonce_lsb);
1058 uint32_t nonce2 = swap32u(nonce_lsb);
1059
1060 if (nonce2 < nonce1)
1061 apsta_db[apsta].fuzz = MIN(fuzz, (int8_t)(nonce2 - nonce1));
1062 else if (nonce2 - nonce1 > 1)
1063 apsta_db[apsta].fuzz = MAX(fuzz, (int8_t)(nonce2 - nonce1));
1064 if (apsta_db[apsta].fuzz && verbosity >= 2)
1065 fprintf(stderr, "anonce LSB inc fuzz %d LE ",
1066 apsta_db[apsta].fuzz);
1067 apsta_db[apsta].endian = 2;
1068 }
1069 else if ((nonce_lsb & 0xffffff00) ==
1070 (apsta_db[apsta].anonce_lsb & 0xffffff00)) {
1071 uint32_t nonce1 = apsta_db[apsta].anonce_lsb;
1072 uint32_t nonce2 = nonce_lsb;
1073
1074 if (nonce2 < nonce1)
1075 apsta_db[apsta].fuzz = MIN(fuzz, (int8_t)(nonce2 - nonce1));
1076 else if (nonce2 - nonce1 > 1)
1077 apsta_db[apsta].fuzz = MAX(fuzz, (int8_t)(nonce2 - nonce1));
1078 if (apsta_db[apsta].fuzz && verbosity >= 2)
1079 fprintf(stderr, "anonce LSB inc fuzz %d BE ",
1080 apsta_db[apsta].fuzz);
1081 apsta_db[apsta].endian = 1;
1082 }
1083 }
1084 apsta_db[apsta].anonce_msb = nonce_msb;
1085 apsta_db[apsta].anonce_lsb = nonce_lsb;
1086 }
1087
1088 if (msg > 1) {
1089 int i;
1090
1091 for (i = msg - 1; i > 0; i--) {
1092 int stp = msg - i;
1093
1094 if (apsta_db[apsta].M[i].eapol &&
1095 cur_ts64 >= apsta_db[apsta].M[i].ts64 &&
1096 cur_ts64 - apsta_db[apsta].M[i].ts64 > stp * rctime) {
1097 if (verbosity >= 3)
1098 fprintf(stderr, "[discarding stale M%d from %u.%06u] ",
1099 i, (uint32_t)(apsta_db[apsta].M[i].ts64 / 1000000),
1100 (uint32_t)(apsta_db[apsta].M[i].ts64 % 1000000));
1101 remove_handshake(apsta, i);
1102 }
1103 }
1104 }
1105
1106 if (!output_dupes && apsta_db[apsta].handshake_done) {
1107 if (verbosity >= 2)
1108 fprintf(stderr,
1109 "EAPOL M%u, %cnonce %08x...%08x rc %"PRIu64"%s (4-way already seen)\n",
1110 msg, (msg == 1 || msg == 3) ? 'a' : 's',
1111 nonce_msb, nonce_lsb, rc,
1112 auth->key_info.KeyDescr == 3 ? " [AES-128-CMAC]" : "");
1113 return; /* no reason to go on. */
1114 }
1115
1116 /* This is canonical for any encapsulations */
1117 eapol_sz = auth->length + 4;
1118
1119 if (msg == 4 && is_zero(auth->wpa_nonce, 32)) {
1120 if (verbosity >= 2)
1121 fprintf(stderr,
1122 "Spurious unusable M4 (anonce nulled) rc %"PRIu64"\n", rc);
1123 return;
1124 }
1125
1126 /*
1127 * If we see M1 followed by M2 which have same replay_cnt, we have a likely
1128 * auth. Or we want a M2 followed by a M3 that are 1 replay count apart
1129 * which means we DO have an auth.
1130 * The M3 is not returned unless the M2 (which came from the client), IS
1131 * valid. So, we get the anonce from either the M1 or the M3 packet.
1132 *
1133 * For our first run, we output ALL valid auths found in the file. That way,
1134 * I can validate that any auths which were produced by aircrack-ng are valid/
1135 * or not. aircrack-ng WILL generate some invalid auths. Also, I want to flag
1136 * "unknown" auths as just that, unk. These are M1-M2's which do not have
1137 * valid M3-M4's. They may be valid, but may also be a client with the wrong
1138 * password.
1139 */
1140 if (msg == 1 && !IGNORE_MSG1) {
1141 if (apsta_db[apsta].M[1].eapol) {
1142 ieee802_1x_eapol_t *auth1 = apsta_db[apsta].M[1].eapol;
1143
1144 if (auth->replay_cnt == auth1->replay_cnt &&
1145 !memcmp(auth->wpa_nonce, auth1->wpa_nonce, 32)) {
1146 if (verbosity >= 2)
1147 fprintf(stderr,
1148 "dupe M1 anonce %08x...%08x rc %"PRIu64"%s\n",
1149 nonce_msb, nonce_lsb, rc,
1150 auth->key_info.KeyDescr == 3 ?
1151 " [AES-128-CMAC]" : "");
1152 apsta_db[apsta].M[1].ts64 = cur_ts64;
1153 return;
1154 }
1155 if (show_unverified && apsta_db[apsta].M[2].eapol) {
1156 ieee802_1x_eapol_t *auth2 = apsta_db[apsta].M[2].eapol;
1157
1158 if (ignore_rc || auth1->replay_cnt == auth2->replay_cnt) {
1159 if (verbosity >= 2)
1160 fprintf(stderr, "Dumping older M1/M2 seen%s\n",
1161 auth1->replay_cnt == auth2->replay_cnt ?
1162 "" : " (rc mismatch)");
1163 dump_auth(apsta, 1, 2, 0);
1164 }
1165 }
1166 }
1167 if (verbosity >= 2)
1168 fprintf(stderr, "EAPOL M1 anonce %08x...%08x rc %"PRIu64"%s\n",
1169 nonce_msb, nonce_lsb, rc,
1170 auth->key_info.KeyDescr == 3 ? " [AES-128-CMAC]" : "");
1171 remove_handshake(apsta, 1);
1172 remove_handshake(apsta, 2);
1173 remove_handshake(apsta, 3);
1174 remove_handshake(apsta, 4);
1175 memcpy(apsta_db[apsta].bssid, packet_TA, 6);
1176 memcpy(apsta_db[apsta].staid, packet_RA, 6);
1177 apsta_db[apsta].M[1].eapol_size = eapol_sz;
1178 apsta_db[apsta].M[1].ts64 = cur_ts64;
1179 safe_malloc(apsta_db[apsta].M[1].eapol, eapol_sz);
1180 memcpy(apsta_db[apsta].M[1].eapol, auth, eapol_sz);
1181 }
1182
1183 else if (msg == 2 && !IGNORE_MSG2) {
1184 if (apsta_db[apsta].M[2].eapol) {
1185 /* Check for dupe */
1186 ieee802_1x_eapol_t *auth2 = apsta_db[apsta].M[2].eapol;
1187
1188 if (!memcmp(auth->wpa_keymic, auth2->wpa_keymic, 16)) {
1189 if (verbosity >= 2)
1190 fprintf(stderr,
1191 "dupe M2 snonce %08x...%08x rc %"PRIu64"%s\n",
1192 nonce_msb, nonce_lsb, rc,
1193 auth->key_info.KeyDescr == 3 ?
1194 " [AES-128-CMAC]" : "");
1195 apsta_db[apsta].M[2].ts64 = cur_ts64;
1196 return;
1197 }
1198 if (show_unverified && apsta_db[apsta].M[1].eapol) {
1199 ieee802_1x_eapol_t *auth1 = apsta_db[apsta].M[1].eapol;
1200
1201 if (ignore_rc || auth1->replay_cnt == auth2->replay_cnt) {
1202 if (verbosity >= 2)
1203 fprintf(stderr,
1204 "EAPOL M2, already got one. Dumping old%s\n",
1205 auth1->replay_cnt == auth2->replay_cnt ?
1206 "" : " (rc mismatch)");
1207 dump_auth(apsta, 1, 2, 0);
1208 }
1209 }
1210 }
1211
1212 remove_handshake(apsta, 2);
1213 remove_handshake(apsta, 3);
1214 remove_handshake(apsta, 4);
1215 memcpy(apsta_db[apsta].staid, packet_TA, 6);
1216 memcpy(apsta_db[apsta].bssid, packet_RA, 6);
1217 apsta_db[apsta].M[2].eapol_size = eapol_sz;
1218 apsta_db[apsta].M[2].ts64 = cur_ts64;
1219 safe_malloc(apsta_db[apsta].M[2].eapol, eapol_sz);
1220 memcpy(apsta_db[apsta].M[2].eapol, auth, eapol_sz);
1221
1222 if (eapol_sz > sizeof(((hccap_t*)(NULL))->eapol)) {
1223 if (verbosity)
1224 fprintf(stderr,
1225 "%s: eapol size %u (too large), skipping packet\n",
1226 filename, eapol_sz);
1227 apsta_db[apsta].M[2].eapol_size = 0;
1228 remove_handshake(apsta, 2);
1229 return;
1230 }
1231 if (eapol_sz < 91) {
1232 if (verbosity)
1233 fprintf(stderr,
1234 "%s: eapol size %u (too small), skipping packet\n",
1235 filename, eapol_sz);
1236 apsta_db[apsta].M[2].eapol_size = 0;
1237 remove_handshake(apsta, 2);
1238 return;
1239 }
1240
1241 /* see if we have a M1 that 'matches'. */
1242 if (apsta_db[apsta].M[1].eapol) {
1243 ieee802_1x_eapol_t *auth2 = auth;
1244 ieee802_1x_eapol_t *auth1 = apsta_db[apsta].M[1].eapol;
1245
1246 if (ignore_rc || auth1->replay_cnt == auth2->replay_cnt) {
1247 if (verbosity >= 2)
1248 fprintf(stderr,
1249 "EAPOL M2 snonce %08x...%08x rc %"PRIu64" for '%s'%s (M1 seen%s)\n",
1250 nonce_msb, nonce_lsb, rc,
1251 get_essid(apsta_db[apsta].bssid),
1252 auth->key_info.KeyDescr == 3 ?
1253 " [AES-128-CMAC]" : "",
1254 auth1->replay_cnt == auth2->replay_cnt ?
1255 "" : " (rc mismatch)");
1256 } else {
1257 if (verbosity >= 2)
1258 fprintf(stderr,
1259 "Spurious M2 snonce %08x...%08x rc %"PRIu64"%s\n",
1260 nonce_msb, nonce_lsb, rc,
1261 auth->key_info.KeyDescr == 3 ?
1262 " [AES-128-CMAC]" : "");
1263 //remove_handshake(apsta, 1);
1264 }
1265 } else {
1266 if (verbosity >= 2)
1267 fprintf(stderr,
1268 "Spurious M2 snonce %08x...%08x rc %"PRIu64"%s\n",
1269 nonce_msb, nonce_lsb, rc, auth->key_info.KeyDescr == 3 ?
1270 " [AES-128-CMAC]" : "");
1271 }
1272 return;
1273 }
1274
1275 else if (msg == 3 && !IGNORE_MSG3) {
1276 /*
1277 * Either we have a M2 that 'matches', (1 less than our replay count)
1278 * or we get a matching M4 (with non-zeroed data) in the future
1279 */
1280 remove_handshake(apsta, 3);
1281 remove_handshake(apsta, 4);
1282 memcpy(apsta_db[apsta].bssid, packet_TA, 6);
1283 memcpy(apsta_db[apsta].staid, packet_RA, 6);
1284 apsta_db[apsta].M[3].eapol_size = eapol_sz;
1285 apsta_db[apsta].M[3].ts64 = cur_ts64;
1286 safe_malloc(apsta_db[apsta].M[3].eapol, eapol_sz);
1287 memcpy(apsta_db[apsta].M[3].eapol, auth, eapol_sz);
1288
1289 if (apsta_db[apsta].M[2].eapol) {
1290 ieee802_1x_eapol_t *auth3 = auth;
1291 ieee802_1x_eapol_t *auth2 = apsta_db[apsta].M[2].eapol;
1292
1293 if (ignore_rc || auth2->replay_cnt + 1 == auth3->replay_cnt) {
1294 ieee802_1x_eapol_t *auth1 = NULL;
1295
1296 if (apsta_db[apsta].M[1].eapol)
1297 auth1 = apsta_db[apsta].M[1].eapol;
1298
1299 /*
1300 * If we saw the M1, its nonce must match the M3 nonce and we
1301 * are 100% sure. If we didn't see it, we are only 99% sure.
1302 */
1303 if (!apsta_db[apsta].M[1].eapol ||
1304 !memcmp(auth1->wpa_nonce, auth3->wpa_nonce, 32)) {
1305 if (verbosity)
1306 fprintf(stderr,
1307 "EAPOL M3 anonce %08x...%08x rc %"PRIu64" for '%s'%s (M2 seen%s, M1%s seen)\n",
1308 nonce_msb, nonce_lsb, rc,
1309 get_essid(apsta_db[apsta].bssid),
1310 auth->key_info.KeyDescr == 3 ?
1311 " [AES-128-CMAC]" : "",
1312 auth2->replay_cnt + 1 == auth3->replay_cnt ?
1313 "" : " (rc mismatch)",
1314 apsta_db[apsta].M[1].eapol ? "" : " not");
1315 dump_auth(apsta, 3, 2, 0);
1316 return;
1317 }
1318 }
1319 }
1320
1321 if (verbosity >= 2)
1322 fprintf(stderr,
1323 "EAPOL M3 anonce %08x...%08x rc %"PRIu64"%s (no M2 seen)\n",
1324 nonce_msb, nonce_lsb, rc, auth->key_info.KeyDescr == 3 ?
1325 " [AES-128-CMAC]" : "");
1326 return;
1327 }
1328
1329 else if (msg == 4) {
1330 if (eapol_sz > sizeof(((hccap_t*)(NULL))->eapol)) {
1331 if (verbosity)
1332 fprintf(stderr,
1333 "%s: eapol size %u (too large), skipping packet\n",
1334 filename, eapol_sz);
1335 apsta_db[apsta].M[4].eapol_size = 0;
1336 remove_handshake(apsta, 4);
1337 return;
1338 }
1339 if (eapol_sz < 91) {
1340 if (verbosity)
1341 fprintf(stderr,
1342 "%s: eapol size %u (too small), skipping packet\n",
1343 filename, eapol_sz);
1344 apsta_db[apsta].M[4].eapol_size = 0;
1345 remove_handshake(apsta, 4);
1346 return;
1347 }
1348
1349 remove_handshake(apsta, 2);
1350 remove_handshake(apsta, 4);
1351 memcpy(apsta_db[apsta].staid, packet_TA, 6);
1352 memcpy(apsta_db[apsta].bssid, packet_RA, 6);
1353 apsta_db[apsta].M[4].eapol_size = eapol_sz;
1354 apsta_db[apsta].M[4].ts64 = cur_ts64;
1355 safe_malloc(apsta_db[apsta].M[4].eapol, eapol_sz);
1356 memcpy(apsta_db[apsta].M[4].eapol, auth, eapol_sz);
1357
1358 /* see if we have a M1 or M3 that 'matches'. */
1359 if (apsta_db[apsta].M[3].eapol) {
1360 ieee802_1x_eapol_t *auth4 = auth;
1361 ieee802_1x_eapol_t *auth3 = apsta_db[apsta].M[3].eapol;
1362
1363 if (ignore_rc || auth3->replay_cnt == auth4->replay_cnt) {
1364 if (verbosity)
1365 fprintf(stderr,
1366 "EAPOL M4 snonce %08x...%08x rc %"PRIu64" for '%s'%s (M3 seen%s)\n",
1367 nonce_msb, nonce_lsb, rc,
1368 get_essid(apsta_db[apsta].bssid),
1369 auth->key_info.KeyDescr == 3 ?
1370 " [AES-128-CMAC]" : "",
1371 auth3->replay_cnt == auth4->replay_cnt ?
1372 "" : " (rc mismatch)");
1373 dump_auth(apsta, 3, 4, 0);
1374 return;
1375 }
1376 }
1377 if (apsta_db[apsta].M[1].eapol) {
1378 ieee802_1x_eapol_t *auth4 = auth;
1379 ieee802_1x_eapol_t *auth1 = apsta_db[apsta].M[1].eapol;
1380
1381 if (ignore_rc || auth1->replay_cnt + 1 == auth4->replay_cnt) {
1382 if (verbosity)
1383 fprintf(stderr,
1384 "EAPOL M4 snonce %08x...%08x rc %"PRIu64" for '%s'%s (M1 seen%s)\n",
1385 nonce_msb, nonce_lsb, rc,
1386 get_essid(apsta_db[apsta].bssid),
1387 auth->key_info.KeyDescr == 3 ?
1388 " [AES-128-CMAC]" : "",
1389 auth1->replay_cnt + 1 == auth4->replay_cnt ?
1390 "" : " (rc mismatch)");
1391 dump_auth(apsta, 1, 4, 0);
1392 return;
1393 } else {
1394 if (verbosity >= 2)
1395 fprintf(stderr,
1396 "EAPOL M4 snonce %08x...%08x rc %"PRIu64" %s (no M1/M3 seen)\n",
1397 nonce_msb, nonce_lsb, rc,
1398 auth->key_info.KeyDescr == 3 ?
1399 " [AES-128-CMAC]" : "");
1400 }
1401
1402 } else {
1403 if (verbosity >= 2)
1404 fprintf(stderr,
1405 "%sM4 snonce %08x...%08x rc %"PRIu64"%s\n",
1406 (apsta_db[apsta].M[1].eapol ||
1407 apsta_db[apsta].M[3].eapol) ?
1408 "" : "Spurious ",
1409 nonce_msb, nonce_lsb, rc,
1410 auth->key_info.KeyDescr == 3 ? " [AES-128-CMAC]" : "");
1411 }
1412 } else
1413 if (verbosity >= 2)
1414 fprintf(stderr, "not EAPOL\n");
1415 }
1416
1417 /*
1418 * This function is the main packet processor. When we are done
1419 * reading packets (i.e. we have done what we want), we return 0, and
1420 * the program will exit gracefully. It is not an error, it is just an
1421 * indication we have completed (or that the data we want is not here).
1422 */
process_packet(uint32_t link_type)1423 static int process_packet(uint32_t link_type)
1424 {
1425 static const char *last_f;
1426 static uint32_t last_l;
1427 ieee802_1x_frame_hdr_t *pkt;
1428 ieee802_1x_frame_ctl_t *ctl;
1429 unsigned int frame_skip = 0;
1430 int has_ht;
1431 unsigned int tzsp_link = 0;
1432
1433 if (filename != last_f || link_type != last_l) {
1434 last_f = filename;
1435 last_l = link_type;
1436
1437 if (link_type == LINKTYPE_IEEE802_11)
1438 fprintf(stderr, "File %s: raw 802.11\n", filename);
1439 else if (link_type == LINKTYPE_PRISM_HEADER)
1440 fprintf(stderr, "File %s: Prism encapsulation\n", filename);
1441 else if (link_type == LINKTYPE_RADIOTAP_HDR)
1442 fprintf(stderr, "File %s: Radiotap encapsulation\n", filename);
1443 else if (link_type == LINKTYPE_PPI_HDR)
1444 fprintf(stderr, "File %s: PPI encapsulation\n", filename);
1445 else if (link_type == LINKTYPE_ETHERNET) {
1446 unsigned char *packet = full_packet;
1447
1448 if (snap_len > 47 &&
1449 packet[12] == 0x08 && packet[13] == 0x00 && // IPv4
1450 packet[23] == 17 && // UDP
1451 packet[42] == 0x01 && packet[44] == 0) // TZSP
1452 {
1453 if (packet[45] == 18)
1454 fprintf(stderr, "File %s: 802.11 over TZSP\n", filename);
1455 else if (packet[45] == 119)
1456 fprintf(stderr, "File %s: Prism over TZSP\n", filename);
1457 else
1458 fprintf(stderr, "File %s: TZSP unknown encapsulation %02x\n",
1459 filename, packet[45]);
1460 } else
1461 fprintf(stderr, "File %s: Ethernet encapsulation\n", filename);
1462 } else {
1463 fprintf(stderr,
1464 "File %s: No 802.11 wireless traffic data (network %d)\n",
1465 filename, link_type);
1466 return 0;
1467 }
1468 }
1469
1470 packet = full_packet;
1471 pkt_num++;
1472
1473 /*
1474 * Handle TZSP over UDP. This is just a hack[tm].
1475 */
1476 if (snap_len > 47 && link_type == LINKTYPE_ETHERNET &&
1477 packet[12] == 0x08 && packet[13] == 0x00 && // IPv4
1478 packet[23] == 17 && // UDP
1479 packet[42] == 0x01 && packet[44] == 0) { // TZSP
1480
1481 if (packet[45] == 18)
1482 tzsp_link = LINKTYPE_IEEE802_11;
1483 else if (packet[45] == 119)
1484 tzsp_link = LINKTYPE_PRISM_HEADER;
1485 else
1486 return 0;
1487
1488 packet += 46;
1489 snap_len -= 46;
1490 orig_len -= 46;
1491
1492 while (packet[0] != 0x01) {
1493 int len = packet[1] + 2;
1494
1495 packet += len;
1496 snap_len -= len;
1497 orig_len -= len;
1498 }
1499 packet += 1;
1500 snap_len -= 1;
1501 orig_len -= 1;
1502 }
1503
1504 /* Skip Prism frame if present */
1505 if (link_type == LINKTYPE_PRISM_HEADER ||
1506 tzsp_link == LINKTYPE_PRISM_HEADER) {
1507 if (snap_len < 8)
1508 return 0;
1509 if (packet[7] == 0x40)
1510 frame_skip = 64;
1511 else {
1512 frame_skip = *(unsigned int*)&packet[4];
1513 #if !ARCH_LITTLE_ENDIAN
1514 frame_skip = swap32u(frame_skip);
1515 #endif
1516 }
1517 if (frame_skip < 8 || frame_skip >= snap_len)
1518 return 0;
1519 packet += frame_skip;
1520 snap_len -= frame_skip;
1521 orig_len -= frame_skip;
1522 }
1523
1524 /* Skip Radiotap frame if present */
1525 if (link_type == LINKTYPE_RADIOTAP_HDR) {
1526 if (snap_len < 4)
1527 return 0;
1528 frame_skip = *(unsigned short*)&packet[2];
1529 #if !ARCH_LITTLE_ENDIAN
1530 frame_skip = swap32u(frame_skip);
1531 #endif
1532 if (frame_skip == 0 || frame_skip >= snap_len)
1533 return 0;
1534 packet += frame_skip;
1535 snap_len -= frame_skip;
1536 orig_len -= frame_skip;
1537 }
1538
1539 /* Skip PPI frame if present */
1540 if (link_type == LINKTYPE_PPI_HDR) {
1541 if (snap_len < 4)
1542 return 0;
1543 frame_skip = *(unsigned short*)&packet[2];
1544 #if !ARCH_LITTLE_ENDIAN
1545 frame_skip = swap32u(frame_skip);
1546 #endif
1547 if (frame_skip <= 0 || frame_skip >= snap_len)
1548 return 0;
1549
1550 /* Kismet logged broken PPI frames for a period */
1551 if (frame_skip == 24 && *(unsigned short*)&packet[8] == 2)
1552 frame_skip = 32;
1553
1554 if (frame_skip == 0 || frame_skip >= snap_len)
1555 return 0;
1556 packet += frame_skip;
1557 snap_len -= frame_skip;
1558 orig_len -= frame_skip;
1559 }
1560
1561 /*
1562 * Handle Ethernet EAPOL data if present. This is typically a pcap
1563 * sniffed in non-monitor-mode.
1564 * We strip the ethernet header and add a fake 802.11 header instead.
1565 */
1566 if (link_type == LINKTYPE_ETHERNET &&
1567 packet[12] == 0x88 && packet[13] == 0x8e) {
1568 int new_len = snap_len - 12 + sizeof(fake802_11);
1569 ieee802_1x_eapol_t *auth;
1570
1571 //dump_hex("Orig packet", packet, snap_len);
1572
1573 if (new_len > new_p_sz) {
1574 safe_realloc(new_p, new_len);
1575 new_p_sz = new_len;
1576 }
1577 /* Start with some fake 802.11 header data */
1578 memcpy(new_p, fake802_11, sizeof(fake802_11));
1579 /* Put original src and dest in the fake 802.11 header */
1580 memcpy(new_p + 4, packet, 12);
1581 /* Add original EAPOL data */
1582 memcpy(new_p + sizeof(fake802_11), packet + 12, snap_len - 12);
1583
1584 auth = (ieee802_1x_eapol_t*)&packet[14];
1585 auth->key_info_u16 = swap16u(auth->key_info_u16);
1586 /* Add the BSSID to the 802.11 header */
1587 if (auth->key_info.KeyACK)
1588 memcpy(new_p + 16, packet + 6, 6);
1589 else
1590 memcpy(new_p + 16, packet, 6);
1591
1592 snap_len += sizeof(fake802_11) - 12;
1593 orig_len += sizeof(fake802_11) - 12;
1594 packet = new_p;
1595 //dump_hex("Fake packet", packet, snap_len);
1596 }
1597
1598 /* our data is in *packet */
1599 pkt = (ieee802_1x_frame_hdr_t*)packet;
1600
1601 if (snap_len < 10) {
1602 if (verbosity >= 2)
1603 fprintf(stderr, "Truncated data\n");
1604 return 0;
1605 }
1606
1607 packet_RA = pkt->addr1;
1608 packet_TA = (snap_len >= 16) ? pkt->addr2 : NULL;
1609
1610 ctl = (ieee802_1x_frame_ctl_t *)&pkt->frame_ctl;
1611
1612 if (ctl->toDS == 0 && ctl->fromDS == 0) {
1613 packet_DA = packet_RA;
1614 packet_SA = packet_TA;
1615 bssid = (snap_len >= 22) ? pkt->addr3 : NULL;
1616 } else if (ctl->toDS == 0 && ctl->fromDS == 1) {
1617 packet_DA = packet_RA;
1618 packet_SA = (snap_len >= 22) ? pkt->addr3 : NULL;
1619 bssid = packet_TA;
1620 } else if (ctl->toDS == 1 && ctl->fromDS == 0) {
1621 bssid = packet_RA;
1622 packet_SA = packet_TA;
1623 packet_DA = (snap_len >= 22) ? pkt->addr3 : NULL;
1624 } else /*if (ctl->toDS == 1 && ctl->fromDS == 1)*/ {
1625 packet_DA = (snap_len >= 22) ? pkt->addr3 : NULL;
1626 packet_SA = (snap_len >= 30) ? &packet[24] : NULL; // addr4
1627 bssid = packet_TA; /* If anything */
1628 }
1629
1630 filter_hit = (!filter_mac[0] ||
1631 !strcmp(filter_mac, to_mac_str(packet_RA)) ||
1632 (packet_TA && !strcmp(filter_mac, to_mac_str(packet_TA))) ||
1633 (packet_SA && !strcmp(filter_mac, to_mac_str(packet_SA))) ||
1634 (packet_DA && !strcmp(filter_mac, to_mac_str(packet_DA))));
1635
1636 if (verbosity >= 2 && filter_hit) {
1637 if (verbosity >= 4)
1638 dump_hex("802.11 packet", pkt, snap_len);
1639
1640 if (verbosity >= 4)
1641 fprintf(stderr, "%4d %2u.%06u %s -> %s %-4d ", pkt_num,
1642 (uint32_t)(abs_ts64 / 1000000),
1643 (uint32_t)(abs_ts64 % 1000000),
1644 to_mac_str(packet_TA),
1645 to_mac_str(packet_RA), snap_len);
1646 else
1647 fprintf(stderr, "%4d %2u.%06u %s -> %s %-4d ", pkt_num,
1648 (uint32_t)(cur_ts64 / 1000000),
1649 (uint32_t)(cur_ts64 % 1000000),
1650 to_mac_str(packet_TA),
1651 to_mac_str(packet_RA), snap_len);
1652
1653 if (verbosity >= 3)
1654 fprintf(stderr, "\n\tRA %s TA %s DA %s SA %s BSSID %s",
1655 packet_RA ? to_hex(packet_RA, 6) : "null",
1656 packet_TA ? to_hex(packet_TA, 6) : "null",
1657 packet_DA ? to_hex(packet_DA, 6) : "null",
1658 packet_SA ? to_hex(packet_SA, 6) : "null",
1659 bssid ? to_hex(bssid, 6) : "null");
1660
1661 if (verbosity >= 2 && filter_hit && packet_TA) {
1662 if (!memcmp(l3mcast, packet_TA, 3))
1663 fprintf(stderr, "[IPv4 mcast src] ");
1664 else if ((packet_TA[0] & 0x03) == 0x03)
1665 fprintf(stderr, "[LA mcast src] ");
1666 else if (packet_TA[0] & 0x01)
1667 fprintf(stderr, "[mcast src] ");
1668 else if (packet_TA[0] & 0x02)
1669 fprintf(stderr, "[LA src] ");
1670 }
1671 if (verbosity >= 2 && filter_hit && memcmp(packet_RA, bcast, 6)) {
1672 if (!memcmp(l3mcast, packet_RA, 3))
1673 fprintf(stderr, "[IPv4 mcast] ");
1674 else if ((packet_RA[0] & 0x03) == 0x03)
1675 fprintf(stderr, "[LA mcast] ");
1676 else if (packet_RA[0] & 0x01)
1677 fprintf(stderr, "[mcast] ");
1678 else if (packet_RA[0] & 0x02)
1679 fprintf(stderr, "[LA dst] ");
1680 }
1681 }
1682
1683 has_ht = (ctl->order == 1); /* 802.11n, 4 extra bytes MAC header */
1684
1685 if (has_ht && verbosity >= 2 && filter_hit)
1686 fprintf(stderr, "[802.11n] ");
1687
1688 /*
1689 * Type 0 is management,
1690 * Beacon is subtype 8 and probe response is subtype 5
1691 * probe request is 4, assoc request is 0, reassoc is 2
1692 */
1693 if (ctl->type == 0 && bssid) {
1694 learn_essid(ctl->subtype, has_ht, bssid);
1695 return 1;
1696 }
1697
1698 if (!filter_hit && (memcmp(bcast, packet_RA, 6) || packet_TA != NULL))
1699 return 1;
1700
1701 /* if not beacon or probe response, then look only for EAPOL 'type' */
1702 if (ctl->type == 2) { /* type 2 is data */
1703 uint8_t *p = packet;
1704 int has_qos = (ctl->subtype & 8) != 0;
1705 int has_addr4 = ctl->toDS & ctl->fromDS;
1706
1707 if (has_qos && verbosity >= 2)
1708 fprintf(stderr, "[QoS] ");
1709 if (has_addr4 && verbosity >= 2)
1710 fprintf(stderr, "[a4] ");
1711
1712 if (!has_addr4 && ((ctl->toDS ^ ctl->fromDS) != 1)) {
1713 /* eapol will ONLY be direct toDS or direct fromDS. */
1714 if (verbosity >= 2)
1715 fprintf(stderr, "Data\n");
1716 return 1;
1717 }
1718 if (sizeof(ieee802_1x_frame_hdr_t)+6+2+
1719 (has_qos?2:0)+(has_ht?4:0)+(has_addr4?6:0) >=
1720 snap_len) {
1721 if (verbosity >= 2)
1722 fprintf(stderr, "QoS Null or malformed EAPOL\n");
1723 return 1;
1724 }
1725 /* Ok, find out if this is an EAPOL packet or not. */
1726
1727 p += sizeof(ieee802_1x_frame_hdr_t);
1728 if (has_addr4)
1729 p += 6;
1730 if (has_qos)
1731 p += 2;
1732 /*
1733 * p now points to the start of the LLC
1734 * this is 8 bytes long, and the last 2 bytes are the 'type' field. What
1735 * we are looking for is 802.1X authentication packets. These are 0x888e
1736 * in value. We are running from an LE point of view, so should look for 0x8e88
1737 */
1738 p += 6;
1739 if (*((uint16_t*)p) == 0x8e88) {
1740 eapext_t *eap;
1741
1742 p += 2;
1743 if (has_ht)
1744 p += 4;
1745 eap = (eapext_t*)p;
1746
1747 if (eap->type == 0) {
1748 if (snap_len < sizeof(eapext_t) + (has_qos ? 10 : 8)) {
1749 fprintf(stderr, "%s: truncated packet\n", filename);
1750 return 1;
1751 }
1752 if (eap->eaptype == EAP_TYPE_ID &&
1753 eap->eapcode == EAP_CODE_RESP) {
1754 /* Identity response */
1755 int len = swap16u(eap->eaplen) - 5;
1756 char *id;
1757
1758 p += sizeof(eapext_t);
1759 safe_malloc(id, len + 1);
1760 memcpy(id, p, len);
1761 id[len] = 0;
1762 if (verbosity >= 2)
1763 fprintf(stderr, "EAP Identity Response: '%s'\n", id);
1764 MEM_FREE(id);
1765 return 1;
1766 }
1767 } else if (eap->type == 1) {
1768 if (verbosity >= 2)
1769 fprintf(stderr, "EAP Start\n");
1770 return 1;
1771 } else if (eap->type == 3) {
1772 /* EAP key */
1773 if (snap_len < sizeof(ieee802_1x_frame_hdr_t) +
1774 (has_qos ? 10 : 8)) {
1775 fprintf(stderr, "%s: truncated packet\n", filename);
1776 } else if (bssid)
1777 handle4way((ieee802_1x_eapol_t*)p, bssid);
1778 return 1;
1779 } else {
1780 if (verbosity >= 2)
1781 fprintf(stderr, "EAP type %d\n", eap->type);
1782 return 1;
1783 }
1784 }
1785 }
1786
1787 if (verbosity >= 2) {
1788 int ts = (ctl->type << 4) | ctl->subtype;
1789
1790 if (ctl->type == 0)
1791 fprintf(stderr, "%s\n", ctl_subtype[ctl->subtype]);
1792 else if (ts == 0x15)
1793 fprintf(stderr, "VHT NDP Announcement\n");
1794 else if (ts == 0x18)
1795 fprintf(stderr, "Block Ack Req\n");
1796 else if (ts == 0x19)
1797 fprintf(stderr, "Block Ack\n");
1798 else if (ts == 0x1b)
1799 fprintf(stderr, "RTS\n");
1800 else if (ts == 0x1c)
1801 fprintf(stderr, "CTS\n");
1802 else if (ts == 0x1d)
1803 fprintf(stderr, "Ack\n");
1804 else if (ts >= 0x20 && ts <= 0x23)
1805 fprintf(stderr, "Data\n");
1806 else if (ts > 0x23 && ts < 0x30)
1807 fprintf(stderr, "QoS Data\n");
1808 else
1809 fprintf(stderr, "Type %d subtype %d\n", ctl->type, ctl->subtype);
1810 }
1811
1812 return 1;
1813 }
1814
pcapng_option_print(FILE * in,size_t len,size_t pad_len,char * name,int verb_lvl)1815 int pcapng_option_print(FILE *in, size_t len, size_t pad_len,
1816 char *name, int verb_lvl)
1817 {
1818 char *string;
1819
1820 safe_malloc(string, pad_len + 1);
1821
1822 if (fread(string, 1, pad_len, in) != pad_len) {
1823 fprintf(stderr, "Malformed %s data in %s\n", name, filename);
1824 MEM_FREE(string);
1825 return 1;
1826 }
1827 if (verbosity >= verb_lvl) {
1828 // These strings are NOT null-terminated unless they happen to be padded
1829 string[len] = 0;
1830 fprintf(stderr, "File %s %s: %s\n", filename, name, string);
1831 }
1832
1833 MEM_FREE(string);
1834 return 0;
1835 }
1836
pcapng_option_walk(FILE * in,uint32_t tl)1837 void pcapng_option_walk(FILE *in, uint32_t tl)
1838 {
1839 uint16_t res;
1840 uint16_t padding;
1841 option_header_t opthdr;
1842 uint16_t len, pad_len;
1843
1844 while (1) {
1845 res = fread(&opthdr, 1, OH_SIZE, in);
1846 if (res != OH_SIZE) {
1847 fprintf(stderr, "Malformed data in %s\n", filename);
1848 break;
1849 }
1850 if (opthdr.option_code == 0) {
1851 break;
1852 }
1853 padding = 0;
1854 len = opthdr.option_length;
1855 if ((len % 4))
1856 padding = 4 - (len % 4);
1857
1858 pad_len = len + padding;
1859
1860 if (pad_len > tl) {
1861 fprintf(stderr, "Malformed data in %s\n", filename);
1862 break;
1863 }
1864 tl -= pad_len;
1865
1866 if (opthdr.option_code == 1) {
1867 if (pcapng_option_print(in, len, pad_len, "comment", 0))
1868 break;
1869 } else if (opthdr.option_code == 2) {
1870 if (pcapng_option_print(in, len, pad_len, "hwinfo", 1))
1871 break;
1872 } else if (opthdr.option_code == 3) {
1873 if (pcapng_option_print(in, len, pad_len, "osinfo", 1))
1874 break;
1875 } else if (opthdr.option_code == 4) {
1876 if (pcapng_option_print(in, len, pad_len, "appinfo", 1))
1877 break;
1878 } else {
1879 // Just skip unknown options
1880 fseek(in, pad_len, SEEK_CUR);
1881 }
1882 }
1883 }
1884
process_ng(FILE * in)1885 static int process_ng(FILE *in)
1886 {
1887 unsigned int res;
1888 int aktseek;
1889
1890 block_header_t pcapngbh;
1891 section_header_block_t pcapngshb;
1892 interface_description_block_t pcapngidb;
1893 packet_block_t pcapngpb;
1894 enhanced_packet_block_t pcapngepb;
1895
1896 while (1) {
1897 res = fread(&pcapngbh, 1, BH_SIZE, in);
1898 if (res == 0) {
1899 break;
1900 }
1901 if (res != BH_SIZE) {
1902 printf("failed to read pcapng header block\n");
1903 break;
1904 }
1905 if (pcapngbh.block_type == PCAPNGBLOCKTYPE) {
1906 res = fread(&pcapngshb, 1, SHB_SIZE, in);
1907 if (res != SHB_SIZE) {
1908 printf("failed to read pcapng section header block\n");
1909 break;
1910 }
1911 #if !ARCH_LITTLE_ENDIAN
1912 pcapngbh.total_length = swap32u(pcapngbh.total_length);
1913 pcapngshb.byte_order_magic = swap32u(pcapngshb.byte_order_magic);
1914 pcapngshb.major_version = swap16u(pcapngshb.major_version);
1915 pcapngshb.minor_version = swap16u(pcapngshb.minor_version);
1916 pcapngshb.section_length = swap64u(pcapngshb.section_length);
1917 #endif
1918 if (pcapngshb.byte_order_magic == PCAPNGMAGICNUMBERBE) {
1919 swap_needed = 1;
1920 pcapngbh.total_length = swap32u(pcapngbh.total_length);
1921 pcapngshb.byte_order_magic = swap32u(pcapngshb.byte_order_magic);
1922 pcapngshb.major_version = swap16u(pcapngshb.major_version);
1923 pcapngshb.minor_version = swap16u(pcapngshb.minor_version);
1924 pcapngshb.section_length = swap64u(pcapngshb.section_length);
1925 }
1926 aktseek = ftell(in);
1927 if (pcapngbh.total_length > (SHB_SIZE + BH_SIZE + 4)) {
1928 pcapng_option_walk(in, pcapngbh.total_length);
1929 }
1930 fseek(in, aktseek + pcapngbh.total_length - BH_SIZE - SHB_SIZE, SEEK_SET);
1931 continue;
1932 }
1933 #if !ARCH_LITTLE_ENDIAN
1934 pcapngbh.block_type = swap32u(pcapngbh.block_type);
1935 pcapngbh.total_length = swap32u(pcapngbh.total_length);
1936 #endif
1937 if (swap_needed == 1) {
1938 pcapngbh.block_type = swap32u(pcapngbh.block_type);
1939 pcapngbh.total_length = swap32u(pcapngbh.total_length);
1940 }
1941
1942 if (pcapngbh.block_type == 1) {
1943 res = fread(&pcapngidb, 1, IDB_SIZE, in);
1944 if (res != IDB_SIZE) {
1945 printf("failed to get pcapng interface description block\n");
1946 break;
1947 }
1948 #if !ARCH_LITTLE_ENDIAN
1949 pcapngidb.linktype = swap16u(pcapngidb.linktype);
1950 pcapngidb.snaplen = swap32u(pcapngidb.snaplen);
1951 #endif
1952 if (swap_needed == 1) {
1953 pcapngidb.linktype = swap16u(pcapngidb.linktype);
1954 pcapngidb.snaplen = swap32u(pcapngidb.snaplen);
1955 }
1956
1957 fseek(in, pcapngbh.total_length - BH_SIZE - IDB_SIZE, SEEK_CUR);
1958 }
1959
1960 else if (pcapngbh.block_type == 2) {
1961 res = fread(&pcapngpb, 1, PB_SIZE, in);
1962 if (res != PB_SIZE) {
1963 printf("failed to get pcapng packet block (obsolete)\n");
1964 break;
1965 }
1966 #if !ARCH_LITTLE_ENDIAN
1967 pcapngpb.interface_id = swap16u(pcapngpb.interface_id);
1968 pcapngpb.drops_count = swap16u(pcapngpb.drops_count);
1969 pcapngpb.timestamp_high = swap32u(pcapngpb.timestamp_high);
1970 pcapngpb.timestamp_low = swap32u(pcapngpb.timestamp_low);
1971 pcapngpb.caplen = swap32u(pcapngpb.caplen);
1972 pcapngpb.len = swap32u(pcapngpb.len);
1973 #endif
1974 if (swap_needed == 1) {
1975 pcapngpb.interface_id = swap16u(pcapngpb.interface_id);
1976 pcapngpb.drops_count = swap16u(pcapngpb.drops_count);
1977 pcapngpb.timestamp_high = swap32u(pcapngpb.timestamp_high);
1978 pcapngpb.timestamp_low = swap32u(pcapngpb.timestamp_low);
1979 pcapngpb.caplen = swap32u(pcapngpb.caplen);
1980 pcapngpb.len = swap32u(pcapngpb.len);
1981 }
1982
1983 if ((pcapngepb.timestamp_high == 0) &&
1984 (pcapngepb.timestamp_low == 0) && !warn_wpaclean++)
1985 fprintf(stderr,
1986 "**\n** Warning: %s seems to be processed with some dubious tool like\n"
1987 "** 'wpaclean'. Important information may be lost.\n**\n", filename);
1988
1989 MEM_FREE(full_packet);
1990 safe_malloc(full_packet, pcapngepb.caplen);
1991 res = fread(full_packet, 1, pcapngpb.caplen, in);
1992 if (res != pcapngpb.caplen) {
1993 printf("failed to read packet: %s truncated?\n", filename);
1994 break;
1995 }
1996 fseek(in, pcapngbh.total_length - BH_SIZE - PB_SIZE - pcapngepb.caplen, SEEK_CUR);
1997
1998 MEM_FREE(full_packet);
1999 safe_malloc(full_packet, pcapngepb.caplen);
2000 res = fread(full_packet, 1, pcapngpb.caplen, in);
2001 if (res != pcapngpb.caplen) {
2002 printf("failed to read packet: %s truncated?\n", filename);
2003 break;
2004 }
2005
2006 fseek(in, pcapngbh.total_length - BH_SIZE - PB_SIZE - pcapngpb.caplen, SEEK_CUR);
2007 }
2008
2009 else if (pcapngbh.block_type == 3) {
2010 fseek(in, pcapngbh.total_length - BH_SIZE, SEEK_CUR);
2011 }
2012
2013 else if (pcapngbh.block_type == 4) {
2014 fseek(in, pcapngbh.total_length - BH_SIZE, SEEK_CUR);
2015 }
2016
2017 else if (pcapngbh.block_type == 5) {
2018 fseek(in, pcapngbh.total_length - BH_SIZE, SEEK_CUR);
2019 }
2020
2021 else if (pcapngbh.block_type == 6) {
2022 res = fread(&pcapngepb, 1, EPB_SIZE, in);
2023 if (res != EPB_SIZE) {
2024 printf("failed to get pcapng enhanced packet block\n");
2025 break;
2026 }
2027 #if !ARCH_LITTLE_ENDIAN
2028 pcapngepb.interface_id = swap32u(pcapngepb.interface_id);
2029 pcapngepb.timestamp_high = swap32u(pcapngepb.timestamp_high);
2030 pcapngepb.timestamp_low = swap32u(pcapngepb.timestamp_low);
2031 pcapngepb.caplen = swap32u(pcapngepb.caplen);
2032 pcapngepb.len = swap32u(pcapngepb.len);
2033 #endif
2034 if (swap_needed == 1) {
2035 pcapngepb.interface_id = swap32u(pcapngepb.interface_id);
2036 pcapngepb.timestamp_high = swap32u(pcapngepb.timestamp_high);
2037 pcapngepb.timestamp_low = swap32u(pcapngepb.timestamp_low);
2038 pcapngepb.caplen = swap32u(pcapngepb.caplen);
2039 pcapngepb.len = swap32u(pcapngepb.len);
2040 }
2041
2042 MEM_FREE(full_packet);
2043 safe_malloc(full_packet, pcapngepb.caplen);
2044 res = fread(full_packet, 1, pcapngepb.caplen, in);
2045 if (res != pcapngepb.caplen) {
2046 printf("failed to read packet: %s truncated?\n", filename);
2047 break;
2048 }
2049 fseek(in, pcapngbh.total_length - BH_SIZE - EPB_SIZE - pcapngepb.caplen, SEEK_CUR);
2050 } else {
2051 fseek(in, pcapngbh.total_length - BH_SIZE, SEEK_CUR);
2052 }
2053 if (pcapngepb.caplen > 0) {
2054 snap_len = pcapngepb.caplen;
2055 orig_len = pcapngepb.len;
2056 // FIXME: Honor if_tsresol from Interface Description Block
2057 abs_ts64 = (((uint64_t)pcapngepb.timestamp_high << 32) +
2058 pcapngepb.timestamp_low);
2059 if (!start_ts64)
2060 start_ts64 = abs_ts64;
2061 cur_ts64 = abs_ts64 - start_ts64;
2062 if (!process_packet(pcapngidb.linktype))
2063 break;
2064 }
2065 }
2066 if (verbosity >= 2)
2067 fprintf(stderr, "File %s: End of data\n", filename);
2068 dump_late();
2069 return 1;
2070 }
2071
get_next_packet(FILE * in)2072 static int get_next_packet(FILE *in)
2073 {
2074 size_t read_size;
2075 pcaprec_hdr_t pkt_hdr;
2076
2077 if (fread(&pkt_hdr, 1, sizeof(pkt_hdr), in) != sizeof(pkt_hdr))
2078 return 0;
2079
2080 if (swap_needed) {
2081 pkt_hdr.ts_sec = swap32u(pkt_hdr.ts_sec);
2082 pkt_hdr.ts_usec = swap32u(pkt_hdr.ts_usec);
2083 pkt_hdr.snap_len = swap32u(pkt_hdr.snap_len);
2084 pkt_hdr.orig_len = swap32u(pkt_hdr.orig_len);
2085 }
2086
2087 snap_len = pkt_hdr.snap_len;
2088 orig_len = pkt_hdr.orig_len;
2089
2090 if (pkt_hdr.ts_sec == 0 && pkt_hdr.ts_usec == 0 && !warn_wpaclean++)
2091 fprintf(stderr,
2092 "**\n** Warning: %s seems to be processed with some dubious tool like\n"
2093 "** 'wpaclean'. Important information may be lost.\n**\n", filename);
2094
2095 if (orig_len > snap_len && !warn_snaplen++)
2096 fprintf(stderr,
2097 "**\n** Warning: %s seems to be recorded with insufficient snaplen, packet was %u bytes but only %u bytes were recorded\n**\n",
2098 filename, orig_len, snap_len);
2099
2100 abs_ts64 = pkt_hdr.ts_sec * 1000000 + pkt_hdr.ts_usec;
2101
2102 if (!start_ts64)
2103 start_ts64 = abs_ts64;
2104
2105 cur_ts64 = abs_ts64 - start_ts64;
2106
2107 MEM_FREE(full_packet);
2108 safe_malloc(full_packet, snap_len);
2109 read_size = fread(full_packet, 1, snap_len, in);
2110 if (verbosity && read_size < snap_len)
2111 fprintf(stderr, "%s: truncated last packet\n", filename);
2112
2113 return (read_size == snap_len);
2114 }
2115
process(FILE * in)2116 static int process(FILE *in)
2117 {
2118 pcap_hdr_t main_hdr;
2119
2120 if (fread(&main_hdr, 1, sizeof(pcap_hdr_t), in) != sizeof(pcap_hdr_t)) {
2121 fprintf(stderr,
2122 "%s: Error, could not read enough bytes to get a common 'main' pcap header\n",
2123 filename);
2124 return 0;
2125 }
2126 if (main_hdr.magic_number == 0xa1b2c3d4)
2127 swap_needed = 0;
2128 else if (main_hdr.magic_number == 0xd4c3b2a1)
2129 swap_needed = 1;
2130 else if (main_hdr.magic_number == PCAPNGBLOCKTYPE) {
2131 fseek(in, 0, SEEK_SET);
2132 return process_ng(in);
2133 } else {
2134 if (convert_ivs2(in)) {
2135 fprintf(stderr, "%s: unknown file. Supported formats are pcap, pcap-ng and ivs2.\n", filename);
2136 return 0;
2137 }
2138 return 1;
2139 }
2140
2141 if (swap_needed) {
2142 main_hdr.magic_number = swap32u(main_hdr.magic_number);
2143 main_hdr.version_major = swap16u(main_hdr.version_major);
2144 main_hdr.version_minor = swap16u(main_hdr.version_minor);
2145 main_hdr.sigfigs = swap32u(main_hdr.sigfigs);
2146 main_hdr.snaplen = swap32u(main_hdr.snaplen);
2147 main_hdr.network = swap32u(main_hdr.network);
2148 }
2149
2150
2151 while (get_next_packet(in)) {
2152 if (!process_packet(main_hdr.network)) {
2153 break;
2154 }
2155 }
2156
2157 if (verbosity >= 2)
2158 fprintf(stderr, "File %s: End of data\n", filename);
2159 dump_late();
2160 return 1;
2161 }
2162
e_fail(void)2163 static void e_fail(void)
2164 {
2165 fprintf(stderr, "Incorrect -e option.\n");
2166 exit(EXIT_FAILURE);
2167 }
2168
manual_beacon(char * essid_bssid)2169 static void manual_beacon(char *essid_bssid)
2170 {
2171 char *essid = essid_bssid;
2172 char *bssid = strchr(essid_bssid, ':');
2173 uint8_t *bssid_bin = essid_db[n_apsta].bssid;
2174 int l = 0;
2175
2176 if (!bssid)
2177 e_fail();
2178
2179 *bssid++ = 0;
2180 if (strlen(essid) > 32 || strlen(bssid) < 12)
2181 e_fail();
2182
2183 strcpy(essid_db[n_apsta].essid, essid);
2184 essid_db[n_apsta].essid_len = strlen(essid);
2185
2186 bssid = strupr(bssid);
2187 while (*bssid && l < 12) {
2188 if (*bssid >= '0' && *bssid <= '9')
2189 *bssid_bin = (*bssid - '0') << 4;
2190 else if (*bssid >= 'A' && *bssid <= 'F')
2191 *bssid_bin = (*bssid - 'A' + 10) << 4;
2192 else {
2193 bssid++;
2194 continue;
2195 }
2196 l++;
2197 bssid++;
2198 if (*bssid >= '0' && *bssid <= '9')
2199 *bssid_bin |= *bssid - '0';
2200 else if (*bssid >= 'A' && *bssid <= 'F')
2201 *bssid_bin |= *bssid - 'A' + 10;
2202 else {
2203 bssid++;
2204 continue;
2205 }
2206 bssid_bin++;
2207 l++;
2208 bssid++;
2209 }
2210 if (*bssid || l != 12)
2211 e_fail();
2212 if (++n_essid >= max_state)
2213 allocate_more_essid();
2214 fprintf(stderr, "Learned BSSID %s ESSID '%s' from command-line option\n",
2215 to_mac_str(essid_db[n_apsta].bssid), essid);
2216 opt_e_used = 1;
2217 }
2218
parse_mac(char * mac)2219 static void parse_mac(char *mac)
2220 {
2221 char *d = filter_mac;
2222 int l = 0;
2223
2224 mac = strupr(mac);
2225
2226 while (*mac && l < 12) {
2227 if ((*mac >= '0' && *mac <= '9') || (*mac >= 'A' && *mac <= 'F')) {
2228 *d++ = *mac;
2229 if (l & 1 && l < 10)
2230 *d++ = ':';
2231 l++;
2232 }
2233 mac++;
2234 }
2235 if (*mac || l != 12) {
2236 fprintf(stderr, "Incorrect -m option.\n");
2237 exit(EXIT_FAILURE);
2238 }
2239
2240 fprintf(stderr, "Ignoring any packets not involving %s\n", filter_mac);
2241 }
2242
2243 #ifdef HAVE_LIBFUZZER
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)2244 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
2245 {
2246 int fd;
2247 char name[] = "/tmp/libFuzzer-XXXXXX";
2248 FILE *in;
2249 char *base;
2250
2251 fd = mkstemp(name);
2252 if (fd < 0) {
2253 fprintf(stderr,
2254 "Problem creating the input file, %s, aborting!\n",
2255 strerror(errno));
2256 exit(EXIT_FAILURE);
2257 }
2258 write(fd, data, size);
2259 close(fd);
2260
2261 apsta_db = calloc(max_state, sizeof(WPA4way_t));
2262 essid_db = calloc(max_essid, sizeof(essid_t));
2263
2264 if (!apsta_db || !essid_db) {
2265 fprintf(stderr, "%s: Memory allocation error", argv[0]);
2266 exit(EXIT_FAILURE);
2267 }
2268
2269 in = fopen(filename = name, "rb");
2270 if (in) {
2271 if ((base = strrchr(filename, '/')))
2272 filename = ++base;
2273 process(in);
2274 fclose(in);
2275 } else
2276 fprintf(stderr, "Error, file %s not found\n", name);
2277 fprintf(stderr, "\n%d AP/STA pairs processed\n", n_apsta);
2278 fprintf(stderr, "\n%d ESSIDS processed\n", n_essid);
2279 remove(name);
2280
2281 free(apsta_db);
2282
2283 return 0;
2284 }
2285 #endif
2286
usage(char * name,int ret)2287 void usage(char *name, int ret)
2288 {
2289 fprintf(stderr,
2290 "Converts PCAP or IVS2 files to JtR format.\n"
2291 "Supported encapsulations: 802.11, Prism, Radiotap, PPI and TZSP over UDP.\n"
2292 "Usage: %s [options] <file[s]>\n"
2293 "\n-c\t\tShow only complete auths (incomplete ones might be wrong passwords\n"
2294 "\t\tbut we can crack what passwords were tried).\n"
2295 "-v\t\tBump verbosity (can be used several times, try -vv)\n"
2296 "-d\t\tDo not suppress dupe hashes (per AP/STA pair)\n"
2297 "-r\t\tIgnore replay-count (may output fuzzed-anonce handshakes)\n"
2298 "-f <n>\t\tForce anonce fuzzing with +/- <n>\n"
2299 "-e <essid:mac>\tManually add Name:MAC pair(s) in case the file lacks beacons.\n"
2300 "\t\teg. -e \"Magnum WIFI:6d:61:67:6e:75:6d\"\n"
2301 "-m <mac>\tIgnore any packets not involving this mac adress\n\n",
2302 name);
2303 exit(ret);
2304 }
2305
2306 #ifdef HAVE_LIBFUZZER
main_dummy(int argc,char ** argv)2307 int main_dummy(int argc, char **argv)
2308 #else
2309 int main(int argc, char **argv)
2310 #endif
2311 {
2312 FILE *in;
2313 int i;
2314 char *base;
2315
2316 apsta_db = calloc(max_state, sizeof(WPA4way_t));
2317 essid_db = calloc(max_essid, sizeof(essid_t));
2318
2319 if (!apsta_db || !essid_db) {
2320 fprintf(stderr, "%s: Memory allocation error", argv[0]);
2321 return EXIT_FAILURE;
2322 }
2323
2324 if (sizeof(struct ivs2_filehdr) != 2 || sizeof(struct ivs2_pkthdr) != 4 ||
2325 sizeof(struct ivs2_WPA_hdsk) != 352 || sizeof(hccap_t) != 356+36) {
2326 fprintf(stderr, "%s: Internal error: struct sizes wrong.\n", argv[0]);
2327 return EXIT_FAILURE;
2328 }
2329
2330 while (argc > 1 && argv[1][0] == '-') {
2331 if (!strcmp(argv[1], "-h"))
2332 usage(argv[0], EXIT_SUCCESS);
2333
2334 if (!strcmp(argv[1], "-c")) {
2335 show_unverified = 0;
2336 argv[1] = argv[0];
2337 argv++; argc--;
2338 continue;
2339 }
2340
2341 if (!strncmp(argv[1], "-v", 2)) {
2342 char *c = argv[1];
2343
2344 while (*++c == 'v')
2345 verbosity++;
2346 if (*c)
2347 usage(argv[0], EXIT_FAILURE);
2348
2349 argv[1] = argv[0];
2350 argv++; argc--;
2351 continue;
2352 }
2353
2354 if (!strcmp(argv[1], "-d")) {
2355 output_dupes = 1;
2356 argv[1] = argv[0];
2357 argv++; argc--;
2358 continue;
2359 }
2360
2361 if (!strcmp(argv[1], "-r")) {
2362 ignore_rc = 1;
2363 rctime = 10 * 1000000;
2364 argv[1] = argv[0];
2365 argv++; argc--;
2366 continue;
2367 }
2368
2369 if (argc > 2 && !strcmp(argv[1], "-e")) {
2370 argv[1] = argv[0];
2371 argv++; argc--;
2372 manual_beacon(argv[1]);
2373 argv[1] = argv[0];
2374 argv++; argc--;
2375 continue;
2376 }
2377
2378 if (argc > 2 && !strcmp(argv[1], "-f")) {
2379 argv[1] = argv[0];
2380 argv++; argc--;
2381 force_fuzz = ABS(atoi(argv[1]));
2382 argv[1] = argv[0];
2383 argv++; argc--;
2384 continue;
2385 }
2386
2387 if (argc > 2 && !strcmp(argv[1], "-m")) {
2388 argv[1] = argv[0];
2389 argv++; argc--;
2390 parse_mac(argv[1]);
2391 argv[1] = argv[0];
2392 argv++; argc--;
2393 continue;
2394 }
2395
2396 if (!strcmp(argv[1], "--")) {
2397 argv[1] = argv[0];
2398 argv++; argc--;
2399 break;
2400 }
2401
2402 usage(argv[0], EXIT_FAILURE);
2403 }
2404
2405 if (argc < 2)
2406 usage(argv[0], EXIT_FAILURE);
2407
2408 for (i = 1; i < argc; i++) {
2409 int j;
2410
2411 if (verbosity && i > 1)
2412 fprintf(stderr, "\n");
2413
2414 /* Re-init between pcap files */
2415 warn_snaplen = 0;
2416 warn_wpaclean = 0;
2417 start_ts64 = 0;
2418 pkt_num = 0;
2419 for (j = 0; j < n_essid; j++)
2420 if (essid_db[j].prio < 5)
2421 essid_db[j].prio = 5;
2422
2423 in = fopen(filename = argv[i], "rb");
2424 if (in) {
2425 if ((base = strrchr(filename, '/')))
2426 filename = ++base;
2427 process(in);
2428 fclose(in);
2429 } else
2430 fprintf(stderr, "Error, file %s not found\n", argv[i]);
2431 }
2432 fprintf(stderr, "\n%d ESSIDS processed and %d AP/STA pairs processed\n",
2433 n_essid, n_apsta);
2434 fprintf(stderr, "%d handshakes written, %d RSN IE PMKIDs\n",
2435 n_handshakes, n_pmkids);
2436
2437 MEM_FREE(new_p);
2438
2439 return 0;
2440 }
2441