implement parallel search of es1 nonce for RTL

each thread searches 1 seed forward, then 1 seed backwards in time.
the main thread handles the case seed enonce==seed es1.
This commit is contained in:
rofl0r 2017-11-29 23:22:24 +00:00 committed by wiire-a
parent 226c2deb39
commit bb5c1d1d5f
2 changed files with 98 additions and 69 deletions

View File

@ -93,6 +93,7 @@ static struct job_control {
int mode;
uint32_t end;
uint32_t randr_enonce[4];
struct global *wps;
struct crack_job *crack_jobs;
volatile uint32_t nonce_seed;
} job_control;
@ -195,6 +196,8 @@ static void crack_thread_rt(struct crack_job *j)
}
}
static void crack_thread_rtl_es(struct crack_job *j);
static void *crack_thread(void *arg)
{
struct crack_job *j = arg;
@ -203,6 +206,8 @@ static void *crack_thread(void *arg)
crack_thread_rtl(j);
else if (job_control.mode == RT)
crack_thread_rt(j);
else if (job_control.mode == -RTL819x)
crack_thread_rtl_es(j);
else
assert(0);
@ -233,6 +238,7 @@ static void setup_thread(int i)
static void init_crack_jobs(struct global *wps, int mode)
{
job_control.wps = wps;
job_control.jobs = wps->jobs;
job_control.end = (mode == RTL819x) ? wps->end : 0xffffffffu;
job_control.mode = mode;
@ -241,7 +247,8 @@ static void init_crack_jobs(struct global *wps, int mode)
/* Converting enrollee nonce to the sequence may be generated by current random function */
int i, j = 0;
if (mode == RTL819x)
if (mode == -RTL819x) ; /* nuffin' */
else if (mode == RTL819x)
for (i = 0; i < 4; i++) {
job_control.randr_enonce[i] |= wps->e_nonce[j++];
job_control.randr_enonce[i] <<= 8;
@ -254,11 +261,11 @@ static void init_crack_jobs(struct global *wps, int mode)
else
memcpy(job_control.randr_enonce, wps->e_nonce, WPS_NONCE_LEN);
job_control.crack_jobs = malloc(wps->jobs * sizeof (struct job_control));
job_control.crack_jobs = malloc(wps->jobs * sizeof (struct crack_job));
uint32_t curr = (mode == RTL819x) ? wps->start : 0;
int32_t add = (mode == RTL819x) ? -SEEDS_PER_JOB_BLOCK : SEEDS_PER_JOB_BLOCK;
for (i = 0; i < wps->jobs; i++) {
job_control.crack_jobs[i].start = curr;
job_control.crack_jobs[i].start = (mode == -RTL819x) ? i + 1 : curr;
setup_thread(i);
curr += add;
}
@ -317,60 +324,72 @@ static int find_rtl_es1(struct global *wps, char *pin, uint8_t *nonce_buf, uint3
return crack_first_half(wps, pin, nonce_buf);
}
static int find_rtl_es_dir(struct global *wps, char *pin, int dir)
static void crack_thread_rtl_es(struct crack_job *j)
{
int i, break_cond = (MODE3_TRIES + 1) * dir;
int thread_id = j->start;
uint8_t nonce_buf[WPS_SECRET_NONCE_LEN];
char pin[WPS_PIN_LEN + 1];
int dist, max_dist = (MODE3_TRIES + 1);
if (dir == 1)
DEBUG_PRINT("Trying forward in time");
else
DEBUG_PRINT("Trying backwards in time");
for (dist = thread_id; !job_control.nonce_seed && dist < max_dist; dist += job_control.jobs) {
if (find_rtl_es1(job_control.wps, pin, nonce_buf, job_control.wps->nonce_seed + dist)) {
job_control.nonce_seed = job_control.wps->nonce_seed + dist;
memcpy(job_control.wps->e_s1, nonce_buf, sizeof nonce_buf);
memcpy(job_control.wps->pin, pin, sizeof pin);
}
for (i = 0; i != break_cond; i += dir) {
uint8_t nonce_buf[WPS_SECRET_NONCE_LEN];
if (job_control.nonce_seed)
break;
DEBUG_PRINT("Trying (%10u) with E-S1: ", wps->nonce_seed + i);
if (find_rtl_es1(job_control.wps, pin, nonce_buf, job_control.wps->nonce_seed - dist)) {
job_control.nonce_seed = job_control.wps->nonce_seed - dist;
memcpy(job_control.wps->e_s1, nonce_buf, sizeof nonce_buf);
memcpy(job_control.wps->pin, pin, sizeof pin);
}
}
}
if (find_rtl_es1(wps, pin, nonce_buf, wps->nonce_seed + i)) {
DEBUG_PRINT("First pin half found");
memcpy(wps->e_s1, nonce_buf, sizeof nonce_buf);
wps->s1_seed = wps->nonce_seed + i;
static int find_rtl_es(struct global *wps)
{
char pin_copy[WPS_PIN_LEN + 1];
strcpy(pin_copy, pin);
int j;
/* we assume that the seed used for es2 is within a range of 10 seconds
forwards in time only */
for (j = 0; j < 10; j++) {
strcpy(pin, pin_copy);
rtl_nonce_fill(wps->e_s2, wps->s1_seed + j);
DEBUG_PRINT("Trying (%10u) with E-S2: ", wps->s1_seed + j);
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
if (crack_second_half(wps, pin)) {
wps->s2_seed = wps->s1_seed + j;
DEBUG_PRINT("Pin found");
return RTL819x;
}
init_crack_jobs(wps, -RTL819x);
/* checking distance 0 in the main thread, as it is the most likely */
uint8_t nonce_buf[WPS_SECRET_NONCE_LEN];
char pin[WPS_PIN_LEN + 1];
if (find_rtl_es1(wps, pin, nonce_buf, wps->nonce_seed)) {
job_control.nonce_seed = wps->nonce_seed;
memcpy(wps->e_s1, nonce_buf, sizeof nonce_buf);
memcpy(wps->pin, pin, sizeof pin);
}
collect_crack_jobs();
if (job_control.nonce_seed) {
DEBUG_PRINT("First pin half found");
wps->s1_seed = job_control.nonce_seed;
char pin_copy[WPS_PIN_LEN + 1];
strcpy(pin_copy, wps->pin);
int j;
/* we assume that the seed used for es2 is within a range of 10 seconds
forwards in time only */
for (j = 0; j < 10; j++) {
strcpy(wps->pin, pin_copy);
rtl_nonce_fill(wps->e_s2, wps->s1_seed + j);
DEBUG_PRINT("Trying (%10u) with E-S2: ", wps->s1_seed + j);
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
if (crack_second_half(wps, wps->pin)) {
wps->s2_seed = wps->s1_seed + j;
DEBUG_PRINT("Pin found");
return RTL819x;
}
}
}
return NONE;
}
static int find_rtl_es(struct global *wps, char *pin)
{
int found_p_mode = find_rtl_es_dir(wps, pin, 1);
if (found_p_mode != NONE)
return found_p_mode;
found_p_mode = find_rtl_es_dir(wps, pin, -1);
return found_p_mode;
}
static void empty_pin_hmac(struct global *wps)
{
/* since the empty pin psk is static once initialized, we calculate it only once */
@ -697,7 +716,6 @@ usage_err:
}
uint_fast8_t pfound = PIN_ERROR;
char pin[WPS_PIN_LEN + 1] = {0};
vtag_t *vtag;
if (decrypted5 && decrypted7 && wps->e_hash1 && wps->e_hash2) {
wps->e_s1 = malloc(WPS_SECRET_NONCE_LEN); if (!wps->e_s1) goto memory_err;
@ -721,7 +739,7 @@ usage_err:
return UNS_ERROR;
}
pfound = crack(wps, pin);
pfound = crack(wps, wps->pin);
}
gettimeofday(&t_end, 0);
@ -761,10 +779,10 @@ usage_err:
printf("\n [*] SSID: %s", buffer);
}
if (pfound == PIN_FOUND) {
if (pin[0] == '\0')
if (wps->pin[0] == '\0')
printf("\n [+] WPS pin: <empty>");
else
printf("\n [+] WPS pin: %s", pin);
printf("\n [+] WPS pin: %s", wps->pin);
}
if ((vtag = find_vtag(decrypted7, wps->m7_encr_len - 16, WPS_TAG_NET_KEY, 0))) {
int tag_size = end_ntoh16(vtag->len);
@ -1012,7 +1030,6 @@ usage_err:
uint_fast8_t k = 0;
uint_fast8_t found_p_mode = NONE;
char pin[WPS_PIN_LEN + 1];
uint32_t seed;
wps->nonce_seed = 0;
@ -1031,7 +1048,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
uint_fast8_t r = crack(wps, pin);
uint_fast8_t r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = RT;
DEBUG_PRINT("Pin found");
@ -1063,7 +1080,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
r = crack(wps, pin);
r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = RT;
DEBUG_PRINT("Pin found");
@ -1108,7 +1125,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
uint_fast8_t r = crack(wps, pin);
uint_fast8_t r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = ECOS_SIMPLE;
DEBUG_PRINT("Pin found");
@ -1130,7 +1147,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
uint_fast8_t r = crack(wps, pin);
uint_fast8_t r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = RTL819x;
DEBUG_PRINT("Pin found");
@ -1172,7 +1189,7 @@ usage_err:
wps->nonce_seed = collect_crack_jobs();
if (wps->nonce_seed) { /* Seed found */
found_p_mode = find_rtl_es(wps, pin);
found_p_mode = find_rtl_es(wps);
}
if (found_p_mode == NONE && !wps->bruteforce) {
@ -1225,7 +1242,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
uint_fast8_t r = crack(wps, pin);
uint_fast8_t r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = ECOS_SIMPLEST;
DEBUG_PRINT("Pin found");
@ -1270,7 +1287,7 @@ usage_err:
DEBUG_PRINT("Trying with E-S2: ");
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
uint_fast8_t r = crack(wps, pin);
uint_fast8_t r = crack(wps, wps->pin);
if (r == PIN_FOUND) {
found_p_mode = ECOS_KNUTH;
DEBUG_PRINT("Pin found");
@ -1347,11 +1364,11 @@ usage_err:
printf("\n [*] ES1: "); byte_array_print(wps->e_s1, WPS_SECRET_NONCE_LEN);
printf("\n [*] ES2: "); byte_array_print(wps->e_s2, WPS_SECRET_NONCE_LEN);
}
if (pin[0] == '\0') {
if (wps->pin[0] == '\0') {
printf("\n [+] WPS pin: <empty>");
}
else {
printf("\n [+] WPS pin: %s", pin);
printf("\n [+] WPS pin: %s", wps->pin);
}
}
else {
@ -1494,11 +1511,13 @@ static int crack_first_half(struct global *wps, char *pin, const uint8_t *es1_ov
}
unsigned first_half;
uint8_t psk[WPS_HASH_LEN];
for (first_half = 0; first_half < 10000; first_half++) {
uint_to_char_array(first_half, 4, pin);
if (check_pin_half(pin, wps->psk1, es1, wps, wps->e_hash1)) {
if (check_pin_half(pin, psk, es1, wps, wps->e_hash1)) {
pin[4] = 0; /* make sure pin string is zero-terminated */
memcpy(wps->psk1, psk, sizeof psk);
return 1;
}
}
@ -1514,13 +1533,17 @@ static int crack_second_half(struct global *wps, char *pin)
unsigned second_half, first_half = atoi(pin);
char *s_pin = pin + strlen(pin);
uint8_t psk[WPS_HASH_LEN];
for (second_half = 0; second_half < 1000; second_half++) {
unsigned int checksum_digit = wps_pin_checksum(first_half * 1000 + second_half);
unsigned int c_second_half = second_half * 10 + checksum_digit;
uint_to_char_array(c_second_half, 4, s_pin);
if (check_pin_half(s_pin, wps->psk2, wps->e_s2, wps, wps->e_hash2))
if (check_pin_half(s_pin, psk, wps->e_s2, wps, wps->e_hash2)) {
memcpy(wps->psk2, psk, sizeof psk);
pin[8] = 0;
return 1;
}
}
for (second_half = 0; second_half < 10000; second_half++) {
@ -1531,7 +1554,8 @@ static int crack_second_half(struct global *wps, char *pin)
}
uint_to_char_array(second_half, 4, s_pin);
if (check_pin_half(s_pin, wps->psk2, wps->e_s2, wps, wps->e_hash2)) {
if (check_pin_half(s_pin, psk, wps->e_s2, wps, wps->e_hash2)) {
memcpy(wps->psk2, psk, sizeof psk);
pin[8] = 0; /* make sure pin string is zero-terminated */
return 1;
}

View File

@ -44,6 +44,10 @@
#include "utils.h"
#ifndef WPS_PIN_LEN
#define WPS_PIN_LEN 8
#endif
#if defined(DEBUG)
# define DEBUG_PRINT(fmt, args...) do { fprintf(stderr, "\n [DEBUG] %s:%d:%s(): " fmt, \
__FILE__, __LINE__, __func__, ##args); fflush(stdout); } while (0)
@ -83,6 +87,7 @@ const uint8_t rtl_rnd_seed[] = {
};
struct global {
uint8_t pin[WPS_PIN_LEN + 1];
uint8_t *pke;
uint8_t *pkr;
uint8_t *e_key;