Detection: Linux Auditd Inline PHP Code Execution

Description

The following analytic detects PHP command-line interpreters executing code supplied directly on the command line with CLI code-execution options such as -r / --run and -B / -R / -E / -F, or PHP runtime INI overrides that can load code. It also detects code supplied to PHPDBG through the -s option and FrankenPHP php-cli execution. It covers common Linux CLI executable names, including php, versioned PHP binaries, phpdbg, and FrankenPHP. PHP-CGI and PHP-FPM are excluded from the CLI option branch because they do not support the PHP CLI inline -r option. This behavior can be used legitimately for administration and automation, but unexpected or obfuscated inline PHP execution may indicate an attacker using an installed interpreter to run commands without dropping a script file.

  1`linux_auditd`
  2type=EXECVE
  3"*php*"
  4
  5
  6| eval process_name=lower(replace(coalesce(a0, ""), "^.*/", ""))
  7
  8| eval process=coalesce(execve_command, _raw)
  9
 10| rex "msg=audit\([^:]+:(?<audit_id>\d+)\)"
 11
 12
 13| eval php_code_option=if(
 14    match(process, "(^
 15|[[:space:]])(-r
 16|--run
 17|-B
 18|-R
 19|-E
 20|-F
 21|--process-begin
 22|--process-code
 23|--process-file
 24|--process-end)(=
 25|[$[:space:]]
 26|$)")
 27    OR match(_raw, "a[0-9]+=\"(-r
 28|--run
 29|-B
 30|-R
 31|-E
 32|-F
 33|--process-begin
 34|--process-code
 35|--process-file
 36|--process-end)(=
 37|[$[:space:]]
 38|\"
 39|$)"),
 40    1, 0
 41  )
 42
 43| eval php_ini_override=if(
 44    match(process, "(^
 45|[[:space:]])(-d[[:space:]]+
 46|-d
 47|--define[[:space:]]+
 48|--define=)(auto_prepend_file
 49|auto_append_file
 50|allow_url_include)=")
 51    OR match(_raw, "a[0-9]+=\"(-d
 52|--define)\" a[0-9]+=\"(auto_prepend_file
 53|auto_append_file
 54|allow_url_include)=")
 55    OR match(_raw, "a[0-9]+=\"-d(auto_prepend_file
 56|auto_append_file
 57|allow_url_include)=")
 58    OR match(_raw, "a[0-9]+=\"--define=(auto_prepend_file
 59|auto_append_file
 60|allow_url_include)=")
 61    , 1, 0
 62  )
 63
 64
 65| where (
 66    match(process_name, "^php([5-9](\\.[0-9]+)*)?(-cli)?$")
 67    AND (php_code_option=1 OR php_ini_override=1)
 68    AND NOT match(process_name, "(cgi
 69|fpm)")
 70  )
 71  OR (
 72    process_name="phpdbg"
 73    AND (
 74      match(process, "(^
 75|[[:space:]])-s(=
 76|[$[:space:]]
 77|$)")
 78      OR match(_raw, "a[0-9]+=\"-s(=
 79|[$[:space:]]
 80|\"
 81|$)")
 82    )
 83  )
 84  OR (
 85    process_name="frankenphp"
 86    AND match(process, "php-cli")
 87    AND (php_code_option=1 OR php_ini_override=1)
 88  )
 89
 90
 91| rename host as dest
 92
 93
 94| stats count min(_time) as firstTime max(_time) as lastTime
 95    values(execve_command) as execve_command
 96    values(a0) as argv0
 97    values(auid) as auid
 98    values(uid) as uid
 99    values(audit_id) as audit_id
100    by dest process_name process
101
102
103| `security_content_ctime(firstTime)`
104
105| `security_content_ctime(lastTime)`
106
107| `linux_auditd_inline_php_code_execution_filter`

Data Source

Name Platform Sourcetype Source
Linux Auditd Execve Linux icon Linux 'auditd' 'auditd'

Macros Used

Name Value
linux_auditd sourcetype="auditd"
linux_auditd_inline_php_code_execution_filter search *
linux_auditd_inline_php_code_execution_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.

Annotations

- MITRE ATT&CK
+ Kill Chain Phases
+ NIST
+ CIS
- Threat Actors
ID Technique Tactic
T1059 Command and Scripting Interpreter Execution
Installation
DE.AE
CIS 10

Default Configuration

This detection is configured by default in Splunk Enterprise Security to run with the following settings:

Setting Value
Disabled true
Cron Schedule 0 * * * *
Earliest Time -70m@m
Latest Time -10m@m
Schedule Window auto
Creates Finding (Notable) No
Creates Intermediate Finding (Risk Event) Yes
Anomaly detections generate Intermediate Findings (Risk Events). They do not generate a Finding (Notable) directly.

Implementation

To implement this detection, the process begins by ingesting auditd data, that consists of SYSCALL, TYPE, EXECVE and PROCTITLE events, which captures command-line executions and process details on Unix/Linux systems. These logs should be ingested and processed using Splunk Add-on for Unix and Linux (https://splunkbase.splunk.com/app/833), which is essential for correctly parsing and categorizing the data. The next step involves normalizing the field names to match the field names set by the Splunk Common Information Model (CIM) to ensure consistency across different data sources and enhance the efficiency of data modeling. This approach enables effective monitoring and detection of Linux endpoints where auditd is deployed.

Known False Positives

Developers and administrators may use PHP CLI or PHPDBG for legitimate automation and troubleshooting. Review the command line, parent process, user, host, and execution context. Tune approved automation by host or parent process as needed.

Associated Analytic Story

Intermediate Findings

Message Entity Field Entity Type Risk Score
PHP inline code execution using [$process_name$] was observed on endpoint [$dest$] with command line [$process$]. dest system 20

Threat Objects

Field Type
process_name process_name
process process

References

Detection Testing

Test Type Status Dataset Source Sourcetype
Validation ✅ Passing N/A N/A N/A
Unit ✅ Passing Dataset auditd auditd
Integration ✅ Passing Dataset auditd auditd

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI. Alternatively you can replay a dataset into a Splunk Attack Range


Source: GitHub |

Version: 1