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 = "2026/09/18"
  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    "Noise: Low",
 86    "Performance: Normal",
 87    "Profile: Recommended",
 88    "Threat: Web Shell",
 89    "Rule Type: Event Correlation (EQL)",
 90    "Platform: Windows",
 91    "Platform: Linux",
 92    "Platform: macOS",
 93    "Data Source: Network Packet Capture",
 94]
 95type = "eql"
 96query = '''
 97sequence by agent.id with maxspan=5m
 98  [network where
 99   data_stream.dataset == "network_traffic.http" and
100   http.request.method in ("POST", "PUT") and
101   /* We can restrict to 200 in the future, but I prefer to broaden the scope and decrease it later if necessary */
102   http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
103   /* These should detect most common file upload activities, adhering to browser standards */
104   http.request.body.content like "*Content-Disposition: form-data*" and
105   http.request.body.content like "*filename=*"
106   /* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
107   and http.request.body.bytes >= 500
108   */
109  ]
110  [file where
111   data_stream.dataset == "endpoint.events.file" and
112   event.action in ("creation", "rename") and
113   file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
114   /* We can add file.path values here in the future, if telemetry is noisy */
115  ]
116  [network where
117   data_stream.dataset == "network_traffic.http" and
118   http.request.method in ("GET", "POST") and
119   /* we may restrict to 200, but keeping it broader right now */
120   http.response.status_code >= 200 and http.response.status_code < 600 and
121   url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
122  ]
123'''
124
125[[rule.threat]]
126framework = "MITRE ATT&CK"
127
128[[rule.threat.technique]]
129id = "T1190"
130name = "Exploit Public-Facing Application"
131reference = "https://attack.mitre.org/techniques/T1190/"
132
133[rule.threat.tactic]
134id = "TA0001"
135name = "Initial Access"
136reference = "https://attack.mitre.org/tactics/TA0001/"
137
138[[rule.threat]]
139framework = "MITRE ATT&CK"
140
141[[rule.threat.technique]]
142id = "T1505"
143name = "Server Software Component"
144reference = "https://attack.mitre.org/techniques/T1505/"
145
146[[rule.threat.technique.subtechnique]]
147id = "T1505.003"
148name = "Web Shell"
149reference = "https://attack.mitre.org/techniques/T1505/003/"
150
151[rule.threat.tactic]
152id = "TA0003"
153name = "Persistence"
154reference = "https://attack.mitre.org/tactics/TA0003/"
155
156[[rule.threat]]
157framework = "MITRE ATT&CK"
158
159[[rule.threat.technique]]
160id = "T1105"
161name = "Ingress Tool Transfer"
162reference = "https://attack.mitre.org/techniques/T1105/"
163
164[rule.threat.tactic]
165id = "TA0011"
166name = "Command and Control"
167reference = "https://attack.mitre.org/tactics/TA0011/"

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

to-top