From 3726611b93f51030466b6c8db8bc026dde4b60c4 Mon Sep 17 00:00:00 2001 From: Samirbous <64742097+Samirbous@users.noreply.github.com> Date: Fri, 12 Dec 2025 14:28:12 +0000 Subject: [PATCH] [Tuning] Top Noisy Rules (#5449) * [Tuning] Windows BruteForce Rules Tuning #1 Multiple Logon Failure from the same Source Address: converted to ES|QL and raised the threshold to 100 failed auths, alert quality should be better since it aggregates all failed auths info into one alert vs multiple EQL matches. (expected reduction more than 50%) #2 Privileged Account Brute Force - coverted to ESQL and set the threshold to 50 in a minute. this should drop noise volume by more than 50%. * ++ * Update execution_shell_evasion_linux_binary.toml * Update execution_shell_evasion_linux_binary.toml * Update defense_evasion_indirect_exec_forfiles.toml * Update lateral_movement_remote_file_copy_hidden_share.toml * Update lateral_movement_remote_file_copy_hidden_share.toml * Update persistence_service_windows_service_winlog.toml * Update credential_access_lsass_openprocess_api.toml * Update persistence_suspicious_scheduled_task_runtime.toml * Update impact_hosts_file_modified.toml * Update defense_evasion_process_termination_followed_by_deletion.toml * Update rules/windows/credential_access_lsass_openprocess_api.toml * Update rules/windows/credential_access_bruteforce_admin_account.toml Co-authored-by: Ruben Groenewoud <78494512+Aegrah@users.noreply.github.com> * Update rules/windows/credential_access_lsass_openprocess_api.toml Co-authored-by: Ruben Groenewoud <78494512+Aegrah@users.noreply.github.com> * Update rules/windows/credential_access_bruteforce_multiple_logon_failure_same_srcip.toml Co-authored-by: Ruben Groenewoud <78494512+Aegrah@users.noreply.github.com> * Update credential_access_lsass_openprocess_api.toml * Update impact_hosts_file_modified.toml * Update credential_access_dollar_account_relay.toml * Update credential_access_new_terms_secretsmanager_getsecretvalue.toml --------- Co-authored-by: Ruben Groenewoud <78494512+Aegrah@users.noreply.github.com> --- .../impact_hosts_file_modified.toml | 26 +++-- ...w_terms_secretsmanager_getsecretvalue.toml | 4 +- .../execution_shell_evasion_linux_binary.toml | 13 ++- ...ntial_access_bruteforce_admin_account.toml | 33 ++++-- ...rce_multiple_logon_failure_same_srcip.toml | 40 +++---- ...redential_access_dollar_account_relay.toml | 24 +++-- ...edential_access_lsass_openprocess_api.toml | 100 ++++++------------ ...efense_evasion_indirect_exec_forfiles.toml | 7 +- ...cess_termination_followed_by_deletion.toml | 6 +- ...ovement_remote_file_copy_hidden_share.toml | 8 +- ...stence_service_windows_service_winlog.toml | 25 +++-- ...nce_suspicious_scheduled_task_runtime.toml | 12 ++- 12 files changed, 153 insertions(+), 145 deletions(-) diff --git a/rules/cross-platform/impact_hosts_file_modified.toml b/rules/cross-platform/impact_hosts_file_modified.toml index ed579049f..7dee2bad9 100644 --- a/rules/cross-platform/impact_hosts_file_modified.toml +++ b/rules/cross-platform/impact_hosts_file_modified.toml @@ -2,7 +2,7 @@ creation_date = "2020/07/07" integration = ["endpoint", "windows"] maturity = "production" -updated_date = "2025/03/20" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -78,14 +78,27 @@ timestamp_override = "event.ingested" type = "eql" query = ''' -any where +any where process.executable != null and /* file events for creation; file change events are not captured by some of the included sources for linux and so may miss this, which is the purpose of the process + command line args logic below */ ( - event.category == "file" and event.type in ("change", "creation") and + event.category == "file" and event.type in ("change", "creation") and event.action != "rename" and file.path : ("/private/etc/hosts", "/etc/hosts", "?:\\Windows\\System32\\drivers\\etc\\hosts") and - not process.name in ("dockerd", "rootlesskit", "podman", "crio") + not process.name in ("dockerd", "rootlesskit", "podman", "crio") and + not process.executable : ("C:\\Program Files\\Fortinet\\FortiClient\\FCDBLog.exe", + "C:\\Program Files\\Seqrite\\Seqrite\\SCANNER.EXE", + "C:\\Windows\\Temp\\*.ins\\inst.exe", + "C:\\Windows\\System32\\svchost.exe", + "C:\\Program Files\\NordVPN\\nordvpn-service.exe", + "C:\\Program Files\\Tailscale\\tailscaled.exe", + "C:\\Program Files\\Docker\\Docker\\com.docker.service", + "C:\\Program Files\\Quick Heal\\Quick Heal AntiVirus Pro\\scanner.exe", + "C:\\Program Files (x86)\\Quick Heal AntiVirus Pro\\SCANNER.EXE", + "C:\\Program Files\\Quick Heal\\Quick Heal Internet Security\\scanner.exe", + "C:\\Program Files (x86)\\Cisco\\Cisco AnyConnect Secure Mobility Client\\vpnagent.exe", + "/opt/IBM/InformationServer/Server/DSEngine/bin/uvsh", + "/usr/local/demisto/server") ) or @@ -93,8 +106,9 @@ any where ( event.category == "process" and event.type in ("start") and process.name in ("nano", "vim", "vi", "emacs", "echo", "sed") and - process.args : ("/etc/hosts") and - not process.parent.name in ("dhclient-script", "google_set_hostname") + (process.args : ("/etc/hosts") or (process.working_directory == "/etc" and process.args == "hosts")) and + not process.parent.name in ("dhclient-script", "google_set_hostname") and + not process.command_line == "sed -i /Added by Google/d /etc/hosts" ) ''' diff --git a/rules/integrations/aws/credential_access_new_terms_secretsmanager_getsecretvalue.toml b/rules/integrations/aws/credential_access_new_terms_secretsmanager_getsecretvalue.toml index 7b71b0a4b..b3817493b 100644 --- a/rules/integrations/aws/credential_access_new_terms_secretsmanager_getsecretvalue.toml +++ b/rules/integrations/aws/credential_access_new_terms_secretsmanager_getsecretvalue.toml @@ -2,7 +2,7 @@ creation_date = "2020/07/06" integration = ["aws"] maturity = "production" -updated_date = "2025/08/18" +updated_date = "2025/12/12" [rule] author = ["Nick Jones", "Elastic"] @@ -97,7 +97,7 @@ type = "new_terms" query = ''' event.dataset:aws.cloudtrail and event.provider:secretsmanager.amazonaws.com and event.action: (GetSecretValue or BatchGetSecretValue) and event.outcome:success and - not user_agent.name: ("Chrome" or "Firefox" or "Safari" or "Edge" or "Brave" or "Opera") + not user_agent.name: ("Chrome" or "Firefox" or "Safari" or "Edge" or "Brave" or "Opera" or "Boto3") ''' [rule.investigation_fields] diff --git a/rules/linux/execution_shell_evasion_linux_binary.toml b/rules/linux/execution_shell_evasion_linux_binary.toml index 7dfe90cd6..a1fd996d2 100644 --- a/rules/linux/execution_shell_evasion_linux_binary.toml +++ b/rules/linux/execution_shell_evasion_linux_binary.toml @@ -2,7 +2,7 @@ creation_date = "2022/05/06" integration = ["endpoint"] maturity = "production" -updated_date = "2025/02/04" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -139,20 +139,18 @@ timestamp_override = "event.ingested" type = "eql" query = ''' -process where host.os.type == "linux" and event.type == "start" and +process where host.os.type == "linux" and event.type == "start" and process.executable != null and ( /* launching shell from capsh */ - (process.name == "capsh" and process.args == "--") or + (process.name == "capsh" and process.args == "--" and not process.parent.executable == "/usr/bin/log4j-cve-2021-44228-hotpatch") or /* launching shells from unusual parents or parent+arg combos */ (process.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and ( (process.parent.name : "*awk" and process.parent.args : "BEGIN {system(*)}") or - (process.parent.name == "git" and process.parent.args : ("*PAGER*", "!*sh", "exec *sh") or - process.args : ("*PAGER*", "!*sh", "exec *sh") and not process.name == "ssh" ) or + (process.parent.name == "git" and process.parent.args : ("!*sh", "exec *sh") and not process.name == "ssh" ) or (process.parent.name : ("byebug", "ftp", "strace", "zip", "tar") and ( process.parent.args : "BEGIN {system(*)}" or - (process.parent.args : ("*PAGER*", "!*sh", "exec *sh") or process.args : ("*PAGER*", "!*sh", "exec *sh")) or ( (process.parent.args : "exec=*sh" or (process.parent.args : "-I" and process.parent.args : "*sh")) or (process.args : "exec=*sh" or (process.args : "-I" and process.args : "*sh")) @@ -182,7 +180,8 @@ process where host.os.type == "linux" and event.type == "start" and )) or (process.name == "busybox" and event.action == "exec" and process.args_count == 2 and process.args : "*sh" and not process.executable : "/var/lib/docker/overlay2/*/merged/bin/busybox" and not (process.parent.args == "init" and - process.parent.args == "runc") and not process.parent.args in ("ls-remote", "push", "fetch") and not process.parent.name == "mkinitramfs") or + process.parent.args == "runc") and not process.parent.args in ("ls-remote", "push", "fetch") and not process.parent.name == "mkinitramfs" and + not process.parent.executable == "/bin/busybox") or (process.name == "env" and process.args_count == 2 and process.args : "*sh") or (process.parent.name in ("vi", "vim") and process.parent.args == "-c" and process.parent.args : ":!*sh") or (process.parent.name in ("c89", "c99", "gcc") and process.parent.args : "*sh,-s" and process.parent.args == "-wrapper") or diff --git a/rules/windows/credential_access_bruteforce_admin_account.toml b/rules/windows/credential_access_bruteforce_admin_account.toml index 18693d111..de820a850 100644 --- a/rules/windows/credential_access_bruteforce_admin_account.toml +++ b/rules/windows/credential_access_bruteforce_admin_account.toml @@ -2,7 +2,7 @@ creation_date = "2020/08/29" integration = ["system", "windows"] maturity = "production" -updated_date = "2025/11/14" +updated_date = "2025/12/11" [transform] [[transform.osquery]] @@ -38,8 +38,7 @@ short time interval. Adversaries will often brute force login attempts across mu password, in an attempt to gain access to accounts. """ from = "now-9m" -index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"] -language = "eql" +language = "esql" license = "Elastic License v2" name = "Privileged Account Brute Force" note = """## Triage and analysis @@ -103,16 +102,28 @@ tags = [ "Resources: Investigation Guide", "Data Source: Windows Security Event Logs", ] -type = "eql" +type = "esql" query = ''' -sequence by winlog.computer_name, source.ip with maxspan=10s - [authentication where host.os.type == "windows" and - event.action == "logon-failed" and winlog.logon.type : "Network" and - source.ip != null and source.ip != "127.0.0.1" and source.ip != "::1" and user.name : "*admin*" and - - /* noisy failure status codes often associated to authentication misconfiguration */ - not winlog.event_data.Status : ("0xC000015B", "0XC000005E", "0XC0000133", "0XC0000192")] with runs=5 +from logs-system.security*, logs-windows.forwarded*, winlogbeat-* metadata _id, _version, _index +| where event.category == "authentication" and host.os.type == "windows" and event.action == "logon-failed" and + winlog.logon.type == "Network" and source.ip is not null and winlog.computer_name is not null and + not cidr_match(TO_IP(source.ip), "127.0.0.0/8", "::1") and + to_lower(winlog.event_data.TargetUserName) like "*admin*" and + /* + noisy failure status codes often associated to authentication misconfiguration + 0xC000015B - The user has not been granted the requested logon type (also called the logon right) at this machine. + 0XC000005E - There are currently no logon servers available to service the logon request. + 0XC0000133 - Clocks between DC and other computer too far out of sync. + 0XC0000192 An attempt was made to logon, but the Netlogon service was not started. + 0xc00000dc - DC is in shutdown phase, it will normally tell current clients to use another DC for authentication. + */ + not winlog.event_data.Status in ("0xc000015b", "0xc000005e", "0xc0000133", "0xc0000192", "0xc00000dc") +// truncate the timestamp to a 60-second window +| eval Esql.time_window = date_trunc(60 seconds, @timestamp) +| stats Esql.failed_auth_count = COUNT(*), Esql.target_user_name_values = VALUES(winlog.event_data.TargetUserName), Esql.user_domain_values = VALUES(user.domain), Esql.error_codes = VALUES(winlog.event_data.Status), Esql.data_stream_namespace.values = VALUES(data_stream.namespace) by winlog.computer_name, source.ip, Esql.time_window, winlog.logon.type +| where Esql.failed_auth_count >= 50 +| KEEP winlog.computer_name, source.ip, Esql.time_window, winlog.logon.type, Esql.* ''' diff --git a/rules/windows/credential_access_bruteforce_multiple_logon_failure_same_srcip.toml b/rules/windows/credential_access_bruteforce_multiple_logon_failure_same_srcip.toml index c5a4a6ceb..e55ae6aa6 100644 --- a/rules/windows/credential_access_bruteforce_multiple_logon_failure_same_srcip.toml +++ b/rules/windows/credential_access_bruteforce_multiple_logon_failure_same_srcip.toml @@ -2,7 +2,7 @@ creation_date = "2020/08/29" integration = ["system", "windows"] maturity = "production" -updated_date = "2025/11/14" +updated_date = "2025/12/11" [transform] [[transform.osquery]] @@ -38,8 +38,7 @@ Adversaries will often brute force login attempts across multiple users with a c to gain access to accounts. """ from = "now-9m" -index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"] -language = "eql" +language = "esql" license = "Elastic License v2" name = "Multiple Logon Failure from the same Source Address" note = """## Triage and analysis @@ -117,24 +116,29 @@ tags = [ "Resources: Investigation Guide", "Data Source: Windows Security Event Logs", ] -type = "eql" +timestamp_override = "event.ingested" +type = "esql" query = ''' -sequence by winlog.computer_name, source.ip with maxspan=10s - [authentication where host.os.type == "windows" and event.action == "logon-failed" and - /* event 4625 need to be logged */ - winlog.logon.type : "Network" and - source.ip != null and source.ip != "127.0.0.1" and source.ip != "::1" and - not user.name : ("ANONYMOUS LOGON", "-", "*$") and not user.domain == "NT AUTHORITY" and - - /* - noisy failure status codes often associated to authentication misconfiguration : +from logs-system.security*, logs-windows.forwarded*, winlogbeat-* metadata _id, _version, _index +| where event.category == "authentication" and host.os.type == "windows" and event.action == "logon-failed" and + winlog.logon.type == "Network" and source.ip is not null and winlog.computer_name is not null and + not cidr_match(TO_IP(source.ip), "127.0.0.0/8", "::1") and + not user.name in ("ANONYMOUS LOGON", "-") and not user.name like "*$" and user.domain != "NT AUTHORITY" and + /* + noisy failure status codes often associated to authentication misconfiguration 0xC000015B - The user has not been granted the requested logon type (also called the logon right) at this machine. - 0XC000005E - There are currently no logon servers available to service the logon request. - 0XC0000133 - Clocks between DC and other computer too far out of sync. - 0XC0000192 An attempt was made to logon, but the Netlogon service was not started. - */ - not winlog.event_data.Status : ("0xC000015B", "0XC000005E", "0XC0000133", "0XC0000192")] with runs=10 + 0XC000005E - There are currently no logon servers available to service the logon request. + 0XC0000133 - Clocks between DC and other computer too far out of sync. + 0XC0000192 An attempt was made to logon, but the Netlogon service was not started. + 0xc00000dc - DC is in shutdown phase, it will normally tell current clients to use another DC for authentication. + */ + not winlog.event_data.Status in ("0xc000015b", "0xc000005e", "0xc0000133", "0xc0000192", "0xc00000dc") +// truncate the timestamp to a 60-second window +| eval Esql.time_window = date_trunc(60 seconds, @timestamp) +| stats Esql.failed_auth_count = COUNT(*), Esql.target_user_name_values = VALUES(winlog.event_data.TargetUserName), Esql.user_domain_values = VALUES(user.domain), Esql.error_codes = VALUES(winlog.event_data.Status), Esql.data_stream_namespace.values = VALUES(data_stream.namespace) by winlog.computer_name, source.ip, Esql.time_window, winlog.logon.type +| where Esql.failed_auth_count >= 100 +| KEEP winlog.computer_name, source.ip, Esql.time_window, winlog.logon.type, Esql.* ''' diff --git a/rules/windows/credential_access_dollar_account_relay.toml b/rules/windows/credential_access_dollar_account_relay.toml index c45ee108e..c0418104f 100644 --- a/rules/windows/credential_access_dollar_account_relay.toml +++ b/rules/windows/credential_access_dollar_account_relay.toml @@ -2,7 +2,7 @@ creation_date = "2024/07/24" integration = ["system", "windows"] maturity = "production" -updated_date = "2025/06/16" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -15,13 +15,13 @@ from = "now-9m" index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"] language = "eql" license = "Elastic License v2" -name = "Potential Computer Account Relay Activity" +name = "Potential Computer Account NTLM Relay Activity" note = """## 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 Potential Computer Account Relay Activity +### Investigating Potential Computer Account NTLM Relay Activity ### Possible investigation steps @@ -58,9 +58,9 @@ references = [ "https://www.thehacker.recipes/a-d/movement/mitm-and-coerced-authentications", "https://attack.mitre.org/techniques/T1187/", ] -risk_score = 21 +risk_score = 47 rule_id = "263481c8-1e9b-492e-912d-d1760707f810" -severity = "low" +severity = "medium" tags = [ "Domain: Endpoint", "OS: Windows", @@ -77,14 +77,16 @@ type = "eql" query = ''' authentication where host.os.type == "windows" and event.code in ("4624", "4625") and - endswith~(user.name, "$") and winlog.logon.type : "network" and + winlog.logon.type == "Network" and winlog.event_data.AuthenticationPackageName == "NTLM" and + endswith~(user.name, "$") and user.name != "$" and + source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1" and - /* Filter for a machine account that matches the hostname */ - startswith~(host.name, substring(user.name, 0, -1)) and + /* Filter for a machine account that matches the hostname */ + startswith~(host.name, substring(user.name, 0, -1)) and - /* Verify if the Source IP belongs to the host */ - not endswith(string(source.ip), string(host.ip)) and - source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1" + /* Verify if the Source IP belongs to the host */ + not endswith(string(source.ip), string(host.ip)) and + not stringContains(string(host.ip), string(source.ip)) ''' diff --git a/rules/windows/credential_access_lsass_openprocess_api.toml b/rules/windows/credential_access_lsass_openprocess_api.toml index dbf7d310a..6e37f1813 100644 --- a/rules/windows/credential_access_lsass_openprocess_api.toml +++ b/rules/windows/credential_access_lsass_openprocess_api.toml @@ -2,7 +2,7 @@ creation_date = "2023/03/02" integration = ["endpoint", "m365_defender"] maturity = "production" -updated_date = "2025/02/03" +updated_date = "2025/12/11" [transform] [[transform.osquery]] @@ -32,10 +32,10 @@ authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.resu [rule] author = ["Elastic"] -description = "Identifies access attempts to the LSASS handle, which may indicate an attempt to dump credentials from LSASS memory.\n" -from = "now-9m" -index = ["logs-endpoint.events.api-*", "logs-m365_defender.event-*"] -language = "eql" +description = "Identifies access attempts to the LSASS handle, which may indicate an attempt to dump credentials from LSASS memory." +from = "now-30m" +interval = "15m" +language = "esql" license = "Elastic License v2" name = "LSASS Process Access via Windows API" note = """## Triage and analysis @@ -116,71 +116,35 @@ tags = [ "Resources: Investigation Guide" ] timestamp_override = "event.ingested" -type = "eql" +type = "esql" query = ''' -api where host.os.type == "windows" and - process.Ext.api.name in ("OpenProcess", "OpenThread") and Target.process.name : "lsass.exe" and - not - ( - process.executable : ( - "?:\\ProgramData\\GetSupportService*\\Updates\\Update_*.exe", - "?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe", - "?:\\Program Files (x86)\\Asiainfo Security\\OfficeScan Client\\NTRTScan.exe", - "?:\\Program Files (x86)\\Blackpoint\\SnapAgent\\SnapAgent.exe", - "?:\\Program Files (x86)\\CheckPoint\\Endpoint Security\\EFR\\EFRService.exe", - "?:\\Program Files (x86)\\CyberCNSAgent\\osqueryi.exe", - "?:\\Program Files (x86)\\cisco\\cisco anyconnect secure mobility client\\vpnagent.exe", - "?:\\Program Files (x86)\\cisco\\cisco anyconnect secure mobility client\\aciseagent.exe", - "?:\\Program Files (x86)\\cisco\\cisco anyconnect secure mobility client\\vpndownloader.exe", - "?:\\Program Files (x86)\\eScan\\reload.exe", - "?:\\Program Files (x86)\\Google\\Update\\GoogleUpdate.exe", - "?:\\Program Files (x86)\\Kaspersky Lab\\*\\avp.exe", - "?:\\Program Files (x86)\\microsoft intune management extension\\microsoft.management.services.intunewindowsagent.exe", - "?:\\Program Files (x86)\\N-able Technologies\\Reactive\\bin\\NableReactiveManagement.exe", - "?:\\Program Files (x86)\\N-able Technologies\\Windows Agent\\bin\\agent.exe", - "?:\\Program Files (x86)\\Tanium\\Tanium Client\\TaniumClient.exe", - "?:\\Program Files (x86)\\Trend Micro\\*\\CCSF\\TmCCSF.exe", - "?:\\Program Files (x86)\\Trend Micro\\Security Agent\\TMASutility.exe", - "?:\\Program Files*\\Windows Defender\\MsMpEng.exe", - "?:\\Program Files\\Bitdefender\\Endpoint Security\\EPSecurityService.exe", - "?:\\Program Files\\Cisco\\AMP\\*\\sfc.exe", - "?:\\Program Files\\Common Files\\McAfee\\AVSolution\\mcshield.exe", - "?:\\Program Files\\EA\\AC\\EAAntiCheat.GameService.exe", - "?:\\Program Files\\Elastic\\Agent\\data\\elastic-agent-*\\components\\agentbeat.exe", - "?:\\Program Files\\Elastic\\Agent\\data\\elastic-agent-*\\components\\metricbeat.exe", - "?:\\Program Files\\Elastic\\Agent\\data\\elastic-agent-*\\components\\osqueryd.exe", - "?:\\Program Files\\Elastic\\Agent\\data\\elastic-agent-*\\components\\packetbeat.exe", - "?:\\Program Files\\ESET\\ESET Security\\ekrn.exe", - "?:\\Program Files\\Fortinet\\FortiClient\\FortiProxy.exe", - "?:\\Program Files\\Fortinet\\FortiClient\\FortiSSLVPNdaemon.exe", - "?:\\Program Files\\Goverlan Inc\\GoverlanAgent\\GovAgentx64.exe", - "?:\\Program Files\\Huntress\\HuntressAgent.exe", - "?:\\Program Files\\LogicMonitor\\Agent\\bin\\sbshutdown.exe", - "?:\\Program Files\\Malwarebytes\\Anti-Malware\\MBAMService.exe", - "?:\\Program Files\\Microsoft Monitoring Agent\\Agent\\Health Service State\\*\\pmfexe.exe", - "?:\\Program Files\\Microsoft Security Client\\MsMpEng.exe", - "?:\\Program Files\\Qualys\\QualysAgent\\QualysAgent.exe", - "?:\\Program Files\\smart-x\\controlupagent\\version*\\cuagent.exe", - "?:\\Program Files\\TDAgent\\ossec-agent\\ossec-agent.exe", - "?:\\Program Files\\Topaz OFD\\Warsaw\\core.exe", - "?:\\Program Files\\Trend Micro\\Deep Security Agent\\netagent\\tm_netagent.exe", - "?:\\Program Files\\VMware\\VMware Tools\\vmtoolsd.exe", - "?:\\Program Files\\Windows Defender Advanced Threat Protection\\MsSense.exe", - "?:\\Program Files\\Wise\\Wise Memory Optimizer\\WiseMemoryOptimzer.exe", - "?:\\Windows\\AdminArsenal\\PDQDeployRunner\\*\\exec\\Sysmon64.exe", - "?:\\Windows\\Sysmon.exe", - "?:\\Windows\\Sysmon64.exe", - "?:\\Windows\\System32\\csrss.exe", - "?:\\Windows\\System32\\MRT.exe", - "?:\\Windows\\System32\\msiexec.exe", - "?:\\Windows\\System32\\taskhostw.exe", - "?:\\Windows\\System32\\RtkAudUService64.exe", - "?:\\Windows\\System32\\wbem\\WmiPrvSE.exe", - "?:\\Windows\\SysWOW64\\wbem\\WmiPrvSE.exe", - "?:\\Windows\\tenable_mw_scan_142a90001fb65e0beb1751cc8c63edd0.exe" - ) and not ?process.code_signature.trusted == false - ) +from logs-endpoint.events.api-*, logs-m365_defender.event-* metadata _id, _version, _index + +| where event.category == "api" and host.os.family == "windows" and + process.Ext.api.name in ("OpenProcess", "OpenThread", "ReadProcessMemory") and + Target.process.name == "lsass.exe" and process.executable is not null and + + // Noisy patterns + not to_lower(process.executable) like """c:\\program files\\*.exe""" and + not to_lower(process.executable) like """c:\\program files (x86)\\*.exe""" and + not process.executable like """C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\MsMpEng.exe""" and + not process.executable like """C:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe""" + + /* normalize process paths to reduce known random patterns in process.executable */ +| eval Esql.process_path = replace(process.executable, """([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\.tmp|DX[A-Z0-9]{3,4}\.tmp|7z[A-Z0-9]{3,5}\.tmp|[0-9\.\-\_]{3,})""", "") + +// Group by process path +| stats Esql.access_count = count(*), + Esql.count_distinct_hosts = count_distinct(host.id), + Esql.host_id_values = VALUES(host.id), + Esql.process_pid_values = VALUES(process.entity_id), + Esql.data_stream_namespace.values = VALUES(data_stream.namespace), + Esql.user_name_values = VALUES(user.name) by Esql.process_path + +// Limit to rare instances +| where Esql.count_distinct_hosts == 1 and Esql.access_count <= 3 +| keep Esql.* ''' diff --git a/rules/windows/defense_evasion_indirect_exec_forfiles.toml b/rules/windows/defense_evasion_indirect_exec_forfiles.toml index 81da810b4..35a8dcd17 100644 --- a/rules/windows/defense_evasion_indirect_exec_forfiles.toml +++ b/rules/windows/defense_evasion_indirect_exec_forfiles.toml @@ -2,7 +2,7 @@ creation_date = "2025/02/03" integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"] maturity = "production" -updated_date = "2025/03/20" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -72,8 +72,9 @@ timestamp_override = "event.ingested" type = "eql" query = ''' -process where host.os.type == "windows" and event.type == "start" and - (process.name : "forfiles.exe" or ?process.pe.original_file_name == "forfiles.exe") and process.args : ("/c", "-c") +process where host.os.type == "windows" and event.type == "start" and user.id != "S-1-5-18" and + (process.name : "forfiles.exe" or ?process.pe.original_file_name == "forfiles.exe") and process.args : ("/c", "-c") and + not process.args : ("-d", "/d", "cmd /c copy @file*", "cmd /c DEL /Q /F @*", "cmd /c del @*", "D:\\*") ''' diff --git a/rules/windows/defense_evasion_process_termination_followed_by_deletion.toml b/rules/windows/defense_evasion_process_termination_followed_by_deletion.toml index 83c94bfe8..02a615cf2 100644 --- a/rules/windows/defense_evasion_process_termination_followed_by_deletion.toml +++ b/rules/windows/defense_evasion_process_termination_followed_by_deletion.toml @@ -2,7 +2,7 @@ creation_date = "2020/11/04" integration = ["endpoint"] maturity = "production" -updated_date = "2025/02/03" +updated_date = "2025/12/11" [transform] [[transform.osquery]] @@ -42,10 +42,10 @@ from = "now-9m" index = ["logs-endpoint.events.process-*", "logs-endpoint.events.file-*"] language = "eql" license = "Elastic License v2" -name = "Process Termination followed by Deletion" +name = "Deprecated - Process Termination followed by Deletion" note = """## Triage and analysis -### Investigating Process Termination followed by Deletion +### Investigating Deprecated - Process Termination followed by Deletion This rule identifies an unsigned process termination event quickly followed by the deletion of its executable file. Attackers can delete programs after their execution in an attempt to cover their tracks in a host. diff --git a/rules/windows/lateral_movement_remote_file_copy_hidden_share.toml b/rules/windows/lateral_movement_remote_file_copy_hidden_share.toml index be836c466..197d4339c 100644 --- a/rules/windows/lateral_movement_remote_file_copy_hidden_share.toml +++ b/rules/windows/lateral_movement_remote_file_copy_hidden_share.toml @@ -2,7 +2,7 @@ creation_date = "2020/11/04" integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"] maturity = "production" -updated_date = "2025/03/20" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -82,9 +82,9 @@ timestamp_override = "event.ingested" type = "eql" query = ''' -process where host.os.type == "windows" and event.type == "start" and - process.name : ("cmd.exe", "powershell.exe", "xcopy.exe", "pwsh.exe", "powershell_ise.exe") and - process.command_line : "*\\\\*\\*$*" and process.command_line : ("*copy*", "*move*", "* cp *", "* mv *") +process where host.os.type == "windows" and event.type == "start" and user.id != "S-1-5-18" and + process.name : ("cmd.exe", "powershell.exe") and + process.command_line : "*\\\\*\\*$*" and process.command_line : ("* copy*", "* move*", "* cp *", "* mv *") ''' diff --git a/rules/windows/persistence_service_windows_service_winlog.toml b/rules/windows/persistence_service_windows_service_winlog.toml index 619860be8..998676891 100644 --- a/rules/windows/persistence_service_windows_service_winlog.toml +++ b/rules/windows/persistence_service_windows_service_winlog.toml @@ -2,7 +2,7 @@ creation_date = "2022/08/30" integration = ["system", "windows"] maturity = "production" -updated_date = "2025/11/14" +updated_date = "2025/12/11" [transform] [[transform.osquery]] @@ -113,18 +113,27 @@ query = ''' any where host.os.type == "windows" and (event.code : "4697" and (winlog.event_data.ServiceFileName : - ("*COMSPEC*", "*\\127.0.0.1*", "*Admin$*", "*powershell*", "*rundll32*", "*cmd.exe*", "*PSEXESVC*", + ("*COMSPEC*", "*\\127.0.0.1*", "*Admin$*", "*powershell*", "*rundll32*", "*cmd.exe*", "*echo*", "*RemComSvc*", "*.bat*", "*.cmd*", "*certutil*", "*vssadmin*", "*certmgr*", "*bitsadmin*", - "*\\Users\\*", "*\\Windows\\Temp\\*", "*\\Windows\\Tasks\\*", "*\\PerfLogs\\*", "*\\Windows\\Debug\\*", + "*\\Users\\*", "*\\Windows\\Tasks\\*", "*\\PerfLogs\\*", "*\\Windows\\Debug\\*", "*regsvr32*", "*msbuild*") or - winlog.event_data.ServiceFileName regex~ """%systemroot%\\[a-z0-9]+\.exe""")) or + winlog.event_data.ServiceFileName regex~ """%systemroot%\\[a-z0-9]+\.exe""") and + not winlog.event_data.ServiceFileName: + ("%SystemRoot%\\PSEXESVC.exe", "%SystemRoot%\\\\RemComSvc.exe", + "%SystemRoot%\\pbpsdeploy.exe", "%SystemRoot%\\system32\\RemComSvc.exe", + "\"C:\\Program Files\\Common Files\\Zoom\\Support\\CptService.exe*", + "\"C:\\Program Files (x86)\\CheckPoint\\Endpoint Security\\EFR\\host\\cpsechost.exe\" service")) or (event.code : "7045" and winlog.event_data.ImagePath : ( - "*COMSPEC*", "*\\127.0.0.1*", "*Admin$*", "*powershell*", "*rundll32*", "*cmd.exe*", "*PSEXESVC*", - "*echo*", "*RemComSvc*", "*.bat*", "*.cmd*", "*certutil*", "*vssadmin*", "*certmgr*", "*bitsadmin*", - "*\\Users\\*", "*\\Windows\\Temp\\*", "*\\Windows\\Tasks\\*", "*\\PerfLogs\\*", "*\\Windows\\Debug\\*", - "*regsvr32*", "*msbuild*")) + "*COMSPEC*", "*\\127.0.0.1*", "*Admin$*", "*powershell*", "*rundll32*", "*cmd.exe*", + "*echo*", "*.bat*", "*.cmd*", "*certutil*", "*vssadmin*", "*certmgr*", "*bitsadmin*", + "*\\Users\\*", "*\\Windows\\Tasks\\*", "*\\PerfLogs\\*", "*\\Windows\\Debug\\*", + "*regsvr32*", "*msbuild*") and + not winlog.event_data.ImagePath : ("%SystemRoot%\\PSEXESVC.exe", "%SystemRoot%\\\\RemComSvc.exe", + "%SystemRoot%\\pbpsdeploy.exe", "%SystemRoot%\\system32\\RemComSvc.exe", + "\"C:\\Program Files\\Common Files\\Zoom\\Support\\CptService.exe*", + "\"C:\\Program Files (x86)\\CheckPoint\\Endpoint Security\\EFR\\host\\cpsechost.exe\" service")) ''' diff --git a/rules/windows/persistence_suspicious_scheduled_task_runtime.toml b/rules/windows/persistence_suspicious_scheduled_task_runtime.toml index c17f96888..ed301eb30 100644 --- a/rules/windows/persistence_suspicious_scheduled_task_runtime.toml +++ b/rules/windows/persistence_suspicious_scheduled_task_runtime.toml @@ -2,7 +2,7 @@ creation_date = "2020/11/19" integration = ["endpoint", "windows"] maturity = "production" -updated_date = "2025/08/26" +updated_date = "2025/12/11" [rule] author = ["Elastic"] @@ -102,17 +102,21 @@ process where host.os.type == "windows" and event.type == "start" and "C:\\Windows\\Debug\\*", "C:\\HP\\*") and - not (process.name : "cmd.exe" and process.args : "?:\\*.bat" and process.working_directory : "?:\\Windows\\System32\\") and + not (process.name : "cmd.exe" and process.args : ("*.bat", "*.cmd")) and not (process.name : "cscript.exe" and process.args : "?:\\Windows\\system32\\calluxxprovider.vbs") and not ( process.name : "powershell.exe" and process.args : ( "-File", "-PSConsoleFile", "C:\\ProgramData\\Microsoft\\AutopatchSetupScheduled\\SetupAutopatchClientV2Package.ps1", - "C:\\ProgramData\\Microsoft\\AutopatchSetupScheduled\\SetupAutopatchClientPackage.ps1" + "C:\\ProgramData\\Microsoft\\AutopatchSetupScheduled\\SetupAutopatchClientPackage.ps1", + "C:\\Windows\\Temp\\MSS\\MDESetup\\Invoke-MDESetup.ps1" ) and user.id : "S-1-5-18" ) and - not (process.name : "msiexec.exe" and user.id : "S-1-5-18") + not (process.name : "msiexec.exe" and user.id : "S-1-5-18") and + not (process.name : "powershell.exe" and + process.command_line : ("C:\\ProgramData\\ElasticAgent-HealthCheck.ps1", + "C:\\ProgramData\\ssh\\puttysetup.ps1")) '''