Skip to content

Instantly share code, notes, and snippets.

@syndicut
Created August 1, 2013 20:31
Show Gist options
  • Save syndicut/6134996 to your computer and use it in GitHub Desktop.
Save syndicut/6134996 to your computer and use it in GitHub Desktop.
Support for Mac OS X in reaver taken from http://code.google.com/p/reaver-wps/issues/detail?id=245
diff --git a/src/80211.c b/src/80211.c
index c2aff59..202556b 100644
--- a/src/80211.c
+++ b/src/80211.c
@@ -39,8 +39,18 @@ const u_char *next_packet(struct pcap_pkthdr *header)
const u_char *packet = NULL;
/* Loop until we get a valid packet, or until we run out of packets */
+#ifdef __APPLE__
+ struct pcap_pkthdr *pkt_header = NULL;
+ int status = 1;
+ while ((status = pcap_next_ex(get_handle(), &pkt_header, &packet)) == 1 || status == 0) // status == 0 indicates timeout
+#else
while((packet = pcap_next(get_handle(), header)) != NULL)
+#endif
{
+#ifdef __APPLE__
+ if (status == 0) continue;
+ memcpy(header, pkt_header, sizeof(*header));
+#endif
if(get_validate_fcs())
{
if(check_fcs(packet, header->len))
@@ -49,7 +59,9 @@ const u_char *next_packet(struct pcap_pkthdr *header)
}
else
{
+#ifndef __APPLE__
cprintf(INFO, "[!] Found packet with bad FCS, skipping...\n");
+#endif
}
}
else
@@ -325,7 +337,7 @@ void authenticate()
memcpy((void *) ((char *) packet+radio_tap_len), dot11_frame, dot11_frame_len);
memcpy((void *) ((char *) packet+radio_tap_len+dot11_frame_len), management_frame, management_frame_len);
- pcap_inject(get_handle(), packet, packet_len);
+ pcap_inject(get_handle(), packet, packet_len);
free((void *) packet);
}
@@ -609,6 +621,69 @@ int check_fcs(const u_char *packet, size_t len)
if(has_rt_header())
{
rt_header = (struct radio_tap_header *) packet;
+#ifdef __APPLE__
+ unsigned char *body = (unsigned char*) (rt_header+1);
+ uint32_t present = rt_header->flags;
+ uint8_t rflags = 0;
+ int i;
+ for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) {
+ if (!(present & (1 << i))) continue;
+ switch (i) {
+ case IEEE80211_RADIOTAP_TSFT:
+ body += sizeof(uint64_t);
+ break;
+
+ case IEEE80211_RADIOTAP_FLAGS:
+ rflags = *((uint8_t*)body);
+ /* fall through */
+ case IEEE80211_RADIOTAP_RATE:
+ body += sizeof(uint8_t);
+ break;
+
+ case IEEE80211_RADIOTAP_CHANNEL:
+ body += sizeof(uint16_t)*2;
+ break;
+
+ case IEEE80211_RADIOTAP_RX_FLAGS:
+ case IEEE80211_RADIOTAP_FHSS:
+ body += sizeof(uint16_t);
+ break;
+
+ case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+ case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DB_ANTNOISE:
+ case IEEE80211_RADIOTAP_ANTENNA:
+ body++;
+ break;
+
+ case 18: // IEEE80211_RADIOTAP_XCHANNEL
+ body += sizeof(uint32_t);
+ body += sizeof(uint16_t);
+ body += sizeof(uint8_t);
+ body += sizeof(uint8_t);
+ break;
+
+ case 19: // IEEE80211_RADIOTAP_MCS
+ body += 3*sizeof(uint8_t);
+ break;
+
+ default:
+ i = IEEE80211_RADIOTAP_EXT+1;
+ break;
+ }
+ }
+ #define IEEE80211_RADIOTAP_F_BADFCS 0x40
+ if (rflags & IEEE80211_RADIOTAP_F_BADFCS) {
+ // bad FCS, ignore
+ return 0;
+ }
+ if (!(rflags & IEEE80211_RADIOTAP_F_FCS)) {
+ // fcs not always present
+ return 1;
+ }
+#endif
+
offset += rt_header->len;
}
diff --git a/src/80211.h b/src/80211.h
index 9ad4efb..fadb208 100644
--- a/src/80211.h
+++ b/src/80211.h
@@ -42,6 +42,9 @@
#include "iface.h"
#include "crc.h"
#include "wps.h"
+#ifdef __APPLE__
+#include "utils/radiotap.h"
+#endif
#define AUTH_OK 1
#define ASSOCIATE_OK 2
diff --git a/src/Makefile.in b/src/Makefile.in
index c0ca978..ccf20b6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -5,14 +5,22 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
CONFDIR=@sysconfdir@/@target@
CFLAGS=-DCONF_DIR='"$(CONFDIR)"' -DREAVER_DATABASE='"$(CONFDIR)/reaver.db"' @CFLAGS@
+UNAME := $(shell uname)
+ifeq ($(UNAME), Linux)
LDFLAGS=$(LIBWPS_DIR)/*.o wps/*.o tls/bignum.o tls/libtls.a utils/libutils.a crypto/libcrypto.a lwe/libiw.a @LDFLAGS@
+LIBIWNAME=libiw
+endif
+ifeq ($(UNAME), Darwin)
+LIBIWNAME=
+LDFLAGS=$(LIBWPS_DIR)/*.o wps/*.o tls/bignum.o tls/libtls.a utils/libutils.a crypto/libcrypto.a @LDFLAGS@
+endif
all: wash reaver
-wash: wps libiw libwps.o argsparser.o globule.o init.o misc.o 80211.o iface.o
+wash: wps $(LIBIWNAME) libwps.o argsparser.o globule.o init.o misc.o 80211.o iface.o
$(CC) $(CFLAGS) $(INC) wpsmon.c *.o $(LDFLAGS) -o wash
-reaver: wps libiw libwps.o argsparser.o globule.o init.o sigint.o sigalrm.o misc.o cracker.o
+reaver: wps $(LIBIWNAME) libwps.o argsparser.o globule.o init.o sigint.o sigalrm.o misc.o cracker.o
$(CC) $(CFLAGS) $(INC) wpscrack.c *.o $(LDFLAGS) -o reaver
libwps.o:
diff --git a/src/iface.c b/src/iface.c
index 60e9ab6..cf5709e 100644
--- a/src/iface.c
+++ b/src/iface.c
@@ -34,6 +34,28 @@
#include "iface.h"
/* Populates globule->mac with the MAC address of the interface globule->iface */
+#ifdef __APPLE__
+int read_iface_mac() {
+ struct ifaddrs* iflist;
+ int found = 0;
+ if (getifaddrs(&iflist) == 0) {
+ struct ifaddrs* cur;
+ for (cur = iflist; cur; cur = cur->ifa_next) {
+ if ((cur->ifa_addr->sa_family == AF_LINK) &&
+ (strcmp(cur->ifa_name, get_iface()) == 0) &&
+ cur->ifa_addr) {
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr;
+ set_mac(LLADDR(sdl));
+ found = 1;
+ break;
+ }
+ }
+
+ freeifaddrs(iflist);
+ }
+ return found;
+}
+#else
int read_iface_mac()
{
struct ifreq ifr;
@@ -68,6 +90,7 @@ int read_iface_mac()
return ret_val;
}
+#endif
/*
* Goes to the next 802.11 channel.
@@ -112,6 +135,24 @@ int next_channel()
}
/* Sets the 802.11 channel for the selected interface */
+#ifdef __APPLE__
+int change_channel(int channel)
+{
+ cprintf(VERBOSE, "[+] Switching %s to channel %d\n", get_iface(), channel);
+ // Unfortunately, there is no API to change the channel
+ pid_t pid = fork();
+ if (!pid) {
+ char chan_arg[32];
+ sprintf(chan_arg, "-c%d", channel);
+ char* argv[] = {"/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", chan_arg, NULL};
+ execve("/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", argv, NULL);
+ }
+ int status;
+ waitpid(pid,&status,0);
+ set_channel(channel);
+ return 0;
+}
+#else
int change_channel(int channel)
{
int skfd = 0, ret_val = 0;
@@ -146,3 +187,4 @@ int change_channel(int channel)
return ret_val;
}
+#endif
diff --git a/src/iface.h b/src/iface.h
index 9b69c1a..ab0c205 100644
--- a/src/iface.h
+++ b/src/iface.h
@@ -35,9 +35,17 @@
#define IFACE_H
#include <sys/ioctl.h>
+#ifdef __APPLE__
+#include <sys/socket.h>
+#include <net/ethernet.h>
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+#endif
#include <net/if.h>
#include <netinet/in.h>
+#ifndef __APPLE__
#include "lwe/iwlib.h"
+#endif
#include "defs.h"
#include "globule.h"
diff --git a/src/init.c b/src/init.c
index 43f2fdb..c8bb9fd 100644
--- a/src/init.c
+++ b/src/init.c
@@ -121,7 +121,30 @@ pcap_t *capture_init(char *capture_source)
pcap_t *handle = NULL;
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
- handle = pcap_open_live(capture_source, BUFSIZ, 1, 0, errbuf);
+#ifdef __APPLE__
+ // must disassociate from any current AP. This is the only way.
+ pid_t pid = fork();
+ if (!pid) {
+ char* argv[] = {"/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", "-z", NULL};
+ execve("/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", argv, NULL);
+ }
+ int status;
+ waitpid(pid,&status,0);
+
+
+ handle = pcap_create(capture_source,errbuf);
+ if (handle) {
+ pcap_set_snaplen(handle, BUFSIZ);
+ pcap_set_timeout(handle, 50);
+ pcap_set_rfmon(handle, 1);
+ pcap_set_promisc(handle, 1);
+ int status = pcap_activate(handle);
+ if (status)
+ cprintf(CRITICAL, "pcap_activate status %d\n", status);
+ }
+#else
+ handle = pcap_open_live(capture_source, BUFSIZ, 1, 0, errbuf);
+#endif
if(!handle)
{
handle = pcap_open_offline(capture_source, errbuf);
diff --git a/src/wpsmon.c b/src/wpsmon.c
index da688b9..2a44b7c 100644
--- a/src/wpsmon.c
+++ b/src/wpsmon.c
@@ -62,7 +62,10 @@ int main(int argc, char *argv[])
fprintf(stderr, "Copyright (c) 2011, Tactical Network Solutions, Craig Heffner <[email protected]>\n\n");
globule_init();
- sql_init();
+ if (!sql_init()) {
+ fprintf(stderr, "[X] ERROR: sql_init failed\n");
+ goto end;
+ }
create_ap_table();
set_auto_channel_select(0);
set_wifi_band(BG_BAND);
@@ -132,6 +135,11 @@ int main(int argc, char *argv[])
usage(argv[0]);
goto end;
}
+ else if(get_iface())
+ {
+ /* Get the MAC address of the specified interface */
+ read_iface_mac();
+ }
if(get_iface() && source == PCAP_FILE)
{
@@ -265,7 +273,9 @@ void monitor(char *bssid, int passive, int source, int channel, int mode)
while((packet = next_packet(&header)))
{
parse_wps_settings(packet, &header, bssid, passive, mode, source);
+#ifndef __APPLE__
memset((void *) packet, 0, header.len);
+#endif
}
return;
@@ -300,6 +310,7 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
set_ssid(NULL);
bssid = (char *) mac2str(frame_header->addr3, ':');
+ set_bssid((unsigned char *) frame_header->addr3);
if(bssid)
{
@@ -328,12 +339,16 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
if(frame_header->fc.sub_type == SUBTYPE_BEACON &&
mode == SCAN &&
!passive &&
- should_probe(bssid))
+ should_probe(bssid)
+#ifdef __APPLE__
+ && 0
+#endif
+ )
{
send_probe_request(get_bssid(), get_ssid());
probe_sent = 1;
}
-
+
if(!insert(bssid, ssid, wps, encryption, rssi))
{
update(bssid, ssid, wps, encryption);
@@ -383,6 +398,7 @@ void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *
end:
if(wps) free(wps);
+ set_bssid((unsigned char *) NULL_MAC);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment