| ID | Technique | Tactic |
|---|---|---|
| T1190 | Exploit Public-Facing Application | Initial Access |
Detection: PHP Session Upload Progress Serialized Payload in Upload Filename
Description
This analytic detects multipart POST requests containing the "PHP_SESSION_UPLOAD_PROGRESS" form field and a serialized PHP structure in an uploaded filename. This combination may indicate an attempt to exploit PHP session upload-progress handling and can be associated with PHP2Shell activity.
Search
1`zeek_http`
2method="POST"
3request_headers="*"
4
5
6| eval src=coalesce(src, src_ip, 'id.orig_h'),
7 dest=coalesce(dest, dest_ip, 'id.resp_h'),
8 dest_port=coalesce(dest_port, 'id.resp_p')
9
10
11| eval has_upload_progress_field=if(match(request_headers, "(?im)\s*form-data;\\s*name=\\\"PHP_SESSION_UPLOAD_PROGRESS\\\""), 1, 0)
12
13
14| rex max_match=0 field=request_headers "(?im)\s*form-data;(?<part_disposition>[^\\r\\n]*)"
15
16
17| eval serialized_filename_headers=mvfilter(match(part_disposition, "(?i)\\bfilename\\s*=.*(?:\\
18|?O:\\d+:
19|C:\\d+:
20|a:\\d+:\\{
21|s:\\d+:
22|E:\\d+:
23|R:\\d+;
24|i:-?\\d+;
25|d:(?:[-+]?(?:\\d+(?:\\.\\d*)?
26|\\.\\d+)(?:[eE][-+]?\\d+)?
27|INF
28|NAN);
29|b:[01];
30|N;)"))
31
32
33| where has_upload_progress_field=1 AND mvcount(serialized_filename_headers)>0
34
35
36| stats count min(_time) as firstTime
37 max(_time) as lastTime
38 values(method) as method
39 values(status_code) as status_code
40 values(user_agent) as user_agent
41 values(serialized_filename_headers) as serialized_filename_headers
42
43 by src dest dest_port uri
44
45
46| `security_content_ctime(firstTime)`
47
48| `security_content_ctime(lastTime)`
49
50| `php_session_upload_progress_serialized_payload_in_upload_filename_filter`
Data Source
| Name | Platform | Sourcetype | Source |
|---|---|---|---|
| Zeek HTTP | Web | 'zeek:http' |
'http.log' |
Macros Used
| Name | Value |
|---|---|
| security_content_ctime | convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$) |
| php_session_upload_progress_serialized_payload_in_upload_filename_filter | search * |
php_session_upload_progress_serialized_payload_in_upload_filename_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
Zeek HTTP logs must be ingested into Splunk using the latest version of Splunk Add-on for Zeek (https://splunkbase.splunk.com/app/5466).
Configure the zeek_http macro to match the sourcetype used by your Zeek add-on.
Known False Positives
Applications may upload files with names containing serialized-looking text as part of testing or unusual workflows. Review the complete request headers, source, destination, and application context before determining intent.
Associated Analytic Story
Intermediate Findings
| Message | Entity Field | Entity Type | Risk Score |
|---|---|---|---|
| A multipart POST request from [$src$] to [$dest$] included PHP_SESSION_UPLOAD_PROGRESS and a serialized PHP structure in an upload filename. | dest | system | 40 |
Threat Objects
| Field | Type |
|---|---|
| src | ip_address |
| serialized_filename_headers | file_name |
References
Detection Testing
| Test Type | Status | Dataset | Source | Sourcetype |
|---|---|---|---|---|
| Validation | ✅ Passing | N/A | N/A | N/A |
| Unit | ✅ Passing | Dataset | http.log |
zeek:http |
| Integration | ✅ Passing | Dataset | http.log |
zeek:http |
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