Skip to content

Commit 4920e9a

Browse files
Aegraheric-forte-elasticshashank-elasticimays11
authored
[New Rule] Web Server Local File Inclusion Activity (#5393)
* [New Rule] Web Server Local File Inclusion Activity * Update discovery_web_server_local_file_inclusion_activity.toml * Update discovery_web_server_local_file_inclusion_activity.toml * Update discovery_web_server_local_file_inclusion_activity.toml * Update rules/cross-platform/discovery_web_server_local_file_inclusion_activity.toml Co-authored-by: Isai <[email protected]> * Add data_stream.namespace to event statistics --------- Co-authored-by: Eric Forte <[email protected]> Co-authored-by: shashank-elastic <[email protected]> Co-authored-by: Isai <[email protected]>
1 parent 36baf8c commit 4920e9a

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
[metadata]
2+
creation_date = "2025/12/02"
3+
integration = ["nginx", "apache", "apache_tomcat", "iis"]
4+
maturity = "production"
5+
min_stack_version = "9.2.0"
6+
min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
7+
updated_date = "2025/12/02"
8+
9+
[rule]
10+
author = ["Elastic"]
11+
description = """
12+
This rule detects potential Local File Inclusion (LFI) activity on web servers by identifying HTTP GET requests that
13+
attempt to access sensitive local files through directory traversal techniques or known file paths. Attackers may
14+
exploit LFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
15+
"""
16+
from = "now-11m"
17+
interval = "10m"
18+
language = "esql"
19+
license = "Elastic License v2"
20+
name = "Web Server Local File Inclusion Activity"
21+
risk_score = 21
22+
rule_id = "90e4ceab-79a5-4f8e-879b-513cac7fcad9"
23+
severity = "low"
24+
tags = [
25+
"Domain: Web",
26+
"Use Case: Threat Detection",
27+
"Tactic: Discovery",
28+
"Data Source: Nginx",
29+
"Data Source: Apache",
30+
"Data Source: Apache Tomcat",
31+
"Data Source: IIS",
32+
]
33+
timestamp_override = "event.ingested"
34+
type = "esql"
35+
query = '''
36+
from
37+
logs-nginx.access-*,
38+
logs-apache.access-*,
39+
logs-apache_tomcat.access-*,
40+
logs-iis.access-*
41+
| where
42+
http.request.method == "GET" and
43+
http.response.status_code == 200 and
44+
url.original like "*=*"
45+
46+
| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
47+
48+
| where
49+
/* 1) Relative traversal */
50+
Esql.url_original_url_decoded_to_lower like "*../../../../*" or // Unix-style traversal
51+
Esql.url_original_url_decoded_to_lower like "*..\\\\..\\\\..\\\\..*" or // Windows-style traversal
52+
// Potential security check bypassing (enforcing multiple dots and shortening the pattern)
53+
Esql.url_original_url_decoded_to_lower like "*..././*" or
54+
Esql.url_original_url_decoded_to_lower like "*...\\*" or
55+
Esql.url_original_url_decoded_to_lower like "*....\\*" or
56+
57+
/* 2) Linux system identity / basic info */
58+
Esql.url_original_url_decoded_to_lower like "*etc/passwd*" or
59+
Esql.url_original_url_decoded_to_lower like "*etc/shadow*" or
60+
Esql.url_original_url_decoded_to_lower like "*etc/hosts*" or
61+
Esql.url_original_url_decoded_to_lower like "*etc/os-release*" or
62+
Esql.url_original_url_decoded_to_lower like "*etc/issue*" or
63+
64+
/* 3) Linux /proc enumeration */
65+
Esql.url_original_url_decoded_to_lower like "*proc/self/environ*" or
66+
Esql.url_original_url_decoded_to_lower like "*proc/self/cmdline*" or
67+
Esql.url_original_url_decoded_to_lower like "*proc/self/fd*" or
68+
Esql.url_original_url_decoded_to_lower like "*proc/self/exe*" or
69+
70+
/* 4) Linux webroots, configs & logs */
71+
Esql.url_original_url_decoded_to_lower like "*var/www*" or // generic webroot
72+
Esql.url_original_url_decoded_to_lower like "*wp-config.php*" or // classic WP config
73+
Esql.url_original_url_decoded_to_lower like "*etc/apache2*" or
74+
Esql.url_original_url_decoded_to_lower like "*etc/httpd*" or
75+
Esql.url_original_url_decoded_to_lower like "*etc/nginx*" or
76+
Esql.url_original_url_decoded_to_lower like "*var/log/apache2*" or
77+
Esql.url_original_url_decoded_to_lower like "*var/log/httpd*" or
78+
Esql.url_original_url_decoded_to_lower like "*var/log/nginx*" or
79+
80+
/* 5) Windows core files / identity */
81+
Esql.url_original_url_decoded_to_lower like "*windows/panther/*unattend*" or
82+
Esql.url_original_url_decoded_to_lower like "*windows/debug/netsetup.log*" or
83+
Esql.url_original_url_decoded_to_lower like "*windows/win.ini*" or
84+
Esql.url_original_url_decoded_to_lower like "*windows/system32/drivers/etc/hosts*" or
85+
Esql.url_original_url_decoded_to_lower like "*boot.ini*" or
86+
Esql.url_original_url_decoded_to_lower like "*windows/system32/config/*" or
87+
Esql.url_original_url_decoded_to_lower like "*windows/repair/sam*" or
88+
Esql.url_original_url_decoded_to_lower like "*windows/system32/license.rtf*" or
89+
90+
/* 6) Windows IIS / .NET configs, webroots & logs */
91+
Esql.url_original_url_decoded_to_lower like "*/inetpub/wwwroot*" or
92+
Esql.url_original_url_decoded_to_lower like "*/inetpub/logs/logfiles*" or
93+
Esql.url_original_url_decoded_to_lower like "*applicationhost.config*" or
94+
Esql.url_original_url_decoded_to_lower like "*/microsoft.net/framework64/*/config/web.config*" or
95+
Esql.url_original_url_decoded_to_lower like "*windows/system32/inetsrv/*" or
96+
97+
/* 7) PHP & protocol wrappers */
98+
Esql.url_original_url_decoded_to_lower like "*php://*" or
99+
Esql.url_original_url_decoded_to_lower like "*zip://*" or
100+
Esql.url_original_url_decoded_to_lower like "*phar://*" or
101+
Esql.url_original_url_decoded_to_lower like "*expect://*" or
102+
Esql.url_original_url_decoded_to_lower like "*file://*" or
103+
Esql.url_original_url_decoded_to_lower like "*data://text/plain;base64*"
104+
105+
| keep
106+
@timestamp,
107+
Esql.url_original_url_decoded_to_lower,
108+
source.ip,
109+
agent.id,
110+
host.name,
111+
http.request.method,
112+
http.response.status_code,
113+
event.dataset,
114+
data_stream.namespace
115+
116+
| stats
117+
Esql.event_count = count(),
118+
Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
119+
Esql.host_name_values = values(host.name),
120+
Esql.agent_id_values = values(agent.id),
121+
Esql.http_request_method_values = values(http.request.method),
122+
Esql.http_response_status_code_values = values(http.response.status_code),
123+
Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
124+
Esql.event_dataset_values = values(event.dataset),
125+
Esql.data_stream_namespace_values = values(data_stream.namespace)
126+
by source.ip
127+
'''
128+
129+
[[rule.threat]]
130+
framework = "MITRE ATT&CK"
131+
132+
[[rule.threat.technique]]
133+
id = "T1083"
134+
name = "File and Directory Discovery"
135+
reference = "https://attack.mitre.org/techniques/T1083/"
136+
137+
[rule.threat.tactic]
138+
id = "TA0007"
139+
name = "Discovery"
140+
reference = "https://attack.mitre.org/tactics/TA0007/"

0 commit comments

Comments
 (0)