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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new format -m 15300 Dpapi master key file version 1 and version 2 #1238

Merged
merged 8 commits into from May 16, 2017

Conversation

@Fist0urs
Copy link
Contributor

@Fist0urs Fist0urs commented May 8, 2017

Hi there,

after implementing the format in John the Ripper (openwall/john#2521) here it is in hashcat.

You will need DPAPImk2john.py, provided in @magnumripper JtR run/ folder

tl;dr: cracking master keys can be useful in some situations:

  • while in compromised user's logon context (eg. after phishing), you can manage to retrieve his logon password without needing admin rights
  • if workstation is hardened and 0 or 1 MSCashX are present, master key files permit to retrieve corresponding users' passwords (indeed, dpapi related stuff is imported in roaming profile within an Active Directory when a user interactively log on). So this is an alternative to dumping MSCashX hash if you are admin 馃槈
  • Much more stealth and reliable as you only need to retrieve master keys that are files on the file system (thus not injecting in memory or accessing registry)
  • Time of creation of master key files are there as these are files on file system, so you can easily deduce if the password is the current user's one 馃槈
  • Much more difficult to spot afterward

If you want some more information:
http://www.synacktiv.ninja/ressources/univershell_2017_dpapi.pdf

Performances:

* Device 3: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU
* Device 4: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU
* Device 5: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU

Hashtype: Domain Cached Credentials 2 (DCC2), MS Cache 2

Speed.Dev.3.....: 322.5 kH/s (49.23ms)
Speed.Dev.4.....: 324.3 kH/s (49.00ms)
Speed.Dev.5.....: 330.2 kH/s (98.64ms)
Speed.Dev.#*.....: 977.0 kH/s

* Device 3: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU
* Device 4: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU
* Device 5: GeForce GTX 1080, 2048/8192 MB allocatable, 20MCU

Hashtype: DPAPI masterkey file v1 and v2

Speed.Dev.3.....: 71304 H/s (48.37ms)
Speed.Dev.4.....: 70829 H/s (48.75ms)
Speed.Dev.5.....: 73656 H/s (93.78ms)
Speed.Dev.#*.....: 215.8 kH/s

Which is not that bad, regarding the high iterations number and algorithms involved!

Cheers!
Ours

@jsteube
Copy link
Member

@jsteube jsteube commented May 14, 2017

Nice work. This really looks interessting for the pentesting community. Here some comments:

  1. Please do not use char in a shared structure datatype (shared between host code an GPU code). Please use only u8, u16, u32 and u64.
+  char cipher_algo[16];
+  char hash_algo[16];

Try to replace with u8 also in ascii_digest ()

  1. Note that whenever you use u8, the performance drops massively as GPU do not have 8 bit registers as CPU have. That's why you should try to always use u32. If you can rewrite your code so that it does not need to work with u8 you will increase the performance alot.

  2. What is the reason to have the password (userKey[]) in the tmps variable?

+  u32 userKey[5];

If possible, please remove that. You should be able to access the password from within _loop() and _comp() kernels the same way as in _init().

  1. Please align the following code. I tried to do it for you but then saw that there's a value missing:
+  DISPLAY_LEN_MIN_15300 =  1 + 7 + 1 + 1 + 1 + 1 + 1 + 10 + 1 + 4 + 1 + 4 + 1 + 1 + 1 + 32 + 1 + 3 + 128,
+  DISPLAY_LEN_MAX_15300 =  1 + 7 + 1 + 1 + 1 + 1 + 1 + 100 + 1 + 6 + 1 + 6 + 1 + 10 + 1 + 32 + 1 + 4 + 1 + 512,

to (please find the ? mark):

+  DISPLAY_LEN_MIN_15300 =  1 + 7 + 1 + 1 + 1 + 1 + 1 +  10 + 1 + 4 + 1 + 4 + 1 +  1 + 1 + 32 + 1 + 3 + ? + 128,
+  DISPLAY_LEN_MAX_15300 =  1 + 7 + 1 + 1 + 1 + 1 + 1 + 100 + 1 + 6 + 1 + 6 + 1 + 10 + 1 + 32 + 1 + 4 + 1 + 512,
  1. In the dpapimk_parse_hash() section, please move all converter code below the parser code. So for example this:
+  cipher_algo_pos = (u8 *) strchr ((const char *) SID_pos, '*');
+
+  if (cipher_algo_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
+  for (int i = 0; i < cipher_algo_pos - SID_pos; i++)
+    dpapimk->SID_tmp[i] = SID_pos[i];
+  dpapimk->SID_tmp[cipher_algo_pos - SID_pos] = '\0';

Shoudl be limited to :

+  cipher_algo_pos = (u8 *) strchr ((const char *) SID_pos, '*');
+
+  if (cipher_algo_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);

And later, once you have did all the parsing and testing (for correct length) code do the converts.

  1. Artifical salt section:
+  salt->salt_buf[0] = dpapimk->iv[0];
+  salt->salt_buf[1] = dpapimk->iv[1];
+  salt->salt_buf[2] = dpapimk->iv[2];
+  salt->salt_buf[3] = dpapimk->iv[3];
+
+  salt->salt_len = 32;

This could lead to problems (in case you had an invalid hash parser before). If you set only 16 byte, set the salt_len to 16, not 32. Or set really 32 byte in salt_buf[]

  1. Please replace all occurances of '\0' with simply 0

Loading

	1) done + got rid of all u8 datatypes in shared struct
	2) cf. previous
	3) necessary as this is computed in _init then used in _comp
	4) done
	5) done
	6) done => switch to 16
	7) done
@jsteube
Copy link
Member

@jsteube jsteube commented May 16, 2017

Great work, thanks!

Loading

@jsteube jsteube merged commit 2eabc36 into hashcat:master May 16, 2017
2 checks passed
Loading
@Fist0urs Fist0urs deleted the DPAPImk branch Mar 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants