Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix for PDF, and a couple of minor tweaks #5532

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ static MAYBE_INLINE int ldr_check_shells(struct list_main *list, char *shell)

void ldr_set_encoding(struct fmt_main *format)
{
if ((!options.target_enc || options.default_target_enc) &&
!options.internal_cp) {
if (!options.loader.showformats &&
(!options.target_enc || options.default_target_enc) && !options.internal_cp) {
if (!strncasecmp(format->params.label, "LM", 2) ||
!strcasecmp(format->params.label, "netlm") ||
!strcasecmp(format->params.label, "nethalflm")) {
Expand Down
54 changes: 38 additions & 16 deletions src/pbkdf2_hmac_common_plug.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ char *pbkdf2_hmac_md4_split(char *ciphertext, int index, struct fmt_main *self)
{
static char out[PBKDF2_MD4_MAX_CIPHERTEXT_LENGTH + 1];
char *cp;

strnzcpylwr(out, ciphertext, sizeof(out));
cp = strchr(out, '.');
while (cp) {

cp = out;
while ((cp = strchr(cp, '.')))
*cp = '$';
cp = strchr(cp, '.');
}

return out;
}

Expand Down Expand Up @@ -261,12 +262,13 @@ int pbkdf2_hmac_md5_valid(char *ciphertext, struct fmt_main *self)
char *pbkdf2_hmac_md5_split(char *ciphertext, int index, struct fmt_main *self) {
static char out[PBKDF2_MD5_MAX_CIPHERTEXT_LENGTH + 1];
char *cp;

strnzcpylwr(out, ciphertext, sizeof(out));
cp = strchr(out, '.');
while (cp) {

cp = out;
while ((cp = strchr(cp, '.')))
*cp = '$';
cp = strchr(cp, '.');
}

return out;
}

Expand Down Expand Up @@ -419,11 +421,11 @@ char *pbkdf2_hmac_sha1_split(char *ciphertext, int index, struct fmt_main *self)
char *cp;

strnzcpylwr(out, ciphertext, sizeof(out));
cp = strchr(out, '.');
while (cp) {

cp = out;
while ((cp = strchr(cp, '.')))
*cp = '$';
cp = strchr(cp, '.');
}

return out;
}

Expand Down Expand Up @@ -638,17 +640,37 @@ char *pbkdf2_hmac_sha256_prepare(char *fields[10], struct fmt_main *self) {
static char Buf[PBKDF2_SHA256_MAX_CIPHERTEXT_LENGTH + 1];
char tmp[43+1], *cp;

// MIME Base64, optionally with escaped slashes. Trailing '=' is also optional.
if (!strncmp(fields[1], PBKDF2_SHA256_FORMAT_TAG, PBKDF2_SHA256_TAG_LEN)) {
if (strchr(fields[1], '\\') || strchr(fields[1], '=') || strchr(fields[1], '+')) {
strcpy(Buf, fields[1]);

cp = Buf;
while ((cp = strchr(cp, '\\')))
memmove(cp, cp + 1, strlen(cp));

cp = Buf;
while ((cp = strchr(cp, '=')))
memmove(cp, cp + 1, strlen(cp));
magnumripper marked this conversation as resolved.
Show resolved Hide resolved

cp = Buf;
while ((cp = strchr(cp, '+')))
*cp = '.';

return Buf;
}
}
if (strncmp(fields[1], FORMAT_TAG_CISCO8, FORMAT_TAG_CISCO8_LEN) != 0)
return fields[1];
if (strlen(fields[1]) != 4+14+43)
return fields[1];
sprintf(Buf, "%s20000$%14.14s$%s", PBKDF2_SHA256_FORMAT_TAG, &(fields[1][FORMAT_TAG_CISCO8_LEN]),
base64_convert_cp(&(fields[1][FORMAT_TAG_CISCO8_LEN+14+1]), e_b64_crypt, 43, tmp, e_b64_mime, sizeof(tmp), flg_Base64_NO_FLAGS, 0));
cp = strchr(Buf, '+');
while (cp) {

cp = Buf;
while ((cp = strchr(cp, '+')))
*cp = '.';
cp = strchr(cp, '+');
}

return Buf;
}

Expand Down
77 changes: 52 additions & 25 deletions src/pdf_fmt_plug.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* PDF cracker patch for JtR. Hacked together during Monsoon of 2012 by
/*
* PDF cracker patch for JtR. Hacked together during Monsoon of 2012 by
* Dhiru Kholia <dhiru.kholia at gmail.com>.
*
* This software is Copyright (c) 2012, Dhiru Kholia <dhiru.kholia at gmail.com>
*
* Uses code from Sumatra PDF and MuPDF which are under GPL.
* This software is
* Copyright (c) 2012, Dhiru Kholia <dhiru.kholia at gmail.com>
* Copyright (c) 2013, Shane Quigley
* Copyright (c) 2024, magnum
*
* Edited by Shane Quigley in 2013.
* Uses code from pdfcrack, Sumatra PDF and MuPDF which are under GPL.
*/

#if FMT_EXTERNS_H
Expand All @@ -31,6 +33,8 @@ john_register_one(&fmt_pdf);
#include "rc4.h"
#include "pdfcrack_md5.h"
#include "loader.h"
#include "options.h"
#include "logger.h"

#define FORMAT_LABEL "PDF"
#define FORMAT_NAME ""
Expand Down Expand Up @@ -76,6 +80,10 @@ static struct custom_salt {
int length_oe;
} *crypt_out;

#define MAX_KEY_SIZE 256
#define MAX_U_SIZE sizeof(crypt_out->u)
#define MAX_O_SIZE sizeof(crypt_out->o)

static struct fmt_tests pdf_tests[] = {
{"$pdf$4*4*128*-1028*1*16*e03460febe17a048b0adc7f7631bcc56*32*3456205208ad52066d5604018d498a6400000000000000000000000000000000*32*6d598152b22f8fa8085b19a866dce1317f645788a065a74831588a739a579ac4", "openwall"},
{"$pdf$2*3*128*-4*1*16*34b1b6e593787af681a9b63fa8bf563b*32*289ece9b5ce451a5d7064693dab3badf101112131415161718191a1b1c1d1e1f*32*badad1e86442699427116d3e5d5271bc80a27814fc5e80f815efeef839354c5f", "test"},
Expand Down Expand Up @@ -140,7 +148,7 @@ static int valid(char *ciphertext, struct fmt_main *self)
goto err;
if (!isdec(p)) goto err;
res = atoi(p);
if (res > 256)
if (res > MAX_KEY_SIZE)
goto err;
if ((p = strtokm(NULL, "*")) == NULL) /* P */
goto err;
Expand All @@ -165,7 +173,7 @@ static int valid(char *ciphertext, struct fmt_main *self)
goto err;
if (!isdec(p)) goto err;
res = atoi(p);
if (res > 127)
if (res > MAX_U_SIZE)
goto err;
if ((p = strtokm(NULL, "*")) == NULL) /* u */
goto err;
Expand All @@ -177,7 +185,7 @@ static int valid(char *ciphertext, struct fmt_main *self)
goto err;
if (!isdec(p)) goto err;
res = atoi(p);
if (res > 127)
if (res > MAX_O_SIZE)
goto err;
if ((p = strtokm(NULL, "*")) == NULL) /* o */
goto err;
Expand Down Expand Up @@ -257,7 +265,7 @@ static int old_valid(char *ciphertext, struct fmt_main *self)
return 0;
}

char * convert_old_to_new(char ciphertext[])
char* convert_old_to_new(char ciphertext[])
{
char *ctcopy = xstrdup(ciphertext);
char *keeptr = ctcopy;
Expand Down Expand Up @@ -425,13 +433,20 @@ pdf_compute_encryption_key(unsigned char *password, int pwlen, unsigned char *ke
/* Step 8 (revision 3 or greater) - do some voodoo 50 times */
if (crypt_out->R >= 3)
{
/* for (i = 0; i < 50; i++)
{
MD5_Init(&md5);
MD5_Update(&md5, buf, n);
MD5_Final(buf, &md5);
} */
md5_50(buf);
switch(crypt_out->length) {
case 128:
md5x50_128(buf);
break;
case 40:
md5x50_40(buf);
break;
default:
for (int i = 0; i < 50; i++) {
MD5_Init(&md5);
MD5_Update(&md5, buf, n);
MD5_Final(buf, &md5);
}
}
}
/* Step 9 - the key is the first 'n' bytes of the result */
memcpy(key, buf, n);
Expand Down Expand Up @@ -548,26 +563,24 @@ pdf_compute_hardened_hash_r6(unsigned char *password, int pwlen, unsigned char s

static void pdf_compute_user_password(unsigned char *password, unsigned char *output)
{

int pwlen = strlen((char*)password);
unsigned char key[128];
unsigned char key[MAX_KEY_SIZE / 8];
int n = crypt_out->length / 8;

if (crypt_out->R == 2) {
RC4_KEY arc4;
int n;
n = crypt_out->length / 8;

pdf_compute_encryption_key(password, pwlen, key);
RC4_set_key(&arc4, n, key);
RC4(&arc4, 32, padding, output);
}

if (crypt_out->R == 3 || crypt_out->R == 4) {
else if (crypt_out->R == 3 || crypt_out->R == 4) {
unsigned char xor[32];
unsigned char digest[16];
MD5_CTX md5;
RC4_KEY arc4;
int i, x, n;
n = crypt_out->length / 8;
int i, x;

pdf_compute_encryption_key(password, pwlen, key);
MD5_Init(&md5);
MD5_Update(&md5, (char*)padding, 32);
Expand All @@ -581,7 +594,7 @@ static void pdf_compute_user_password(unsigned char *password, unsigned char *o
RC4_set_key(&arc4, n, xor);
RC4(&arc4, 16, output, output);
}
memcpy(output + 16, padding, 16);
//memcpy(output + 16, padding, 16); /* pointless - we only test 16 bytes of it */
}
if (crypt_out->R == 5) {
pdf_compute_encryption_key_r5(password, pwlen, 0, output);
Expand All @@ -590,6 +603,20 @@ static void pdf_compute_user_password(unsigned char *password, unsigned char *o
/* SumatraPDF: support crypt version 5 revision 6 */
if (crypt_out->R == 6)
pdf_compute_hardened_hash_r6(password, pwlen, crypt_out->u + 32, NULL, output);

if (!bench_or_test_running && crypt_out->length == 40 && !memcmp(output, crypt_out->u, 16)) {
char h_key[2 * 5 + 1], *p;
int i;

p = &h_key[0];
for (i = 0; i < 2 * n; i++)
*p++ = itoa16[key[i >> 1] >> (4 * ((i & 0x1) ^ 1)) & 0xf];
*p = 0;

log_event("+ RC4 key: %s", h_key);
if (options.verbosity > VERB_DEFAULT)
fprintf(stderr, "+ RC4 key: %s\n", h_key);
}
}

static int crypt_all(int *pcount, struct db_salt *salt)
Expand Down
4 changes: 2 additions & 2 deletions src/pdfcrack_md5.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

#include <stdint.h>

void md5(const uint8_t * msg, const unsigned int msgLen, uint8_t * digest);

void md5_50(uint8_t * msg);
extern void md5x50_40(uint8_t * msg);
extern void md5x50_128(uint8_t * msg);

#endif /** _MD5_H_ */
Loading