static void pdf_128b_bench(int numThreads, const unsigned int numCpuCores) { clock_t startTime, endTime; struct timeval wallTimeStart, wallTimeEnd; uint8_t o_string[32] = {0xcf, 0xeb, 0x57, 0x1b, 0xa4, 0x56, 0x35, 0x19, 0x4e, 0x09, 0x95, 0x24, 0x23, 0xf3, 0x9b, 0x81, 0x05, 0xae, 0xbc, 0xb2, 0x8c, 0x18, 0xd2, 0xbb, 0xff, 0x00, 0xc9, 0xaa, 0x3f, 0x36, 0xe3, 0x13}; uint8_t u_string[32] = {0x72, 0xf6, 0x56, 0x9e, 0xda, 0x7d, 0x20, 0x1a, 0x10, 0x6d, 0x8a, 0x5b, 0xfa, 0xb2, 0xe9, 0xc0, 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08}; uint8_t fileid[16] = {0xc9, 0xaa, 0x55, 0xc3, 0x6f, 0x3f, 0x5e, 0x84, 0x0d, 0x3d, 0x96, 0x8b, 0x97, 0xdb, 0xb2, 0xfe}; EncData e = { handler, o_string, u_string, fileid, true, 16, 1, 4, 128, -2359344, 3, 2 }; initPDFCrack(&e, NULL, true, NULL, Generative, NULL, charset, 0, 4, true, numThreads, numCpuCores, 1, 1); startTime = clock(); runCrackRev3(); endTime = clock(); print_and_clean("PDF (128, user):", getNrProcessed(), &startTime, &endTime); initPDFCrack(&e, NULL, false, NULL, Generative, NULL, charset, 0, 4, true, numThreads, numCpuCores, 1, 1); startTime = clock(); runCrackRev3_o(); endTime = clock(); print_and_clean("PDF (128, owner):", getNrProcessed(), &startTime, &endTime); initPDFCrack(&e, password, false, NULL, Generative, NULL, charset, 0, 4, true, numThreads, numCpuCores, 1, 1); startTime = clock(); runCrackRev3_of(); endTime = clock(); print_and_clean("PDF (128, owner, fast):", getNrProcessed(), &startTime, &endTime); if (numThreads > 0) { printf("\n"); printf("Benchmark (Wall time):\tAverage Speed (passwords / second):\n"); initPDFCrack(&e, NULL, true, NULL, Generative, NULL, charset, 0, 5, true, numThreads, numCpuCores, 1, 1); gettimeofday(&wallTimeStart, NULL); runCrackMultiThreads(); gettimeofday(&wallTimeEnd, NULL); char buf[32]; sprintf(buf, "PDF (128, user, %i threads):", numThreads); print_and_clean_wall_time(buf, getNrProcessed(), wallTimeStart, wallTimeEnd); } }
static void *get_salt(char *ciphertext) { char *ctcopy = strdup(ciphertext); char *keeptr = ctcopy; int i; char *p; ctcopy += 5; /* skip over "$pdf$" marker */ salt_struct = mem_calloc_tiny(sizeof(struct custom_salt), MEM_ALIGN_WORD); /* restore serialized data */ salt_struct->e.s_handler = strtok(ctcopy, "*"); salt_struct->e.o_string = (uint8_t *) malloc(32); p = strtok(NULL, "*"); for (i = 0; i < 32; i++) salt_struct->e.o_string[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + atoi16[ARCH_INDEX(p[i * 2 + 1])]; salt_struct->e.u_string = (uint8_t *) malloc(32); p = strtok(NULL, "*"); for (i = 0; i < 32; i++) salt_struct->e.u_string[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + atoi16[ARCH_INDEX(p[i * 2 + 1])]; p = strtok(NULL, "*"); salt_struct->e.fileIDLen = atoi(p); salt_struct->e.fileID = (uint8_t *) malloc(salt_struct->e.fileIDLen); p = strtok(NULL, "*"); for (i = 0; i < salt_struct->e.fileIDLen; i++) salt_struct->e.fileID[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + atoi16[ARCH_INDEX(p[i * 2 + 1])]; p = strtok(NULL, "*"); salt_struct->e.encryptMetaData = atoi(p); p = strtok(NULL, "*"); salt_struct->e.work_with_user = atoi(p); p = strtok(NULL, "*"); salt_struct->e.have_userpassword = atoi(p); p = strtok(NULL, "*"); salt_struct->e.version_major = atoi(p); p = strtok(NULL, "*"); salt_struct->e.version_minor = atoi(p); p = strtok(NULL, "*"); salt_struct->e.length = atoi(p); p = strtok(NULL, "*"); salt_struct->e.permissions = atoi(p); p = strtok(NULL, "*"); salt_struct->e.revision = atoi(p); p = strtok(NULL, "*"); salt_struct->e.version = atoi(p); if (salt_struct->e.have_userpassword) salt_struct->userpassword = (unsigned char *)strtok(NULL, "*"); free(keeptr); /* try to initialize the cracking-engine */ if (!initPDFCrack(salt_struct)) { fprintf(stderr, "Wrong userpassword, '%s'\n", salt_struct->userpassword); exit(-1); } return (void *)salt_struct; }
static void pdf_40b_bench(void) { clock_t startTime, endTime; uint8_t o_string[32] = { 0xb7, 0x81, 0xc8, 0x3d, 0x93, 0x79, 0x21, 0xcc, 0x0f, 0x3d, 0x40, 0xed, 0x18, 0xe7, 0x7f, 0x7e, 0xc0, 0x15, 0xb1, 0x63, 0xf5, 0xc8, 0x34, 0xe0, 0x54, 0x37, 0x41, 0x29, 0xe7, 0xc5, 0x1d, 0xe3 }; uint8_t u_string[32] = { 0x61, 0x74, 0x7c, 0x5c, 0xb5, 0x38, 0x3d, 0xdd, 0x6f, 0xcb, 0xb2, 0xf2, 0xfe, 0xe3, 0x34, 0x8d, 0x81, 0xe2, 0x49, 0x99, 0xc4, 0x14, 0xf6, 0x6f, 0xd0, 0x0f, 0x97, 0xe8, 0xb8, 0x29, 0xe6, 0x27 }; uint8_t fileid[16] = { 0x21, 0x76, 0x36, 0x66, 0x67, 0xf0, 0x86, 0xd5, 0x09, 0x88, 0xc3, 0xa7, 0xe9, 0x3a, 0x92, 0xca }; EncData e = { handler, o_string, u_string, fileid, true, 16, 1, 4, 40, -64, 2, 1 }; initPDFCrack(&e, NULL, true, NULL, Generative, NULL, charset, 0, 5, true); startTime = clock(); runCrackRev2(); endTime = clock(); print_and_clean("PDF (40, user):\t",getNrProcessed(),&startTime, &endTime); initPDFCrack(&e, NULL, false, NULL, Generative, NULL, charset, 0, 5, true); startTime = clock(); runCrackRev2_o(); endTime = clock(); print_and_clean("PDF (40, owner):",getNrProcessed(), &startTime, &endTime); initPDFCrack(&e, password, false, NULL, Generative, NULL, charset,0, 5,true); startTime = clock(); runCrackRev2_of(); endTime = clock(); print_and_clean("PDF (40, owner, fast):", getNrProcessed(), &startTime, &endTime); }
static void pdf_128b_bench(void) { clock_t startTime, endTime; uint8_t o_string[32] = { 0xcf, 0xeb, 0x57, 0x1b, 0xa4, 0x56, 0x35, 0x19, 0x4e, 0x09, 0x95, 0x24, 0x23, 0xf3, 0x9b, 0x81, 0x05, 0xae, 0xbc, 0xb2, 0x8c, 0x18, 0xd2, 0xbb, 0xff, 0x00, 0xc9, 0xaa, 0x3f, 0x36, 0xe3, 0x13 }; uint8_t u_string[32] = { 0x72, 0xf6, 0x56, 0x9e, 0xda, 0x7d, 0x20, 0x1a, 0x10, 0x6d, 0x8a, 0x5b, 0xfa, 0xb2, 0xe9, 0xc0, 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08 }; uint8_t fileid[16] = { 0xc9, 0xaa, 0x55, 0xc3, 0x6f, 0x3f, 0x5e, 0x84, 0x0d, 0x3d, 0x96, 0x8b, 0x97, 0xdb, 0xb2, 0xfe }; EncData e = { handler, o_string, u_string, fileid, true, 16, 1, 4, 128, -2359344, 3, 2 }; initPDFCrack(&e, NULL, true, NULL, Generative, NULL, charset, 0, 4, true); startTime = clock(); runCrackRev3(); endTime = clock(); print_and_clean("PDF (128, user):", getNrProcessed(), &startTime, &endTime); initPDFCrack(&e, NULL, false, NULL, Generative, NULL, charset, 0, 4, true); startTime = clock(); runCrackRev3_o(); endTime = clock(); print_and_clean("PDF (128, owner):", getNrProcessed(), &startTime, &endTime); initPDFCrack(&e,password, false, NULL, Generative, NULL, charset, 0, 4,true); startTime = clock(); runCrackRev3_of(); endTime = clock(); print_and_clean("PDF (128, owner, fast):", getNrProcessed(), &startTime, &endTime); }
int pdf2john(int argc, char **argv) { int ret = 0; int c, i; FILE *file = NULL; uint8_t *userpassword = NULL; char *inputfile = NULL; unsigned char *p; struct custom_salt cs; cs.e.work_with_user = true; cs.e.have_userpassword = false; /* parse arguments */ while (true) { c = getopt(argc, argv, "op:v"); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 'o': cs.e.work_with_user = false; break; case 'p': userpassword = (uint8_t *) strdup(optarg); cs.e.work_with_user = false; cs.e.have_userpassword = true; break; case 'v': printf("pdfcrack version %d.%d\n", VERSION_MAJOR, VERSION_MINOR); return 0; default: printHelp(argv[0]); ret = 1; } } i = optind; if (i > 0) { if (i < argc) inputfile = strdup(argv[i++]); } if (!inputfile) { printHelp(argv[0]); ret = 1; goto cleanup; } if ((file = fopen(inputfile, "r")) == 0) { fprintf(stderr, "Error: file %s not found\n", inputfile); ret = 2; goto cleanup; } if (!openPDF(file, &cs.e)) { fprintf(stderr, "Error: Not a valid PDF\n"); ret = 3; goto cleanup; } ret = getEncryptedInfo(file, &cs.e); if (ret) { if (ret == EENCNF) fprintf(stderr, "Error: Could not extract encryption information\n"); else if (ret == ETRANF || ret == ETRENF || ret == ETRINF) fprintf(stderr, "Error: Encryption not detected (is the document password protected?)\n"); ret = 4; goto cleanup; } else if (cs.e.revision < 2 || (strcmp(cs.e.s_handler, "Standard") != 0)) { fprintf(stderr, "The specific version is not supported (%s - %d)\n", cs.e.s_handler, cs.e.revision); ret = 5; goto cleanup; } if (fclose(file)) { fprintf(stderr, "Error: closing file %s\n", inputfile); } #ifdef UNPDF_DEBUG printEncData(&cs.e); #endif /* try to initialize the cracking-engine */ if (!initPDFCrack(&cs)) { fprintf(stderr, "Wrong userpassword given, '%s'\n", userpassword); exit(-1); } /* deep serialize "e" structure */ printf("%s:$pdf$%s*", inputfile, cs.e.s_handler); p = cs.e.o_string; for (i = 0; i < 32; i++) printf("%c%c", itoa16[ARCH_INDEX(p[i] >> 4)], itoa16[ARCH_INDEX(p[i] & 0x0f)]); printf("*"); p = cs.e.u_string; for (i = 0; i < 32; i++) printf("%c%c", itoa16[ARCH_INDEX(p[i] >> 4)], itoa16[ARCH_INDEX(p[i] & 0x0f)]); printf("*%d*", cs.e.fileIDLen); p = cs.e.fileID; for (i = 0; i < cs.e.fileIDLen; i++) printf("%c%c", itoa16[ARCH_INDEX(p[i] >> 4)], itoa16[ARCH_INDEX(p[i] & 0x0f)]); printf("*%d*%d*%d*%u*%u*%d*%d*%d*%d", cs.e.encryptMetaData, cs.e.work_with_user, cs.e.have_userpassword, cs.e.version_major, cs.e.version_minor, cs.e.length, cs.e.permissions, cs.e.revision, cs.e.version); if (cs.e.have_userpassword) printf("*%s\n", userpassword); else printf("\n"); exit(0); cleanup: return ret; }
int main(int argc, char** argv) { int ret = 0, minpw = 0, maxpw = 32; struct sigaction act1, act2; FILE *file = NULL, *wordlist = NULL; bool recovery = false, quiet = false, work_with_user = true, permutation = false; uint8_t *userpassword = NULL; char *charset = NULL, *inputfile = NULL, *wordlistfile = NULL; EncData *e; /** Parse arguments */ while(true) { int c, option_index; static struct option long_options[] = { {"bench", no_argument , 0, 'b'}, {"charset", required_argument, 0, 'c'}, {"file", required_argument, 0, 'f'}, {"loadState",required_argument, 0, 'l'}, {"maxpw", required_argument, 0, 'm'}, {"minpw", required_argument, 0, 'n'}, {"owner", no_argument , 0, 'o'}, {"password", required_argument, 0, 'p'}, {"quiet", required_argument, 0, 'q'}, {"permutate",no_argument, 0, 's'}, {"user", no_argument , 0, 'u'}, {"wordlist", required_argument, 0, 'w'}, {"version", no_argument , 0, 'v'}, {0, 0, 0, 0}}; /* getopt_long stores the option index here. */ option_index = 0; c = getopt_long(argc, argv, "bc:f:l:m:n:op:qsuw:v", long_options, &option_index); /* Detect the end of the options. */ if(c == -1) break; switch(c) { case 'b': runBenchmark(); return 0; case 'c': if(charset) fprintf(stderr,"Charset already set\n"); else charset = strdup(optarg); break; case 'f': if(!recovery) inputfile = strdup(optarg); break; case 'l': if(inputfile) { free(inputfile); inputfile = NULL; } inputfile = strdup(optarg); recovery = true; break; case 'm': maxpw = atoi(optarg); break; case 'n': minpw = atoi(optarg); break; case 'o': work_with_user = false; break; case 'p': userpassword = (uint8_t*)strdup(optarg); work_with_user = false; break; case 'q': quiet = true; break; case 'u': if(!work_with_user) { fprintf(stderr, "Cannot work with both user- and owner-password\n"); exit(1); } work_with_user = true; break; case 's': permutation = true; break; case 'w': if(wordlistfile) fprintf(stderr, "Wordlist already set\n"); else wordlistfile = strdup(optarg); break; case 'v': printf("pdfcrack version %d.%d\n", VERSION_MAJOR, VERSION_MINOR); return 0; default: printHelp(argv[0]); ret = 1; goto out3; } } /** If there are any unhandled arguments and the filename and/or wordlist is not set: try to match the first as the filename and the second as wordlist. */ { int i = optind; if(i > 0) { if(i < argc && !inputfile) inputfile = strdup(argv[i++]); if(i < argc && !wordlistfile) wordlistfile = strdup(argv[i++]); if(i < argc) while(i<argc) { fprintf(stderr,"Non-option argument %s\n", argv[i++]); } } } if(!inputfile || minpw < 0 || maxpw < 0) { printHelp(argv[0]); ret = 1; goto out3; } if((file = fopen(inputfile, "r")) == 0) { fprintf(stderr,"Error: file %s not found\n", inputfile); ret = 2; goto out3; } e = calloc(1,sizeof(EncData)); if(recovery) { if(wordlistfile) { free(wordlistfile); wordlistfile = NULL; } if(!loadState(file, e, &wordlistfile, &work_with_user)) { fprintf(stderr, "Error: Not a savefile or savefile is damaged\n"); ret = 3; goto out1; } if(!quiet) printf("Loaded state for %s\n", inputfile); } else { /** !recovery */ if(!openPDF(file,e)) { fprintf(stderr, "Error: Not a valid PDF\n"); ret = 3; goto out1; } ret = getEncryptedInfo(file, e); if(ret) { if(ret == EENCNF) fprintf(stderr, "Error: Could not extract encryption information\n"); else if(ret == ETRANF || ret == ETRENF || ret == ETRINF) fprintf(stderr, "Error: Encryption not detected (is the document password protected?)\n"); ret = 4; goto out1; } else if(e->revision < 2 || (strcmp(e->s_handler,"Standard") != 0)) { fprintf(stderr, "The specific version is not supported (%s - %d)\n", e->s_handler, e->revision); ret = 5; goto out1; } } if(fclose(file)) { fprintf(stderr, "Error: closing file %s\n", inputfile); } if(minpw > maxpw) { fprintf(stderr, "Warning: minimum pw-length bigger than max\n"); } if(wordlistfile) { if((wordlist = fopen(wordlistfile, "r")) == 0) { fprintf(stderr,"Error: file %s not found\n", wordlistfile); ret = 6; goto out2; } } act2.sa_handler = autoSave; sigfillset(&act2.sa_mask); act2.sa_flags = 0; sigaction(SIGINT, &act2, 0); if(!quiet) { printEncData(e); act1.sa_handler = alarmInterrupt; sigemptyset(&act1.sa_mask); act1.sa_flags = 0; sigaction(SIGALRM, &act1, 0); alarm(PRINTERVAL); } /** Try to initialize the cracking-engine */ if(!initPDFCrack(e, userpassword, work_with_user, wordlistfile, wordlistfile?Wordlist:Generative, wordlist, charset, (unsigned int)minpw, (unsigned int)maxpw, permutation)) { cleanPDFCrack(); fprintf(stderr, "Wrong userpassword, '%s'\n", userpassword); ret = 7; goto out2; } /** Do the actual crunching */ runCrack(); /** cleanup */ cleanPDFCrack(); freeEncData(e); if(wordlistfile) { fclose(wordlist); free(wordlistfile); } if(inputfile) free(inputfile); if(charset) free(charset); if(userpassword) free(userpassword); return 0; out1: if(fclose(file)) fprintf(stderr, "Error: closing file %s\n", inputfile); out2: freeEncData(e); out3: if(inputfile) free(inputfile); if(charset) free(charset); if(userpassword) free(userpassword); exit(ret); }