nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4  
5 #include "fragmenting.h"
6 #include "mac_addr.h"
7 #include "osdep.h"
8  
9 int frag_min = 0, frag_max = 0, std_comp = 0, percentage = 0;
10  
11 char *frag_help = "#### This version supports IDS Evasion (Fragmenting) ####\n"
12 "# Just append --frag <min_frags>,<max_frags>,<percent> #\n"
13 "# after your attack mode identifier to fragment all #\n"
14 "# outgoing packets, possibly avoiding lots of IDS! #\n"
15 "# <min_frags> : Minimum fragments to split packets into #\n"
16 "# <max_frags> : Maximum amount of fragments to create #\n"
17 "# <percent> : Percantage of packets to fragment #\n"
18 "# NOTE: May not fully work with every driver, YMMV... #\n"
19 "# HINT: Set max_frags to 0 to enable standard compliance #\n"
20 "##########################################################\n";
21  
22 void frag_print_help() {
23 printf("%s\n", frag_help);
24 }
25  
26 int frag_is_enabled() {
27 return frag_min;
28 }
29  
30 int frag_send_frag(struct packet *pkt, int start, int size, uint8_t fragno, int last_frag) {
31 struct packet inject;
32 struct ieee_hdr *hdr = (struct ieee_hdr *) inject.data;
33 int payload_start = sizeof(struct ieee_hdr);
34  
35 memcpy(inject.data, pkt->data, pkt->len);
36 if (hdr->type == 0x88) payload_start += 2; //handle QoS frames
37  
38 set_fragno(&inject, fragno, last_frag);
39  
40 memmove(inject.data + payload_start, inject.data + start + payload_start, size);
41 inject.len = payload_start + size;
42  
43 return osdep_send_packet(&inject);
44 }
45  
46 int frag_send_packet(struct packet *pkt) {
47 struct ieee_hdr *hdr = (struct ieee_hdr *) pkt->data;
48 struct ether_addr *dst = get_destination(pkt);
49 int q = 0, rnd, payload_size, fragsize, i, last_frag = 0;
50 float fragfsize, fi;
51 uint8_t fragno = 0;
52  
53 //Check if already fragged => inject normally
54 if (get_fragno(pkt)) return osdep_send_packet(pkt);
55  
56 //Encrypted packets cannot be fragmented, since each fragment is encrypted individually
57 if (hdr->flags & 0xB0) return osdep_send_packet(pkt);
58  
59 //Std Comp: Only frag Unicast packets!
60 //"The MAC may fragment and reassemble individually addressed MSDUs"
61 if (std_comp && MAC_IS_BCAST(*dst)) return osdep_send_packet(pkt);
62  
63 if (hdr->type == 0x88) q = 2; //handle QoS frames
64 payload_size = pkt->len -(sizeof(struct ieee_hdr) + q);
65  
66 //Check if packet is fraggable (has payload), no => inject normally
67 if (pkt->len <= sizeof(struct ieee_hdr) + q) return osdep_send_packet(pkt);
68  
69 //Make a choice if packet is in the frag percentage
70 rnd = random() % 100;
71 if (rnd > percentage) return osdep_send_packet(pkt);
72  
73 //Select fragment count
74 rnd = random() % (frag_max - frag_min + 1);
75 rnd += frag_min;
76  
77 //Check if payload is longer than frag count, no => inject bytewise
78 //Std Comp. Payload TWICE the frag count
79 if (std_comp) {
80 if ((2 * rnd) > payload_size) rnd = payload_size / 2;
81 } else {
82 if (rnd > payload_size) rnd = payload_size;
83 }
84  
85 //Inject frags
86 if (std_comp) {
87 //Be compliant!
88 //"The length of each fragment shall be an equal number of octets for all fragments except the last."
89 fragsize = payload_size / rnd;
90 if (fragsize % 2) fragsize++; //"The length of each fragment shall be an even number of octets, except for the last fragment."
91 if ((fragsize * 15) < payload_size) fragsize += 2; //We can only send 15 frags max
92  
93 for (i=0; i<payload_size; i+=fragsize) {
94 if ((i + fragsize) > payload_size) fragsize = (payload_size - i); //Adjust size of last fragment
95 if (frag_send_frag(pkt, i, fragsize, fragno++, ((i + fragsize) == payload_size))) return -1;
96 }
97 } else {
98 //VIOLATE THE STANDARD NOW:
99 //"The MAC may fragment and reassemble individually addressed MSDUs"
100 //"The length of each fragment shall be an equal number of octets for all fragments except the last."
101 //"The length of each fragment shall be an even number of octets, except for the last fragment."
102 fragfsize = (float) payload_size / (float) rnd;
103  
104 i = 0;
105 for (fi=fragfsize; fi <= ((float)payload_size) + 0.5; fi+=fragfsize) {
106 fragsize = (int) floorf(fi) - i;
107  
108 if (fragno == (rnd - 1)) { //Adjust size of last fragment because floats aren't exact
109 last_frag = 1;
110 fragsize = payload_size - i;
111 }
112  
113 if (frag_send_frag(pkt, i, fragsize, fragno++, last_frag)) return -1;
114 i = (int) floorf(fi); //Store where last fragment ended
115 }
116 }
117  
118 return 0;
119 }
120  
121 void start_fragging(int min, int max, int perc) {
122  
123 if (max == 0) {
124 printf("Standard Compliant Fragmentation activated! Will not fragment Broadcasts!\n");
125 std_comp = 1;
126 max = 15;
127 }
128  
129 if ((min < 1) || (max < 1)) {
130 printf("NOT funny: Packets must be sent in at least one fragment! Raising fragment count\n");
131 if (min < 1) min = 1;
132 if (max < 1) max = 1;
133 }
134  
135 if ((min > 15) || (max > 15)) {
136 printf("IEEE 802.11 only supports up to 15 fragments, lowering fragment count\n");
137 if (min > 15) min = 15;
138 if (max > 15) max = 15;
139 }
140  
141 if (min > max) {
142 printf("Your fragmenting minimum is greater than the maximum, raising maximum to 15\n");
143 max = 15;
144 }
145  
146 frag_min = min;
147 frag_max = max;
148  
149 if (perc < 1) { printf("Adjusting percentage to 1\n"); perc = 1; }
150 else if (perc > 100) { printf("Adjusting percentage to 100\n"); perc = 100; }
151 percentage = perc;
152  
153 printf("IDS Evasion via Fragmentation is enabled and set to select %d to %d fragments for %d%% of all injected packets.\n", min, max, perc);
154 }
155  
156 void parse_frag(const char *input) {
157 int parseok;
158 int min, max, perc;
159  
160 parseok = sscanf(input, "%d,%d, %d", &min, &max, &perc);
161  
162 if (parseok != 3) {
163 printf("Your fragmenting parameters are unparseable...\n");
164 exit(-1);
165 }
166  
167 start_fragging(min, max, perc);
168 }