Import upstream version 1.6.6+git20210519.1.d6c931c
Kali Janitor
2 years ago
105 | 105 | -w, --win7 Mimic a Windows 7 registrar [False] |
106 | 106 | -K, --pixie-dust Run pixiedust attack |
107 | 107 | -Z Run pixiedust attack |
108 | -O, --output-file=<filename> Write packets of interest into pcap file | |
109 | -M, --mac-changer Change the last digit of the MAC Address for each pin attempt [False] | |
108 | 110 | |
109 | 111 | Example: |
110 | 112 | reaver -i wlan0mon -b 00:90:4C:C1:AC:21 -vv |
131 | 133 | Optional Arguments: |
132 | 134 | -c, --channel=<num> Channel to listen on [auto] |
133 | 135 | -n, --probes=<num> Maximum number of probes to send to each AP in scan mode [15] |
136 | -O, --output-file=<filename> Write packets of interest into pcap file | |
134 | 137 | -F, --ignore-fcs Ignore frame checksum errors |
135 | 138 | -2, --2ghz Use 2.4GHz 802.11 channels |
136 | 139 | -5, --5ghz Use 5GHz 802.11 channels |
138 | 141 | -u, --survey Use survey mode [default] |
139 | 142 | -a, --all Show all APs, even those without WPS |
140 | 143 | -j, --json print extended WPS info as json |
144 | -U, --utf8 Show UTF8 ESSID (does not sanitize ESSID, dangerous) | |
141 | 145 | -p, --progress Show percentage of crack progress |
142 | 146 | -h, --help Show help |
143 | 147 | |
166 | 170 | `rofl0r` |
167 | 171 | |
168 | 172 | Modifications made by: |
169 | `t6_x`, `DataHead`, `Soxrok2212`, `Wiire`, `AAnarchYY`, `kib0rg`, `KokoSoft`, `rofl0r`, `horrorho`, `binarymaster`, `Ǹotaz` | |
173 | `t6_x`, `DataHead`, `Soxrok2212`, `Wiire`, `AAnarchYY`, `kib0rg`, `KokoSoft`, `rofl0r`, `horrorho`, `binarymaster`, `Ǹotaz`, `Adde88` | |
170 | 174 | |
171 | 175 | Some ideas made by: |
172 | 176 | `nuroo`, `kcdtv` |
345 | 345 | state++; |
346 | 346 | break; |
347 | 347 | case 4: |
348 | ret = process_authenticate_associate_resp(0); | |
348 | ret = process_authenticate_associate_resp(1); | |
349 | 349 | if(ret) state++; |
350 | 350 | else return 0; |
351 | 351 | break; |
49 | 49 | int long_opt_index = 0; |
50 | 50 | char bssid[MAC_ADDR_LEN] = { 0 }; |
51 | 51 | char mac[MAC_ADDR_LEN] = { 0 }; |
52 | char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:p:s:C:O:KZA5ELfnqvDShwN6JFu"; | |
52 | char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:p:s:C:O:KZA5ELfnqvDShwN6JFuM"; | |
53 | 53 | struct option long_options[] = { |
54 | 54 | { "pixie-dust", no_argument, NULL, 'K' }, |
55 | 55 | { "interface", required_argument, NULL, 'i' }, |
83 | 83 | { "timeout-is-nack", no_argument, NULL, 'J' }, |
84 | 84 | { "ignore-fcs", no_argument, NULL, 'F' }, |
85 | 85 | { "output-file", required_argument, NULL, 'O'}, |
86 | { "mac-changer", no_argument, NULL, 'M' }, | |
86 | 87 | { 0, 0, 0, 0 } |
87 | 88 | }; |
88 | 89 | |
200 | 201 | break; |
201 | 202 | case 'F': |
202 | 203 | set_validate_fcs(0); |
204 | break; | |
205 | case 'M': | |
206 | set_mac_changer(1); | |
203 | 207 | break; |
204 | 208 | default: |
205 | 209 | ret_val = EXIT_FAILURE; |
229 | 233 | set_validate_fcs(1); |
230 | 234 | pixie.do_pixie = 0; |
231 | 235 | set_pin_string_mode(0); |
236 | set_mac_changer(0); | |
232 | 237 | } |
233 | 238 | |
234 | 239 | /* Parses the recurring delay optarg */ |
33 | 33 | #include "cracker.h" |
34 | 34 | #include "pixie.h" |
35 | 35 | #include "utils/vendor.h" |
36 | #include "utils/endianness.h" | |
36 | 37 | |
37 | 38 | void update_wpc_from_pin(void) { |
38 | 39 | /* update WPC file with found pin */ |
65 | 66 | uint64_t timestamp; |
66 | 67 | memcpy(×tamp, beacon->timestamp, 8); |
67 | 68 | globule->uptime = end_le64toh(timestamp); |
69 | } | |
70 | ||
71 | static void set_next_mac() { | |
72 | unsigned char newmac[6]; | |
73 | uint32_t l4b; | |
74 | memcpy(newmac, get_mac(), 6); | |
75 | memcpy(&l4b, newmac+2, 4); | |
76 | l4b = end_be32toh(l4b); | |
77 | do ++l4b; | |
78 | while ((l4b & 0xff) == 0 || (l4b & 0xff) == 0xff); | |
79 | l4b = end_htobe32(l4b); | |
80 | memcpy(newmac+2, &l4b, 4); | |
81 | set_mac(newmac); | |
82 | cprintf(WARNING, "[+] Using MAC %s\n", mac2str(get_mac(), ':')); | |
68 | 83 | } |
69 | 84 | |
70 | 85 | /* Brute force all possible WPS pins for a given access point */ |
160 | 175 | /* Main cracking loop */ |
161 | 176 | for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++) |
162 | 177 | { |
178 | /* MAC Changer */ | |
179 | if (get_mac_changer()) { | |
180 | set_next_mac(); | |
181 | } | |
182 | ||
163 | 183 | /* |
164 | 184 | * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS |
165 | 185 | * registrar requests. Using a delay here can help prevent the AP from locking us out. |
149 | 149 | SETUP_LOCKED = 15, |
150 | 150 | MESSAGE_TIMEOUT = 16, |
151 | 151 | REGISTRATION_TIMEOUT = 17, |
152 | AUTH_FAILURE = 18 | |
152 | AUTH_FAILURE = 18, | |
153 | UNKNOWN_CFG_ERROR = 0x1003 | |
153 | 154 | }; |
154 | 155 | |
155 | 156 | enum wps_type |
148 | 148 | tx_type = SEND_WSC_NACK; |
149 | 149 | break; |
150 | 150 | case NACK: |
151 | cprintf(VERBOSE, "[+] Received WSC NACK\n"); | |
151 | cprintf(VERBOSE, "[+] Received WSC NACK (reason: 0x%04X)\n", get_nack_reason()); | |
152 | 152 | got_nack = 1; |
153 | 153 | break; |
154 | 154 | case TERMINATE: |
230 | 230 | set_timeout_is_nack(0); |
231 | 231 | |
232 | 232 | ret_val = KEY_REJECTED; |
233 | ||
234 | /* Check the reason code for the received NACK message */ | |
235 | if (get_nack_reason() == MESSAGE_TIMEOUT) { | |
236 | ret_val = UNKNOWN_ERROR; | |
237 | cprintf(WARNING, "[!] WARNING: Potential FAKE NACK!\n"); | |
238 | } | |
239 | /* Got NACK instead of an M5 message, when cracking second half */ | |
240 | else if (!get_pin_string_mode() && last_msg == M3 && get_key_status() == KEY2_WIP) { | |
241 | ret_val = UNKNOWN_ERROR; | |
242 | cprintf(WARNING, "[!] WARNING: Potential first half pin has changed!\n"); | |
243 | } | |
233 | 244 | } |
234 | 245 | else |
235 | 246 | { |
248 | 259 | (last_msg == M3 || last_msg == M5)) |
249 | 260 | { |
250 | 261 | ret_val = KEY_REJECTED; |
262 | /* Got timeout instead of an M5 message, when cracking second half */ | |
263 | if (!get_pin_string_mode() && last_msg == M3 && get_key_status() == KEY2_WIP) { | |
264 | ret_val = UNKNOWN_ERROR; | |
265 | cprintf(WARNING, "[!] WARNING: Potential first half pin has changed!\n"); | |
266 | } | |
251 | 267 | } |
252 | 268 | else |
253 | 269 | { |
471 | 487 | case MESSAGE_TYPE: |
472 | 488 | type = (uint8_t) element_data[0]; |
473 | 489 | break; |
490 | case CONFIGURATION_ERROR: | |
491 | /* Check element_data length */ | |
492 | if (element.length == 2) | |
493 | set_nack_reason(WPA_GET_BE16(element_data)); | |
494 | break; | |
474 | 495 | default: |
475 | 496 | break; |
476 | 497 | } |
628 | 628 | return globule->oo_send_nack; |
629 | 629 | } |
630 | 630 | |
631 | void set_mac_changer(int value) | |
632 | { | |
633 | globule->mac_changer = value; | |
634 | } | |
635 | int get_mac_changer() | |
636 | { | |
637 | return globule->mac_changer; | |
638 | } | |
639 | ||
631 | 640 | void set_vendor(int is_set, const unsigned char* v) { |
632 | 641 | globule->vendor_oui[0] = is_set; |
633 | 642 | if(is_set) memcpy(globule->vendor_oui+1, v, 3); |
155 | 155 | * wpa_supplicant's wps_data structure, needed for almost all wpa_supplicant |
156 | 156 | * function calls. |
157 | 157 | */ |
158 | int mac_changer; /* Use MAC changer */ | |
159 | ||
158 | 160 | }; |
159 | 161 | |
160 | 162 | extern struct globals *globule; |
267 | 269 | int get_repeat_m6(void); |
268 | 270 | void set_output_fd(int fd); |
269 | 271 | int get_output_fd(void); |
272 | void set_mac_changer(int value); | |
273 | int get_mac_changer(void); | |
270 | 274 | #endif |
142 | 142 | pcap_set_timeout(handle, 50); |
143 | 143 | pcap_set_rfmon(handle, activate_rfmon); |
144 | 144 | pcap_set_promisc(handle, 1); |
145 | if(!(status = pcap_activate(handle))) | |
145 | status = pcap_activate(handle); | |
146 | if(status >= 0) { | |
147 | // Complete success, or success with warning. | |
148 | // XXX - report warning? | |
146 | 149 | return handle; |
150 | } | |
147 | 151 | if(status == PCAP_ERROR_RFMON_NOTSUP) { |
148 | 152 | pcap_set_rfmon(handle, 0); |
149 | 153 | status = pcap_activate(handle); |
150 | if(!status) return handle; | |
154 | if(status >= 0) { | |
155 | // Complete success, or success with warning. | |
156 | // XXX - report warning? | |
157 | return handle; | |
158 | } | |
151 | 159 | } |
152 | cprintf(CRITICAL, "[X] ERROR: pcap_activate status %d\n", status); | |
153 | static const char *pcap_errmsg[] = { | |
154 | [1] = "generic error code", | |
155 | [2] = "loop terminated by pcap_breakloop", | |
156 | [3] = "the capture needs to be activated", | |
157 | [4] = "the operation can't be performed on already activated captures", | |
158 | [5] = "no such device exists", | |
159 | [6] = "this device doesn't support rfmon (monitor) mode", | |
160 | [7] = "operation supported only in monitor mode", | |
161 | [8] = "no permission to open the device", | |
162 | [9] = "interface isn't up", | |
163 | [10]= "this device doesn't support setting the time stamp type", | |
164 | [11]= "you don't have permission to capture in promiscuous mode", | |
165 | [12]= "the requested time stamp precision is not supported", | |
166 | }; | |
167 | if(status < 0 && status > -13) | |
168 | cprintf(CRITICAL, "[X] PCAP: %s\n", pcap_errmsg[-status]); | |
160 | if(status < 0) { | |
161 | if(status == PCAP_ERROR) | |
162 | cprintf(CRITICAL, "[X] ERROR: pcap_activate status %d - %s, %s\n", status, pcap_statustostr(status), pcap_geterr(handle)); | |
163 | else | |
164 | cprintf(CRITICAL, "[X] ERROR: pcap_activate status %d - %s\n", status, pcap_statustostr(status)); | |
165 | } | |
169 | 166 | pcap_close(handle); |
170 | 167 | handle = 0; |
171 | 168 | } |
180 | 180 | fprintf(stderr, "\t-K, --pixie-dust Run pixiedust attack\n"); |
181 | 181 | fprintf(stderr, "\t-Z Run pixiedust attack\n"); |
182 | 182 | fprintf(stderr, "\t-O, --output-file=<filename> Write packets of interest into pcap file\n"); |
183 | fprintf(stderr, "\t-M, --mac-changer Change the last digit of the MAC Address for each pin try [False]\n"); | |
183 | 184 | |
184 | 185 | fprintf(stderr, "\nExample:\n\t%s -i wlan0mon -b 00:90:4C:C1:AC:21 -vv\n\n", prog_name); |
185 | 186 |