Codebase list reaver / 21faa78
Update upstream source from tag 'upstream/1.6.5' Update to upstream version '1.6.5' with Debian dir 1651acc292407323acadfef15f3d62f5738dfa1f Sophie Brun 6 years ago
20 changed file(s) with 286 addition(s) and 141 deletion(s). Raw diff Collapse all Expand all
1313 Reaver versioning was updated to **1.6.x** in order to identify the new cycle.
1414 All stable relases since the first beta version of reaver 1.6 can be downloaded from our [Releases](https://github.com/t6x/reaver-wps-fork-t6x/releases) page.
1515 * More information about the Pixie Dust attack (including **which APs are vulnerable**) can be found in [pixiewps repository](https://github.com/wiire/pixiewps),
16 [pixie dust thread in Kali forum)](https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-(Offline-WPS-Attack) & [Dominique Bongard's full disclosure](https://docs.google.com/spreadsheets/d/1tSlbqVQ59kGn8hgmwcPTHUECQ3o9YhXR91A_p7Nnj5Y/edit?usp=sharing)
16 [pixie dust thread (in Kali forum)](https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-(Offline-WPS-Attack)) & [Dominique Bongard's full disclosure](https://docs.google.com/spreadsheets/d/1tSlbqVQ59kGn8hgmwcPTHUECQ3o9YhXR91A_p7Nnj5Y/edit?usp=sharing)
1717
1818 - - -
1919
6767
6868 # Reaver Usage
6969
70 ```Reaver v1.6.4 WiFi Protected Setup Attack Tool
70 ```
7171 Copyright (c) 2011, Tactical Network Solutions, Craig Heffner <[email protected]>
7272
7373 Required Arguments:
7878 -m, --mac=<mac> MAC of the host system
7979 -e, --essid=<ssid> ESSID of the target AP
8080 -c, --channel=<channel> Set the 802.11 channel for the interface (implies -f)
81 -o, --out-file=<file> Send output to a log file [stdout]
8281 -s, --session=<file> Restore a previous session file
8382 -C, --exec=<command> Execute the supplied command upon successful pin recovery
84 -D, --daemonize Daemonize reaver
8583 -f, --fixed Disable channel hopping
8684 -5, --5ghz Use 5GHz 802.11 channels
8785 -v, --verbose Display non-critical warnings (-vv or -vvv for more)
103101 -L, --ignore-locks Ignore locked state reported by the target AP
104102 -E, --eap-terminate Terminate each WPS session with an EAP FAIL packet
105103 -J, --timeout-is-nack Treat timeout as NACK (DIR-300/320)
104 -F, --ignore-fcs Ignore frame checksum errors
106105 -w, --win7 Mimic a Windows 7 registrar [False]
107106 -K, --pixie-dust Run pixiedust attack
108107 -Z Run pixiedust attack
109108
110109 Example:
111 ./reaver -i wlan0mon -b 00:90:4C:C1:AC:21 -vv
110 reaver -i wlan0mon -b 00:90:4C:C1:AC:21 -vv
112111 ```
113112
114113 Options description and examples of use can be found in the [Readme from Craig Heffner](https://github.com/t6x/reaver-wps-fork-t6x/blob/master/docs/README.REAVER). Here comes a description of the new options introduced since then:
123122 # Wash Usage
124123
125124 ```
126 Wash v1.6.3 WiFi Protected Setup Scan Tool
127125 Copyright (c) 2011, Tactical Network Solutions, Craig Heffner
128126
129127 Required Arguments:
132130
133131 Optional Arguments:
134132 -c, --channel=<num> Channel to listen on [auto]
135 -o, --out-file=<file> Write data to file
136133 -n, --probes=<num> Maximum number of probes to send to each AP in scan mode [15]
137 -D, --daemonize Daemonize wash
134 -F, --ignore-fcs Ignore frame checksum errors
135 -2, --2ghz Use 2.4GHz 802.11 channels
138136 -5, --5ghz Use 5GHz 802.11 channels
139137 -s, --scan Use scan mode
140138 -u, --survey Use survey mode [default]
147145 ```
148146
149147 A detailed description of the options with concrete syntax examples can be found in [Craig Heffner's wash readme](https://github.com/t6x/reaver-wps-fork-t6x/blob/master/docs/README.WASH).
150 About the new options:
148 About the new options and features:
151149 ## -a // --all
152150 The option `-a` of Wash will list all access points, including those without WPS enabled.
153151 ## -j // --json
154152 The extended WPS information (serial, model...) from the AP probe answer will be printed in the terminal (in json format)
155
153 ## "Vendor" column
154 Wash now displays the manufacturer of the wifi chipset from the Acces Points in order to know if they are vulnerable to pixie dust attack.
155 ## Stdout can be piped
156156 Notice that wash output can be piped into other commands. For more information see the wiki article [Everything about the new options from wash](https://github.com/t6x/reaver-wps-fork-t6x/wiki/Everything-about-the-new-options-from-wash)
157157
158158 # Acknowledgements
0 .TH Reaver "1" "29 December, 2011" "1.3"
1 .SH NAME
2 .P
3 .B Reaver
4 - WPS Cracker
5 .SH SYNOPSIS
6 .P
7 .B reaver -i <interface> -b <target bssid> -vv
8 .SH DESCRIPTION
9 .P
10 Reaver implements a brute force attack against WiFi Protected Setup which can crack the WPS pin of an access point in a matter of hours and subsequently recover the WPA/WPA2 passphrase.
11 .P
12 Specifically, Reaver targets the registrar functionality of WPS, which is flawed in that it only takes 11,000 attempts to guess the correct WPS pin in order to become a WPS registrar. Once registred as a registrar with the access point, the access point will give you the WPA passphrase.
13 .SH OPTIONS
14 .P
15 .RS
16 .B -m, --mac=<mac>
17 .RS
18 MAC of the host system (should be resolved automatically)
19 .RE
20 .RE
21 .P
22 .RS
23 .B -e, --essid=<ssid>
24 .RS
25 ESSID of the target AP. Unless cloaked, this will be resolved automatically.
26 .RE
27 .RE
28 .P
29 .RS
30 .B -c, --channel=<channel>
31 .RS
32 Set the 802.11 channel for the interface (implies -f)
33 .RE
34 .RE
35 .P
36 .RS
37 .B -o, --out-file=<file>
38 .RS
39 Send output to a log file [default: stdout]
40 .RE
41 .RE
42 .P
43 .RS
44 .B -f, --fixed
45 .RS
46 Disable channel hopping
47 .RE
48 .RE
49 .P
50 .RS
51 .B -5, --5ghz
52 .RS
53 Use 5GHz 802.11 channels
54 .RE
55 .RE
56 .P
57 .RS
58 .B -v, --verbose
59 .RS
60 Display non-critical warnings (-vv for more)
61 .RE
62 .RE
63 .P
64 .RS
65 .B -q, --quiet
66 .RS
67 Only display critical messages
68 .RE
69 .RE
70 .P
71 .RS
72 .B -i, --interface=<wlan>
73 .RS
74 Name of the monitor-mode interface to use
75 .RE
76 .RE
77 .P
78 .RS
79 .B -b, --bssid=<mac>
80 .RS
81 BSSID of the target AP
82 .RE
83 .RE
84 .P
85 .RS
86 .B -p, --pin=<wps pin>
87 .RS
88 Use the specified WPS pin
89 .RE
90 .RE
91 .P
92 .RS
93 .B -h, --help
94 .RS
95 Show help
96 .RE
97 .RE
98 .SH AUTHOR
99 .P
100 This manual page was written by Craig Heffner <[email protected]>, Tactical Network Solutions. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL.
docs/reaver.1.gz less more
Binary diff not shown
4747 static void deauthenticate(void);
4848 static void authenticate(void);
4949 static void associate(void);
50 static int check_fcs(const unsigned char *packet, size_t len);
51
5052
5153 /*Reads the next packet from pcap_next() and validates the FCS. */
5254 unsigned char *next_packet(struct pcap_pkthdr *header)
5355 {
5456 const unsigned char *packet = NULL;
5557 struct pcap_pkthdr *pkt_header;
58 static int warning_shown = 0;
5659 int status;
5760
5861 /* Loop until we get a valid packet, or until we run out of packets */
6265
6366 memcpy(header, pkt_header, sizeof(*header));
6467
65 if(get_validate_fcs() && !check_fcs(packet, header->len))
68 if(get_validate_fcs() && !check_fcs(packet, header->len)) {
69 if(!warning_shown)
70 cprintf(INFO, "[!] Found packet with bad FCS, skipping...\n");
71 warning_shown = 1;
6672 continue;
73 }
6774
6875 break;
6976 }
602609 }
603610
604611 /* Validates a packet's reported FCS value */
605 int check_fcs(const unsigned char *packet, size_t len)
606 {
612 static int check_fcs(const unsigned char *packet, size_t len)
613 {
614 if(!has_rt_header()) return 1;
615
607616 uint32_t offset = 0, match = 0;
608617 uint32_t fcs = 0, fcs_calc = 0;
609618 struct radio_tap_header *rt_header = NULL;
612621 {
613622
614623 /* FCS is not calculated over the radio tap header */
615 if(has_rt_header() && len >= sizeof(*rt_header))
624 if(len >= sizeof(*rt_header))
616625 {
617626 uint32_t presentflags, flags;
618627 if(!rt_get_presentflags(packet, len, &presentflags, &offset))
8181 int parse_beacon_tags(const unsigned char *data, size_t len);
8282 unsigned char *parse_ie_data(const unsigned char *data, size_t len, uint8_t tag_number, size_t *ie_len, size_t *ie_offset);
8383 int is_target(struct dot11_frame_header *frame_header);
84 int check_fcs(const unsigned char *packet, size_t len);
8584 int has_rt_header(void);
8685 unsigned char *radio_header(const unsigned char *packet, size_t len);
8786
0 1.6.4
0 1.6.5
4848 int long_opt_index = 0;
4949 char bssid[MAC_ADDR_LEN] = { 0 };
5050 char mac[MAC_ADDR_LEN] = { 0 };
51 char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:o:p:s:C:KZA5ELfnqvDShwN6J";
51 char *short_options = "b:e:m:i:t:d:c:T:x:r:g:l:p:s:C:KZA5ELfnqvDShwN6JF";
5252 struct option long_options[] = {
5353 { "pixie-dust", no_argument, NULL, 'K' },
5454 { "interface", required_argument, NULL, 'i' },
6464 { "session", required_argument, NULL, 's' },
6565 { "recurring-delay", required_argument, NULL, 'r' },
6666 { "max-attempts", required_argument, NULL, 'g' },
67 { "out-file", required_argument, NULL, 'o' },
6867 { "pin", required_argument, NULL, 'p' },
6968 { "exec", required_argument, NULL, 'C' },
7069 { "no-associate", no_argument, NULL, 'A' },
7372 { "eap-terminate", no_argument, NULL, 'E' },
7473 { "dh-small", no_argument, NULL, 'S' },
7574 { "fixed", no_argument, NULL, 'f' },
76 { "daemonize", no_argument, NULL, 'D' },
7775 { "5ghz", no_argument, NULL, '5' },
7876 { "repeat-m6", no_argument, NULL, '6' },
7977 { "nack", no_argument, NULL, 'n' },
8280 { "win7", no_argument, NULL, 'w' },
8381 { "help", no_argument, NULL, 'h' },
8482 { "timeout-is-nack", no_argument, NULL, 'J' },
83 { "ignore-fcs", no_argument, NULL, 'F' },
8584 { 0, 0, 0, 0 }
8685 };
8786
147146 case 'L':
148147 set_ignore_locks(1);
149148 break;
150 case 'o':
151 set_log_file(fopen(optarg, "w"));
152 break;
153149 case 'x':
154150 set_fail_delay(atoi(optarg));
155151 break;
159155 case 'g':
160156 set_max_pin_attempts(atoi(optarg));
161157 break;
162 case 'D':
163 daemonize();
164 break;
165158 case 'E':
166159 set_eap_terminate(1);
167160 break;
188181 break;
189182 case 'N':
190183 set_oo_send_nack(0);
184 break;
185 case 'F':
186 set_validate_fcs(0);
191187 break;
192188 default:
193189 ret_val = EXIT_FAILURE;
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for reaver 1.6.4.
2 # Generated by GNU Autoconf 2.69 for reaver 1.6.5.
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.4'
580 PACKAGE_STRING='reaver 1.6.4'
579 PACKAGE_VERSION='1.6.5'
580 PACKAGE_STRING='reaver 1.6.5'
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.4 to adapt to many kinds of systems.
1225 \`configure' configures reaver 1.6.5 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.4:";;
1286 short | recursive ) echo "Configuration of reaver 1.6.5:";;
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.4
1374 reaver configure 1.6.5
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.4, which was
1672 It was created by reaver $as_me 1.6.5, 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.4, which was
3889 This file was extended by reaver $as_me 1.6.5, 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.4
3942 reaver config.status 1.6.5
39433943 configured by $0, generated by GNU Autoconf 2.69,
39443944 with options \\"\$ac_cs_config\\"
39453945
9898 }
9999 #endif
100100
101 /*
101 /*
102102 * Goes to the next 802.11 channel.
103103 * This is mostly required for APs that hop channels, which usually hop between channels 1, 6, and 11.
104104 * We just hop channels until we successfully associate with the AP.
106106 */
107107 int next_channel()
108108 {
109 #define BG_CHANNELS 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
110 #define AN_CHANNELS 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 183, 184, 185, 187, 188, 189, 192, 196
111
109112 static int i;
110 int n = 0;
111 int bg_channels[] = BG_CHANNELS;
112 int an_channels[] = AN_CHANNELS;
113 int *channels = NULL;
113 static const short bg_channels[] = {BG_CHANNELS};
114 static const short an_channels[] = {AN_CHANNELS};
115 static const short bgan_channels[] = {BG_CHANNELS, AN_CHANNELS};
116 static const int band_chan_count[] = {
117 [BG_BAND] = sizeof(bg_channels)/sizeof(bg_channels[0]),
118 [AN_BAND] = sizeof(an_channels)/sizeof(an_channels[0]),
119 [BG_BAND|AN_BAND] = sizeof(bgan_channels)/sizeof(bgan_channels[0]),
120 };
121 static const short* band_select[] = {
122 [BG_BAND] = bg_channels,
123 [AN_BAND] = an_channels,
124 [BG_BAND|AN_BAND] = bgan_channels,
125 };
114126
115 /* Select the appropriate channels for the target 802.11 band */
116 if(get_wifi_band() == AN_BAND)
117 {
118 channels = (int *) &an_channels;
119 n = sizeof(an_channels) / sizeof(int);
120 }
121 else
122 {
123 channels = (int *) &bg_channels;
124 n = sizeof(bg_channels) / sizeof(int);
125 }
127 int band = get_wifi_band();
128 const short *channels = band_select[band];
129 int n = band_chan_count[band];
126130
127131 /* Only switch channels if fixed channel operation is disabled */
128132 if(!get_fixed_channel())
129133 {
130 i++;
134 i++;
135 if((i >= n) || i < 0) i = 0;
136 return change_channel(channels[i]);
137 }
131138
132 if((i >= n) || i < 0)
133 {
134 i = 0;
135 }
136
137 return change_channel(channels[i]);
138 }
139
140139 return 0;
141140 }
142141
3333 #ifndef IFACE_H
3434 #define IFACE_H
3535
36 #define BG_BAND 0
37 #define AN_BAND 1
38
39 #define BG_CHANNELS { 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
40 #define AN_CHANNELS { 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 183, 184, 185, 187, 188, 189, 192, 196 }
36 #define BG_BAND (1 << 0)
37 #define AN_BAND (1 << 1)
4138
4239 int read_iface_mac();
4340 int next_channel();
148148 if(!status) return handle;
149149 }
150150 cprintf(CRITICAL, "[X] ERROR: pcap_activate status %d\n", status);
151 if(status == PCAP_ERROR_NO_SUCH_DEVICE)
152 cprintf(CRITICAL, "[X] PCAP: no such device\n");
153 /* TODO : print nice error message for other codes */
151 static const char *pcap_errmsg[] = {
152 [1] = "generic error code",
153 [2] = "loop terminated by pcap_breakloop",
154 [3] = "the capture needs to be activated",
155 [4] = "the operation can't be performed on already activated captures",
156 [5] = "no such device exists",
157 [6] = "this device doesn't support rfmon (monitor) mode",
158 [7] = "operation supported only in monitor mode",
159 [8] = "no permission to open the device",
160 [9] = "interface isn't up",
161 [10]= "this device doesn't support setting the time stamp type",
162 [11]= "you don't have permission to capture in promiscuous mode",
163 [12]= "the requested time stamp precision is not supported",
164 };
165 if(status < 0 && status > -13)
166 cprintf(CRITICAL, "[X] PCAP: %s\n", pcap_errmsg[-status]);
154167 pcap_close(handle);
155168 handle = 0;
156169 }
8585 fflush(get_log_file());
8686 }
8787
88 /* Daemonizes the process */
89 void daemonize(void)
90 {
91 if(fork() > 0)
92 {
93 exit(EXIT_SUCCESS);
94 }
95
96 if(chdir("/") == 0)
97 {
98 setsid();
99 umask(0);
100
101 if(fork() > 0)
102 {
103 exit(EXIT_SUCCESS);
104 }
105 }
106 }
107
10888 /* Closes libpcap during sleep period to avoid stale packet data in pcap buffer */
10989 void pcap_sleep(int seconds)
11090 {
2525 p->pke, p->ehash1, p->ehash2, p->authkey, p->enonce,
2626 dh_small ? "-S" : "-r" , dh_small ? "" : p->pkr);
2727 printf("executing %s\n", cmd);
28 system(cmd);
29 exit(0);
28 exit(system(cmd));
3029 }
3130 PIXIE_FREE(authkey);
3231 PIXIE_FREE(pkr);
378378 return new;
379379 }
380380
381 int verifyssid(const unsigned char *s)
382 {
383 int i;
384 unsigned char c;
385
386 if(!s || strlen(s)>32) { //32 characters
387 return 0;
388 }
389
390 for (i = 0; (c = s[i++]);) {
391 if ((c & 0x80) == 0) {//ascii flag
392 if(c < 0x20 || c == 0x7f) {
393 return 0;
394 }
395 } else if ((c & 0xe0) == 0xc0) {//utf8 flag
396 if ((s[i++] & 0xc0) != 0x80) {
397 return 0;
398 }
399 } else if ((c & 0xf0) == 0xe0) {//utf8 flag
400 if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
401 return 0;
402 }
403 } else if ((c & 0xf8) == 0xf0) {//utf8 flag
404 if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
405 return 0;
406 }
407 } else {
408 return 0;
409 }
410 }
411 return 1;
412 }
447447 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
448448 size_t len);
449449 char* sanitize_string(const char *s);
450 int verifyssid(const unsigned char *s);
450451
451452 #ifdef CONFIG_NATIVE_WINDOWS
452453 void wpa_unicode2ascii_inplace(TCHAR *str);
126126 # error "Sorry, we couldn't detect endiannes for your system! Please set -DENDIANNESS_LE=1 or 0 using your CPPFLAGS/CFLAGS and open an issue for your system on https://github.com/rofl0r/endianness.h - Thanks!"
127127 #endif
128128
129 #ifdef ENDIANNESS_DEBUG
130 # if ENDIANNESS_LE == 1
131 # warning "Detected Little Endian target CPU"
132 # endif
133 # if ENDIANNESS_BE == 1
134 # warning "Detected BIG Endian target CPU"
135 # endif
136 #endif
137
129138 #include <stdint.h>
130139 #include <limits.h>
131140
210219 return result;
211220 }
212221
213 #ifdef ENDIANNESS_LE
222 #if ENDIANNESS_LE+0 == 1
214223 # define end_htobe16(x) end_bswap16(x)
215224 # define end_be16toh(x) end_bswap16(x)
216225 # define end_htobe32(x) end_bswap32(x)
223232 # define end_le32toh(x) (uint32_t)(x)
224233 # define end_htole64(x) (uint64_t)(x)
225234 # define end_le64toh(x) (uint64_t)(x)
226 #elif ENDIANNESS_BE
235 #elif ENDIANNESS_BE+0 == 1
227236 # define end_htobe16(x) (uint16_t)(x)
228237 # define end_be16toh(x) (uint16_t)(x)
229238 # define end_htobe32(x) (uint32_t)(x)
1818 {"\x00\x1c\x51", "CelenoCo"}, /* Celeno Communications */
1919 {"\x00\x50\x43", "MarvellS"}, /* Marvell Semiconductor, Inc. */
2020 {"\x00\x26\x86", "Quantenn"}, /* Quantenna */
21 {"\x00\x09\x86", "LantiqML"}, /* Lantiq/MetaLink */
2122 {"\x00\x50\xf2", "Microsof"} /* Microsoft */
2223 };
2324
00 #!/bin/sh
11
2 BINDIR=$(dirname $(readlink -f "$0"))
2 argv0=$(echo "$0" | sed -e 's,\\,/,g')
3 BINDIR=$(dirname "$(readlink "$0" || echo "$argv0")")
34
45 if test -d "$BINDIR"/../.git ; then
56 if type git >/dev/null 2>&1 ; then
151151 fprintf(stderr, "\t-m, --mac=<mac> MAC of the host system\n");
152152 fprintf(stderr, "\t-e, --essid=<ssid> ESSID of the target AP\n");
153153 fprintf(stderr, "\t-c, --channel=<channel> Set the 802.11 channel for the interface (implies -f)\n");
154 fprintf(stderr, "\t-o, --out-file=<file> Send output to a log file [stdout]\n");
155154 fprintf(stderr, "\t-s, --session=<file> Restore a previous session file\n");
156155 fprintf(stderr, "\t-C, --exec=<command> Execute the supplied command upon successful pin recovery\n");
157 fprintf(stderr, "\t-D, --daemonize Daemonize reaver\n");
158156 fprintf(stderr, "\t-f, --fixed Disable channel hopping\n");
159157 fprintf(stderr, "\t-5, --5ghz Use 5GHz 802.11 channels\n");
160158 //fprintf(stderr, "\t-6, --repeat-m6 Send M6 again upon duplicated M5 reception\n");
177175 fprintf(stderr, "\t-L, --ignore-locks Ignore locked state reported by the target AP\n");
178176 fprintf(stderr, "\t-E, --eap-terminate Terminate each WPS session with an EAP FAIL packet\n");
179177 fprintf(stderr, "\t-J, --timeout-is-nack Treat timeout as NACK (DIR-300/320)\n");
178 fprintf(stderr, "\t-F, --ignore-fcs Ignore frame checksum errors\n");
180179 fprintf(stderr, "\t-w, --win7 Mimic a Windows 7 registrar [False]\n");
181180 fprintf(stderr, "\t-K, --pixie-dust Run pixiedust attack\n");
182181 fprintf(stderr, "\t-Z Run pixiedust attack\n");
3535 #include "utils/vendor.h"
3636 #include "send.h"
3737
38 #define MAX_APS 512
39
3840 extern const char* get_version(void);
3941 static void wash_usage(char *prog);
4042
4143 int show_all_aps = 0;
4244 int json_mode = 0;
45 int show_utf8_ssid = 0;
4346
4447 static struct mac {
4548 unsigned char mac[6];
4649 unsigned char vendor_oui[1+3];
4750 unsigned char probes;
4851 unsigned char flags;
49 } seen_list[256];
52 } seen_list[MAX_APS];
5053 enum seen_flags {
5154 SEEN_FLAG_PRINTED = 1,
5255 SEEN_FLAG_COMPLETE = 2,
5659 unsigned i;
5760 unsigned char mac[6];
5861 str2mac(bssid, mac);
59 if(seen_count >= 256) return -1;
6062 for(i=0; i<seen_count; i++)
6163 if(!memcmp(seen_list[i].mac, mac, 6)) return i;
64 if(seen_count >= MAX_APS) return -1;
6265 memcpy(seen_list[seen_count].mac, mac, 6);
6366 return seen_count++;
6467 }
6568 static int was_printed(char* bssid) {
6669 int x = list_insert(bssid);
67 if(x >= 0 && x < 256) {
70 if(x >= 0 && x < MAX_APS) {
6871 unsigned f = seen_list[x].flags;
6972 seen_list[x].flags |= SEEN_FLAG_PRINTED;
7073 return f & SEEN_FLAG_PRINTED;
7376 }
7477 static void mark_ap_complete(char *bssid) {
7578 int x = list_insert(bssid);
76 if(x >= 0 && x < 256) seen_list[x].flags |= SEEN_FLAG_COMPLETE;
79 if(x >= 0 && x < MAX_APS) seen_list[x].flags |= SEEN_FLAG_COMPLETE;
7780 }
7881 static int is_done(char *bssid) {
7982 int x = list_insert(bssid);
80 if(x >= 0 && x < 256) return seen_list[x].flags & SEEN_FLAG_COMPLETE;
83 if(x >= 0 && x < MAX_APS) return seen_list[x].flags & SEEN_FLAG_COMPLETE;
8184 return 1;
8285 }
8386 static int should_probe(char *bssid) {
8487 int x = list_insert(bssid);
85 if(x >= 0 && x < 256) return seen_list[x].probes < get_max_num_probes();
88 if(x >= 0 && x < MAX_APS) return seen_list[x].probes < get_max_num_probes();
8689 return 0;
8790 }
8891 static void update_probe_count(char *bssid) {
8992 int x = list_insert(bssid);
90 if(x >= 0 && x < 256) seen_list[x].probes++;
93 if(x >= 0 && x < MAX_APS) seen_list[x].probes++;
9194 }
9295 static void set_ap_vendor(char *bssid) {
9396 int x = list_insert(bssid);
94 if(x >= 0 && x < 256) memcpy(seen_list[x].vendor_oui, globule->vendor_oui, sizeof(seen_list[x].vendor_oui));
97 if(x >= 0 && x < MAX_APS) memcpy(seen_list[x].vendor_oui, globule->vendor_oui, sizeof(seen_list[x].vendor_oui));
9598 }
9699 static unsigned char *get_ap_vendor(char* bssid) {
97100 int x = list_insert(bssid);
98 if(x >= 0 && x < 256 && seen_list[x].vendor_oui[0])
101 if(x >= 0 && x < MAX_APS && seen_list[x].vendor_oui[0])
99102 return seen_list[x].vendor_oui+1;
100103 return 0;
101104 }
105
102106 int wash_main(int argc, char *argv[])
103107 {
104108 int c = 0;
106110 int long_opt_index = 0, i = 0, channel = 0, passive = 0, mode = 0;
107111 int source = INTERFACE, ret_val = EXIT_FAILURE;
108112 struct bpf_program bpf = { 0 };
109 char *out_file = NULL, *last_optarg = NULL, *target = NULL, *bssid = NULL;
110 char *short_options = "i:c:n:o:b:5sfuDhaj";
113 char *last_optarg = NULL, *target = NULL, *bssid = NULL;
114 char *short_options = "i:c:n:b:25sfuFDhajU";
111115 struct option long_options[] = {
112116 { "bssid", required_argument, NULL, 'b' },
113117 { "interface", required_argument, NULL, 'i' },
114118 { "channel", required_argument, NULL, 'c' },
115 { "out-file", required_argument, NULL, 'o' },
116119 { "probes", required_argument, NULL, 'n' },
117 { "daemonize", no_argument, NULL, 'D' },
118120 { "file", no_argument, NULL, 'f' },
121 { "ignore-fcs", no_argument, NULL, 'F' },
122 { "2ghz", no_argument, NULL, '2' },
119123 { "5ghz", no_argument, NULL, '5' },
120124 { "scan", no_argument, NULL, 's' },
121125 { "survey", no_argument, NULL, 'u' },
122126 { "all", no_argument, NULL, 'a' },
123127 { "json", no_argument, NULL, 'j' },
128 { "utf8", no_argument, NULL, 'U' },
124129 { "help", no_argument, NULL, 'h' },
125130 { 0, 0, 0, 0 }
126131 };
127132
128 fprintf(stderr, "\nWash v%s WiFi Protected Setup Scan Tool\n", get_version());
129 fprintf(stderr, "Copyright (c) 2011, Tactical Network Solutions, Craig Heffner\n\n");
130
131133 globule_init();
132134 set_auto_channel_select(0);
133 set_wifi_band(BG_BAND);
135 set_wifi_band(0);
134136 set_debug(INFO);
135137 set_validate_fcs(1);
136 set_log_file(stdout);
138 /* send all warnings, etc to stderr */
139 set_log_file(stderr);
137140 set_max_num_probes(DEFAULT_MAX_NUM_PROBES);
141
142 setvbuf(stdout, 0, _IONBF, 0);
143 setvbuf(stderr, 0, _IONBF, 0);
138144
139145 while((c = getopt_long(argc, argv, short_options, long_options, &long_opt_index)) != -1)
140146 {
154160 set_fixed_channel(1);
155161 break;
156162 case '5':
157 set_wifi_band(AN_BAND);
163 set_wifi_band(get_wifi_band() | AN_BAND);
164 break;
165 case '2':
166 set_wifi_band(get_wifi_band() | BG_BAND);
158167 break;
159168 case 'n':
160169 set_max_num_probes(atoi(optarg));
161170 break;
162 case 'o':
163 out_file = strdup(optarg);
164 break;
165171 case 'j':
166172 json_mode = 1;
167173 break;
171177 case 'u':
172178 mode = SURVEY;
173179 break;
174 case 'D':
175 daemonize();
180 case 'F':
181 set_validate_fcs(0);
176182 break;
177183 case 'a':
178184 show_all_aps = 1;
185 break;
186 case 'U':
187 show_utf8_ssid = 1;
179188 break;
180189 default:
181190 wash_usage(argv[0]);
194203 }
195204 }
196205
206 if(get_wifi_band() == 0) set_wifi_band(BG_BAND);
207
197208 /* The interface value won't be set if capture files were specified; else, there should have been an interface specified */
198209 if(!get_iface() && source != PCAP_FILE)
199210 {
217228 if(source == PCAP_FILE)
218229 {
219230 passive = 1;
220 }
221
222 /* Open the output file, if any. If none, write to stdout. */
223 if(out_file)
224 {
225 fp = fopen(out_file, "wb");
226 if(!fp)
227 {
228 cprintf(CRITICAL, "[X] ERROR: Failed to open '%s' for writing\n", out_file);
229 goto end;
230 }
231
232 set_log_file(fp);
233231 }
234232
235233 /*
290288 end:
291289 globule_deinit();
292290 if(bssid) free(bssid);
293 if(out_file) free(out_file);
294291 if(wpsmon.fp) fclose(wpsmon.fp);
295292 return ret_val;
296293 }
334331 if(!header_printed)
335332 {
336333 if(!json_mode) {
337 cprintf (INFO, "BSSID Ch dBm WPS Lck Vendor ESSID\n");
338 //cprintf(INFO, "00:11:22:33:44:55 104 -77 1.0 Yes Bloatcom 0123456789abcdef0123456789abcdef\n");
339 cprintf (INFO, "--------------------------------------------------------------------------------\n");
334 fprintf (stdout, "BSSID Ch dBm WPS Lck Vendor ESSID\n");
335 //fprintf(stdout, "00:11:22:33:44:55 104 -77 1.0 Yes Bloatcom 0123456789abcdef0123456789abcdef\n");
336 fprintf (stdout, "--------------------------------------------------------------------------------\n");
340337 }
341338 header_printed = 1;
342339 }
438435
439436 char* vendor = get_vendor_string(get_ap_vendor(bssid));
440437 char* sane_ssid = sanitize_string(ssid);
438
439 if(show_utf8_ssid && verifyssid(ssid))
440 strcpy(sane_ssid,ssid);
441
441442 if(wps->version > 0)
442 cprintf(INFO, "%17s %3d %.2d %d.%d %3s %8s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, vendor ? vendor : " ", sane_ssid);
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);
443444 else
444 cprintf(INFO, "%17s %3d %.2d %8s %s\n", bssid, channel, rssi, vendor ? vendor : " ", sane_ssid);
445 fprintf(stdout, "%17s %3d %.2d %8s %s\n", bssid, channel, rssi, vendor ? vendor : " ", sane_ssid);
445446 free(sane_ssid);
446447 }
447448
459460 mark_ap_complete(bssid);
460461 if(json_mode && (show_all_aps || wps->version > 0)) {
461462 char *json_string = wps_data_to_json(bssid, ssid, channel, rssi, get_ap_vendor(bssid), wps);
462 fprintf(get_log_file(), "%s\n", json_string);
463 fflush(get_log_file());
463 fprintf(stdout, "%s\n", json_string);
464 fflush(stdout);
464465 free(json_string);
465466 }
466467 }
501502 next_channel();
502503 }
503504
505 static void print_header(void) {
506 fprintf(stderr, "\nWash v%s WiFi Protected Setup Scan Tool\n", get_version());
507 fprintf(stderr, "Copyright (c) 2011, Tactical Network Solutions, Craig Heffner\n\n");
508 }
509
504510 static void wash_usage(char *prog)
505511 {
512 print_header();
513
506514 fprintf(stderr, "Required Arguments:\n");
507515 fprintf(stderr, "\t-i, --interface=<iface> Interface to capture packets on\n");
508516 fprintf(stderr, "\t-f, --file [FILE1 FILE2 FILE3 ...] Read packets from capture files\n");
509517
510518 fprintf(stderr, "\nOptional Arguments:\n");
511519 fprintf(stderr, "\t-c, --channel=<num> Channel to listen on [auto]\n");
512 fprintf(stderr, "\t-o, --out-file=<file> Write data to file\n");
513520 fprintf(stderr, "\t-n, --probes=<num> Maximum number of probes to send to each AP in scan mode [%d]\n", DEFAULT_MAX_NUM_PROBES);
514 fprintf(stderr, "\t-D, --daemonize Daemonize wash\n");
521 fprintf(stderr, "\t-F, --ignore-fcs Ignore frame checksum errors\n");
522 fprintf(stderr, "\t-2, --2ghz Use 2.4GHz 802.11 channels\n");
515523 fprintf(stderr, "\t-5, --5ghz Use 5GHz 802.11 channels\n");
516524 fprintf(stderr, "\t-s, --scan Use scan mode\n");
517525 fprintf(stderr, "\t-u, --survey Use survey mode [default]\n");
518526 fprintf(stderr, "\t-a, --all Show all APs, even those without WPS\n");
519527 fprintf(stderr, "\t-j, --json print extended WPS info as json\n");
528 fprintf(stderr, "\t-U, --utf8 Show UTF8 ESSID (does not sanitize ESSID, dangerous)\n");
520529 fprintf(stderr, "\t-h, --help Show help\n");
521530
522531 fprintf(stderr, "\nExample:\n");