In this post we will be demonstrating how to perform an over-pass-the-hash attack using rubeus.exe and getTGT.py. We will run through a quick example scenario where we have gotten a foothold on a Windows 10 domain-joined host. From there, we will elevate privileges by finding a local password in the PowerShell history file. We will use the credentials we found to get a SYSTEM shell on the host. Finally, we will dump the LSASS process to find a domain admin hash stored on the system, which will allow us to execute an over-pass-the-hash attack to move laterally onto the DC.
The nice thing about performing an over-pass-the-hash attack using rubeus.exe and getTGT.py is that no GUI is necessary!
Another tool that can be used to execute this attack is mimikatz; however, that technique does require GUI.
In the simplest terms, an over-pass-the-hash attack is when you use an NTLM hash to request/create a Kerberos (TGT) ticket. Since many services in the domain require kerberos authentication, this will increase the level of access you have across the entire domain.
Essentially we will be using a pass-the-hash attack to create a ticket that we can then use to move laterally with a pass-the-ticket attack. By combining a pass-the-hash attack and pass-the-ticket attack, we have an over-pass-the-hash attack.
Example Scenario – Privilege Escalation to SYSTEM and Dumping the LSASS Process
For this scenario, we have two domain connected machines. The first machine is a Windows 10 host with IP 172.16.1.100 and the other is the DC with IP 172.16.1.5.
We will quickly run through a scenario where we have gotten a foothold as a regular domain user on the Windows 10 host; and then we will escalate privileges from regular user to local SYSTEM. From there, we will dump the LSASS process remotely to find a domain admin token containing their NTLM hash.
Finally, we will explore a few tools and techniques we can use the NTLM hash to create a Kerberos ticket. After creating the ticket, we will pass-the-ticket to the DC using a service that requires kerberos authentication. This will complete our over-pass-the-hash attack.
We have already gained a foothold on the victim Windows 10 workstation as regular domain user: efrost
During our enumeration, we noted that domain user cmarko is a local admin on this machine.
net localgroup "administrators"
Further enumeration revealed that the PowerShell history file had commands executed by our current user. Here we can see that the user executed runas as the local admin user cmarko and attempted to pass the credentials directly into the runas command:
cmarko : N0cturn@l21
When using runas.exe, you can no longer add the password directly into the command. However, by removing the password from the command, you will be prompted for it. Since this command is interactive, you will not be able to see or interact with this password prompt from a reverse shell. Today, runas can only be abused with a stored credential if you don’t have GUI. Otherwise, from a reverse shell with a provided set of credentials you can do the PowerShell version of runas. This technique will save the credentials into variables and then you can pass them into a command. An example of the PowerShell runas can be found in this post here.
Breaking down the users commands we can see that the user attempted to copy MajorUpgrade.config from a share on another host. The user must not have had permissions to access the file so they used runas to copy the file to their workstation with a local admin account’s credentials.
Now that we have found a local admin password, we will use a great tool called psexec.py from the Impacket Suite of Tools to get a SYSTEM shell on the victim.
Now that we have a reverse shell, we will need to upgrade to a PowerShell prompt for the POC at the end of the demonstration.
From our reverse shell we can’t simply use powershell -ep bypass to upgrade to Powershell. While this usually works from a netcat reverse shell, with some shells it does not work. For example, if we tried to do an in-place upgrade from our psexec.py prompt, you will find that it will cause the prompt to hang.
To upgrade to PowerShell, we will download nc.exe on the victim and start a netcat listener on our attack machine. Once that is done, we will push a reverse shell to our attacker machine with nc.exe and from that shell we will be able to use powershell -ep bypass to do an in-place upgrade.
And back on our attacker machine…
Now that we have a PowerShell prompt on the victim as the local SYSTEM user, we want to dump the LSASS process to see if there were any tokens left behind. If we are lucky, we may find a token that we can leverage to escalate our privileges further and move laterally.
For this example we will actually dump the LSASS process remotely. Doing it this way will remove the need to create a DMP file on the victim that we would need to send to our attacker machine.
To dump the LSASS process remotely, we will be using one of my favourite tools: crackmapexec.
crackmapexec has lsassy built-in, which can be used perform remote LSASS dumps.
crackmapexec smb 172.16.1.100 -d juggernaut.local -u cmarko -p 'N0cturn@l21' -M lsassy
From the dump we can see that the domain admin had logged into this system and their NTLM was cached in the LSASS process!
After dumping the LSASS process and finding the domain admins NTLM, we now have all the information required to perform an over-pass-the-hash attack.
Over-Pass-the-Hash Attack Using Rubeus.exe
Rubeus.exe is one of the best tools available for interacting with and abusing kerberos.
This technique requires a SYSTEM shell to work. When I tested this from a high-integrity shell as local admin user cmarko, it failed. This is why we used psexec.py to get a SYSTEM shell on the victim.
In this example, we will see how we can use Rubeus.exe to perform an over-pass-the-hash attack. We will use the domain admin’s hash to request a ticket from the TGT and then to confirm that it worked, we will start a PS-Remoting session on the DC as the domain admin.
The best part is that all of this will be done from the same reverse shell!
From our reverse shell as local SYSTEM, we need to download Rubeus.exe onto the victim.
With Rubeus.exe on the system we can request a ticket from the TGT as the domain admin. This ticket will be inserted into our current session, so even though it shows we are still SYSTEM, we will be able to execute commands as the domain administrator.
Using the following command with the domain admin hash found in the LSASS dump with crackmapexec, we can import a domain admin ticket into our current session:
.\Rubeus.exe asktgt /domain:juggernaut.local /user:administrator /rc4:5b38382017f8c0ac215895d5f9aacac4 /ptt
The output shows that the ticket was successfully imported into the current session. To confirm this we can use the command klist. However, since we do not have GUI, this command will not work. Fortunately, it is also built-in to Rubeus.exe.
From the output above we can see that the SYSTEM account currently has a ticket in their session that was created by krbtgt (server) for the domain admin (client).
When you see the computer name with a ‘$’ as the username, that refers to the SYSTEM user of that host.
To confirm that we have the domain admin privileges applied to our session, we can query the DC using the following command:
Finally, for POC we will start a PS session on the DC using the following command:
Enter-PSSession -ComputerName Juggernaut-DC
This confirms that we have successfully used a pass-the-hash attack to import a ticket into our current session; therefore, we have successfully moved laterally with an over-pass-the-hash attack!
To enter a PS Session, you need to authenticate using kerberos. If we had just used a pass the hash attack without importing a ticket, we would not have been able to access this service.
Over-Pass-the-Hash Attack Using getTGT.py
getTGT.py is another tool that is part of the Impacket Suite of Tools. With this tool, we are able to remotely request a ticket using a pass-the-hash attack. Once a ticket has been created and cached, we can then export that ticket into our current session on our attacker machine and then use it to log into the DC remotely by only using the ticket.
The nice thing about this script is that we will not need to download any tools onto the victim like we did with Rubeus.exe.
Having extracting the domain admins NTLM hash by dumping the LSASS process with crackmapexec, we do not need to interact with the Windows 10 host anymore. Instead of using psexec.py to get a SYSTEM shell, we can use the following command to request a TGT as the domain admin using a pass-the hash attack.
getTGT.py -dc-ip 172.16.1.5 juggernaut.local/administrator -hashes :5b38382017f8c0ac215895d5f9aacac4
Note that the leading colon ( : ) needs to be added to the hash to indicate that the LM portion is blank. NTLM hashes are in the form of LM:NT and majority of the time the LM portion will be blank.
At this point we have passed the admin hash to craft our kerberos ticket (over-passed-the-hash). This ticket will be saved in the current directory as <username>.ccache.
Exporting this ticket into our current session, we will be able to pass-the-ticket to get a SYSTEM shell on the DC. To do this we will use psexec.py again like so:
psexec.py email@example.com -target-ip 172.16.1.5 -dc-ip 172.16.1.5 -k -no-pass
As a final note, I just want to mention that I had tested the Mimikatz method but it was not working. From a GUI session, I tested using the ptt command to start a new terminal session as the domain admin and that worked fine.
The part that failed to work is where you query the DC to get a ticket. No matter what resources I tried to access, it was not importing a ticket as the domain admin. I was stuck on the pass-the-hash attack and couldn’t upgrade to a pass-the-ticket attack or couldn’t “over-pass-the-hash”.
Since Mimikatz is the most common method for conducting this attack from blogs I have seen and courses I have done, I am compelled to keep trying. For now though, it appears this method is not working on a fully updated Windows 10 or Server 2019 machine.