Reversing MSCHAPv2 to NTLM
#11
I screwed up in my post:

Step 9) EvilMog writes a script to use atoms script to generate a raw NTLM hash for use in PTH

#!/bin/bash

challenge=$(echo -n "$1" | base64 -d | xxd | head -n1 | cut -d " " -f2-5 | sed 's/ //g')
ct2=$(echo -n "$1" | base64 -d | xxd | tail -n1 | cut -d " " -f2-5 | sed 's/ //g')
pt3=$(echo -n "$1" | base64 -d | xxd | tail -n1 |cut -d " " -f6-7 | sed 's/ //g')
ct1=$(echo -n "$1" | base64 -d | xxd | head -n 1 | cut -d " " -f6-9 | sed 's/ //g')
echo $ct1:$challenge > hashes.txt
echo $ct2$challenge >> hashes.txt
echo $pt3 > pt3.txt


the screwup is in 'echo $ct2$challenge' >> hashes.txt it should be 'echo $ct2:$challenge >> hashes.txt'

The corrected script is:

#!/bin/bash

challenge=$(echo -n "$1" | base64 -d | xxd | head -n1 | cut -d " " -f2-5 | sed 's/ //g')
ct2=$(echo -n "$1" | base64 -d | xxd | tail -n1 | cut -d " " -f2-5 | sed 's/ //g')
pt3=$(echo -n "$1" | base64 -d | xxd | tail -n1 |cut -d " " -f6-7 | sed 's/ //g')
ct1=$(echo -n "$1" | base64 -d | xxd | head -n 1 | cut -d " " -f6-9 | sed 's/ //g')
echo $ct1:$challenge > hashes.txt
echo $ct2:$challenge >> hashes.txt
echo $pt3 > pt3.txt
Reply
#12
Is this process the same for NetNtlmV2?
Reply
#13
No, netntlmv2 is completely different and has a dedicated hash-mode in hashcat.
Reply
#14
Sorry for reviving an old thread but I felt compelled to publish a few corrections as my original post wasn't exactly clear.

For NTLMv1-ESS, the plaintext password for the below hash is 'hashcat' and is taken from the example hashes on the hashcat wiki https://hashcat.net/wiki/doku.php?id=example_hashes

---BEGIN PYTHON DEMONSTRATOR CODE---

hash = "u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c"

hashsplit = hash.split(':')
challenge=hashsplit[5]
combined = combined=test[4]
ct1 = combined[0:16]
ct2 = combined[16:32]
f3 = hashsplit[3]
#>>> f3
#'338d08f8e26de93300000000000000000000000000000000'
#>>> challenge
#'cb8086049ec4736c'
#ct3 = combined[32:48]
#>>> ct3
#'2e1e4bf33006ba41'

print "./ct3_to_ntlm.bin " + ct3 + " " + challenge + " " + f3
#./ct3_to_ntlm.bin 2e1e4bf33006ba41 cb8086049ec4736c 338d08f8e26de93300000000000000000000000000000000

# execute the command below and the output is:
# 1e2b

import hashlib,binascii
hash = hashlib.new('md4', "hashcat".encode('utf-16le')).digest()
print binascii.hexlify(hash)
#b4b9b02e6f09a9bd760f388b67351e2b

print binascii.hexlify(hash)[28:32]
#1e2b

print ct1 + ":" + challenge
print ct2 + ":" + challenge
# run the output of the above through hashcat mode 14000 and you will get the appropriate DES keys to be converted into ntlm challenge hashes
---END DEMONSTRATOR CODE---

So for those of us who aren't coders:

1) The hash was pulled from the example hashes in NTLMv1-ESS format, this is a very common responder format

2) The hash needs to be split into chunks, all fields are delimited by :
Field 1: hostname - u4-netntlm

Field 2: blank

Field 3: username - kNS

Field 4: I honestly can't remember the technical name, I call it F3 above but its the ESS chunk you feed into atoms ct3_to_ntlm.bin after ct3 and the challenge in order to get the last 4 characters of the cracked ntlm hash - 338d08f8e26de93300000000000000000000000000000000

Field 5: ct1+ct2+ct3, first 8 bytes are ct1, second 8 are ct2, third 8 are ct3 - 9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41

Field 6: challenge

3) run ./ct3_to_ntlm.bin ct3 challenge f3 [for ess only]
./ct3_to_ntlm.bin 2e1e4bf33006ba41 cb8086049ec4736c 338d08f8e26de93300000000000000000000000000000000
1e2b

4) make a 14000.hash file formatted like this
challenge:ct1
challenge:ct2

example

cb8086049ec4736c:9526fb8c23a90751
cb8086049ec4736c:cdd619b6cea56474

5) crack with hashcat
./hashcat -m 14000 -a 3 -1 charsets/DES_full.charset --hex-charset hashes.txt ?1?1?1?1?1?1?1?1

6) if you are so inclined split it up using --keyspace and --skip and limit, although --keyspace appears broken it should be 34359738368

7) the ntlm hash of hashcat is b4b9b02e6f09a9bd760f388b67351e2b and the last 4 characters are 1e2b which equal3 what was output from step 3, once things are cracked you then use atoms tools to convert the des keys into NTLM from https://hashcat.net/forum/thread-5832.html


root@et:~/hashcat-utils/src# perl deskey_to_ntlm.pl [deskey1]

root@et:~/hashcat-utils/src# perl deskey_to_ntlm.pl [deskey2]

the final ntlm hash is b4b9b02e6f09a9bd760f388b67351e2b which is
b4b9b02e6f09a9 - deskey 1
bd760f388b6735 - deskey 2
1e2b - deskey 3 calculated from step 3

Hopefully this clears things up for NTLMv1-ESS
Reply
#15
And the first release of the NTLMv1 multi tool is out

https://github.com/evilmog/ntlmv1-multi
Reply
#16
Well since there is a revival of the thread, I would like to ask whether the following makes sense in theory and then, if it is feasible to be implemented.

tl;dr I believe that we can reduce 25% the time required to bruteforce a NetLMv1 hash by offloading the bruteforce candidates to an MD4 bruteforce where we know the last 2 bytes.

Please bear with me, it is quite long.

Taking the example above:
hash = "u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c"

we can quickly get the last 2 bytes of the MD4 of the password, i.e. "1e2b" in our case.

If (I know this is not the case - https://hashcat.net/forum/archive/index....-7049.html) hashcat would support wildcards in hashes, we could provide an MD4 hash with 14 wildcard bytes and 2 fixed ones, in a (let's say) mask attack of 8 characters, for example:

(1) hashcat -m 900 -a 3 ****************************1e2b ?a?a?a?a?a?a?a?a
and let's say this is done in time = T1

This would give a lot of potential candidates but I cannot estimate how many; I can roughly make the following abstraction:
(Please be gentle if this is totally nonsense, I am new to this)

The total keyspace of the candidates is:
(2) 101 (if I counted correctly all characters - upper/lower/numeric/special) to the power of 8, i.e. 101^8 = ~11 Peta combinations

The portion of MD4 hashes ending in "1e2b" compared to all MD4 hashes is:
(3) 2^8 (one byte) for 14 bytes / 2^8 (one byte) for 16 bytes = 1 / 2^2 = 1/4

If we assume that MD4 provides uniformly distributed outputs for all possible 8 characters inputs, we could also assume that the candidates of our hashcat command (1) will be the 1/4 of all the candidates, i.e. (2) (3)~2.75 Peta 

Now, if we pipe/direct these candidates as dictionary to the normal netlmv1 hashcat command:
(4) | hashcat -m 5500 -a 0 "u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c" 

we have reduced 3/4 of the required time for 8 characters (upper/lower/numeric/special as in (1)) candidates for netlmv1, at the cost of T1.

Taking a random benchmark (setup is not very important since we will be doing comparisons - https://gist.github.com/epixoip/a83d38f4...804a270c40) we have:

MD4 = 350 Gh/s
NetLMv1 = 180 Gh/s

Let's say roughly, MD4 is two times faster than NetLMv1. 
So if T2 the time to brute force all 8 length candidates for NetLMv1:
hashcat -m 5500 -a 3 "u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c" ?a?a?a?a?a?a?a?a

we have that T1 = ~T2/2.

Then by using the above mentioned method we need:
T2/2 + T2/4 = (3/4)T2 
i.e. 25% reduction in time for bruteforcing NetLMv1 hashes comparing to the current method.

Does it make any sense or I lost it somewhere?

Regarding the implementation side, I have no idea if this is feasible or how you should feed the ouput candidates of the MD4 command to the NetLMv1 one or what kind of delay you may introduce by modifying the actual implementation or if it's even worth it.

Thanks for making it this far Smile
Reply
#17
@ktinoulas: you are talking about an early-reject in the 5500 kernel. Looks like this is already implemented: https://github.com/hashcat/hashcat/blob/...a0.cl#L707
Reply
#18
Nice catch/answer, undeath
Reply
#19
(05-07-2018, 05:13 PM)undeath Wrote: @ktinoulas: you are talking about an early-reject in the 5500 kernel. Looks like this is already implemented: https://github.com/hashcat/hashcat/blob/...a0.cl#L707

Damn, hashcat is good!!

Thanks undeath Smile
Reply