ycam@domain.tld | MD4(UTF-16-LE("")) (plaintext password) | |||||
(NT-hash) | ||||||
PT1: | PT2: | PT3: | ||||
K1: | K2: | K3: | Challenge client: | Challenge server: LMresp[0:16]+0pad | ||
DES-ECB({K1,K2,K3}, FinalChallenge) === {CT1,CT2,CT3} | Final challenge: | |||||
NTresp{CT1: | CT2: | CT3:} | ||||
:::::
$MSCHAPv2$$$
$NETLM$$
$NETNTLM$$
$99$
LMHASH:
NTHASH: |
Note:
This generator allows you to make valid authentication tokens in various formats detailed in the table below.
Starting from a plaintext password, or from its version in NT-hash directly, it is possible to customized the challenge on the client-side (default: 1122334455667788), as well as the challenge on the server-side by activating the ESS/SSP (Extended Session Security / Security Support Provider).
The results are generated on the fly, and these can be tested directly on the hash shucking module.
Explanation:
To produce a network authentication token following the NTLM protocol (NetNTLMv(-ESS/SSP), MSCHAPv2, PPTP-VPN, etc. format), several elements are necessary.
Such a token is not actually a hash although it is often called that. These tokens are formed from two main elements:
- A secret which will serve as a key (more precisely 3 DES-ECB keys), which is the NT-hash of the identity (and not its plaintext password);
- A challenge, to add a notion of hazard, which will be encrypted with each of the 3 keys.
- From the NT-hash of the identity (which corresponds to the MD4 of the plaintext after conversion to UTF-16 Little-Indian), this hash is divided into 3 parts named PT1 (7 bytes), PT2 (7 bytes) and PT3 (2 bytes);
- Each of these 3 parts applies a binary transformation to derive in 3 keys, K1, K2 and K3 of 8 bytes each. It will be noted that the derivation of PT3 (2 bytes) to give K3 (8 bytes) generates a key deemed to be weak
arrayout.push((((arrayin[0] & 0xfe) | 1))); arrayout.push((((arrayin[0] << 7 & 0x80) | (arrayin[1] >> 1) & 0x7e) | 1)); arrayout.push((((arrayin[1] << 6 & 0xc0) | (arrayin[2] >> 2) & 0x3e) | 1)); arrayout.push((((arrayin[2] << 5 & 0xe0) | (arrayin[3] >> 3) & 0x1e) | 1)); arrayout.push((((arrayin[3] << 4 & 0xf0) | (arrayin[4] >> 4) & 0x0e) | 1)); arrayout.push((((arrayin[4] << 3 & 0xf8) | (arrayin[5] >> 5) & 0x06) | 1)); arrayout.push((((arrayin[5] << 2 & 0xfc) | (arrayin[6] >> 6) & 0x02) | 1)); arrayout.push((((arrayin[6] << 1 & 0xfe) | 1)));
- At the same time, a hazard called "challenge" is produced:
- This random number is generated on the client side (8 bytes), so its value is known and can be predefined (1122334455667788);
- To reinforce global security, the notion of ESS/SSP (Extended Session Security / Security Support Provider) can be used, where a random generated on the server side (8 bytes), over which an attacker cannot have control, is placed in the LM-response with 0's-padding.
- The final challenge actually used for token generation is therefore either the client-side challenge in the absence of ESS/SSP, or the first 8 bytes of the MD5 hash from the concatenation of the client challenge and server challenge in the presence of ESS/ SSP.
- So if an LM-response has 8 bytes then many 0s in padding, it means that there is ESS/SSP security, otherwise no: the LM-response is not used.
- From K1, K2, K3 and the final challenge, the DES-ECB symmetric encryption algorithm is applied to produce 3 ciphertexts CT1, CT2 and CT3 of 8 bytes each.
DES-ECB(K1, FinalChallenge) === CT1 DES-ECB(K2, FinalChallenge) === CT2 DES-ECB(K3, FinalChallenge) === CT3
- The concatenation of these 3 ciphertexts, CT1, CT2 and CT3 forms the NT-response which is included directly in the final tokens.
Compatibility & Formats:
The output results are in various formats summarized in the following table with their tool's compatibility.
Token Format | Type | Shuck.sh |
Crack.sh |
HashCat |
Description |
---|---|---|---|---|---|
login::domain:lmresp:ntresp:clientChall |
NetNTLMv1-noESS/SSP | Ready to be shucked freely! | Incompatible format / requires conversion | Yes, mode 5500 / 27000 or 14000 | NET(NT)LM hashes captured with a random challenge without ESS/SSP. |
login::domain:lmresp(serverChall+0padding):ntresp:clientChall |
NetNTLMv1-ESS/SSP | Ready to be shucked freely! | Incompatible format / requires conversion | Yes, mode 5500 / 27000 or 14000 | NET(NT)LM hashes captured with a random challenge with ESS/SSP (server challenge in LMresp with 0's padding). |
(LM|NT)HASH:ntresp |
NET(NT)LM | Ready to be shucked freely! | FREE/$20-$200 |
Incompatible format / requires conversion | NET(NT)LM with the 1122334455667788 challenge without ESS/SSP. |
$NET(NT)?LM$challenge$ntresp |
NET(NT)LM | Ready to be shucked freely! | $20-$200 |
Incompatible format / requires conversion | NET(NT)LM hashes captured with a random challenge. |
$99$b64encode(hex2bin(challenge+{ntresp=CT1+CT2+PT3}) |
ChapCrack | Ready to be shucked freely! | $20-$200 |
Incompatible format / requires conversion | PPTP VPN and WPA-Enterprise MSCHAPv2 authentication captures. |
$MSCHAPv2$challenge$ntresp$(login)? |
MSCHAPv2 | Ready to be shucked freely! | Incompatible format / requires conversion | Incompatible format / requires conversion | PPTP VPN and WPA-Enterprise MSCHAPv2 authentication captures. |
How to convert formats?
To convert an authentication token from one format to another, simply submit it freely to the Hash-Shucking module or use the Converter to follow algorithm's dissection.