HackTheBox: Authority

HackTheBox: Authority

·

10 min read

Introduction

Authority is rated as a medium difficulty machine on the HackTheBox platform. This machine simulates an Active Directory Domain Controller, presents an opportunity to gain a foothold through a number of common services and ultimately allows escalation through a unique, but increasingly commonplace method of unintended authentication. This was hands down one of my favorite machines from all of 2023 simply because it learned so much from the concepts it requires and the troubleshooting I did along the way to root. So without further ado, lets just start hacking.

Recon

  • Our initial scan shows 13 open ports with services commonly seen on Active Directory Domain Controllers.

    • We kick off a full port scan and uncover a total of 29 open ports.
  • At a glance we have:

    • DNS (53)

    • HTTP (80)

    • Kerberos (88)

    • MSRPC (135)

    • Netbios/SMB (139/445)

    • LDAP (389/636/3268/3269)

    • WinRM (5985)

    • HTTPS (8443)

  • Lastly we have a handful of MSRPC ports in the upper ranges (as expected)

SMB

  • We do an initial check for any open shares with CrackMapExec

  • When we connect to the 'Development' share we find a folder called 'Automation' that looks to contain some Ansible files.

  • We download the entire share with the following commands from within SMBClient.

mask ""
recurse
prompt
mget *
  • Within the downloaded codebase we find an ansible_inventory file in Automation/Ansible/PWM/ansible_inventory which appears to contain a password for 'administrator' to use on 5985 but when we try logging in we get an auth error.

    • Might try passing these creds around to other services too.

    • administrator:Welcome1

  • More creds in Automation/Ansible/PWM/templates/tomcat-users.xml.j2

<user username="admin" password="T0mc@tAdm1n" roles="manager-gui"/>

<user username="robot" password="T0mc@tR00t" roles="manager-script"/>

HTTP (80)

  • We just find the generic IIS landing page when visiting this service. We see the same response when using either the IP address or the domain name of authority.htb

  • We start a gobuster scan just to have something running on it.

HTTPS (8443)

  • We find that PWM app we saw mention of earlier.

  • It definitely feels like we need some creds to get in here.

    • Within /Automation/Ansible/PWM/defaults/main.yml we come across a few Ansible Vaults. These are basically encrypted blobs used to store sensitive information. The idea being, you store it once with a secure password and then you don't have to re-enter creds for each deployment.

  • After a bit of reading it looks like these should be crackable.

    • We separate each vault section into its own file as well as remove any leading whitespace.

    • Then we use the following for each of the three vaults ansible2john vault1 >vault1.in

    • We initially tried cracking them with hashcat based on a blog post we came across, but it kept failing and complaining about 'Signature unmatched'

      • Eventually we try cracking them with john instead of hashcat and we get some quick wins this time.

  • Each of the three have the same password when cracked. Now we need to use the ansible-vault decrypt command along with this password to decrypt each of the three vaults.

  • It seems like we can login to the PWM app now, but we just get an error message relating some issue with connecting to LDAP.

  • So we try logging in to the config manager instead

    • From here we can download the config, view the config summary, and download log files in the 'Troubleshooting Bundle'

  • Took me a little while to realize this but if we click on the down arrow at the top, we can actually enter the Configuration Editor as well.

  • Eventually we manage to get LDAP configured correctly after we import the LDAP certificate and see its for authority.htb.corp and not authority.authority.htb which is the default LDAP url PWM was using.

  • We still can't move forward too much here.

    • Also been trying to run crackmapexec in its LDAP attack form but no real luck there.

    • Same with ldapsearch.

    • Feels like the best response I've gotten from LDAP so far has just been with an Nmap unauthenticated scan.

Kerberos

  • While still looking for a foothold, we try running the users we have through GetNPUsers to see if there any possibility of cracking a TGT for a user password.

    • Nobody has UF_DONT_REQUIRE_PreAuth set, but we also see the only valid users (as far as Kerberos is concerned) is svc_ldap and administrator
  • Took a break overnight and came back to it the next day.

  • Strangely enough I recently had an interview question specifically about what I would do if i was testing a web application which connected to LDAP on the backend and had a field to enter an arbitrary hostname as the target LDAP server.

    • I had no idea what to do at the time, but thankfully my interviewer started explaining that they could enter their own hosted server or listener and see what the initial handshake and credential exchange looked like.
  • Despite what the screen is showing the password actually does not include the htb portion. After piping this same request through xxd we see a break between DC=htb and the pass that follows. Just something to be aware of when intercepting unintended comms protocols with unprepared (albeit versatile) client receivers, like netcat.

  • We still have trouble connecting to LDAP with this password. But it feels like a good lead so we start passing it around elsewhere to see if it's still valid with other services. We get a hit when testing SMB.

  • Looks like we finally have some valid domain credentials!

  • We find we can hop on the server and grab a shell with evil-winrm.

    • We collect the user flag and keep moving.
  • We transfer over winpeas to have something moving in the background. But based on the box's name 'Authority', and the fact that we've seen it issue its own SSL certificates makes we want to inspect the Certificate Authority service for any potentially vulnerable certs.

    • We transfer Certify.exe from SpectreOps over. FIrst we run it with just ./certify.exe find /vulnerable and we get a hit. But when we run it with the /currentuser flag we see that our current user doesn't have access to the vulnerable template.

  • Taking a step back, we inspect the vulnerable certificate template Certify.exe found when we weren't using our current user's permissions.

    • The command to identify vulnerable templates, even if you don't currently have access to request them is the following:

    • ./certify.exe find /vulnerable

  • For the Vulnerable Certificate Template above we can see the Template Name: CorpVPN, we see it can be used for Client Authentication, however in the Enrollment Rights section we see we either need to be a member of the group HTB\Domain Admins, HTB\Enterprise Admins, or HTB\Domain Computers.

  • I've highlighted the HTB\Domain Computers group, because this might be easier to reach than an Admin group. If we can simply compromise the machine account for a domain joined computer, we should be able to request an arbitrary certificate that we could then use to authenticate as a Domain Admin.

  • Looking at the current user's permissions, it seems we should be able to 'Add workstations to domain'

  • Got a bit stuck here for a while, eventually took a break and came back with some fresh eyes.

    • We find a new certificate file in C:\certs\LDAPs.pfx
  • Our powershell instance kept freezing whenever we'd try to create a New-MachineAccount with the powermad.ps1 module.

    • Eventually we see Ippsec using it for another box. There he passes in the password along with the one-liner rather than waiting for the shell to ask(which is where our winrm session seems to hang).

    • import-module .\powermad.ps1

    • New-MachineAccount -MachineAccount fakeComputer -Password $(ConvertTo-SecureString 'blahblah' -AsPlainText -Force)

  • We can make a new machineaccount but how do we use it to run certify or forge a new certificate? Rubeus to the rescue!

  • Then we can pull down a tgt ticket in ticket.kirbi form with the following rubeus command

    • .\rubeus.exe asktgt /user:FAKECOMPUTER$ /aes256:C261FA8BEDC89AD979AEE06043F5C9CA923FBA5275D45949D316DC179731C8CC /aes128:59C6E01F26EEF612009F688040F0B535 /rc4:BBF7D1528AFA8B0FDD40A5B2531BBB6D /domain:authority.htb /dc:authority.authority.htb /ptt
  • We copy/paste that ticket to our local and use the impacket ticketConverter.py script to convert from .kirbi to .ccache

    • We could somewhat get this working with the .ccache files, but psexec, smbexec, and wmiexec would all fail because none of hte shares are writable as this new machine account.
  • Feels like we need to be able to pass this ticket while we're in as the other user.

@10:52

Troubleshooting (Privesc)

  • We keep getting the DCE RPC fault status code : 00000721

    • Should have caught this from the debug statement but someone pointed it out on the forum, it's trying to resolve the target hostname from my local DNS. In the screenshot below it states its Trying to resolve 'authority.authority.htb' at '192.168.1.254', only 192.168.1.254 is my local router. My local router has no idea how to resolve hosts on the HackTheBox VPN networks.

    • So to get past this we need to add the DC's DNS server to our /etc/resolv.conf file.

  • Strangely enough i got the tool working working without error by requesting the default 'user' template. We get a pfx file but it doesn't actually grant us any privileges over administrator...b/c user. (lol).

  • But this does confirm that we can successfully connect to our target. By removing one more unknown from this equation we come a step closer to our solution.

  • Getting much closer as fakeComputer$!

    • Such a goof but we forgot to escape the dollar sign earlier!!

    • Always need to be mindful when submitting commands from *nix to Windows syntax that certain metacharacters have different meanings across these different interpreters.

  • Now we've got it connecting correctly, but it's timing out.

    • Luckily there's a -timeout s flag!

    • We add the new flag and get a certificate with the UPN set to administrator@authority.htb

  • Now we have a .pfx certificate that we can use to authenticate as the DA adminsitrator@authority.htb

  • We can use the passthecert.py script to change the password for this user. But first we need to convert the certificate from a .pfx file to a .crt and a .key files

  • We use the certipy-ad tool once again to make the certificate conversion.

    • certipy-ad cert -pfx <cert_name>.pfx -nocert -out <cert_name>.key

    • certipy-ad cert -pfx <cert_name>.pfx -nocert -out <cert_name>.crt

  • Now we can use the .crt and .key file to authenticate through LDAP and change the password for the administrator user.

    • NOTE: We could do a couple different things at this point with passthecert.py to compromise the domain. Changing the admins password serves our purposes for this CTF box just fine, but also consider how the ability to impersonate a domain admin can be abused in other ways. There are other techniques which may allow a malicious actor to create persistence without disturbing pre-existing account credentials or triggering SIEM response in Enterprise environments...anywhoo!

    • python3passthecert.py-action modify_user -crt <path_to_crt_file> -key <path_to_key_file> -domain <DOMAIN> -dc-ip $IP -target administrator -new-pass

  • With a knowledge of a new password for the administrator, we can just login through WinRM now. We are the domain administrator after all.

Conclusion

This was a great box for practicing a few different Active Directory attack vectors but my favorite part was definitely the abuse of ADCS. If you've been looking for a reason to learn or practice the ESC methods of privilege escalation this box is a great introduction.