| ID | Technique | Tactic |
|---|---|---|
| T1190 | Exploit Public-Facing Application | Initial Access |
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.
Search
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 | '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 |
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
-
https://github.com/php/php-src/commit/3584a98bda0f2c0d367255b046798b0d3a221a19
-
https://docs.suricata.io/en/latest/output/eve/eve-json-output.html
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