Security Service Provider Interface
Microsoft explain it best:
(SSPI) A common interface between transport-level applications, such as Microsoft Remote Procedure Call (RPC), and security providers, such as Windows Distributed Security. SSPI allows a transport application to call one of several security providers to obtain an authenticated connection. These calls do not require extensive knowledge of the security protocol’s details. 1
Essentially, an SSPI allows an application to use various security models available on a computer or network without changing the interface to the security system.
A SSP is contained in a dynamic-link library (DLL) that implements the SSPI by making one or more security packages available to applications. Each security package provides mappings between the SSPI function calls of an application and the functions of an actual security model. These security packages will be described within this post.2
On this MSDN page, it lists the packages as:
- Credential Security Support Provider
- Microsoft Negotiate
- Microsoft NTLM
- Microsoft Kerberos
- Microsoft Digest SSP
- Secure Channel
However, I have previously discussed Kerberos before and this post will focus on NTLM and Microsoft Digest SSP.
Confusingly, NTLM Hashes and NTLM Authentication are different; but use very similar names. As an SSPI, Windows describes it as the following:
Windows Challenge/Response (NTLM) is the authentication protocol used on networks that include systems running the Windows operating system and on stand-alone systems. [^3]
Before discussing this any further, the different types of NTLM need to be explored.
For local credentials, they are stored as an NTLM hash within the Security Account Manager (SAM) database on the box. However, within Active Directory, the domain credentials are stored in NTLM format on the Domain Controlled within the NDTS.dit database. [^4]
NTLM hashes are stored in the Security Account Manager (SAM) database and in Domain Controller’s NTDS.dit database. They look like this:
The LM hash is the one before the semicolon and the NT hash is the one after the semicolon.
The hash for NTLM is obtained via the following algorithm:
Net-NTLM hashes are used for network authentication and are derived from a challenge/response algorithm and are based on the user’s NT hash. Here’s an example of an NTLMv2 has, taken from hashcat:
They key difference between NTLM and Net-NTLM, is how the algorithms work. But, essentially, do the same thing.
The following is straight from Wikipedia, its explained so well:
The server authenticates the client by sending an 8-byte random number, known as the challenge.
The client performs an operation involving the challenge and a secret shared between client and server, specifically one of the two password hashes described above.
The client returns the 24-byte result of the computation. In fact, in NTLMv1 the computations are usually made using both hashes and both 24-byte results are sent.
The server verifies that the client has computed the correct result, and from this infers possession of the secret, and hence the authenticity of the client.
Both the hashes produce 16-byte quantities. Five bytes of zeros are appended to obtain 21 bytes. The 21 bytes are separated in three 7-byte (56-bit) quantities. Each of these 56-bit quantities is used as a key to DES encrypt the 64 bit challenge. The three encryptions of the challenge are reunited to form the 24-byte response. Both the response using the LM hash and the NT hash are returned as the response, but this is configurable.
NTLMv2, was introduced in Windows NT 4.0 SP4. It is a cryptographically strengthened replacement for NTLMv1.
NTLMv2 sends two responses to an 8-byte server challenge. Each response contains a 16-byte HMAC-MD5 hash of the server challenge, a randomly generated client challenge, and an HMAC-MD5 hash of the user’s password and other identifying information.
The two responses differ in the format of the client challenge. The shorter response uses an 8-byte random value for this challenge. In order to verify the response, the server must receive as part of the response the client challenge. For this shorter response, the 8-byte client challenge appended to the 16-byte response makes a 24-byte package which is consistent with the 24-byte response format of the previous NTLMv1 protocol.
The second response sent by NTLMv2 uses a variable length client challenge which includes:
- The current time in NT Time format
- An 8-byte random value
- The domain name
NTLMv1 vs NTLMv2
The difference between NTLMv1 and v2 comes down to the algorithm.
The concept is the same as NTLMv1, only different algorithm and responses sent to the server. [^5]
C = 8-byte server challenge, random K1 | K2 | K3 = LM/NT-hash | 5-bytes-0 response = DES(K1,C) | DES(K2,C) | DES(K3,C)
SC = 8-byte server challenge, random CC = 8-byte client challenge, random CC* = (X, time, CC2, domain name) v2-Hash = HMAC-MD5(NT-Hash, user name, domain name) LMv2 = HMAC-MD5(v2-Hash, SC, CC) NTv2 = HMAC-MD5(v2-Hash, SC, CC*) response = LMv2 | CC | NTv2 | CC*
Obtaining NTLM Hashes
Common NTLM Attacks
Credential hashes are always going to have dedicated researchers. And due to this, there are a bunch of attack vectors for NTLM hashes.
Pass-the-hash is a method of authenticating as a user without having access to the user’s clear-text password [^6].
By using this method the attacker bypasses the standard authentication steps that require a clear-text password, and skips straight into the authentication stage that uses the hash.
This works because native Windows applications ask users for the clear-text password, and then it will call APIs like
LsaLogonUser that convert that password to a hash value and then send that to the remote server during the NTLM authentication. In fact, the clear-text password is not required to complete network authentication successfully, only the hashes are needed. [^7]
This is easy enough, CrackMapExec makes it simple:
crackmapexec smb <target(s)> -u username -H LMHASH:NTHASH
crackmapexec smb <target(s)> -u username -H NTHASH
Additionally, this can be done with all the
psexec.py WORKGROUPemail@example.com -hashes 'LMHASH:NTHASH'
Obtaining Net-NTLM Hashes
This is slightly more complex, but its something I’ve addressed seperately: https://mez0.cc/posts/ntlm-relaying/
The general idea here is to man-in-the-middle the hashes. But, I won’t repeat myself. The above post summarises this section/
Additionally to Relaying Net-NTLMs, Reflection is also possible. Similarly to Relaying, its explained in great detail: