nldcsc-elastic-rules 0.0.8__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nldcsc_elastic_rules/__init__.py +1 -1
- nldcsc_elastic_rules/rules/{linux → cross-platform}/command_and_control_curl_wget_spawn_via_nodejs_parent.toml +32 -11
- nldcsc_elastic_rules/rules/cross-platform/command_and_control_genai_process_suspicious_tld_connection.toml +134 -0
- nldcsc_elastic_rules/rules/cross-platform/command_and_control_genai_process_unusual_domain.toml +128 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_genai_process_sensitive_file_access.toml +154 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_gitleaks_execution.toml +114 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_multi_could_secrets_via_api.toml +198 -0
- nldcsc_elastic_rules/rules/cross-platform/credential_access_trufflehog_execution.toml +24 -5
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_config_modification.toml +120 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_process_compiling_executables.toml +158 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_genai_process_encoding_prior_to_network_activity.toml +172 -0
- nldcsc_elastic_rules/rules/cross-platform/defense_evasion_potential_http_downgrade_attack.toml +98 -0
- nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_local_file_inclusion_activity.toml +172 -0
- nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_remote_file_inclusion_activity.toml +133 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +250 -0
- nldcsc_elastic_rules/rules/{linux/persistence_nodejs_pre_or_post_install_script_execution.toml → cross-platform/execution_nodejs_pre_or_post_install_script_execution.toml} +40 -24
- nldcsc_elastic_rules/rules/cross-platform/execution_privileged_container_creation_with_host_reference.toml +146 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_register_github_actions_runner.toml +126 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_via_github_actions_runner.toml +130 -0
- nldcsc_elastic_rules/rules/cross-platform/execution_via_github_runner_with_runner_tracking_id_tampering_via_env_vars.toml +163 -0
- nldcsc_elastic_rules/rules/cross-platform/initial_access_execution_susp_react_serv_child.toml +130 -0
- nldcsc_elastic_rules/rules/cross-platform/initial_access_file_upload_followed_by_get_request.toml +145 -0
- nldcsc_elastic_rules/rules/cross-platform/multiple_alerts_elastic_defend_netsecurity_by_host.toml +4 -1
- nldcsc_elastic_rules/rules/cross-platform/persistence_credential_access_modify_auth_module_or_config.toml +3 -4
- nldcsc_elastic_rules/rules/cross-platform/persistence_web_server_potential_command_injection.toml +23 -25
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_discovery_or_fuzzing_activity.toml +13 -14
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_logs.toml +8 -5
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_spike_in_error_response_codes.toml +12 -12
- nldcsc_elastic_rules/rules/cross-platform/reconnaissance_web_server_unusual_user_agents.toml +37 -43
- nldcsc_elastic_rules/rules/integrations/aws/defense_evasion_rds_instance_restored.toml +137 -45
- nldcsc_elastic_rules/rules/integrations/aws/discovery_iam_principal_enumeration_via_update_assume_role_policy.toml +152 -0
- nldcsc_elastic_rules/rules/integrations/aws/discovery_multiple_discovery_api_calls_via_cli.toml +242 -0
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_rds_snapshot_export.toml +141 -33
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_rds_snapshot_shared_with_another_account.toml +108 -30
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_s3_bucket_policy_added_for_external_account_access.toml +2 -1
- nldcsc_elastic_rules/rules/integrations/aws/exfiltration_s3_bucket_replicated_to_external_account.toml +114 -27
- nldcsc_elastic_rules/rules/integrations/aws/impact_efs_filesystem_deleted.toml +174 -0
- nldcsc_elastic_rules/rules/integrations/aws/impact_kms_cmk_disabled_or_scheduled_for_deletion.toml +111 -33
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_instance_cluster_deletion.toml +129 -43
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_instance_cluster_deletion_protection_disabled.toml +89 -27
- nldcsc_elastic_rules/rules/integrations/aws/impact_rds_snapshot_deleted.toml +127 -37
- nldcsc_elastic_rules/rules/integrations/aws/impact_s3_object_encryption_with_external_key.toml +160 -43
- nldcsc_elastic_rules/rules/integrations/aws/initial_access_iam_session_token_used_from_multiple_addresses.toml +20 -10
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_error_message_spike.toml +35 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_error_code.toml +59 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_city.toml +19 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_country.toml +19 -1
- nldcsc_elastic_rules/rules/integrations/aws/ml_cloudtrail_rare_method_by_user.toml +58 -1
- nldcsc_elastic_rules/rules/integrations/aws/persistence_rds_db_instance_password_modified.toml +109 -35
- nldcsc_elastic_rules/rules/integrations/aws/persistence_rds_instance_made_public.toml +103 -22
- nldcsc_elastic_rules/rules/integrations/aws/persistence_redshift_instance_creation.toml +3 -3
- nldcsc_elastic_rules/rules/integrations/aws/privilege_escalation_sts_assume_root_from_rare_user_and_member_account.toml +126 -69
- nldcsc_elastic_rules/rules/integrations/azure/credential_access_azure_entra_susp_device_code_signin.toml +134 -0
- nldcsc_elastic_rules/rules/integrations/azure/credential_access_entra_id_excessive_account_lockouts.toml +2 -2
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_event_failures.toml +124 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_event_failures.toml +148 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_city.toml +109 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_country.toml +108 -0
- nldcsc_elastic_rules/rules/integrations/azure/ml_azure_rare_method_by_user.toml +147 -0
- nldcsc_elastic_rules/rules/integrations/fim/persistence_suspicious_file_modifications.toml +9 -1
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_error_message_spike.toml +95 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_error_code.toml +118 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_city.toml +79 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_country.toml +79 -0
- nldcsc_elastic_rules/rules/integrations/gcp/ml_gcp_rare_method_by_user.toml +117 -0
- nldcsc_elastic_rules/rules/integrations/github/initial_access_github_register_self_hosted_runner.toml +92 -0
- nldcsc_elastic_rules/rules/integrations/o365/collection_onedrive_excessive_file_downloads.toml +24 -14
- nldcsc_elastic_rules/rules/linux/defense_evasion_file_deletion_via_shred.toml +12 -5
- nldcsc_elastic_rules/rules/linux/execution_suspicious_pod_or_container_creation_command_execution.toml +150 -0
- nldcsc_elastic_rules/rules/linux/persistence_at_job_creation.toml +4 -4
- nldcsc_elastic_rules/rules/linux/persistence_pluggable_authentication_module_creation.toml +12 -7
- nldcsc_elastic_rules/rules/linux/persistence_pth_file_creation.toml +6 -1
- nldcsc_elastic_rules/rules/linux/persistence_site_and_user_customize_file_creation.toml +6 -1
- nldcsc_elastic_rules/rules/linux/persistence_web_server_unusual_command_execution.toml +155 -0
- nldcsc_elastic_rules/rules/ml/ml_high_count_events_for_a_host_name.toml +58 -1
- nldcsc_elastic_rules/rules/ml/ml_high_count_network_denies.toml +71 -1
- nldcsc_elastic_rules/rules/ml/ml_high_count_network_events.toml +53 -1
- nldcsc_elastic_rules/rules/ml/ml_linux_anomalous_network_activity.toml +56 -1
- nldcsc_elastic_rules/rules/ml/ml_linux_anomalous_network_port_activity.toml +40 -1
- nldcsc_elastic_rules/rules/ml/ml_low_count_events_for_a_host_name.toml +27 -1
- nldcsc_elastic_rules/rules/ml/ml_packetbeat_rare_server_domain.toml +63 -1
- nldcsc_elastic_rules/rules/ml/ml_rare_destination_country.toml +68 -1
- nldcsc_elastic_rules/rules/ml/ml_spike_in_traffic_to_a_country.toml +53 -1
- nldcsc_elastic_rules/rules/ml/ml_windows_anomalous_network_activity.toml +56 -1
- nldcsc_elastic_rules/rules/network/initial_access_react_server_components_rce_attempt.toml +123 -0
- nldcsc_elastic_rules/rules/promotions/external_alerts.toml +2 -2
- nldcsc_elastic_rules/rules/windows/command_and_control_common_webservices.toml +4 -3
- nldcsc_elastic_rules/rules/windows/credential_access_rare_webdav_destination.toml +3 -4
- nldcsc_elastic_rules/rules/windows/defense_evasion_masquerading_as_svchost.toml +11 -8
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation.toml +25 -2
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_backtick.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_backtick_var.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_char_arrays.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_concat_dynamic.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_high_number_proportion.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_iex_env_vars_reconstruction.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_iex_string_reconstruction.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_index_reversal.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_reverse_keyword.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_string_concat.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_string_format.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_posh_obfuscation_whitespace_special_proportion.toml +2 -3
- nldcsc_elastic_rules/rules/windows/defense_evasion_wsl_filesystem.toml +13 -10
- nldcsc_elastic_rules/rules/windows/execution_posh_hacktool_functions.toml +3 -2
- nldcsc_elastic_rules/rules/windows/execution_suspicious_powershell_imgload.toml +7 -2
- nldcsc_elastic_rules/rules/windows/execution_windows_powershell_susp_args.toml +9 -2
- nldcsc_elastic_rules/rules/windows/impact_mod_critical_os_files.toml +16 -6
- nldcsc_elastic_rules/rules/windows/lateral_movement_credential_access_kerberos_correlation.toml +7 -2
- nldcsc_elastic_rules/rules/windows/lateral_movement_scheduled_task_target.toml +2 -2
- nldcsc_elastic_rules/rules/windows/persistence_browser_extension_install.toml +19 -2
- nldcsc_elastic_rules/rules/windows/persistence_msi_installer_task_startup.toml +50 -13
- nldcsc_elastic_rules/rules/windows/persistence_via_application_shimming.toml +12 -2
- nldcsc_elastic_rules/rules/windows/privilege_escalation_tokenmanip_sedebugpriv_enabled.toml +24 -18
- nldcsc_elastic_rules/rules/windows/privilege_escalation_unusual_printspooler_childprocess.toml +14 -2
- nldcsc_elastic_rules/rules/windows/privilege_escalation_via_ppid_spoofing.toml +3 -2
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/METADATA +1 -1
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/RECORD +119 -87
- nldcsc_elastic_rules/rules/integrations/aws/credential_access_aws_iam_assume_role_brute_force.toml +0 -105
- nldcsc_elastic_rules/rules/integrations/aws/discovery_ec2_multi_region_describe_instances.toml +0 -135
- nldcsc_elastic_rules/rules/integrations/aws/discovery_ec2_multiple_discovery_api_calls_via_cli.toml +0 -155
- nldcsc_elastic_rules/rules/integrations/aws/impact_efs_filesystem_or_mount_deleted.toml +0 -95
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/WHEEL +0 -0
- {nldcsc_elastic_rules-0.0.8.dist-info → nldcsc_elastic_rules-0.0.16.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/12/04"
|
|
3
|
+
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "m365_defender"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/12/04"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
Detects when GenAI processes perform encoding or chunking (base64, gzip, tar, zip) followed by outbound network
|
|
11
|
+
activity. This sequence indicates data preparation for exfiltration. Attackers encode or compress sensitive data before
|
|
12
|
+
transmission to obfuscate contents and evade detection. Legitimate GenAI workflows rarely encode data before network
|
|
13
|
+
communications.
|
|
14
|
+
"""
|
|
15
|
+
from = "now-9m"
|
|
16
|
+
index = [
|
|
17
|
+
"logs-endpoint.events.process-*",
|
|
18
|
+
"logs-endpoint.events.network-*",
|
|
19
|
+
"logs-windows.sysmon_operational-*",
|
|
20
|
+
"winlogbeat-*",
|
|
21
|
+
"logs-m365_defender.event-*",
|
|
22
|
+
"logs-sentinel_one_cloud_funnel.*",
|
|
23
|
+
]
|
|
24
|
+
language = "eql"
|
|
25
|
+
license = "Elastic License v2"
|
|
26
|
+
name = "GenAI Process Performing Encoding/Chunking Prior to Network Activity"
|
|
27
|
+
note = """## Triage and analysis
|
|
28
|
+
|
|
29
|
+
### Investigating GenAI Process Performing Encoding/Chunking Prior to Network Activity
|
|
30
|
+
|
|
31
|
+
GenAI processes performing encoding or chunking operations followed by network activity is highly suspicious. This behavior indicates data preparation for exfiltration via GenAI prompts or agents, which is a strong indicator of malicious activity.
|
|
32
|
+
|
|
33
|
+
### Possible investigation steps
|
|
34
|
+
|
|
35
|
+
- Review the GenAI process that performed the encoding to identify which tool is running and verify if it's an expected/authorized tool.
|
|
36
|
+
- Examine the encoding/chunking command line arguments to understand what data is being processed.
|
|
37
|
+
- Review the network connection details to identify the destination and determine if it's expected.
|
|
38
|
+
- Investigate the user account associated with the GenAI process to determine if this activity is expected for that user.
|
|
39
|
+
- Review the data that was encoded to determine if it contains sensitive information.
|
|
40
|
+
- Determine whether the encoding was initiated by a GenAI agent or automation loop rather than a user action.
|
|
41
|
+
- Check whether the encoded data size or entropy suggests credential files, browser data, SSH keys, or cloud tokens.
|
|
42
|
+
- Validate that the GenAI tool is installed from a trusted source and has not been modified.
|
|
43
|
+
|
|
44
|
+
### False positive analysis
|
|
45
|
+
|
|
46
|
+
- Legitimate data processing workflows that use GenAI tools may trigger this rule if they encode data before transmission.
|
|
47
|
+
- Some local developer workflows may encode files before uploading training data or embeddings; confirm whether the host is a model-development workstation.
|
|
48
|
+
|
|
49
|
+
### Response and remediation
|
|
50
|
+
|
|
51
|
+
- Terminate the GenAI process and any spawned encoding/network processes to stop the malicious activity.
|
|
52
|
+
- Review and revoke any API keys, tokens, or credentials that may have been exposed or used by the GenAI tool.
|
|
53
|
+
- Investigate the encoded data and network destination to determine the scope of potential data exfiltration.
|
|
54
|
+
"""
|
|
55
|
+
references = [
|
|
56
|
+
"https://atlas.mitre.org/techniques/AML.T0086",
|
|
57
|
+
"https://glama.ai/blog/2025-11-11-the-lethal-trifecta-securing-model-context-protocol-against-data-flow-attacks",
|
|
58
|
+
"https://www.elastic.co/security-labs/elastic-advances-llm-security",
|
|
59
|
+
]
|
|
60
|
+
risk_score = 47
|
|
61
|
+
rule_id = "c3d4e5f6-a7b8-9012-cdef-123456789abc"
|
|
62
|
+
severity = "medium"
|
|
63
|
+
tags = [
|
|
64
|
+
"Domain: Endpoint",
|
|
65
|
+
"OS: Linux",
|
|
66
|
+
"OS: macOS",
|
|
67
|
+
"OS: Windows",
|
|
68
|
+
"Use Case: Threat Detection",
|
|
69
|
+
"Tactic: Exfiltration",
|
|
70
|
+
"Tactic: Defense Evasion",
|
|
71
|
+
"Data Source: Elastic Defend",
|
|
72
|
+
"Data Source: Sysmon",
|
|
73
|
+
"Data Source: Microsoft Defender for Endpoint",
|
|
74
|
+
"Data Source: SentinelOne",
|
|
75
|
+
"Resources: Investigation Guide",
|
|
76
|
+
"Domain: LLM",
|
|
77
|
+
"Mitre Atlas: T0086",
|
|
78
|
+
]
|
|
79
|
+
timestamp_override = "event.ingested"
|
|
80
|
+
type = "eql"
|
|
81
|
+
|
|
82
|
+
query = '''
|
|
83
|
+
sequence by process.entity_id with maxspan=30s
|
|
84
|
+
|
|
85
|
+
// Encoding/compression followed by network activity
|
|
86
|
+
[process where event.type == "start"
|
|
87
|
+
and event.type == "start"
|
|
88
|
+
|
|
89
|
+
// Encoding/chunking tools
|
|
90
|
+
and (
|
|
91
|
+
// Native encoding tools
|
|
92
|
+
process.name in ("base64", "gzip", "tar", "zip", "split", "7z", "7za", "7zr") or
|
|
93
|
+
|
|
94
|
+
// PowerShell encoding
|
|
95
|
+
(process.name in ("powershell.exe", "pwsh.exe") and
|
|
96
|
+
process.command_line like~ ("*Compress-Archive*", "*[Convert]::ToBase64String*")) or
|
|
97
|
+
|
|
98
|
+
// Python encoding
|
|
99
|
+
(process.name like~ "python*" and
|
|
100
|
+
process.command_line like~ ("*base64*", "*gzip*", "*zlib*", "*tarfile*", "*zipfile*")) or
|
|
101
|
+
|
|
102
|
+
// Node.js encoding
|
|
103
|
+
(process.name in ("node.exe", "node") and
|
|
104
|
+
process.command_line like~ ("*Buffer.from*", "*zlib*", "*gzip*") and
|
|
105
|
+
not process.command_line like~ ("*mcp*start*", "*mcp-server*", "*npm exec*mcp*"))
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
// GenAI parent process
|
|
109
|
+
and (
|
|
110
|
+
process.parent.name in (
|
|
111
|
+
"ollama.exe", "ollama", "Ollama",
|
|
112
|
+
"textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
|
|
113
|
+
"lmstudio.exe", "lmstudio", "LM Studio",
|
|
114
|
+
"claude.exe", "claude", "Claude",
|
|
115
|
+
"cursor.exe", "cursor", "Cursor", "Cursor Helper", "Cursor Helper (Plugin)",
|
|
116
|
+
"copilot.exe", "copilot", "Copilot",
|
|
117
|
+
"codex.exe", "codex",
|
|
118
|
+
"Jan", "jan.exe", "jan", "Jan Helper",
|
|
119
|
+
"gpt4all.exe", "gpt4all", "GPT4All",
|
|
120
|
+
"gemini-cli.exe", "gemini-cli",
|
|
121
|
+
"genaiscript.exe", "genaiscript",
|
|
122
|
+
"grok.exe", "grok",
|
|
123
|
+
"qwen.exe", "qwen",
|
|
124
|
+
"koboldcpp.exe", "koboldcpp", "KoboldCpp",
|
|
125
|
+
"llama-server", "llama-cli"
|
|
126
|
+
) or
|
|
127
|
+
|
|
128
|
+
// Node/Deno with GenAI frameworks
|
|
129
|
+
(process.parent.name in ("node.exe", "node", "deno.exe", "deno") and
|
|
130
|
+
process.parent.command_line like~ (
|
|
131
|
+
"*ollama*", "*mcp-server*", "*@modelcontextprotocol*", "*langchain*", "*autogpt*",
|
|
132
|
+
"*babyagi*", "*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*",
|
|
133
|
+
"*haystack*", "*openai*", "*anthropic*", "*cohere*", "*mistral*"
|
|
134
|
+
)) or
|
|
135
|
+
|
|
136
|
+
// Python with GenAI frameworks
|
|
137
|
+
(process.parent.name like~ "python*" and
|
|
138
|
+
process.parent.command_line like~ (
|
|
139
|
+
"*ollama*", "*mcp-server*", "*langchain*", "*autogpt*", "*babyagi*",
|
|
140
|
+
"*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*", "*haystack*",
|
|
141
|
+
"*openai*", "*anthropic*", "*cohere*", "*mistral*"
|
|
142
|
+
))
|
|
143
|
+
)
|
|
144
|
+
] by process.entity_id
|
|
145
|
+
|
|
146
|
+
// Outbound network connection (non-local)
|
|
147
|
+
[network where event.type == "start"
|
|
148
|
+
and event.action == "connection_attempted"
|
|
149
|
+
and destination.ip != null
|
|
150
|
+
and not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
|
|
151
|
+
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
|
|
152
|
+
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
|
|
153
|
+
"192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
|
|
154
|
+
"FF00::/8")
|
|
155
|
+
|
|
156
|
+
] by process.entity_id
|
|
157
|
+
'''
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
[[rule.threat]]
|
|
161
|
+
framework = "MITRE ATT&CK"
|
|
162
|
+
[[rule.threat.technique]]
|
|
163
|
+
id = "T1027"
|
|
164
|
+
name = "Obfuscated Files or Information"
|
|
165
|
+
reference = "https://attack.mitre.org/techniques/T1027/"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
[rule.threat.tactic]
|
|
169
|
+
id = "TA0005"
|
|
170
|
+
name = "Defense Evasion"
|
|
171
|
+
reference = "https://attack.mitre.org/tactics/TA0005/"
|
|
172
|
+
|
nldcsc_elastic_rules/rules/cross-platform/defense_evasion_potential_http_downgrade_attack.toml
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/11/27"
|
|
3
|
+
integration = ["nginx", "apache", "apache_tomcat"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
updated_date = "2025/12/08"
|
|
6
|
+
|
|
7
|
+
[rule]
|
|
8
|
+
author = ["Elastic"]
|
|
9
|
+
description = """
|
|
10
|
+
Through the new_terms rule type, this rule detects potential HTTP downgrade attacks by identifying
|
|
11
|
+
HTTP traffic that uses a different HTTP version than the one typically used in the environment. An
|
|
12
|
+
HTTP downgrade attack occurs when an attacker forces a connection via an older HTTP version,
|
|
13
|
+
resulting in potentially less secure communication. For example, an attacker might downgrade a
|
|
14
|
+
connection from HTTP/2 to HTTP/1.1 or HTTP/1.0 to exploit known vulnerabilities or weaknesses in
|
|
15
|
+
the older protocol versions.
|
|
16
|
+
"""
|
|
17
|
+
from = "now-9m"
|
|
18
|
+
index = [
|
|
19
|
+
"logs-nginx.access-*",
|
|
20
|
+
"logs-apache.access-*",
|
|
21
|
+
"logs-apache_tomcat.access-*",
|
|
22
|
+
]
|
|
23
|
+
language = "kuery"
|
|
24
|
+
license = "Elastic License v2"
|
|
25
|
+
name = "Potential HTTP Downgrade Attack"
|
|
26
|
+
note = """## Triage and analysis
|
|
27
|
+
|
|
28
|
+
> **Disclaimer**:
|
|
29
|
+
> 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.
|
|
30
|
+
|
|
31
|
+
### Investigating Potential HTTP Downgrade Attack
|
|
32
|
+
|
|
33
|
+
This detection surfaces HTTP traffic negotiating a protocol version that deviates from your baseline, a sign of downgrade attempts that strip protections and enable evasion or exploit paths in older behaviors. An attacker deliberately breaks HTTP/2 negotiation so the server falls back to HTTP/1.1, then probes with crafted headers and chunked bodies to attempt request smuggling or cache bypass against web services.
|
|
34
|
+
|
|
35
|
+
### Possible investigation steps
|
|
36
|
+
|
|
37
|
+
- Correlate with TLS termination or load balancer logs to verify ALPN or Upgrade negotiation (server advertising h2) and whether the same client/IP previously used h2 with the same SNI/Host, distinguishing forced downgrade from capability mismatch.
|
|
38
|
+
- Review the downgraded requests for exploitation indicators such as simultaneous Content-Length and Transfer-Encoding headers, duplicated or mixed-case headers, unusual methods (TRACE or PRI), or inconsistent chunked encoding suggesting smuggling attempts.
|
|
39
|
+
- Examine surrounding response patterns for increased 400/421/426/431/505, backend 5xx, connection resets, or latency spikes that coincide with these requests and indicate error-driven fallback or probing.
|
|
40
|
+
- Check for recent config changes or incidents on CDNs/WAFs/load balancers and web servers (e.g., http2 enablement, ALPN lists, h2/h2c settings) that could have disabled HTTP/2 and caused benign fallbacks.
|
|
41
|
+
- Cluster events by source IP/User-Agent/ASN and targeted host to identify campaign activity across services and pivot the sources through threat intelligence or reputation feeds.
|
|
42
|
+
|
|
43
|
+
### False positive analysis
|
|
44
|
+
|
|
45
|
+
- Recent Nginx/Apache/Tomcat configuration changes that disable HTTP/2/h2c or alter TLS/ALPN on specific virtual hosts can legitimately force clients to fall back to HTTP/1.1, surfacing as a downgrade event in access logs.
|
|
46
|
+
- Newly onboarded internal services or scripts that only support HTTP/1.0/1.1 and begin hitting an endpoint for the first time can introduce a first-seen older http.version relative to an HTTP/2 baseline without malicious intent.
|
|
47
|
+
|
|
48
|
+
### Response and remediation
|
|
49
|
+
|
|
50
|
+
- Immediately block or challenge source IPs/ASNs repeatedly forcing HTTP/1.1 to hosts that previously negotiated HTTP/2 via ALPN, and enable WAF rules to drop “Upgrade: h2c” attempts, requests with both Content-Length and Transfer-Encoding, or duplicated/mixed-case headers.
|
|
51
|
+
- Remove downgrade paths by requiring TLS+ALPN “h2” on 443 (e.g., Nginx listen 443 ssl http2; Apache Protocols h2 http/1.1), disabling cleartext h2c and HTTP/1.0 on public endpoints, and ensuring intermediaries do not strip ALPN or rewrite headers.
|
|
52
|
+
- Redeploy corrected configs and validate end-to-end HTTP/2 with curl --http2 and browser devtools, then confirm normal 2xx/3xx rates and elimination of 421/426/431/505 responses and backend 5xx spikes around previously downgraded traffic.
|
|
53
|
+
- Escalate to Incident Response if downgraded requests show smuggling patterns (simultaneous Content-Length and Transfer-Encoding, mixed-case duplicates, TRACE/PRI methods), hit sensitive paths (/admin, /login, /actuator), or trigger cache anomalies like cross-user content.
|
|
54
|
+
- Harden parsing and caching by normalizing headers at the edge, enforcing a single Content-Length, disabling TRACE, setting strict client_header_buffer_size and large_client_header_buffers, and configuring proxies/backends to reject conflicting CL/TE or ambiguous chunked bodies.
|
|
55
|
+
"""
|
|
56
|
+
risk_score = 21
|
|
57
|
+
rule_id = "9797d2c8-8ec9-48e6-a022-350cdfbf2d5e"
|
|
58
|
+
severity = "low"
|
|
59
|
+
tags = [
|
|
60
|
+
"Domain: Web",
|
|
61
|
+
"Use Case: Threat Detection",
|
|
62
|
+
"Tactic: Defense Evasion",
|
|
63
|
+
"Data Source: Nginx",
|
|
64
|
+
"Data Source: Apache",
|
|
65
|
+
"Data Source: Apache Tomcat",
|
|
66
|
+
"Resources: Investigation Guide",
|
|
67
|
+
]
|
|
68
|
+
timestamp_override = "event.ingested"
|
|
69
|
+
type = "new_terms"
|
|
70
|
+
query = '''
|
|
71
|
+
http.version:*
|
|
72
|
+
'''
|
|
73
|
+
|
|
74
|
+
[[rule.threat]]
|
|
75
|
+
framework = "MITRE ATT&CK"
|
|
76
|
+
|
|
77
|
+
[[rule.threat.technique]]
|
|
78
|
+
id = "T1562"
|
|
79
|
+
name = "Impair Defenses"
|
|
80
|
+
reference = "https://attack.mitre.org/techniques/T1562/"
|
|
81
|
+
|
|
82
|
+
[[rule.threat.technique.subtechnique]]
|
|
83
|
+
id = "T1562.010"
|
|
84
|
+
name = "Downgrade Attack"
|
|
85
|
+
reference = "https://attack.mitre.org/techniques/T1562/010/"
|
|
86
|
+
|
|
87
|
+
[rule.threat.tactic]
|
|
88
|
+
id = "TA0005"
|
|
89
|
+
name = "Defense Evasion"
|
|
90
|
+
reference = "https://attack.mitre.org/tactics/TA0005/"
|
|
91
|
+
|
|
92
|
+
[rule.new_terms]
|
|
93
|
+
field = "new_terms_fields"
|
|
94
|
+
value = ["http.version", "agent.id"]
|
|
95
|
+
|
|
96
|
+
[[rule.new_terms.history_window_start]]
|
|
97
|
+
field = "history_window_start"
|
|
98
|
+
value = "now-7d"
|
nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_local_file_inclusion_activity.toml
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/12/02"
|
|
3
|
+
integration = ["nginx", "apache", "apache_tomcat", "iis"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
min_stack_version = "9.2.0"
|
|
6
|
+
min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
|
|
7
|
+
updated_date = "2025/12/08"
|
|
8
|
+
|
|
9
|
+
[rule]
|
|
10
|
+
author = ["Elastic"]
|
|
11
|
+
description = """
|
|
12
|
+
This rule detects potential Local File Inclusion (LFI) activity on web servers by identifying HTTP GET requests that
|
|
13
|
+
attempt to access sensitive local files through directory traversal techniques or known file paths. Attackers may
|
|
14
|
+
exploit LFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
|
|
15
|
+
"""
|
|
16
|
+
from = "now-11m"
|
|
17
|
+
interval = "10m"
|
|
18
|
+
language = "esql"
|
|
19
|
+
license = "Elastic License v2"
|
|
20
|
+
name = "Web Server Local File Inclusion Activity"
|
|
21
|
+
note = """ ## Triage and analysis
|
|
22
|
+
|
|
23
|
+
> **Disclaimer**:
|
|
24
|
+
> 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.
|
|
25
|
+
|
|
26
|
+
### Investigating Web Server Local File Inclusion Activity
|
|
27
|
+
|
|
28
|
+
This rule surfaces successful GET requests containing directory traversal or direct access to sensitive paths, signaling Local File Inclusion exploitation that can expose credentials, configuration, and process context and enable further compromise. A common attacker pattern is abusing a vulnerable parameter to fetch ../../../../etc/passwd, then pivoting to /proc/self/environ to harvest secrets and identify execution context for subsequent steps.
|
|
29
|
+
|
|
30
|
+
### Possible investigation steps
|
|
31
|
+
|
|
32
|
+
- Retrieve contiguous access logs around the alert to rebuild each request/response pair (URI, parameters, user agent, referer, cookies, X-Forwarded-For) and identify which parameter reflected traversal or wrapper usage and whether the response likely contained file contents.
|
|
33
|
+
- Compare response sizes and content-types for the suspicious requests to normal pages and look for signatures such as "root:x:" lines, INI/XML keys, or base64 blobs that indicate disclosure of /etc/passwd, web.config/applicationhost.config, or other sensitive files.
|
|
34
|
+
- Review web server and application error logs at the same timestamps for include/open stream warnings, open_basedir or allow_url_fopen messages, and stack traces to confirm the code path handling the input and any mitigations in place.
|
|
35
|
+
- Pivot on the same source and timeframe to find adjacent probes (php://filter, data://, expect://, zip://, phar://, /proc/self/environ, traversal into webroots/configs) and any follow-on POSTs to upload endpoints or new script paths, signaling progression toward RCE or webshell placement.
|
|
36
|
+
- Determine whether the traffic was authenticated and whether it traversed a WAF or reverse proxy by correlating cookies or session IDs and client IPs with proxy/WAF logs, noting any blocks, rule matches, or bypasses to bound scope and urgency.
|
|
37
|
+
|
|
38
|
+
### False positive analysis
|
|
39
|
+
|
|
40
|
+
- A site search or documentation endpoint echoing user-supplied text can include strings like ../../../../etc/passwd, windows/win.ini, or php://filter in the query string and return a normal 200 OK results page rather than performing a file include.
|
|
41
|
+
- An authenticated admin feature (such as a log viewer or file browser) may legitimately accept path= or file= parameters referencing local paths like /var/log/nginx or /inetpub/logs/logfiles and return 200 when serving allowed files, producing URLs that match the rule without exploitation.
|
|
42
|
+
|
|
43
|
+
### Response and remediation
|
|
44
|
+
|
|
45
|
+
- Immediately block the source IP at the reverse proxy/WAF and deploy deny rules for GET requests using ../../ or ..\\..\\ traversal or wrappers (php://, expect://, data://) that fetch /etc/passwd, /proc/self/environ, wp-config.php, web.config, or applicationhost.config.
|
|
46
|
+
- Configure the web server to return 403 for paths resolving to /proc, /etc, /var/log, /inetpub, applicationhost.config, and web.config and to reject wrapper schemes like php:// and expect://, then reload Nginx/Apache/IIS to apply.
|
|
47
|
+
- Fix the vulnerable include logic by canonicalizing input with realpath, rejecting any .. segments or absolute paths, enforcing a whitelist of allowed files, and in PHP disabling allow_url_include/allow_url_fopen and setting open_basedir to a safe directory.
|
|
48
|
+
- Rotate exposed secrets by changing database and API credentials from wp-config.php, connection strings and machine keys from web.config/applicationhost.config, and any tokens in /proc/self/environ, then invalidate active sessions and cache.
|
|
49
|
+
- Escalate to incident leadership and quarantine the host if response bodies contain credential patterns (e.g., "root:x:" from /etc/passwd or XML keys from web.config), if /etc/shadow or windows/system32/config/SAM was requested, or if follow-on POSTs or new .php/.aspx files appear in the webroot.
|
|
50
|
+
- Recover by verifying integrity of /var/www and /inetpub/wwwroot, scanning for webshells and unexpected includes, redeploying a known-good build or container image if tampering is found, and adding WAF normalization to double-decode URLs and 403 traversal attempts.
|
|
51
|
+
"""
|
|
52
|
+
risk_score = 21
|
|
53
|
+
rule_id = "90e4ceab-79a5-4f8e-879b-513cac7fcad9"
|
|
54
|
+
severity = "low"
|
|
55
|
+
tags = [
|
|
56
|
+
"Domain: Web",
|
|
57
|
+
"Use Case: Threat Detection",
|
|
58
|
+
"Tactic: Discovery",
|
|
59
|
+
"Data Source: Nginx",
|
|
60
|
+
"Data Source: Apache",
|
|
61
|
+
"Data Source: Apache Tomcat",
|
|
62
|
+
"Data Source: IIS",
|
|
63
|
+
"Resources: Investigation Guide",
|
|
64
|
+
]
|
|
65
|
+
timestamp_override = "event.ingested"
|
|
66
|
+
type = "esql"
|
|
67
|
+
query = '''
|
|
68
|
+
from
|
|
69
|
+
logs-nginx.access-*,
|
|
70
|
+
logs-apache.access-*,
|
|
71
|
+
logs-apache_tomcat.access-*,
|
|
72
|
+
logs-iis.access-*
|
|
73
|
+
| where
|
|
74
|
+
http.request.method == "GET" and
|
|
75
|
+
http.response.status_code == 200 and
|
|
76
|
+
url.original like "*=*"
|
|
77
|
+
|
|
78
|
+
| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
|
|
79
|
+
|
|
80
|
+
| where
|
|
81
|
+
/* 1) Relative traversal */
|
|
82
|
+
Esql.url_original_url_decoded_to_lower like "*../../../../*" or // Unix-style traversal
|
|
83
|
+
Esql.url_original_url_decoded_to_lower like "*..\\\\..\\\\..\\\\..*" or // Windows-style traversal
|
|
84
|
+
// Potential security check bypassing (enforcing multiple dots and shortening the pattern)
|
|
85
|
+
Esql.url_original_url_decoded_to_lower like "*..././*" or
|
|
86
|
+
Esql.url_original_url_decoded_to_lower like "*...\\*" or
|
|
87
|
+
Esql.url_original_url_decoded_to_lower like "*....\\*" or
|
|
88
|
+
|
|
89
|
+
/* 2) Linux system identity / basic info */
|
|
90
|
+
Esql.url_original_url_decoded_to_lower like "*etc/passwd*" or
|
|
91
|
+
Esql.url_original_url_decoded_to_lower like "*etc/shadow*" or
|
|
92
|
+
Esql.url_original_url_decoded_to_lower like "*etc/hosts*" or
|
|
93
|
+
Esql.url_original_url_decoded_to_lower like "*etc/os-release*" or
|
|
94
|
+
Esql.url_original_url_decoded_to_lower like "*etc/issue*" or
|
|
95
|
+
|
|
96
|
+
/* 3) Linux /proc enumeration */
|
|
97
|
+
Esql.url_original_url_decoded_to_lower like "*proc/self/environ*" or
|
|
98
|
+
Esql.url_original_url_decoded_to_lower like "*proc/self/cmdline*" or
|
|
99
|
+
Esql.url_original_url_decoded_to_lower like "*proc/self/fd*" or
|
|
100
|
+
Esql.url_original_url_decoded_to_lower like "*proc/self/exe*" or
|
|
101
|
+
|
|
102
|
+
/* 4) Linux webroots, configs & logs */
|
|
103
|
+
Esql.url_original_url_decoded_to_lower like "*var/www*" or // generic webroot
|
|
104
|
+
Esql.url_original_url_decoded_to_lower like "*wp-config.php*" or // classic WP config
|
|
105
|
+
Esql.url_original_url_decoded_to_lower like "*etc/apache2*" or
|
|
106
|
+
Esql.url_original_url_decoded_to_lower like "*etc/httpd*" or
|
|
107
|
+
Esql.url_original_url_decoded_to_lower like "*etc/nginx*" or
|
|
108
|
+
Esql.url_original_url_decoded_to_lower like "*var/log/apache2*" or
|
|
109
|
+
Esql.url_original_url_decoded_to_lower like "*var/log/httpd*" or
|
|
110
|
+
Esql.url_original_url_decoded_to_lower like "*var/log/nginx*" or
|
|
111
|
+
|
|
112
|
+
/* 5) Windows core files / identity */
|
|
113
|
+
Esql.url_original_url_decoded_to_lower like "*windows/panther/*unattend*" or
|
|
114
|
+
Esql.url_original_url_decoded_to_lower like "*windows/debug/netsetup.log*" or
|
|
115
|
+
Esql.url_original_url_decoded_to_lower like "*windows/win.ini*" or
|
|
116
|
+
Esql.url_original_url_decoded_to_lower like "*windows/system32/drivers/etc/hosts*" or
|
|
117
|
+
Esql.url_original_url_decoded_to_lower like "*boot.ini*" or
|
|
118
|
+
Esql.url_original_url_decoded_to_lower like "*windows/system32/config/*" or
|
|
119
|
+
Esql.url_original_url_decoded_to_lower like "*windows/repair/sam*" or
|
|
120
|
+
Esql.url_original_url_decoded_to_lower like "*windows/system32/license.rtf*" or
|
|
121
|
+
|
|
122
|
+
/* 6) Windows IIS / .NET configs, webroots & logs */
|
|
123
|
+
Esql.url_original_url_decoded_to_lower like "*/inetpub/wwwroot*" or
|
|
124
|
+
Esql.url_original_url_decoded_to_lower like "*/inetpub/logs/logfiles*" or
|
|
125
|
+
Esql.url_original_url_decoded_to_lower like "*applicationhost.config*" or
|
|
126
|
+
Esql.url_original_url_decoded_to_lower like "*/microsoft.net/framework64/*/config/web.config*" or
|
|
127
|
+
Esql.url_original_url_decoded_to_lower like "*windows/system32/inetsrv/*" or
|
|
128
|
+
|
|
129
|
+
/* 7) PHP & protocol wrappers */
|
|
130
|
+
Esql.url_original_url_decoded_to_lower like "*php://*" or
|
|
131
|
+
Esql.url_original_url_decoded_to_lower like "*zip://*" or
|
|
132
|
+
Esql.url_original_url_decoded_to_lower like "*phar://*" or
|
|
133
|
+
Esql.url_original_url_decoded_to_lower like "*expect://*" or
|
|
134
|
+
Esql.url_original_url_decoded_to_lower like "*file://*" or
|
|
135
|
+
Esql.url_original_url_decoded_to_lower like "*data://text/plain;base64*"
|
|
136
|
+
|
|
137
|
+
| keep
|
|
138
|
+
@timestamp,
|
|
139
|
+
Esql.url_original_url_decoded_to_lower,
|
|
140
|
+
source.ip,
|
|
141
|
+
agent.id,
|
|
142
|
+
host.name,
|
|
143
|
+
http.request.method,
|
|
144
|
+
http.response.status_code,
|
|
145
|
+
event.dataset,
|
|
146
|
+
data_stream.namespace
|
|
147
|
+
|
|
148
|
+
| stats
|
|
149
|
+
Esql.event_count = count(),
|
|
150
|
+
Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
|
|
151
|
+
Esql.host_name_values = values(host.name),
|
|
152
|
+
Esql.agent_id_values = values(agent.id),
|
|
153
|
+
Esql.http_request_method_values = values(http.request.method),
|
|
154
|
+
Esql.http_response_status_code_values = values(http.response.status_code),
|
|
155
|
+
Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
|
|
156
|
+
Esql.event_dataset_values = values(event.dataset),
|
|
157
|
+
Esql.data_stream_namespace_values = values(data_stream.namespace)
|
|
158
|
+
by source.ip
|
|
159
|
+
'''
|
|
160
|
+
|
|
161
|
+
[[rule.threat]]
|
|
162
|
+
framework = "MITRE ATT&CK"
|
|
163
|
+
|
|
164
|
+
[[rule.threat.technique]]
|
|
165
|
+
id = "T1083"
|
|
166
|
+
name = "File and Directory Discovery"
|
|
167
|
+
reference = "https://attack.mitre.org/techniques/T1083/"
|
|
168
|
+
|
|
169
|
+
[rule.threat.tactic]
|
|
170
|
+
id = "TA0007"
|
|
171
|
+
name = "Discovery"
|
|
172
|
+
reference = "https://attack.mitre.org/tactics/TA0007/"
|
nldcsc_elastic_rules/rules/cross-platform/discovery_web_server_remote_file_inclusion_activity.toml
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
creation_date = "2025/12/02"
|
|
3
|
+
integration = ["nginx", "apache", "apache_tomcat", "iis"]
|
|
4
|
+
maturity = "production"
|
|
5
|
+
min_stack_version = "9.2.0"
|
|
6
|
+
min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
|
|
7
|
+
updated_date = "2025/12/08"
|
|
8
|
+
|
|
9
|
+
[rule]
|
|
10
|
+
author = ["Elastic"]
|
|
11
|
+
description = """
|
|
12
|
+
This rule detects potential Remote File Inclusion (RFI) activity on web servers by identifying HTTP GET requests that
|
|
13
|
+
attempt to access sensitive remote files through directory traversal techniques or known file paths. Attackers may
|
|
14
|
+
exploit RFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
|
|
15
|
+
"""
|
|
16
|
+
from = "now-11m"
|
|
17
|
+
interval = "10m"
|
|
18
|
+
language = "esql"
|
|
19
|
+
license = "Elastic License v2"
|
|
20
|
+
name = "Web Server Potential Remote File Inclusion Activity"
|
|
21
|
+
note = """## Triage and analysis
|
|
22
|
+
|
|
23
|
+
> **Disclaimer**:
|
|
24
|
+
> 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.
|
|
25
|
+
|
|
26
|
+
### Investigating Web Server Potential Remote File Inclusion Activity
|
|
27
|
+
|
|
28
|
+
This rule identifies successful GET requests that pass a remote URL or raw IP in a parameter, signaling Remote File Inclusion attempts that coerce the app to fetch external content or reveal local files. RFI matters because it enables discovery, leaks sensitive data, and can bootstrap code retrieval for persistence or command-and-control. Example behavior: probing an include endpoint with /index.php?page=http://203.0.113.10/drop.txt to verify remote fetch and execution via a vulnerable loader.
|
|
29
|
+
|
|
30
|
+
### Possible investigation steps
|
|
31
|
+
|
|
32
|
+
- Decode the full request URL and parameters, identify the endpoint and parameter names, and confirm with application owners whether passing remote URLs is expected behavior for that route.
|
|
33
|
+
- Correlate the event time with outbound connections from the web server to the referenced domain or IP using egress firewall, proxy, DNS, or NetFlow logs to verify whether a fetch occurred.
|
|
34
|
+
- Review adjacent web access entries from the same source IP and user agent to detect scanning behavior, varied include parameters, wrapper strings (php://, data://, file://), or local file probes that indicate exploitation attempts.
|
|
35
|
+
- Check the referenced remote domain or IP with threat intelligence, and if needed, safely retrieve it in an isolated environment to examine content, redirects, and headers for droppers or callbacks.
|
|
36
|
+
- Look for post-inclusion artifacts by checking webroot and temp directories for newly created or modified files, suspicious script writes, and unusual access patterns, and inspect server or application configuration for risky URL include settings.
|
|
37
|
+
|
|
38
|
+
### False positive analysis
|
|
39
|
+
|
|
40
|
+
- Applications that legitimately accept full URLs in query parameters for link previews, content proxies, image fetching, or feed importers (e.g., url= or src=) will return 200 and match *=http(s)://*, appearing as RFI despite expected behavior.
|
|
41
|
+
- Administrative or diagnostic endpoints that allow users to supply IP addresses or URI schemes (ftp://, smb://, file://) to test connectivity or preview resources (e.g., target=192.168.1.10) can return 200 and trigger this rule even though no inclusion vulnerability is present.
|
|
42
|
+
|
|
43
|
+
### Response and remediation
|
|
44
|
+
|
|
45
|
+
- Immediately block offending source IPs and request patterns at the WAF/reverse proxy (e.g., GETs where page=, url=, or src= contains http://, https://, ftp://, smb://, or file://) and temporarily disable the affected include/loader endpoints until fixed.
|
|
46
|
+
- Restrict outbound connections from the web server to the domains and IPs referenced in the requests and quarantine the host if 200 OK responses align with remote downloads or wrapper usage such as php://, data://, file://.
|
|
47
|
+
- Collect forensic images, then remove newly created or modified scripts in webroot and temp directories (e.g., /var/www, uploads, /tmp), delete unauthorized .htaccess/web.config entries, clear caches, and terminate suspicious processes running under the web server account.
|
|
48
|
+
- Redeploy the application from a known-good build, restore clean configuration files, rotate credentials exposed by local file probes (e.g., config.php, .env), invalidate sessions, and verify functionality before returning the service to production.
|
|
49
|
+
- Harden by disabling risky features and enforcing strict input controls: set PHP allow_url_include=Off and allow_url_fopen=Off, apply open_basedir restrictions, implement scheme/domain allowlists for any include/load functionality, and sanitize and normalize user-supplied parameters.
|
|
50
|
+
- Escalate to incident response and preserve disk and memory images if remote content was fetched and executed, a webshell or unknown script is found in the webroot, or the same actor generates successful 200 RFI-style requests across multiple hosts.
|
|
51
|
+
- Enhance monitoring for RFI attempts by tuning WAF rules to alert on suspicious include parameters, enabling detailed web server logging, and setting up alerts for anomalous outbound connections from web servers.
|
|
52
|
+
"""
|
|
53
|
+
risk_score = 21
|
|
54
|
+
rule_id = "45d099b4-a12e-4913-951c-0129f73efb41"
|
|
55
|
+
severity = "low"
|
|
56
|
+
tags = [
|
|
57
|
+
"Domain: Web",
|
|
58
|
+
"Use Case: Threat Detection",
|
|
59
|
+
"Tactic: Discovery",
|
|
60
|
+
"Tactic: Command and Control",
|
|
61
|
+
"Data Source: Nginx",
|
|
62
|
+
"Data Source: Apache",
|
|
63
|
+
"Data Source: Apache Tomcat",
|
|
64
|
+
"Data Source: IIS",
|
|
65
|
+
"Resources: Investigation Guide",
|
|
66
|
+
]
|
|
67
|
+
timestamp_override = "event.ingested"
|
|
68
|
+
type = "esql"
|
|
69
|
+
query = '''
|
|
70
|
+
from
|
|
71
|
+
logs-nginx.access-*,
|
|
72
|
+
logs-apache.access-*,
|
|
73
|
+
logs-apache_tomcat.access-*,
|
|
74
|
+
logs-iis.access-*
|
|
75
|
+
| where
|
|
76
|
+
http.request.method == "GET" and
|
|
77
|
+
http.response.status_code == 200 and
|
|
78
|
+
url.original like "*=*"
|
|
79
|
+
|
|
80
|
+
| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
|
|
81
|
+
|
|
82
|
+
| where
|
|
83
|
+
Esql.url_original_url_decoded_to_lower like "*=http://*" or
|
|
84
|
+
Esql.url_original_url_decoded_to_lower like "*=https://*" or
|
|
85
|
+
Esql.url_original_url_decoded_to_lower like "*=ftp://*" or
|
|
86
|
+
Esql.url_original_url_decoded_to_lower like "*=smb://*" or
|
|
87
|
+
Esql.url_original_url_decoded_to_lower like "*=file://*" or
|
|
88
|
+
Esql.url_original_url_decoded_to_lower rlike """.*=.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.*"""
|
|
89
|
+
|
|
90
|
+
| keep
|
|
91
|
+
@timestamp,
|
|
92
|
+
Esql.url_original_url_decoded_to_lower,
|
|
93
|
+
source.ip,
|
|
94
|
+
agent.id,
|
|
95
|
+
host.name,
|
|
96
|
+
http.request.method,
|
|
97
|
+
http.response.status_code,
|
|
98
|
+
event.dataset,
|
|
99
|
+
data_stream.namespace
|
|
100
|
+
|
|
101
|
+
| stats
|
|
102
|
+
Esql.event_count = count(),
|
|
103
|
+
Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
|
|
104
|
+
Esql.host_name_values = values(host.name),
|
|
105
|
+
Esql.agent_id_values = values(agent.id),
|
|
106
|
+
Esql.http_request_method_values = values(http.request.method),
|
|
107
|
+
Esql.http_response_status_code_values = values(http.response.status_code),
|
|
108
|
+
Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
|
|
109
|
+
Esql.event_dataset_values = values(event.dataset),
|
|
110
|
+
Esql.data_stream_namespace_values = values(data_stream.namespace)
|
|
111
|
+
by source.ip
|
|
112
|
+
'''
|
|
113
|
+
|
|
114
|
+
[[rule.threat]]
|
|
115
|
+
framework = "MITRE ATT&CK"
|
|
116
|
+
|
|
117
|
+
[[rule.threat.technique]]
|
|
118
|
+
id = "T1083"
|
|
119
|
+
name = "File and Directory Discovery"
|
|
120
|
+
reference = "https://attack.mitre.org/techniques/T1083/"
|
|
121
|
+
|
|
122
|
+
[rule.threat.tactic]
|
|
123
|
+
id = "TA0007"
|
|
124
|
+
name = "Discovery"
|
|
125
|
+
reference = "https://attack.mitre.org/tactics/TA0007/"
|
|
126
|
+
|
|
127
|
+
[[rule.threat]]
|
|
128
|
+
framework = "MITRE ATT&CK"
|
|
129
|
+
|
|
130
|
+
[rule.threat.tactic]
|
|
131
|
+
id = "TA0011"
|
|
132
|
+
name = "Command and Control"
|
|
133
|
+
reference = "https://attack.mitre.org/tactics/TA0011/"
|