Detection rules › Elastic
Suspicious PHP Command Execution
This rule monitors for suspicious PHP command executions by detecting the start of a PHP process with a command line argument that contains keywords commonly used by attackers to execute malicious code. These command line arguments include operations to execute code, create subprocesses, and encode or decode data.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule body
[rule]
description = """
This rule monitors for suspicious PHP command executions by detecting the start of a PHP process with a command line
argument that contains keywords commonly used by attackers to execute malicious code. These command line arguments
include operations to execute code, create subprocesses, and encode or decode data.
"""
id = "d00bd50b-577e-47a7-9234-b4bfaa599791"
license = "Elastic License v2"
name = "Suspicious PHP Command Execution"
os_list = ["linux"]
version = "1.0.10"
query = '''
process where event.type == "start" and event.action == "exec" and process.parent.executable != null and
process.executable like ("/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*") and
process.args == "-r" and process.command_line like~ (
"*exec(*", "*system(*", "*shell_exec(*", "*passthru(*", "*proc_open(*", "*pcntl_exec(*", "*popen(*",
"*eval(*", "*assert(*", "*create_function(*", "*preg_replace(*e*", "*include(*", "*require(*",
"*base64_decode(*", "*gzinflate(*", "*gzuncompress(*", "*str_rot13(*", "*urldecode(*", "*chr(*",
"*ord(*", "*strrev(*", "*strtr(*", "*pack(*", "*unpack(*", "*curl_exec(*", "*curl_multi_exec(*",
"*file_get_contents(*", "*fopen(*", "*fsockopen(*", "*pfsockopen(*", "*stream_socket_client(*",
"*socket_create(*", "*socket_connect(*", "*socket_write(*", "*socket_read(*", "*mail(*",
"*move_uploaded_file(*"
) and not (
// Exclude web server processes as these are covered by other rules
process.working_directory like (
"/var/www/*", "/builds/*", "/home/*/jenkins/*", "/home/*/public_html*", "/var/lib/ldap-account-manager/config",
"/workspace/*", "/mnt/*"
) or
process.parent.args like (
"/var/www/html/*", "source /home/*/.claude/shell*", "scripts/ci/render_build_configs.sh", "scripts/ci/build_package_vendor_cache.sh",
"../source/scripts/ci/build_package_vendor_cache.sh", "/usr/local/bin/ncp-notify-update", "/usr/local/bin/ncp-notify-unattended-upgrade",
"/usr/local/bin/ncp-check-nc-version", "/usr/local/bin/ncp-check-version"
) or
process.args like "/usr/local/cpanel/*" or
process.command_line like (
"*https://composer.github.io/installer.sig*",
"*json_decode(file_get_contents('php://stdin')*",
"php -r exit(@fsockopen(getenv('DB_HOST')?:'postgres', (int)(getenv('DB_PORT')?:5432)) ? 0 : 1);",
"php -r exit(@fsockopen(\"127.0.0.1\", 9501) ? 0 : 1);",
"php -r echo urldecode(stream_get_contents(STDIN));"
) or
process.parent.command_line == "runc init" or
process.parent.executable in ("/opt/teleport/system/bin/teleport", "/usr/sbin/sshd")
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.parent.executable != null and
process.executable like ("/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*") and
process.args == "-r" and process.command_line like~ (
"*exec(*", "*system(*", "*shell_exec(*", "*passthru(*", "*proc_open(*", "*pcntl_exec(*", "*popen(*",
"*eval(*", "*assert(*", "*create_function(*", "*preg_replace(*e*", "*include(*", "*require(*",
"*base64_decode(*", "*gzinflate(*", "*gzuncompress(*", "*str_rot13(*", "*urldecode(*", "*chr(*",
"*ord(*", "*strrev(*", "*strtr(*", "*pack(*", "*unpack(*", "*curl_exec(*", "*curl_multi_exec(*",
"*file_get_contents(*", "*fopen(*", "*fsockopen(*", "*pfsockopen(*", "*stream_socket_client(*",
"*socket_create(*", "*socket_connect(*", "*socket_write(*", "*socket_read(*", "*mail(*",
"*move_uploaded_file(*"
) and not (
process.working_directory like (
"/var/www/*", "/builds/*", "/home/*/jenkins/*", "/home/*/public_html*", "/var/lib/ldap-account-manager/config",
"/workspace/*", "/mnt/*"
) or
process.parent.args like (
"/var/www/html/*", "source /home/*/.claude/shell*", "scripts/ci/render_build_configs.sh", "scripts/ci/build_package_vendor_cache.sh",
"../source/scripts/ci/build_package_vendor_cache.sh", "/usr/local/bin/ncp-notify-update", "/usr/local/bin/ncp-notify-unattended-upgrade",
"/usr/local/bin/ncp-check-nc-version", "/usr/local/bin/ncp-check-version"
) or
process.args like "/usr/local/cpanel/*" or
process.command_line like (
"*https://composer.github.io/installer.sig*",
"*json_decode(file_get_contents('php://stdin')*",
"php -r exit(@fsockopen(getenv('DB_HOST')?:'postgres', (int)(getenv('DB_PORT')?:5432)) ? 0 : 1);",
"php -r exit(@fsockopen(\"127.0.0.1\", 9501) ? 0 : 1);",
"php -r echo urldecode(stream_get_contents(STDIN));"
) or
process.parent.command_line == "runc init" or
process.parent.executable in ("/opt/teleport/system/bin/teleport", "/usr/sbin/sshd")
)
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | starts_with | /usr/local/cpanel/ | excludes:process.args field:"process.args" value:"/usr/local/cpanel/" |
process.command_line | wildcard | *https://composer.github.io/installer.sig*, *json_decode(file_get_contents('php://stdin')*, php -r exit(@fsockopen(getenv('DB_HOST')?:'postgres', (int)(getenv('DB_PORT')?:5432)) ? 0 : 1);, php -r exit(@fsockopen("127.0.0.1", 9501) ? 0 : 1);, php -r echo urldecode(stream_get_contents(STDIN)); | excludes:process.command_line |
process.parent.args | wildcard | /var/www/html/*, source /home/*/.claude/shell*, scripts/ci/render_build_configs.sh, scripts/ci/build_package_vendor_cache.sh, ../source/scripts/ci/build_package_vendor_cache.sh, /usr/local/bin/ncp-notify-update, /usr/local/bin/ncp-notify-unattended-upgrade, /usr/local/bin/ncp-check-nc-version, /usr/local/bin/ncp-check-version | excludes:process.parent.args |
process.parent.command_line | eq | runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"runc init" |
process.parent.executable | in | /opt/teleport/system/bin/teleport, /usr/sbin/sshd | excludes:process.parent.executable field:"process.parent.executable" value:"/opt/teleport/system/bin/teleport" field:"process.parent.executable" value:"/usr/sbin/sshd" |
process.working_directory | wildcard | /var/www/*, /builds/*, /home/*/jenkins/*, /home/*/public_html*, /var/lib/ldap-account-manager/config, /workspace/*, /mnt/* | excludes:process.working_directory |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-r" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null |