Last active
October 13, 2022 19:56
-
-
Save garrettheaver/2fdbd09a73fb4b7cd9dbf985d4fa6646 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <pthread.h> | |
#include <openssl/pem.h> | |
#include <openssl/err.h> | |
#include <openssl/pkcs12.h> | |
/* I hate the globals being here - don't judge me, this whole thing | |
* was supposed to just be quick and dirty to get the job done! ;-) */ | |
PKCS12 *p12 = NULL; | |
int64_t pin = 0; | |
int32_t BLOCK_SIZE = 1000000; // balance between getting work done and feedback | |
int8_t THREADS = 8; // set roughly to how many cores your CPU has | |
// process (attempt) a range of pins on a thread | |
void *processRange(void *arg) { | |
int64_t current = *((int64_t *) arg); | |
int64_t end = current + BLOCK_SIZE; | |
char buf[32] = {0}; | |
for(; current < end; current++) { | |
int64_t itos = current; | |
int8_t idx = 30; | |
// convert the integer to a string (for PKCS12 func) | |
for(; itos && idx ; --idx, itos /= 10) { | |
buf[idx] = "0123456789"[itos % 10]; | |
} | |
// where the real work happens - see does the pin decode the file | |
if (PKCS12_parse(p12, &buf[idx+1], NULL, NULL, NULL)) { | |
pin = current; | |
break; | |
} | |
} | |
free(arg); | |
} | |
int main(int argc, char **argv) | |
{ | |
FILE *fp; | |
pthread_t threads[THREADS]; | |
int64_t offset = 0; | |
int8_t tid = 0; | |
if (argc != 2) { | |
fprintf(stderr, "Usage: breaker p12file\n"); | |
exit(EXIT_FAILURE); | |
} | |
if ((fp = fopen(argv[1], "rb")) == NULL) { | |
fprintf(stderr, "Error opening file %s\n", argv[1]); | |
exit(EXIT_FAILURE); | |
} | |
p12 = d2i_PKCS12_fp(fp, NULL); | |
fclose(fp); | |
if (p12 == NULL) { | |
fprintf(stderr, "Error reading PKCS#12 file\n"); | |
return 1; | |
} | |
setbuf(stdout, NULL); // don't wait for a newline from printf | |
while(true) { | |
for (tid = 0; tid < THREADS; tid++) { | |
int64_t *arg = malloc(sizeof(*arg)); | |
*arg = offset; | |
// tell me how you're getting on periodically | |
if (offset % 100000000 == 0 && offset != 0) { | |
printf(" %llu ", offset); | |
} | |
// start a new thread to process a range of pins | |
pthread_create(&threads[tid], NULL, processRange, (void *)arg); | |
offset += BLOCK_SIZE; | |
} | |
for (tid = 0; tid < THREADS; tid++) { | |
pthread_join(threads[tid], NULL); // sync up the threads | |
printf("."); // minimal console feedback so I know it's alive | |
} | |
if (pin > 0) { | |
printf("\nPIN is %llu\n", pin); | |
break; | |
} | |
} | |
PKCS12_free(p12); | |
return 0; | |
} |
To compile on Mac (after install openssl@1.1) you can use the following gcc breaker.c -o breaker -I/opt/homebrew/opt/openssl@1.1/include -L/opt/homebrew/opt/openssl@1.1/lib -lcrypto
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
if you're on linux compile it with
gcc breaker.c -o breaker -lcrypto
. If you're on a Mac you'll have tobrew install openssl@1.1
first