2
* Copyright (C) 2011 Andrea Bittau <bittau@cs.stanford.edu>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* In addition, as a special exception, the copyright holders give
20
* permission to link the code of portions of this program with the
21
* OpenSSL library under certain conditions as described in each
22
* individual source file, and distribute linked combinations
24
* You must obey the GNU General Public License in all respects
25
* for all of the code used other than OpenSSL. * If you modify
26
* file(s) with this exception, you may extend this exception to your
27
* version of the file(s), but you are not obligated to do so. * If you
28
* do not wish to do so, delete this exception statement from your
29
* version. * If you delete this exception statement from all source
30
* files in the program, then also delete it here.
33
#include <sys/types.h>
43
#include "aircrack-ng.h"
45
#include "aircrack-ptw-lib.h"
46
#include "osdep/osdep.h"
47
#include "ieee80211.h"
51
static uchar ZERO[32] =
52
"\x00\x00\x00\x00\x00\x00\x00\x00"
53
"\x00\x00\x00\x00\x00\x00\x00\x00"
54
"\x00\x00\x00\x00\x00\x00\x00\x00"
55
"\x00\x00\x00\x00\x00\x00\x00\x00";
58
unsigned char p_data[2048];
63
unsigned char c_mac[6];
66
struct packet c_handshake[4];
67
struct client *c_next;
71
unsigned char n_bssid[6];
72
unsigned char n_beacon[2048];
75
struct client n_clients;
76
struct client *n_handshake;
77
struct network *n_next;
82
static int open_pcap(char *fname)
85
struct pcap_file_header pfh;
87
memset(&pfh, 0, sizeof(pfh));
88
pfh.magic = TCPDUMP_MAGIC;
89
pfh.version_major = PCAP_VERSION_MAJOR;
90
pfh.version_minor = PCAP_VERSION_MINOR;
94
pfh.linktype = LINKTYPE_IEEE802_11;
96
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC,
97
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
99
err(1, "open(%s)", fname);
101
if (write(fd, &pfh, sizeof(pfh)) != sizeof(pfh))
107
static void write_pcap(int fd, void *p, int len)
109
struct pcap_pkthdr pkh;
111
memset(&pkh, 0, sizeof(pkh));
113
pkh.caplen = pkh.len = len;
117
if (write(fd, &pkh, sizeof(pkh)) != sizeof(pkh))
120
if (write(fd, p, len) != len)
124
static void packet_write_pcap(int fd, struct packet *p)
126
write_pcap(fd, p->p_data, p->p_len);
129
static void print_network(struct network *n)
131
printf("Net %.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s\n",
141
static void save_network(struct network *n)
145
write_pcap(_outfd, n->n_beacon, n->n_beaconlen);
147
for (i = 0; i < 4; i++) {
148
struct packet *p = &n->n_handshake->c_handshake[i];
151
packet_write_pcap(_outfd, p);
155
static void fix_beacon(struct network *n)
162
p = n->n_beacon + sizeof(struct ieee80211_frame) + 8 + 2 + 2;
164
ssidlen = strlen(n->n_ssid);
165
assert((n->n_beaconlen + ssidlen) <=
166
(int) sizeof(n->n_beacon));
168
assert(*p == IEEE80211_ELEMID_SSID);
171
if (*p != 0 && p[1] != 0)
177
assert(origlen == 0 || p[0] == 0);
179
memmove(p + ssidlen, p + origlen,
180
n->n_beaconlen - (p + origlen - n->n_beacon));
181
memcpy(p, n->n_ssid, ssidlen);
183
n->n_beaconlen += ssidlen - origlen;
186
static void check_network(struct network *n)
188
if (!n->n_beaconlen || !n->n_handshake || !n->n_ssid[0])
198
static struct network *find_net(unsigned char *b)
200
struct network *n = _networks.n_next;
203
if (memcmp(b, n->n_bssid, sizeof(n->n_bssid)) == 0)
212
static struct network *net_add(unsigned char *bssid)
214
struct network *n = malloc(sizeof(*n));
219
memset(n, 0, sizeof(*n));
221
memcpy(n->n_bssid, bssid, sizeof(n->n_bssid));
223
n->n_next = _networks.n_next;
224
_networks.n_next = n;
229
static struct network *find_add_net(unsigned char *bssid)
237
return net_add(bssid);
240
static struct client *find_client(struct network *n, unsigned char *mac)
242
struct client *c = n->n_clients.c_next;
245
if (memcmp(c->c_mac, mac, sizeof(c->c_mac)) == 0)
254
static struct client *find_add_client(struct network *n, unsigned char *mac)
258
c = find_client(n, mac);
262
c = malloc(sizeof(*c));
266
memset(c, 0, sizeof(*c));
268
memcpy(c->c_mac, mac, sizeof(c->c_mac));
270
c->c_next = n->n_clients.c_next;
271
n->n_clients.c_next = c;
277
static void hexdump(void *p, int len)
279
unsigned char *x = p;
282
printf("%.2x ", *x++);
288
static int parse_rsn(unsigned char *p, int l, int rsn)
291
unsigned char *start = p;
298
if (memcmp(p, "\x01\x00", 2) != 0)
310
c = le16toh(*((uint16_t*) p));
314
if (l < ((p - start) + 2))
318
c = le16toh(*((uint16_t*) p));
321
if (l < ((p - start) + c * 4))
325
if (rsn && memcmp(p, "\x00\x0f\xac\x02", 4) == 0)
328
if (!rsn && memcmp(p, "\x00\x50\xf2\x02", 4) == 0)
334
assert(l >= (p - start));
343
static int parse_elem_vendor(unsigned char *e, int l)
345
struct ieee80211_ie_wpa *wpa = (struct ieee80211_ie_wpa*) e;
350
if (memcmp(wpa->wpa_oui, "\x00\x50\xf2", 3) != 0)
356
if (wpa->wpa_type != WPA_OUI_TYPE)
359
return parse_rsn((unsigned char*) &wpa->wpa_version, l - 6, 0);
362
static void process_beacon(struct ieee80211_frame *wh, int totlen)
364
unsigned char *p = (unsigned char*) (wh + 1);
365
int bhlen = 8 + 2 + 2;
374
totlen -= sizeof(*wh);
379
if (!(IEEE80211_BEACON_CAPABILITY(p) & IEEE80211_CAPINFO_PRIVACY))
397
case IEEE80211_ELEMID_SSID:
401
if (l == 0 || p[0] == 0)
409
case IEEE80211_ELEMID_VENDOR:
410
if ((rc = parse_elem_vendor(&p[-2], l + 2)) == -1)
417
case IEEE80211_ELEMID_RSN:
418
if ((rc = parse_rsn(p, l, 1)) == -1)
434
printf("Hidden SSID\n");
438
n = find_add_net(wh->i_addr3);
443
n->n_beaconlen = len;
444
assert(n->n_beaconlen <= (int) sizeof(n->n_beacon));
445
memcpy(n->n_beacon, wh, n->n_beaconlen);
446
strcpy(n->n_ssid, ssid);
449
printf("got beacon [%s]\n", n->n_ssid);
455
printf("bad beacon\n");
458
static int eapol_handshake_step(unsigned char *eapol, int len)
460
int eapol_size = 4 + 1 + 2 + 2 + 8 + 32 + 16 + 8 + 8 + 16 + 2;
462
if (len < eapol_size)
466
if ((eapol[6] & 0x08) == 0)
470
if ((eapol[5] & 1) == 0)
474
if ((eapol[6] & 0x80) != 0)
477
if (*((uint16_t*) &eapol[eapol_size - 2]) == 0)
483
static void packet_copy(struct packet *p, void *d, int len)
485
assert(len <= (int) sizeof(p->p_data));
488
memcpy(p->p_data, d, len);
491
static void process_eapol(struct network *n, struct client *c, unsigned char *p,
492
int len, struct ieee80211_frame *wh, int totlen)
496
num = eapol_handshake_step(p, len);
500
/* reset... should use time, too. XXX conservative - check retry */
501
if (c->c_wpa == 0 || num <= c->c_wpa) {
502
for (i = 0; i < 4; i++)
503
c->c_handshake[i].p_len = 0;
521
if (memcmp(&p[17], ZERO, 32) != 0)
528
if (memcmp(&p[17], ZERO, 32) != 0)
538
packet_copy(&c->c_handshake[num - 1], wh, totlen);
540
if (c->c_wpa_got == 7)
544
static void process_data(struct ieee80211_frame *wh, int len)
546
unsigned char *p = (unsigned char*) (wh + 1);
548
int wep = wh->i_fc[1] & IEEE80211_FC1_WEP;
551
int stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
553
unsigned char *bssid, *clientaddr;
558
if (stype == IEEE80211_FC0_SUBTYPE_QOS) {
563
if (!wep && len >= 8) {
564
llc = (struct llc*) p;
566
eapol = memcmp(llc, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8) == 0;
582
/* desc == WPA or RSN */
583
if (p[4] != 0xFE && p[4] != 0x02)
587
clientaddr = wh->i_addr2;
589
if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
591
clientaddr = wh->i_addr1;
592
} else if (!(wh->i_fc[1] & IEEE80211_FC1_DIR_TODS))
593
bssid = wh->i_addr3; /* IBSS */
595
n = find_add_net(bssid);
600
c = find_add_client(n, clientaddr);
602
process_eapol(n, c, p, len, wh, orig);
608
static void grab_hidden_ssid(unsigned char *bssid, struct ieee80211_frame *wh,
612
unsigned char *p = ((unsigned char *)(wh + 1)) + off;
616
if (n && n->n_ssid[0])
619
len -= sizeof(*wh) + off + 2;
624
if (*p++ != IEEE80211_ELEMID_SSID)
637
memcpy(n->n_ssid, p, l);
644
printf("bad grab_hidden_ssid\n");
648
static void process_packet(void *packet, int len)
650
struct ieee80211_frame *wh = (struct ieee80211_frame*) packet;
653
printf("GOT %d\n", len);
654
hexdump(packet, len);
657
if (len < (int) sizeof(*wh))
660
switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
661
case IEEE80211_FC0_TYPE_MGT:
662
switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
663
case IEEE80211_FC0_SUBTYPE_BEACON:
664
process_beacon(wh, len);
667
case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
668
grab_hidden_ssid(wh->i_addr3, wh, len, 2 + 2);
671
case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
672
grab_hidden_ssid(wh->i_addr3, wh, len, 2 + 2 + 6);
675
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
676
grab_hidden_ssid(wh->i_addr3, wh, len, 8 + 2 + 2);
681
case IEEE80211_FC0_TYPE_DATA:
682
process_data(wh, len);
687
static void pwn(char *fname)
693
snprintf(crap, sizeof(crap), "file://%s", fname);
697
printf("Bad file - skipping %s\n", fname);
701
while ((rc = wi_read(wi, (unsigned char*) crap, sizeof(crap), NULL)) > 0)
702
process_packet(crap, rc);
707
int main(int argc, char *argv[])
713
printf("Usage: %s <out.cap> <in.cap> [in2.cap] [...]\n", argv[0]);
718
_outfd = open_pcap(out);
720
for (i = 2; i < argc; i++) {
722
int prog = (int) (((double) (i - 1)) / ((double)(argc - 2))
725
printf("Pwning %s (%d/%d %d%%)\n", in, i - 1, argc - 2, prog);