Hack The Box: Intelligence


Jump Ahead: EnumUserRootResources

TL;DR;

To solve this machine, we begin by enumerating all ports. The ports returned are consistent with an Active Directory server, so we are likely dealing with an active directory domain. From the webserver on port 80, we find a downloadable file that appears to be named according to a template. Fuzzing for more files using this template, we find several additional files. Enumerating the metadata, we get a list of potential usernames. Additionally, we go through the files, and find some useful information in a couple of them – including a default password. Using the password against the list of usernames, we are able to find credentials for the Tiffany.Molina user. With tiffany’s credentials, we are able to log into SMB, and get user.txt. From the files we previously downloaded, it mentioned a script, which we find, and learn it searches DNS records for entries that start with “web”, and attempts to connect to them. Using LDAP, we are able to add our own DNS record to attempt to get the machine to connect to us. After the machine attempts to connect to us as the ted.graves user, we get his NTLM hash, which we are able to crack. From further enumeration, we find the svc_int service account has constrained delegation enabled, which allows us to get a service ticket impersonating the administrator user. Using psexec, we are able to get a shell on the machine as NT Authority\SYSTEM – allowing us to read root.txt.

Enumeration

Like all machines, we begin by enumerating open ports – finding ports 53, 80, 88,135, 139, 389, 445, 464, 593, 636, 3268, 3269, 5985, 9389, 49667, 49677, 49678, 49696, and 49700 open.

$ sudo nmap -v -p- --min-rate 3000 $RHOST
[...]
$ sudo nmap -sV -A -oA enum/nmap/tcp-scripts -p 53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49667,49677,49678,49696,49700 $RHOST
# Nmap 7.91 scan initiated Sat Jul  3 20:01:40 2021 as: nmap -sV -A -oA enum/nmap/tcp-scripts -p 53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49667,49677,49678,49696,49700 10.129.178.146
Nmap scan report for 10.129.178.146
Host is up (0.048s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Intelligence
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2021-07-04 08:01:53Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.intelligence.htb
| Not valid before: 2021-04-19T00:43:16
|_Not valid after:  2022-04-19T00:43:16
|_ssl-date: 2021-07-04T08:03:33+00:00; +7h00m00s from scanner time.
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.intelligence.htb
| Not valid before: 2021-04-19T00:43:16
|_Not valid after:  2022-04-19T00:43:16
|_ssl-date: 2021-07-04T08:03:34+00:00; +7h00m00s from scanner time.
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.intelligence.htb
| Not valid before: 2021-04-19T00:43:16
|_Not valid after:  2022-04-19T00:43:16
|_ssl-date: 2021-07-04T08:03:33+00:00; +7h00m00s from scanner time.
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername:<unsupported>, DNS:dc.intelligence.htb
| Not valid before: 2021-04-19T00:43:16
|_Not valid after:  2022-04-19T00:43:16
|_ssl-date: 2021-07-04T08:03:34+00:00; +7h00m00s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49667/tcp open  msrpc         Microsoft Windows RPC
49677/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49678/tcp open  msrpc         Microsoft Windows RPC
49696/tcp open  msrpc         Microsoft Windows RPC
49700/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 2 hops
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2021-07-04T08:02:54
|_  start_date: N/A

TRACEROUTE (using port 139/tcp)
HOP RTT      ADDRESS
1   48.48 ms 10.10.14.1
2   48.54 ms 10.129.178.146

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jul  3 20:03:36 2021 -- 1 IP address (1 host up) scanned in 116.31 seconds

From the list of ports, we can tell the machine is likely an Active Directory domain controller. Looking at the outputs of the nmap scripts, we see LDAP reveals the FQDNs intelligence.htb, and dc.intelligence.htb. For now, we save those to our /etc/hosts file. Enumerating port 80 with gobuster and nikto does not return many results that we can use to our advantage. RPC (port 135) allows anonymous authentication, however, we do not find anything of particular interest. Checking SMB for anonymous and guest access also appears to be disabled. Lastly, we use ldapsearch to attempt to enumerate LDAP, however, we also do not get many results.

Getting User

Going to the webserver, we see a pretty simple webpage that has the machine name on it, and a lot of Lorem Ipsum text.

Looking around the page, we find a couple links for documents that we can download.

After clicking one of the links, we are presented a PDF file located in the documents/ directory. The text on the document is also Lorem Ipsum, so there is not much value in it. Opening the other document, we are given a similar PDF. One thing that we notice is that file names follow a template that includes a date in the format of “yyyy-mm-dd-upload.pdf”.

To test out this theory, we need to generate a file containing the months in two digit format, as well as a file for the days also in two digit format. Next, we use a tool like wfuzz to try to bruteforce other files.

From the results, we see there are other valid files in the directory. As they may potentially contain sensitive information, we use bash and wget to enumerate and download all files it discovers. Additionally, we expand the year to be “2020” in case the webserver contains files from that year as well. After doing this, we have a lot of PDF files that were downloaded.

Before we start looking at the content of the files, use use a tool like exiftool to check the files for valuable metadata. After running the tool, we see a field named “Creator” that contains potential usernames. We extract these usernames, and save them to a file.

Since we have potential usernames, we use Impacket’s GetNPUsers.py to try to check if any do not require Pre-Authentication to get a Kerberos Ticket-Granting Ticket (try to crack their password). Unfortunately, they all appear to have Kerberos Pre-Authentication enabled. Next, we attempt to read the PDFs, however, they appear to only contain Lorem Ipsum. Unfortunately, we do not know of another path forward, so we will continue reading all the files, until we have opened them all. Eventually, we find 2 valid files that contain useful information. “2020-12-30-upload.pdf” mentions that service accounts are not locked down, and that there is a script to check web services for outages. “2020-06-04-upload.pdf” contains the default password for newly created accounts.

Since we now have a potential password, we can use crackmapexec to try to bruteforce account credentials. Doing so, we find tiffany.molina has not changed their password, so we now have a valid set of credentials.

Trying the credentials to get a shell via WinRM is unsuccessful, so we move to SMB. Using Impacket’s smbclient.py, we are able to enumerate shares, and find “C:\Users” is exported as a shared. From here, we are able to find user.txt from Tiffany’s desktop.

Getting Root

Looking at the “IT” share, we find a PowerShell script. Looking at it, it appears the script queries the Active Directory DNS for services whose names start with “web”, and tries to connect to them. If the connection fails, it emails Ted to notify him. From this, we assume it to be the script Ted created to check services for downtime.

Using the script’s DNS query, we replicate the same query on our machine using ldapsearch. From the results, we see there is one web service named “web1”.

One thing we note when looking at the script, is that ted’s credentials are also sent when the script attempts to connect to the web service. If we are able to add our own DNS record, we should be able to get Ted’s NTLM hash. Since we only have access to LDAP, we will need to research if it is possible to add DNS records via LDAP. For this, we google “active directory ldap add dns records github”, and find this tool. Using the tool, we are able to add a DNS record that points to our machine (prefixing it with “web-” so the script will attempt to connect to it). Using ldapsearch, we are able to verify the DNS record was added.

Setting up a simple listener on port 80, we verify the script does attempt to connect to our machine.

Next, to force the script to attempt to authenticate to our webserver (in order to get the NTLM hash), we can use responder. As responder can have some adverse effects if ran incorrect, we use the “-A” option to disable the automatic poisoning. For added safety, we also disable all the servers except the HTTP server. After we have it setup, we start responder, and eventually get a connection with Ted‘s credentials.

Using hashcat, are able to crack the hash to get Ted’s password.

Since we now have Ted’s password, we attempt to use it with SMB, however, we do not get any additional information than we had from using Tiffany’s account. Next, we use bloodhound-python to enumerate the domain.

Once we ran the python script, we can run bloodhound to get the graphical interface to open. Once open, we drag the files into the interface to import the results. Once the results are imported, we start clicking the preset queries to find something that stands out. When we run the “Shortest Paths to Unconstrained Delegation Systems” query, we see ted.graves is a member member of the “itsupport” group, which can read the Group Managed Service Account (GMSA) password for the svc_int account.

If we get access to this account, we will be able to delegate to the WWW service on the domain controller, and impersonate another user.

In order to get the GMSA password, we Google “gmsa password python”, and find this repo. We note the repo is owned by the machine creator, so we are likely on the right path. Using the script, we are able to get the NTLM hash for the svc_int account.

Now that we have credentials for the svc_int account, we attempt to get a service ticket to impersonate the administrator user, however, we are unable to because our clock skew is too great.

To fix this, we can pull the server’s local time from the “Date” HTTP header, and use the timedatectl command to set our local time to match it.

Once we have adjusted our time to match the domain controller’s, we are able to use Impacket’s getST.py to get a Service Ticket as the administrator user.

Now that we have an impersonated service ticket as administrator to the dc.intelligence.htb machine, we can attempt to get a local shell using Impacket’s psexec.py. We get a shell as NT Authority\SYSTEM, and can now read root.txt from adminsitrator‘s desktop.

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!

Resources