Extract PDF hash (edit passwd)
#11
Philsmd I couldn't agree more. Being able to crack the owner password can give additional information to be used in future efforts. I did some searching and didn't see any thing, but have you made any further progress on this? Have you posted a patch or alternate kernel on github or elsewhere? I would like to test this for myself. Thanks.

(01-26-2017, 06:03 PM)philsmd Wrote: It seems that the differences between the algorithms used for checking the owner password (- editing - permissions) compared to the user password (password to open the file aka encrypted PDFs) at least for rev 3 (PDF 1.4 - 1.6 (Acrobat 5 - 8)) is very little:
the difference is just the input (length) to the first MD5 and what is used for the rc4 key.
Here is a diff of the -m 10500 kernel (the file is [hashcat_root]/OpenCL/m10500.cl):
Code:
diff --git a/OpenCL/m10500.cl b/OpenCL/m10500.cl
index c4ba5df..67ef4a0 100644
--- a/OpenCL/m10500.cl
+++ b/OpenCL/m10500.cl
@@ -325,29 +325,10 @@ __kernel void m10500_init (__global pw_t *pws, __global const kernel_rule_t *rul
  id_buf[10] = 0;
  id_buf[11] = 0;

-  u32 id_len  = pdf_bufs[salt_pos].id_len;
-  u32 id_len4 = id_len / 4;
-
  u32 rc4data[2];

-  rc4data[0] = pdf_bufs[salt_pos].rc4data[0];
-  rc4data[1] = pdf_bufs[salt_pos].rc4data[1];
-
-  u32 final_length = 68 + id_len;
-
-  u32 w11 = 0x80;
-  u32 w12 = 0;
-
-  if (pdf_bufs[salt_pos].enc_md != 1)
-  {
-    w11 = 0xffffffff;
-    w12 = 0x80;
-
-    final_length += 4;
-  }
-
-  id_buf[id_len4 + 0] = w11;
-  id_buf[id_len4 + 1] = w12;
+  rc4data[0] = padding[0];
+  rc4data[1] = padding[1];

  /**
   * main init
@@ -391,14 +372,14 @@ __kernel void m10500_init (__global pw_t *pws, __global const kernel_rule_t *rul
  w1_t[1] |= w1[1];
  w1_t[2] |= w1[2];
  w1_t[3] |= w1[3];
-  w2_t[0]  = o_buf[0];
-  w2_t[1]  = o_buf[1];
-  w2_t[2]  = o_buf[2];
-  w2_t[3]  = o_buf[3];
-  w3_t[0]  = o_buf[4];
-  w3_t[1]  = o_buf[5];
-  w3_t[2]  = o_buf[6];
-  w3_t[3]  = o_buf[7];
+  w2_t[0] = 0x80;
+  w2_t[1] = 0;
+  w2_t[2] = 0;
+  w2_t[3] = 0;
+  w3_t[0] = 0;
+  w3_t[1] = 0;
+  w3_t[2] = 32 * 8;
+  w3_t[3] = 0;

  u32 digest[4];

@@ -409,25 +390,6 @@ __kernel void m10500_init (__global pw_t *pws, __global const kernel_rule_t *rul

  md5_transform (w0_t, w1_t, w2_t, w3_t, digest);

-  w0_t[0] = P;
-  w0_t[1] = id_buf[ 0];
-  w0_t[2] = id_buf[ 1];
-  w0_t[3] = id_buf[ 2];
-  w1_t[0] = id_buf[ 3];
-  w1_t[1] = id_buf[ 4];
-  w1_t[2] = id_buf[ 5];
-  w1_t[3] = id_buf[ 6];
-  w2_t[0] = id_buf[ 7];
-  w2_t[1] = id_buf[ 8];
-  w2_t[2] = id_buf[ 9];
-  w2_t[3] = id_buf[10];
-  w3_t[0] = id_buf[11];
-  w3_t[1] = 0;
-  w3_t[2] = final_length * 8;
-  w3_t[3] = 0;
-
-  md5_transform (w0_t, w1_t, w2_t, w3_t, digest);
-
  tmps[gid].digest[0] = digest[0];
  tmps[gid].digest[1] = digest[1];
  tmps[gid].digest[2] = digest[2];

you can play with it by just using "git apply a.patch" and removing the cached kernels (rm -r [hashcat_root]/kernels).

The only changes you need to do with the "hash" itself is to swap the user and owner part (i.e. swap the 2 last fields with the 2 second to last fields), e.g.:

Code:
$pdf$2*3*128*-3904*1*16*631ed33746e50fba5caf56bcc39e09c6*32*5f9d0e4f0b39835dace0d306c40cd6b700000000000000000000000000000000*32*842103b0a0dc886db9223b94afe2d7cd63389079b61986a4fcf70095ad630c24
becomes
Code:
$pdf$2*3*128*-3904*1*0*631ed33746e50fba5caf56bcc39e09c6*32*842103b0a0dc886db9223b94afe2d7cd63389079b61986a4fcf70095ad630c24*32*5f9d0e4f0b39835dace0d306c40cd6b700000000000000000000000000000000

or
Code:
$pdf$4*4*128*-1084*1*16*51765003ed0e2944a8991e710ec8aaa1*32*6554d929ab86fdd40a078d4e8cefb0ea2e0000000000000059028800188f3b00*32*34d5f6a6a8766b703d03a9ed1a8e3565f5cd34a85a506332737a70fb429e2bf6
becomes
Code:
$pdf$4*4*128*-1084*1*16*51765003ed0e2944a8991e710ec8aaa1*32*34d5f6a6a8766b703d03a9ed1a8e3565f5cd34a85a506332737a70fb429e2bf6*32*6554d929ab86fdd40a078d4e8cefb0ea2e0000000000000059028800188f3b00

Example run:
Code:
./hashcat -m 10500 '$pdf$2*3*128*-3904*1*16*631ed33746e50fba5caf56bcc39e09c6*32*842103b0a0dc886db9223b94afe2d7cd63389079b61986a4fcf70095ad630c24*32*5f9d0e4f0b39835dace0d306c40cd6b700000000000000000000000000000000' dict.txt

$pdf$2*3*128*-3904*1*16*631ed33746e50fba5caf56bcc39e09c6*32*842103b0a0dc886db9223b94afe2d7cd63389079b61986a4fcf70095ad630c24*32*5f9d0e4f0b39835dace0d306c40cd6b700000000000000000000000000000000:hashcat

I just think that support for this type of password recovery is just not demanded enough. Most users just workaround the permissions, without even caring what the password is. But of course for some forensic use cases it could be sometimes nice to get the password that was originally used to produce the PDF file.

The file used for analysis: http://www.filedropper.com/pdfownerpassonly
Reply
#12
Could not agree more with statements above, despite I tried hashcat just twice yet (but with PDF files exactly). You weren't able to get anything from a document that not encrypted, but you might consider getting hash from that without cracking - just using one of the dozens of free online edition tools, like this one e.g.: https://ds11.pdffiller.com And there's no some sort of magic about that. By no means, hashcat is a marvellous piece of soft, but don't try to use it for every single purpose
Reply
#13
It has been mentioned that there is existing software that can strip the editing functionality from pdf files. Can i get a lead on some of these? Google has alot of noise to signal.
Reply
#14
(09-21-2018, 07:18 PM)duhblow7 Wrote: It has been mentioned that there is existing software that can strip the editing functionality from pdf files. Can i get a lead on some of these? Google has alot of noise to signal.

qpdf is the tool.
Reply