nexmon – Blame information for rev 1
?pathlinks?
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 | } |