Web Server Potential Remote File Inclusion Activity

This rule detects potential Remote File Inclusion (RFI) activity on web servers by identifying HTTP GET requests that attempt to access sensitive remote files through directory traversal techniques or known file paths. Attackers may exploit RFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/12/02"
  3integration = ["nginx", "apache", "apache_tomcat", "iis"]
  4maturity = "production"
  5min_stack_version = "9.2.0"
  6min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
  7updated_date = "2025/12/02"
  8
  9[rule]
 10author = ["Elastic"]
 11description = """
 12This rule detects potential Remote File Inclusion (RFI) activity on web servers by identifying HTTP GET requests that
 13attempt to access sensitive remote files through directory traversal techniques or known file paths. Attackers may
 14exploit RFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
 15"""
 16from = "now-11m"
 17interval = "10m"
 18language = "esql"
 19license = "Elastic License v2"
 20name = "Web Server Potential Remote File Inclusion Activity"
 21risk_score = 21
 22rule_id = "45d099b4-a12e-4913-951c-0129f73efb41"
 23severity = "low"
 24tags = [
 25    "Domain: Web",
 26    "Use Case: Threat Detection",
 27    "Tactic: Discovery",
 28    "Tactic: Command and Control",
 29    "Data Source: Nginx",
 30    "Data Source: Apache",
 31    "Data Source: Apache Tomcat",
 32    "Data Source: IIS",
 33]
 34timestamp_override = "event.ingested"
 35type = "esql"
 36query = '''
 37from
 38  logs-nginx.access-*,
 39  logs-apache.access-*,
 40  logs-apache_tomcat.access-*,
 41  logs-iis.access-*
 42| where
 43    http.request.method == "GET" and
 44    http.response.status_code == 200 and
 45    url.original like "*=*"
 46
 47| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
 48
 49| where
 50    Esql.url_original_url_decoded_to_lower like "*=http://*" or
 51    Esql.url_original_url_decoded_to_lower like "*=https://*" or
 52    Esql.url_original_url_decoded_to_lower like "*=ftp://*" or
 53    Esql.url_original_url_decoded_to_lower like "*=smb://*" or
 54    Esql.url_original_url_decoded_to_lower like "*=file://*" or
 55    Esql.url_original_url_decoded_to_lower rlike """.*=.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.*"""
 56
 57| keep
 58    @timestamp,
 59    Esql.url_original_url_decoded_to_lower,
 60    source.ip,
 61    agent.id,
 62    host.name,
 63    http.request.method,
 64    http.response.status_code,
 65    event.dataset,
 66    data_stream.namespace
 67
 68| stats
 69    Esql.event_count = count(),
 70    Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
 71    Esql.host_name_values = values(host.name),
 72    Esql.agent_id_values = values(agent.id),
 73    Esql.http_request_method_values = values(http.request.method),
 74    Esql.http_response_status_code_values = values(http.response.status_code),
 75    Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
 76    Esql.event_dataset_values = values(event.dataset),
 77    Esql.data_stream_namespace_values = values(data_stream.namespace)
 78    by source.ip
 79'''
 80
 81[[rule.threat]]
 82framework = "MITRE ATT&CK"
 83
 84[[rule.threat.technique]]
 85id = "T1083"
 86name = "File and Directory Discovery"
 87reference = "https://attack.mitre.org/techniques/T1083/"
 88
 89[rule.threat.tactic]
 90id = "TA0007"
 91name = "Discovery"
 92reference = "https://attack.mitre.org/tactics/TA0007/"
 93
 94[[rule.threat]]
 95framework = "MITRE ATT&CK"
 96
 97[rule.threat.tactic]
 98id = "TA0011"
 99name = "Command and Control"
100reference = "https://attack.mitre.org/tactics/TA0011/"

Related rules

to-top