Initial Access via File Upload Followed by GET Request
This rule detects potential initial access activity where an adversary uploads a web shell or malicious script to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web servers.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/11/27"
3integration = ["endpoint", "network_traffic"]
4maturity = "production"
5updated_date = "2025/12/08"
6
7[rule]
8author = ["Elastic"]
9description = """
10This rule detects potential initial access activity where an adversary uploads a web shell or malicious script
11to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by
12a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload
13indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload
14activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web
15servers.
16"""
17from = "now-9m"
18index = ["logs-endpoint.events.*", "logs-network_traffic.*"]
19language = "eql"
20license = "Elastic License v2"
21name = "Initial Access via File Upload Followed by GET Request"
22note = """## Triage and analysis
23
24> **Disclaimer**:
25> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
26
27### Investigating Initial Access via File Upload Followed by GET Request
28
29This rule flags a common initial-access pattern: a multipart/form-data upload that drops a dynamic web script on a server, followed shortly by a request to execute that file and establish a foothold. Attackers exploit a permissive upload form to plant shell.php or shell.jsp in an uploads or temp directory, then immediately request it to spawn a web shell, enumerate files, and run commands—often leveraging redirects or 2xx/3xx responses that indicate successful placement and access.
30
31### Possible investigation steps
32
33- Correlate the upload transaction with the server-side file creation and the subsequent access to the same resource, matching timestamps, source IP, and path, and follow any redirects to the final executed file.
34- Retrieve the uploaded artifact from disk, verify it sits in a web-accessible location, inspect content for web shell traits (eval/system/exec, obfuscation, password gates), and record hashes.
35- Examine server process telemetry immediately after the access for interpreter or shell spawns and unexpected outbound connections originating from web server workers.
36- Review application logs and access context to determine whether the upload was authenticated, which account or session performed it, and whether user-agent, referer, or headers deviate from normal clients.
37- Broaden the timeline to identify related uploads, file renames, or repeated requests from the same actor, including parameterized calls that suggest command execution or directory enumeration.
38
39### False positive analysis
40
41- An authenticated administrator installs a legitimate plugin or module via the application’s upload form, which unpacks or renames .php or .jsp files and then auto-loads a setup page, producing the multipart upload, file creation/rename, and immediate GET pattern.
42- Automated deployment or QA routines upload and deploy a .war or server-side script through a web-based admin interface and then perform health-check or warm-up requests, resulting in the same multipart upload, server-side file creation, and follow-up GET sequence.
43
44### Response and remediation
45
46- Immediately block access to the uploaded script that was invoked via GET/POST (e.g., /uploads/shell.php) and the source IPs that executed it, restrict the site to allowlisted IPs or maintenance mode, and temporarily disable the upload endpoint.
47- Quarantine and remove the uploaded web shell and any additional executable scripts or WARs in web-accessible directories (uploads, webroot, temp), terminate interpreter or shell processes spawned by the web server account (www-data/nginx/w3wp/tomcat), and revert malicious .htaccess/web.config rewrites.
48- Hunt for persistence and lateral-movement artifacts created after the upload, including recent .php/.jsp/.cgi file creations or renames in static asset folders, cron/systemd tasks, startup scripts, unauthorized admin users or plugins, and remove them.
49- Restore altered application files from known-good backups or redeploy a clean container/VM, rotate database and API credentials stored in config files or environment variables, invalidate active sessions, and only re-enable uploads after confirming execution is blocked in upload directories.
50- Escalate to incident command and privacy/legal if you observe command execution parameters on the uploaded page (?cmd=, ?exec=), shells spawning (/bin/sh, powershell.exe), database dumps, or outbound callbacks from web server processes to external hosts.
51- Harden by storing uploads outside the webroot, denying execution in upload paths (disable PHP/CGI handlers and set noexec permissions), enforcing strict extension/MIME allowlists and AV/sandbox scanning for multipart/form-data, enabling file-integrity alerts on new .php/.jsp in served paths, and deploying WAF rules to block direct requests to uploaded executables.
52"""
53risk_score = 47
54rule_id = "1d306bf0-7bcf-4acd-83fd-042f5711acc9"
55setup = """## Setup
56
57This rule requires data coming in from both Elastic Defend (for file events) and Network Packet Capture integrations (for HTTP traffic analysis).
58
59### Network Packet Capture Integration Setup
60
61**IMPORTANT**: This rule requires HTTP request body capture to be enabled in order to detect the multipart/form-data content containing WebKitFormBoundary indicators. The network traffic integration must be configured to capture HTTP request bodies for POST requests with `multipart/form-data` content type.
62
63To enable HTTP request body capture, follow these steps:
641. Navigate to the Fleet policy leveraging the Network Packet Capture integration in Kibana.
652. Locate and select the "Network Packet Capture" integration, and edit the integration.
663. Locate "Change Default", and scroll down to the "HTTP" section.
674. Enable the "HTTP" toggle to capture HTTP traffic, add the correct ports for your web application, and click "advanced options".
685. Edit the integration settings to enable HTTP request body capture for POST requests with `multipart/form-data` content type.
696. Save the integration configuration and wait for the policy to deploy to the agents.
70"""
71severity = "medium"
72tags = [
73 "Domain: Endpoint",
74 "Domain: Web",
75 "Domain: Network",
76 "OS: Linux",
77 "OS: Windows",
78 "OS: macOS",
79 "Use Case: Threat Detection",
80 "Tactic: Initial Access",
81 "Tactic: Persistence",
82 "Data Source: Elastic Defend",
83 "Data Source: Network Traffic",
84 "Resources: Investigation Guide",
85]
86type = "eql"
87query = '''
88sequence by agent.id with maxspan=5m
89 [network where
90 data_stream.dataset == "network_traffic.http" and
91 http.request.method in ("POST", "PUT") and
92 /* We can restrict to 200 in the future, but I prefer to broaden the scope and decrease it later if necessary */
93 http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
94 /* These should detect most common file upload activities, adhering to browser standards */
95 http.request.body.content like "*Content-Disposition: form-data*" and
96 http.request.body.content like "*filename=*"
97 /* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
98 and http.request.body.bytes >= 500
99 */
100 ]
101 [file where
102 event.dataset == "endpoint.events.file" and
103 event.action in ("creation", "rename") and
104 file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
105 /* We can add file.path values here in the future, if telemetry is noisy */
106 ]
107 [network where
108 data_stream.dataset == "network_traffic.http" and
109 http.request.method in ("GET", "POST") and
110 /* we may restrict to 200, but keeping it broader right now */
111 http.response.status_code >= 200 and http.response.status_code < 600 and
112 url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
113 ]
114'''
115
116[[rule.threat]]
117framework = "MITRE ATT&CK"
118
119[[rule.threat.technique]]
120id = "T1190"
121name = "Exploit Public-Facing Application"
122reference = "https://attack.mitre.org/techniques/T1190/"
123
124[rule.threat.tactic]
125id = "TA0001"
126name = "Initial Access"
127reference = "https://attack.mitre.org/tactics/TA0001/"
128
129[[rule.threat]]
130framework = "MITRE ATT&CK"
131
132[[rule.threat.technique]]
133id = "T1505"
134name = "Server Software Component"
135reference = "https://attack.mitre.org/techniques/T1505/"
136
137[[rule.threat.technique.subtechnique]]
138id = "T1505.003"
139name = "Web Shell"
140reference = "https://attack.mitre.org/techniques/T1505/003/"
141
142[rule.threat.tactic]
143id = "TA0003"
144name = "Persistence"
145reference = "https://attack.mitre.org/tactics/TA0003/"
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
Investigating Initial Access via File Upload Followed by GET Request
This rule flags a common initial-access pattern: a multipart/form-data upload that drops a dynamic web script on a server, followed shortly by a request to execute that file and establish a foothold. Attackers exploit a permissive upload form to plant shell.php or shell.jsp in an uploads or temp directory, then immediately request it to spawn a web shell, enumerate files, and run commands—often leveraging redirects or 2xx/3xx responses that indicate successful placement and access.
Possible investigation steps
- Correlate the upload transaction with the server-side file creation and the subsequent access to the same resource, matching timestamps, source IP, and path, and follow any redirects to the final executed file.
- Retrieve the uploaded artifact from disk, verify it sits in a web-accessible location, inspect content for web shell traits (eval/system/exec, obfuscation, password gates), and record hashes.
- Examine server process telemetry immediately after the access for interpreter or shell spawns and unexpected outbound connections originating from web server workers.
- Review application logs and access context to determine whether the upload was authenticated, which account or session performed it, and whether user-agent, referer, or headers deviate from normal clients.
- Broaden the timeline to identify related uploads, file renames, or repeated requests from the same actor, including parameterized calls that suggest command execution or directory enumeration.
False positive analysis
- An authenticated administrator installs a legitimate plugin or module via the application’s upload form, which unpacks or renames .php or .jsp files and then auto-loads a setup page, producing the multipart upload, file creation/rename, and immediate GET pattern.
- Automated deployment or QA routines upload and deploy a .war or server-side script through a web-based admin interface and then perform health-check or warm-up requests, resulting in the same multipart upload, server-side file creation, and follow-up GET sequence.
Response and remediation
- Immediately block access to the uploaded script that was invoked via GET/POST (e.g., /uploads/shell.php) and the source IPs that executed it, restrict the site to allowlisted IPs or maintenance mode, and temporarily disable the upload endpoint.
- Quarantine and remove the uploaded web shell and any additional executable scripts or WARs in web-accessible directories (uploads, webroot, temp), terminate interpreter or shell processes spawned by the web server account (www-data/nginx/w3wp/tomcat), and revert malicious .htaccess/web.config rewrites.
- Hunt for persistence and lateral-movement artifacts created after the upload, including recent .php/.jsp/.cgi file creations or renames in static asset folders, cron/systemd tasks, startup scripts, unauthorized admin users or plugins, and remove them.
- Restore altered application files from known-good backups or redeploy a clean container/VM, rotate database and API credentials stored in config files or environment variables, invalidate active sessions, and only re-enable uploads after confirming execution is blocked in upload directories.
- Escalate to incident command and privacy/legal if you observe command execution parameters on the uploaded page (?cmd=, ?exec=), shells spawning (/bin/sh, powershell.exe), database dumps, or outbound callbacks from web server processes to external hosts.
- Harden by storing uploads outside the webroot, denying execution in upload paths (disable PHP/CGI handlers and set noexec permissions), enforcing strict extension/MIME allowlists and AV/sandbox scanning for multipart/form-data, enabling file-integrity alerts on new .php/.jsp in served paths, and deploying WAF rules to block direct requests to uploaded executables.
Related rules
- Potential Webshell Deployed via Apache Struts CVE-2023-50164 Exploitation
- Execution via GitHub Actions Runner
- Remote GitHub Actions Runner Registration
- Deprecated - Modification of Standard Authentication Module or Configuration
- GenAI Process Accessing Sensitive Files