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

to-top