[New Rule] Web Server Unusual Spike in Error Response Codes (#5338)

* [New Rule] Web Server Unusual Spike in Error Response Codes

* Update reconnaissance_web_server_unusual_spike_in_error_response_codes.toml

* Update tags in reconnaissance web server rule

* Add network domain tag and modify ESQL queries

* Remove url.path from error response rules

* ++

* Update reconnaissance_web_server_unusual_spike_in_error_response_codes.toml

* Update reconnaissance_web_server_unusual_spike_in_error_response_codes.toml

* fixing from indices formatting

---------

Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com>
Co-authored-by: terrancedejesus <terrance.dejesus@elastic.co>
This commit is contained in:
Ruben Groenewoud
2025-11-24 19:08:25 +01:00
committed by GitHub
parent 167def0bc1
commit 296049e1ff
@@ -0,0 +1,95 @@
[metadata]
creation_date = "2025/11/19"
integration = ["network_traffic", "nginx", "apache", "apache_tomcat", "iis"]
maturity = "production"
updated_date = "2025/11/19"
[rule]
author = ["Elastic"]
description = """
This rule detects unusual spikes in error response codes (500, 502, 503, 504) from web servers, which may indicate
reconnaissance activities such as vulnerability scanning or fuzzing attempts by adversaries. These activities often
generate a high volume of error responses as they probe for weaknesses in web applications. Error response codes
may potentially indicate server-side issues that could be exploited.
"""
from = "now-9m"
interval = "10m"
language = "esql"
license = "Elastic License v2"
name = "Web Server Potential Spike in Error Response Codes"
risk_score = 21
rule_id = "6fa3abe3-9cd8-41de-951b-51ed8f710523"
severity = "low"
tags = [
"Domain: Web",
"Domain: Network",
"Use Case: Threat Detection",
"Tactic: Reconnaissance",
"Data Source: Network Packet Capture",
"Data Source: Nginx",
"Data Source: Apache",
"Data Source: Apache Tomcat",
"Data Source: IIS",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-network_traffic.http-*, logs-network_traffic.tls-*, logs-nginx.access-*, logs-apache.access-*, logs-apache_tomcat.access-*, logs-iis.access-*
| where
(url.original is not null or url.full is not null) and
http.request.method == "GET" and
http.response.status_code in (
500, // Internal Server Error
502, // Bad Gateway
503, // Service Unavailable
504 // Gateway Timeout
)
| eval Esql.url_text = case(url.original is not null, url.original, url.full)
| eval Esql.url_lower = to_lower(Esql.url_text)
| keep
@timestamp,
event.dataset,
http.request.method,
http.response.status_code,
source.ip,
agent.id,
host.name,
Esql.url_lower
| stats
Esql.event_count = count(),
Esql.http_response_status_code_count = count(http.response.status_code),
Esql.http_response_status_code_values = values(http.response.status_code),
Esql.host_name_values = values(host.name),
Esql.agent_id_values = values(agent.id),
Esql.http_request_method_values = values(http.request.method),
Esql.http_response_status_code_values = values(http.response.status_code),
Esql.url_path_values = values(Esql.url_lower),
Esql.event_dataset_values = values(event.dataset)
by source.ip, agent.id
| where
Esql.http_response_status_code_count > 10
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"
[[rule.threat.technique.subtechnique]]
id = "T1595.002"
name = "Vulnerability Scanning"
reference = "https://attack.mitre.org/techniques/T1595/002/"
[[rule.threat.technique.subtechnique]]
id = "T1595.003"
name = "Wordlist Scanning"
reference = "https://attack.mitre.org/techniques/T1595/003/"
[rule.threat.tactic]
id = "TA0043"
name = "Reconnaissance"
reference = "https://attack.mitre.org/tactics/TA0043/"