Skip to content

Instantly share code, notes, and snippets.

@garrettheaver
Last active October 13, 2022 19:56
Show Gist options
  • Save garrettheaver/2fdbd09a73fb4b7cd9dbf985d4fa6646 to your computer and use it in GitHub Desktop.
Save garrettheaver/2fdbd09a73fb4b7cd9dbf985d4fa6646 to your computer and use it in GitHub Desktop.
#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;
}
@garrettheaver
Copy link
Author

if you're on linux compile it with gcc breaker.c -o breaker -lcrypto. If you're on a Mac you'll have to brew install openssl@1.1 first

@garrettheaver
Copy link
Author

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