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.

 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
Anomaly detections generate Intermediate Findings (Risk Events). They do not generate a Finding (Notable) directly.

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