PHP Memory Exhaustion Exploitation Attempt via Multipart Request


Description

This analytic correlates Apache and Nginx access and error logs when "multipart/form-data" requests and PHP memory-limit exhaustion errors occur for the same PID, host, and client. It extracts web request details and "PHP" error messages to support investigation of possible PHP2Shell exploitation attempts.

Query · spl

(
    `apache_access_logs`
    OR
    `apache_error_logs`
    OR
    `nginx_access_logs`
    OR
    `nginx_error_logs`
)
(
    "multipart/form-data"
    OR
    (
        "Allowed memory size of"
        AND
        "bytes exhausted"
    )
)

| rex field=_raw "\[pid\s+(?<pid>\d+)"
| rex field=_raw "\]\s+(?<pid>\d+)\#\d+\:"

| rex field=_raw "client\:?\s+(?<client>.*?)(?:,|\]|$)"
| rex mode=sed field=client "s/\:\d+$//g"

| rex field=_raw "server\:\s+(?<server>.*?)(?:,\s|$)"

| rex field=_raw "request\:\s+\"(?<method>\w+)\s+(?<uri>.*?)\s+HTTP\/\d+\.\d+\"(?:,\s|$)"

| rex field=_raw "(?i)PHP(?:\s+\w+){1,}:\s+(?<error_message>.*?)$"

| eval pid=coalesce(worker_pid,pid)
| eval message=coalesce(error_message,message)
| eval src=coalesce(client,src,src_ip)
| eval dest=coalesce(server,dest,dest_ip)
| eval http_method=coalesce(method,http_method)
| eval http_content_length=coalesce(content_length,http_content_length)
| eval http_content_type=coalesce(content_type,http_content_type)
| eval http_user_agent=coalesce(user_agent,http_user_agent)
| eval http_referrer=coalesce(referrer,http_referrer)

| stats count min(_time) as firstTime last(_time) as lastTime
    dc(source) as dc_source
    values(source) as source
    values(http_method) as http_method
    values(dest) as dest
    values(dest_port) as dest_port
    values(site) as site
    values(uri) as uri
    values(status) as status
    values(memory_bytes) as memory_bytes
    values(http_content_length) as http_content_length
    values(http_content_type) as http_content_type
    values(http_referrer) as http_referrer
    values(http_user_agent) as http_user_agent
    values(message) as message
    by pid host src
| where mvfind(source,"access")>=0 AND mvfind(source,"error")>=0

| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `php_memory_exhaustion_exploitation_attempt_via_multipart_request_filter`

Implementation guide

Ingest Apache and/or Nginx access and error logs into Splunk. Configure the apache_access_logs and apache_error_logs or nginx_access_logs and nginx_error_logs macros with the corresponding source and sourcetype patterns. Ensure events contain host, source, PID, client, web request fields, and "PHP" error messages. The search groups events by PID, host, and client, and correlates access and error source types.

Known false positives

  • Legitimate large multipart uploads, application bugs, or load tests can cause memory-limit errors. Review the correlated access and PHP error events before classifying this activity as exploitation.

Analyst notes

Known false positives: Legitimate large multipart uploads, application bugs, or load tests can cause memory-limit errors. Review the correlated access and PHP error events before classifying this activity as exploitation.

Raw source PHP Memory Exhaustion Exploitation Attempt via Multipart Request · SPL
Esc
Published by splunk/security_content ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
name: PHP Memory Exhaustion Exploitation Attempt via Multipart Request
id: 53db8c3a-aea4-4eef-9cb4-a20c84b7f133
version: 1
creation_date: '2026-10-22'
modification_date: '2026-10-22'
author: Onur Mustafa Erdogan, Raven Tait, Nasreddine Bencherchali, Splunk
status: production
type: Anomaly
description: |-
    This analytic correlates Apache and Nginx access and error logs when "multipart/form-data" requests and PHP memory-limit exhaustion errors occur for the same PID, host, and client.
    It extracts web request details and "PHP" error messages to support investigation of possible PHP2Shell exploitation attempts.
data_source:
    - Nginx Access
    - Nginx Error Log
search: |-
    (
        `apache_access_logs`
        OR
        `apache_error_logs`
        OR
        `nginx_access_logs`
        OR
        `nginx_error_logs`
    )
    (
        "multipart/form-data"
        OR
        (
            "Allowed memory size of"
            AND
            "bytes exhausted"
        )
    )

    | rex field=_raw "\[pid\s+(?<pid>\d+)"
    | rex field=_raw "\]\s+(?<pid>\d+)\#\d+\:"

    | rex field=_raw "client\:?\s+(?<client>.*?)(?:,|\]|$)"
    | rex mode=sed field=client "s/\:\d+$//g"

    | rex field=_raw "server\:\s+(?<server>.*?)(?:,\s|$)"

    | rex field=_raw "request\:\s+\"(?<method>\w+)\s+(?<uri>.*?)\s+HTTP\/\d+\.\d+\"(?:,\s|$)"

    | rex field=_raw "(?i)PHP(?:\s+\w+){1,}:\s+(?<error_message>.*?)$"

    | eval pid=coalesce(worker_pid,pid)
    | eval message=coalesce(error_message,message)
    | eval src=coalesce(client,src,src_ip)
    | eval dest=coalesce(server,dest,dest_ip)
    | eval http_method=coalesce(method,http_method)
    | eval http_content_length=coalesce(content_length,http_content_length)
    | eval http_content_type=coalesce(content_type,http_content_type)
    | eval http_user_agent=coalesce(user_agent,http_user_agent)
    | eval http_referrer=coalesce(referrer,http_referrer)

    | stats count min(_time) as firstTime last(_time) as lastTime
        dc(source) as dc_source
        values(source) as source
        values(http_method) as http_method
        values(dest) as dest
        values(dest_port) as dest_port
        values(site) as site
        values(uri) as uri
        values(status) as status
        values(memory_bytes) as memory_bytes
        values(http_content_length) as http_content_length
        values(http_content_type) as http_content_type
        values(http_referrer) as http_referrer
        values(http_user_agent) as http_user_agent
        values(message) as message
        by pid host src
    | where mvfind(source,"access")>=0 AND mvfind(source,"error")>=0

    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `php_memory_exhaustion_exploitation_attempt_via_multipart_request_filter`
how_to_implement: |-
    Ingest Apache and/or Nginx access and error logs into Splunk.
    Configure the `apache_access_logs` and `apache_error_logs` or `nginx_access_logs` and `nginx_error_logs` macros with the corresponding source and sourcetype patterns.
    Ensure events contain host, source, PID, client, web request fields, and "PHP" error messages. The search groups events by PID, host, and client, and correlates access and error source types.
known_false_positives: |-
    Legitimate large multipart uploads, application bugs, or load tests can cause memory-limit errors.
    Review the correlated access and PHP error events before classifying this activity as exploitation.
references:
    - https://www.php2shell.com/
    - https://github.com/php/php-src/commit/3584a98bda0f2c0d367255b046798b0d3a221a19
intermediate_findings:
    entities:
        - field: pid
          type: system
          score: 30
          message: PHP memory exhaustion exploitation attempt via multipart/form-data access was observed for PID [$pid$] on host [$dest$] from client [$src$].
threat_objects:
    - field: uri
      type: uri
analytic_story:
    - PHP2Shell
asset_type: Web Application
cve:
    - CVE-2026-109618
    - CVE-2026-109619
mitre_attack_id:
    - T1190
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: web
security_domain: network
tests:
    - name: True Positive Test
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/emerging_threats/php2shell/memory_exhaustion_error.log
          source: /var/log/nginx/error.log
          sourcetype: nginx:plus:error
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/emerging_threats/php2shell/memory_exhaustion_access.log
          source: /var/log/nginx/access.log
          sourcetype: nginx:plus:kv
      test_type: unit

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.