Detection: Large HTTP POST Request Failure or Missing Response - Suricata

Description

This analytic detects HTTP POST requests with a declared body size of at least one megabyte that receive an HTTP 500 response or have no response status recorded. Large failed or unanswered uploads can indicate attempts to trigger resource exhaustion or exploit vulnerable request handling, including behavior associated with PHP2Shell, but require investigation with related web and application logs.

 1`suricata`
 2event_type=http
 3http_method=POST
 4
 5
 6| spath input=_raw path=http.status output=response_status
 7
 8| spath input=_raw path=http.request_headers{}.name output=request_header_names
 9
10| spath input=_raw path=http.request_headers{}.value output=request_header_values
11
12
13| eval request_header=mvzip(request_header_names, request_header_values, "
14|
15|
16|")
17
18
19| mvexpand request_header
20
21
22| rex field=request_header "(?i)^Content-Length\\
23|\\
24|\\
25|(?<request_bytes>\\d+)$"
26
27
28| eval request_bytes=tonumber(request_bytes),
29       response_status=tonumber(response_status),
30       status_code=if(isnull(response_status), "missing", tostring(response_status))
31
32
33| where request_bytes>=1000000 AND (response_status=500 OR isnull(response_status))
34
35
36| eval src=coalesce(src, src_ip), dest=coalesce(dest, dest_ip), uri=coalesce(url, 'http.url')
37
38
39| stats count min(_time) as firstTime
40              max(_time) as lastTime
41              max(request_bytes) as request_bytes
42              values(status_code) as status_code
43              values(http_user_agent) as http_user_agent
44  by src dest dest_port uri http_method
45
46
47| `security_content_ctime(firstTime)`
48
49| `security_content_ctime(lastTime)`
50
51| `large_http_post_request_failure_or_missing_response___suricata_filter`

Data Source

Name Platform Sourcetype Source
Suricata Network icon Network 'suricata' 'not_applicable'

Macros Used

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

Annotations

CVE

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

Configure Suricata EVE JSON HTTP logging with extended: yes and dump-all-headers: both under the EVE http type, then ingest the JSON with the Splunk TA for Suricata. Set the suricata macro to the TA's sourcetype (commonly sourcetype=suricata). The search requires event_type=http, http_method, and http.request_headers name/value pairs so it can read Content-Length; http.status may be absent for requests without a response. Verify that the TA extracts the nested EVE fields used by this search.

Known False Positives

Large legitimate uploads can fail because of application limits, timeouts, storage constraints, transient server errors, or network interruptions that prevent a response from being recorded. Review the request URI, declared upload size, server logs, and client behavior before classifying the activity as malicious.

Associated Analytic Story

Intermediate Findings

Message Entity Field Entity Type Risk Score
A large HTTP POST request from [$src$] to [$dest$] received HTTP 500 or had no response status recorded. dest system 20

Threat Objects

Field Type
src ip_address

References

Detection Testing

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

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