Web Server Discovery or Fuzzing Activity
This rule detects potential web server discovery or fuzzing activity by identifying a high volume of HTTP GET requests resulting in 404 or 403 status codes from a single source IP address within a short timeframe. Such patterns may indicate that an attacker is attempting to discover hidden or unlinked resources on a web server, which can be a precursor to more targeted attacks.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/11/19"
3integration = ["nginx", "apache", "apache_tomcat", "iis"]
4maturity = "production"
5updated_date = "2025/12/01"
6
7[rule]
8author = ["Elastic"]
9description = """
10This rule detects potential web server discovery or fuzzing activity by identifying a high volume of HTTP GET requests resulting
11in 404 or 403 status codes from a single source IP address within a short timeframe. Such patterns may indicate that an attacker
12is attempting to discover hidden or unlinked resources on a web server, which can be a precursor to more targeted attacks.
13"""
14from = "now-9m"
15interval = "10m"
16language = "esql"
17license = "Elastic License v2"
18name = "Web Server Discovery or Fuzzing Activity"
19note = """ ## Triage and analysis
20
21> **Disclaimer**:
22> 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.
23
24### Investigating Web Server Discovery or Fuzzing Activity
25
26This rule flags a single origin generating a rapid burst of GET requests that produce many 404/403 responses, a hallmark of automated web discovery or fuzzing. Attackers commonly run wordlist-driven enumeration to probe paths such as /admin/, /login, /backup.zip, /.env, /.git/, and undocumented API routes, gauging which resources exist and where access controls fail. Detecting this reconnaissance early helps prevent subsequent targeted exploitation of newly found endpoints and weak authentication flows.
27
28### Possible investigation steps
29
30- Correlate user-agent, TLS JA3/JA4, Host/SNI, and X-Forwarded-For to fingerprint the client, identify common fuzzing tools or disguised automation, and recover the true origin if traffic traversed a CDN or proxy.
31- Summarize the top requested paths and response codes for this source to spot any 2xx or 401 outcomes amid the denials, flagging hits on sensitive locations such as /.env, /.git, /admin interfaces, backups, installer scripts, and undocumented API routes.
32- Pivot to the same timeframe for adjacent web and authentication activity from this origin to see whether POSTs, credential attempts, or parameterized requests followed the enumeration, indicating progression toward exploitation or spraying.
33- Review WAF/CDN and reverse-proxy logs for blocks, challenges, or rate limiting and whether multiple virtual hosts were targeted via the Host header, confirming if and how far requests reached the application tier.
34- Validate whether the source aligns with approved internal scanners or scheduled testing via inventories and change records, and if not, enrich with ASN/geolocation, reverse DNS, and threat intel to assess reputation and recurrence across your estate.
35
36### False positive analysis
37
38- An internal QA link checker or monitoring crawler run from a single host can request hundreds of unique paths and generate many 404/403 GETs when routes, assets, or permissions are misconfigured.
39- A shared egress IP (NAT or corporate proxy) aggregating many users during a faulty deployment can trigger high volumes of 404/403 GETs as browsers collectively hit moved or newly restricted resources.
40
41### Response and remediation
42
43- Immediately rate-limit or block the offending source IP at the WAF/CDN and reverse proxy, applying a challenge or temporary ban to the observed User-Agent and JA3/JA4 fingerprint driving the 500+ unique-path 404/403 GET burst.
44- If traffic came through a proxy or CDN, use X-Forwarded-For to identify and block the true origin, and add a temporary ASN or geolocation block if the source aligns with known scanner networks.
45- Verify whether the source is an approved internal scanner; if not, disable the job or container, remove any scheduled tasks and API keys used, and notify the owner to stop testing against production immediately.
46- Review the requested path list to identify any 2xx or 401 hits and remediate exposures such as accessible /.env, /.git, /admin interfaces, backup archives, or installer scripts by removing files, disabling endpoints, and rotating secrets.
47- Escalate to incident response if enumeration persists after blocking, pivots to POSTs or credential attempts, originates from rotating IPs (Tor/VPN/residential), or produces 2xx on sensitive endpoints despite WAF rules.
48- Harden the web tier by enabling per-IP rate limiting and bot challenges, turning off directory listing and default app endpoints, blocking patterns like /.git/, /.env, and /backup.zip at the WAF, and restricting origin access to CDN egress only.
49"""
50risk_score = 21
51rule_id = "8383a8d0-008b-47a5-94e5-496629dc3590"
52severity = "low"
53tags = [
54 "Domain: Web",
55 "Use Case: Threat Detection",
56 "Tactic: Reconnaissance",
57 "Data Source: Nginx",
58 "Data Source: Apache",
59 "Data Source: Apache Tomcat",
60 "Data Source: IIS",
61 "Resources: Investigation Guide",
62]
63timestamp_override = "event.ingested"
64type = "esql"
65query = '''
66from logs-nginx.access-*, logs-apache.access-*, logs-apache_tomcat.access-*, logs-iis.access-*
67| where
68 http.request.method == "GET" and
69 http.response.status_code in (404, 403)
70
71| eval Esql.url_original_to_lower = to_lower(url.original)
72
73| keep
74 @timestamp,
75 event.dataset,
76 http.request.method,
77 http.response.status_code,
78 source.ip,
79 agent.id,
80 host.name,
81 Esql.url_original_to_lower
82| stats
83 Esql.event_count = count(),
84 Esql.url_original_count_distinct = count_distinct(Esql.url_original_to_lower),
85 Esql.host_name_values = values(host.name),
86 Esql.agent_id_values = values(agent.id),
87 Esql.http_request_method_values = values(http.request.method),
88 Esql.http_response_status_code_values = values(http.response.status_code),
89 Esql.url_original_values = values(Esql.url_original_to_lower),
90 Esql.event_dataset_values = values(event.dataset)
91 by source.ip
92| where
93 Esql.event_count > 500 and Esql.url_original_count_distinct > 250
94'''
95
96[[rule.threat]]
97framework = "MITRE ATT&CK"
98
99[[rule.threat.technique]]
100id = "T1595"
101name = "Active Scanning"
102reference = "https://attack.mitre.org/techniques/T1595/"
103
104[[rule.threat.technique.subtechnique]]
105id = "T1595.002"
106name = "Vulnerability Scanning"
107reference = "https://attack.mitre.org/techniques/T1595/002/"
108
109[[rule.threat.technique.subtechnique]]
110id = "T1595.003"
111name = "Wordlist Scanning"
112reference = "https://attack.mitre.org/techniques/T1595/003/"
113
114[rule.threat.tactic]
115id = "TA0043"
116name = "Reconnaissance"
117reference = "https://attack.mitre.org/tactics/TA0043/"
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 Web Server Discovery or Fuzzing Activity
This rule flags a single origin generating a rapid burst of GET requests that produce many 404/403 responses, a hallmark of automated web discovery or fuzzing. Attackers commonly run wordlist-driven enumeration to probe paths such as /admin/, /login, /backup.zip, /.env, /.git/, and undocumented API routes, gauging which resources exist and where access controls fail. Detecting this reconnaissance early helps prevent subsequent targeted exploitation of newly found endpoints and weak authentication flows.
Possible investigation steps
- Correlate user-agent, TLS JA3/JA4, Host/SNI, and X-Forwarded-For to fingerprint the client, identify common fuzzing tools or disguised automation, and recover the true origin if traffic traversed a CDN or proxy.
- Summarize the top requested paths and response codes for this source to spot any 2xx or 401 outcomes amid the denials, flagging hits on sensitive locations such as /.env, /.git, /admin interfaces, backups, installer scripts, and undocumented API routes.
- Pivot to the same timeframe for adjacent web and authentication activity from this origin to see whether POSTs, credential attempts, or parameterized requests followed the enumeration, indicating progression toward exploitation or spraying.
- Review WAF/CDN and reverse-proxy logs for blocks, challenges, or rate limiting and whether multiple virtual hosts were targeted via the Host header, confirming if and how far requests reached the application tier.
- Validate whether the source aligns with approved internal scanners or scheduled testing via inventories and change records, and if not, enrich with ASN/geolocation, reverse DNS, and threat intel to assess reputation and recurrence across your estate.
False positive analysis
- An internal QA link checker or monitoring crawler run from a single host can request hundreds of unique paths and generate many 404/403 GETs when routes, assets, or permissions are misconfigured.
- A shared egress IP (NAT or corporate proxy) aggregating many users during a faulty deployment can trigger high volumes of 404/403 GETs as browsers collectively hit moved or newly restricted resources.
Response and remediation
- Immediately rate-limit or block the offending source IP at the WAF/CDN and reverse proxy, applying a challenge or temporary ban to the observed User-Agent and JA3/JA4 fingerprint driving the 500+ unique-path 404/403 GET burst.
- If traffic came through a proxy or CDN, use X-Forwarded-For to identify and block the true origin, and add a temporary ASN or geolocation block if the source aligns with known scanner networks.
- Verify whether the source is an approved internal scanner; if not, disable the job or container, remove any scheduled tasks and API keys used, and notify the owner to stop testing against production immediately.
- Review the requested path list to identify any 2xx or 401 hits and remediate exposures such as accessible /.env, /.git, /admin interfaces, backup archives, or installer scripts by removing files, disabling endpoints, and rotating secrets.
- Escalate to incident response if enumeration persists after blocking, pivots to POSTs or credential attempts, originates from rotating IPs (Tor/VPN/residential), or produces 2xx on sensitive endpoints despite WAF rules.
- Harden the web tier by enabling per-IP rate limiting and bot challenges, turning off directory listing and default app endpoints, blocking patterns like /.git/, /.env, and /backup.zip at the WAF, and restricting origin access to CDN egress only.
Related rules
- Potential Spike in Web Server Error Logs
- Web Server Potential Command Injection Request
- Web Server Potential Spike in Error Response Codes
- Web Server Suspicious User Agent Requests
- Potential Webshell Deployed via Apache Struts CVE-2023-50164 Exploitation