diff --git a/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_response_codes.toml b/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_response_codes.toml new file mode 100644 index 000000000..7c9ebf245 --- /dev/null +++ b/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_response_codes.toml @@ -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/"