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/11/27"
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"
22risk_score = 47
23rule_id = "1d306bf0-7bcf-4acd-83fd-042f5711acc9"
24setup = """## Setup
25
26This rule requires data coming in from both Elastic Defend (for file events) and Network Packet Capture integrations (for HTTP traffic analysis).
27
28### Network Packet Capture Integration Setup
29
30**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.
31
32To enable HTTP request body capture, follow these steps:
331. Navigate to the Fleet policy leveraging the Network Packet Capture integration in Kibana.
342. Locate and select the "Network Packet Capture" integration, and edit the integration.
353. Locate "Change Default", and scroll down to the "HTTP" section.
364. Enable the "HTTP" toggle to capture HTTP traffic, add the correct ports for your web application, and click "advanced options".
375. Edit the integration settings to enable HTTP request body capture for POST requests with `multipart/form-data` content type.
386. Save the integration configuration and wait for the policy to deploy to the agents.
39"""
40severity = "medium"
41tags = [
42 "Domain: Endpoint",
43 "Domain: Web",
44 "Domain: Network",
45 "OS: Linux",
46 "OS: Windows",
47 "OS: macOS",
48 "Use Case: Threat Detection",
49 "Tactic: Initial Access",
50 "Tactic: Persistence",
51 "Data Source: Elastic Defend",
52 "Data Source: Network Traffic",
53]
54type = "eql"
55query = '''
56sequence by agent.id with maxspan=5m
57 [network where
58 data_stream.dataset == "network_traffic.http" and
59 http.request.method in ("POST", "PUT") and
60 /* We can restrict to 200 in the future, but I prefer to broaden the scope and decrease it later if necessary */
61 http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
62 /* These should detect most common file upload activities, adhering to browser standards */
63 http.request.body.content like "*Content-Disposition: form-data*" and
64 http.request.body.content like "*filename=*"
65 /* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
66 and http.request.body.bytes >= 500
67 */
68 ]
69 [file where
70 event.dataset == "endpoint.events.file" and
71 event.action in ("creation", "rename") and
72 file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
73 /* We can add file.path values here in the future, if telemetry is noisy */
74 ]
75 [network where
76 data_stream.dataset == "network_traffic.http" and
77 http.request.method in ("GET", "POST") and
78 /* we may restrict to 200, but keeping it broader right now */
79 http.response.status_code >= 200 and http.response.status_code < 600 and
80 url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
81 ]
82'''
83
84[[rule.threat]]
85framework = "MITRE ATT&CK"
86
87[[rule.threat.technique]]
88id = "T1190"
89name = "Exploit Public-Facing Application"
90reference = "https://attack.mitre.org/techniques/T1190/"
91
92[rule.threat.tactic]
93id = "TA0001"
94name = "Initial Access"
95reference = "https://attack.mitre.org/tactics/TA0001/"
96
97[[rule.threat]]
98framework = "MITRE ATT&CK"
99
100[[rule.threat.technique]]
101id = "T1505"
102name = "Server Software Component"
103reference = "https://attack.mitre.org/techniques/T1505/"
104
105[[rule.threat.technique.subtechnique]]
106id = "T1505.003"
107name = "Web Shell"
108reference = "https://attack.mitre.org/techniques/T1505/003/"
109
110[rule.threat.tactic]
111id = "TA0003"
112name = "Persistence"
113reference = "https://attack.mitre.org/tactics/TA0003/"
Related rules
- Potential Webshell Deployed via Apache Struts CVE-2023-50164 Exploitation
- Execution via GitHub Actions Runner
- Remote GitHub Actions Runner Registration
- Node.js Pre or Post-Install Script Execution
- Unusual Web Server Command Execution