Skip to content

Commit f42b514

Browse files
Aegrahterrancedejesusshashank-elastic
authored
[New Rule] Initial Access via File Upload Followed by GET Request (#5371)
* [New Rule] Initial Access via File Upload Followed by GET Request * Slightly increase timespan * ++ * Update rules/cross-platform/initial_access_file_upload_followed_by_get_request.toml Co-authored-by: Terrance DeJesus <[email protected]> --------- Co-authored-by: Terrance DeJesus <[email protected]> Co-authored-by: shashank-elastic <[email protected]>
1 parent 7a884eb commit f42b514

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
[metadata]
2+
creation_date = "2025/11/27"
3+
integration = ["endpoint", "network_traffic"]
4+
maturity = "production"
5+
updated_date = "2025/11/27"
6+
7+
[rule]
8+
author = ["Elastic"]
9+
description = """
10+
This rule detects potential initial access activity where an adversary uploads a web shell or malicious script
11+
to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by
12+
a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload
13+
indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload
14+
activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web
15+
servers.
16+
"""
17+
from = "now-9m"
18+
index = ["logs-endpoint.events.*", "logs-network_traffic.*"]
19+
language = "eql"
20+
license = "Elastic License v2"
21+
name = "Initial Access via File Upload Followed by GET Request"
22+
risk_score = 47
23+
rule_id = "1d306bf0-7bcf-4acd-83fd-042f5711acc9"
24+
setup = """## Setup
25+
26+
This 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+
32+
To enable HTTP request body capture, follow these steps:
33+
1. Navigate to the Fleet policy leveraging the Network Packet Capture integration in Kibana.
34+
2. Locate and select the "Network Packet Capture" integration, and edit the integration.
35+
3. Locate "Change Default", and scroll down to the "HTTP" section.
36+
4. Enable the "HTTP" toggle to capture HTTP traffic, add the correct ports for your web application, and click "advanced options".
37+
5. Edit the integration settings to enable HTTP request body capture for POST requests with `multipart/form-data` content type.
38+
6. Save the integration configuration and wait for the policy to deploy to the agents.
39+
"""
40+
severity = "medium"
41+
tags = [
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+
]
54+
type = "eql"
55+
query = '''
56+
sequence 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]]
85+
framework = "MITRE ATT&CK"
86+
87+
[[rule.threat.technique]]
88+
id = "T1190"
89+
name = "Exploit Public-Facing Application"
90+
reference = "https://attack.mitre.org/techniques/T1190/"
91+
92+
[rule.threat.tactic]
93+
id = "TA0001"
94+
name = "Initial Access"
95+
reference = "https://attack.mitre.org/tactics/TA0001/"
96+
97+
[[rule.threat]]
98+
framework = "MITRE ATT&CK"
99+
100+
[[rule.threat.technique]]
101+
id = "T1505"
102+
name = "Server Software Component"
103+
reference = "https://attack.mitre.org/techniques/T1505/"
104+
105+
[[rule.threat.technique.subtechnique]]
106+
id = "T1505.003"
107+
name = "Web Shell"
108+
reference = "https://attack.mitre.org/techniques/T1505/003/"
109+
110+
[rule.threat.tactic]
111+
id = "TA0003"
112+
name = "Persistence"
113+
reference = "https://attack.mitre.org/tactics/TA0003/"

0 commit comments

Comments
 (0)