diff --git a/hunting/README.md b/hunting/README.md index 1cae0608d1f..aaa161d4b53 100644 --- a/hunting/README.md +++ b/hunting/README.md @@ -2,15 +2,23 @@ --- -Welcome to the `hunting` folder within the `detection-rules` repository! This directory houses a curated collection of threat hunting queries designed to enhance security monitoring and threat detection capabilities using the Elastic Stack. Each file in this directory provides a query tailored for identifying specific security threats or suspicious activities. +Welcome to the `hunting` folder within the `detection-rules` repository! This directory houses a curated collection of threat hunting queries designed to enhance security monitoring and threat detection capabilities using the Elastic Stack. Each file in this directory provides a query tailored for the initial evidence gathering of specific hunts. -These queries are designed for use with the Elastic Security platform, part of the broader Elastic Stack, enabling security teams to proactively hunt for potential threats in their environment. +Each hunt has a designated TOML and Markdown file, intended to be used either programatically or via copy and pasted. Notes about data considerations, pivoting, exploring data further and more have been added to each hunting query. These queries are designed for use with the Elastic Security platform, part of the broader Elastic Stack, enabling security teams to proactively hunt for potential threats in their environment. -- KQL -- EQL -- ES|QL -- OsQuery -- YARA +Note that some hunting files will include a mix of queries with different languages whose sole purpose is to provide optional queries to gather evidence for the hunt. + +- [KQL](https://www.elastic.co/guide/en/kibana/current/kuery-query.html) +- [EQL](https://www.elastic.co/guide/en/elasticsearch/reference/current/eql.html) +- [ES|QL](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html) +- [OsQuery/SQL](https://www.elastic.co/guide/en/kibana/current/osquery.html) +- [YARA](https://yara.readthedocs.io/en/stable/writingrules.html) + +The hunting queries shared in this folder are a mix of the following hunting methods: + +- Hypothesis-Driven - Assumed breach method with specific hypothesis of where adversary dwells or where footprints exist. +- CTI-Driven - Retro-active searches for specific indicators-of-compromise or tactics, techniques and procedures (TTPs) related to adversaries and/or tooling. +- Data-Driven - Initial evidence collecting query that requires more advanced data analysis to uncover anomalies. ## How to Contribute @@ -18,25 +26,20 @@ Contributing to the `hunting` folder is a great way to share your expertise and ### Names and Related Queries -All query names should be unique and descriptive. If a query's intent is identical or related to another query, consider -adding a suffix with the integration(s) to the name to indicate the relationship and distinguish them from each other. +All query names should be unique and descriptive. If a query's intent is identical or related to another query, consider +adding a suffix with the integration(s) to the name to indicate the relationship and distinguish them from each other. Otherwise, the names do not require the integration, since it is already annotated within the `integration` field. -The filename should reflect the query name. - -For example: -- `Detect DLL Hijack via Masquerading as Microsoft Native Libraries - Elastic Defend` -- `Detect DLL Hijack via Masquerading as Microsoft Native Libraries - Sysmon` - ### Adding New Queries - **TOML File Naming and Organization**: Ensure that any new queries are named descriptively and grouped by the type of threat they address. Place your TOML files inside the `queries` folder and ensure they are named in a way that reflects the nature of the threat or behavior they are designed to detect. - **TOML Fields**: To ensure the hunt queries are consistent and comprehensive, it's important to structure the threat detection rules with specific fields. When contributing a new rule, please include the following fields in the TOML file to describe and configure the analytic: - **author**: The name of the individual or organization authoring the rule. + - **description**: The purpose of the hunt with a clear threat explanation and hunting goal. - **integration**: The specific integration or data source the rule applies to, such as `aws_bedrock.invocation`. - **uuid**: A unique identifier for the rule to maintain version control and tracking. - **name**: A descriptive name for the rule that clearly indicates its purpose. - - **language**: The query language used in the rule, such as `KQL`, `EQL`, `ES|QL`, `OsQuery`, or `YARA`. - - **query**: The actual query or analytic expression written in the appropriate query language that executes the detection logic. + - **language**: The query language(s) used in the rule, such as `KQL`, `EQL`, `ES|QL`, `OsQuery`, or `YARA`. + - **query**: An array of actual queries or analytic expressions written in the appropriate query language that executes the detection logic. - **notes**: An array of strings providing detailed insights into the rationale behind the rule, suggestions for further investigation, and tips on distinguishing false positives from true activity. - **mitre**: Reference to applicable MITRE ATT&CK tactics or techniques that the rule addresses, enhancing the contextual understanding of its security implications. - **references**: Links to external documents, research papers, or websites that provide additional information or validation for the detection logic. diff --git a/hunting/generate_markdown.py b/hunting/generate_markdown.py index fa5dad3b35e..2cf080d61c3 100644 --- a/hunting/generate_markdown.py +++ b/hunting/generate_markdown.py @@ -32,7 +32,7 @@ class Hunt: integration: list[str] uuid: str name: str - language: str + language: list[str] license: str query: list[str] notes: Optional[List[str]] = field(default_factory=list) @@ -85,7 +85,7 @@ def convert_toml_to_markdown(hunt_config: Hunt, file_path: Path) -> str: markdown += f"- **Description:** {hunt_config.description}\n" markdown += f"- **UUID:** `{hunt_config.uuid}`\n" markdown += f"- **Integration:** {", ".join(generate_integration_links(hunt_config.integration))}\n" - markdown += f"- **Language:** `{hunt_config.language}`\n\n" + markdown += f"- **Language:** `{hunt_config.language}`\n\n".replace("'", "").replace('"', "") markdown += "## Query\n\n" for query in hunt_config.query: markdown += f"```sql\n{query}```\n\n" @@ -127,7 +127,7 @@ def process_toml_files(base_path: Path) -> None: index_content += f"\n\n## {folder}\n" for file_path, rule_name, language in sorted(files): index_path = "./" + str(file_path) - index_content += f"- [{rule_name}]({index_path}) ({language})\n" + index_content += f"- [{rule_name}]({index_path}) ({", ".join(language)})\n" # Write the index file at the base directory level index_path = base_path / "index.md" diff --git a/hunting/index.md b/hunting/index.md index 33bb3d17c8b..e2037d6f93b 100644 --- a/hunting/index.md +++ b/hunting/index.md @@ -2,6 +2,39 @@ Here are the queries currently available: +## linux +- [Network Connections with Low Occurrence Frequency for Unique Agent ID](./linux/docs/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.md) (ES|QL) +- [Unusual File Downloads from Source Addresses](./linux/docs/command_and_control_via_unusual_file_downloads_from_source_addresses.md) (ES|QL) +- [Defense Evasion via Capitalized Process Execution](./linux/docs/defense_evasion_via_capitalized_process_execution.md) (ES|QL) +- [Hidden Process Execution](./linux/docs/defense_evasion_via_hidden_process_execution.md) (ES|QL) +- [Potential Defense Evasion via Multi-Dot Process Execution](./linux/docs/defense_evasion_via_multi_dot_process_execution.md) (ES|QL) +- [Excessive SSH Network Activity to Unique Destinations](./linux/docs/excessive_ssh_network_activity_unique_destinations.md) (ES|QL) +- [Uncommon Process Execution from Suspicious Directory](./linux/docs/execution_uncommon_process_execution_from_suspicious_directory.md) (ES|QL) +- [Logon Activity by Source IP](./linux/docs/login_activity_by_source_address.md) (ES|QL) +- [Low Volume External Network Connections from Process by Unique Agent](./linux/docs/low_volume_external_network_connections_from_process.md) (ES|QL) +- [Low Volume GTFOBins External Network Connections](./linux/docs/low_volume_gtfobins_external_network_connections.md) (ES|QL) +- [Low Volume Modifications to Critical System Binaries by Unique Host](./linux/docs/low_volume_modifications_to_critical_system_binaries.md) (ES|QL) +- [Low Volume Process Injection-Related Syscalls by Process Executable](./linux/docs/low_volume_process_injection_syscalls_by_executable.md) (ES|QL) +- [Persistence Through Reverse/Bind Shells](./linux/docs/persistence_reverse_bind_shells.md) (SQL) +- [Persistence via Cron](./linux/docs/persistence_via_cron.md) (ES|QL, SQL) +- [Drivers Load with Low Occurrence Frequency](./linux/docs/persistence_via_driver_load_with_low_occurrence_frequency.md) (ES|QL) +- [Git Hook/Pager Persistence](./linux/docs/persistence_via_git_hook_pager.md) (ES|QL, SQL) +- [Persistence via Message-of-the-Day](./linux/docs/persistence_via_message_of_the_day.md) (ES|QL, SQL) +- [Persistence via Packager Manager](./linux/docs/persistence_via_package_manager.md) (ES|QL, SQL) +- [Persistence via rc.local/rc.common](./linux/docs/persistence_via_rc_local.md) (ES|QL, SQL) +- [Shell Modification Persistence](./linux/docs/persistence_via_shell_modification_persistence.md) (ES|QL, SQL) +- [Persistence via SSH Configurations and/or Keys](./linux/docs/persistence_via_ssh_configurations_and_keys.md) (SQL) +- [Persistence via Systemd (Timers)](./linux/docs/persistence_via_systemd_timers.md) (ES|QL, SQL) +- [Persistence via Udev](./linux/docs/persistence_via_udev.md) (ES|QL, SQL) +- [Unusual System Binary Parent (Potential System Binary Hijacking Attempt)](./linux/docs/persistence_via_unusual_system_binary_parent.md) (ES|QL) +- [Privilege Escalation/Persistence via User/Group Creation and/or Modification](./linux/docs/persistence_via_user_group_creation_modification.md) (SQL) +- [XDG Persistence](./linux/docs/persistence_via_xdg_autostart_modifications.md) (ES|QL, SQL) +- [Privilege Escalation Identification via Existing Sudoers File](./linux/docs/privilege_escalation_via_existing_sudoers.md) (SQL) +- [Process Capability Hunting](./linux/docs/privilege_escalation_via_process_capabilities.md) (ES|QL) +- [Segmentation Fault & Potential Buffer Overflow Hunting](./linux/docs/privilege_escalation_via_segmentation_fault_and_buffer_overflow.md) (ES|QL) +- [OSQuery SUID Hunting](./linux/docs/privilege_escalation_via_suid_binaries.md) (SQL) + + ## llm - [AWS Bedrock LLM Denial-of-Service or Resource Exhaustion](./llm/docs/aws_bedrock_dos_resource_exhaustion_detection.md) (ES|QL) - [AWS Bedrock LLM Latency Anomalies](./llm/docs/aws_bedrock_latency_anomalies_detection.md) (ES|QL) diff --git a/hunting/linux/docs/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.md b/hunting/linux/docs/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.md new file mode 100644 index 00000000000..f1ab66f74c8 --- /dev/null +++ b/hunting/linux/docs/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.md @@ -0,0 +1,78 @@ +# Network Connections with Low Occurrence Frequency for Unique Agent ID + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies network connections with low occurrence frequency for unique agent IDs on Linux systems. It monitors network connection attempts and acceptances, focusing on those initiated by processes that are rarely seen in the environment. By accounting for known low-frequency legitimate binaries (LoLBins) and suspicious directories, this hunt aims to detect unusual network activity that may indicate malicious behavior. + +- **UUID:** `ecd84bc7-32ae-474b-93a8-d1d9736c3464` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.executable +| where agent_count == 1 and cc > 0 and cc <= 3 +| limit 100 +| sort cc asc +``` + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and ( + process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "socat", "java", "awk", "gawk", "mawk", "nawk", "openssl", "nc", "ncat", "netcat", "nc.openbsd", "telnet") or + process.name like "python*" or + process.name like "perl*" or + process.name like "ruby*" or + process.name like "lua*" or + process.name like "php*" +) and +destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.name +| where agent_count <= 3 and cc > 0 and cc <= 5 +| limit 100 +| sort cc asc +``` + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and ( + process.executable like "./*" or + process.executable like "/dev/shm/*" or + process.executable like "/var/www/*" or + process.executable like "/boot/*" or + process.executable like "/srv/*" or + process.executable rlike "/tmp/[^/]+" or + process.executable rlike "/var/tmp/[^/]+" or + process.executable rlike "/run/[^/]+" or + process.executable rlike "/var/run/[^/]+" +) and +destination.ip IS NOT null and not CIDR_MATCH(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.executable +| where agent_count <= 3 and cc > 0 and cc <= 5 +| limit 100 +| sort cc asc +``` + +## Notes + +- Monitors for network connections initiated by processes that have low occurrence frequency, focusing on unique agent IDs. +- Excludes common internal IP ranges to minimize false positives. +- Accounts for known low-frequency legitimate binaries (LoLBins) to reduce noise. +- Identifies suspicious directories where processes are executed from, which can indicate malicious activity. +## MITRE ATT&CK Techniques + +- [T1071.001](https://attack.mitre.org/techniques/T1071/001) +- [T1071.004](https://attack.mitre.org/techniques/T1071/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/command_and_control_via_unusual_file_downloads_from_source_addresses.md b/hunting/linux/docs/command_and_control_via_unusual_file_downloads_from_source_addresses.md new file mode 100644 index 00000000000..17268e7ef06 --- /dev/null +++ b/hunting/linux/docs/command_and_control_via_unusual_file_downloads_from_source_addresses.md @@ -0,0 +1,39 @@ +# Unusual File Downloads from Source Addresses + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies unusual file download activities on Linux systems. It detects instances where commonly used download utilities such as curl and wget are executed with command lines that contain IP addresses, which can indicate potentially suspicious file downloads. + +- **UUID:** `0d061fad-cf35-43a6-b9b7-986c348bf182` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and process.name in ("curl", "wget") and process.command_line rlike """.*[0-9]{1,3}(\.[0-9]{1,3}){3}.*""" +| stats cc = count(), host_count = count_distinct(host.id) by process.command_line, process.executable +| where cc <= 10 and host_count <= 5 +| sort cc asc +| limit 100 +``` + +## Notes + +- Detects instances where download utilities like curl and wget are used with IP addresses in their command lines. +- Monitors for potentially suspicious file downloads, which are often seen in malicious activities. +- Uses process command line counting in conjunction with host counting to minimize false positives caused by legitimate downloads. +- The process command line count threshold is set to <= 10, and the host count threshold is set to <= 5 to balance detection and noise. +## MITRE ATT&CK Techniques + +- [T1071.001](https://attack.mitre.org/techniques/T1071/001) +- [T1071.004](https://attack.mitre.org/techniques/T1071/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/defense_evasion_via_capitalized_process_execution.md b/hunting/linux/docs/defense_evasion_via_capitalized_process_execution.md new file mode 100644 index 00000000000..97a9cd85791 --- /dev/null +++ b/hunting/linux/docs/defense_evasion_via_capitalized_process_execution.md @@ -0,0 +1,41 @@ +# Defense Evasion via Capitalized Process Execution + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential defense evasion techniques via capitalized process execution on Linux systems. It detects processes that have two or more consecutive capital letters within their names, which can indicate an attempt to evade detection. Such naming conventions are often used in malicious payloads to blend in with legitimate processes. + +- **UUID:** `9d485892-1ca2-464b-9e4e-6b21ab379b9a` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 10 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( + (process.name rlike """[A-Z]{2,}[a-z]{1,}[0-9]{0,}""") or + (process.name rlike """[A-Z]{1,}[0-9]{0,}""") +) +| stats cc = count(), host_count = count_distinct(host.name) by process.name +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| limit 100 +``` + +## Notes + +- Detects processes that have two or more consecutive capital letters within their names, with optional digits. +- This technique is often used in malicious payloads, such as Metasploit payloads, to evade detection. +- Included a process count of <= 3 and a host count of <= 3 to eliminate common processes across different hosts. +## MITRE ATT&CK Techniques + +- [T1036.004](https://attack.mitre.org/techniques/T1036/004) +- [T1070](https://attack.mitre.org/techniques/T1070) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/defense_evasion_via_hidden_process_execution.md b/hunting/linux/docs/defense_evasion_via_hidden_process_execution.md new file mode 100644 index 00000000000..c5a146298f1 --- /dev/null +++ b/hunting/linux/docs/defense_evasion_via_hidden_process_execution.md @@ -0,0 +1,39 @@ +# Hidden Process Execution + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies hidden process executions on Linux systems. It detects processes executed from hidden files, which are often used by malicious actors to conceal their activities. By focusing on hidden files rather than directories, this hunt aims to catch stealthy processes while minimizing noise. + +- **UUID:** `00461198-9a2d-4823-b4cc-f3d1b5c17935` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and + process.executable rlike "/[^/]+/\\.[^/]+" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable, user.id +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| sort cc asc +| limit 100 +``` + +## Notes + +- Included only hidden files, excluding hidden directories, as hidden directories are common in Unix. +- Included a process or parent process count of <= 3, and a host count of <= 3 to eliminate common processes across different hosts. +## MITRE ATT&CK Techniques + +- [T1036.004](https://attack.mitre.org/techniques/T1036/004) +- [T1059](https://attack.mitre.org/techniques/T1059) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/defense_evasion_via_multi_dot_process_execution.md b/hunting/linux/docs/defense_evasion_via_multi_dot_process_execution.md new file mode 100644 index 00000000000..b777b443383 --- /dev/null +++ b/hunting/linux/docs/defense_evasion_via_multi_dot_process_execution.md @@ -0,0 +1,38 @@ +# Potential Defense Evasion via Multi-Dot Process Execution + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential defense evasion techniques via multi-dot process execution on Linux systems. It looks for processes with executables that contain three or more consecutive dots in their names. Such naming conventions can be used by malicious actors to evade detection and blend in with legitimate processes. + +- **UUID:** `11810497-8ce3-4960-9777-9d0e97052682` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.executable rlike """.*\.{3,}.*""" +| stats cc = count() by process.executable +// Alter this threshold to make sense for your environment +| where cc <= 10 +| sort cc asc +| limit 100 +``` + +## Notes + +- This query identifies processes with executables containing three or more consecutive dots in their names. +- The process count threshold of <= 10 can be adjusted based on the environment's baseline activity. +## MITRE ATT&CK Techniques + +- [T1036.004](https://attack.mitre.org/techniques/T1036/004) +- [T1070](https://attack.mitre.org/techniques/T1070) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/excessive_ssh_network_activity_unique_destinations.md b/hunting/linux/docs/excessive_ssh_network_activity_unique_destinations.md new file mode 100644 index 00000000000..ecd02301321 --- /dev/null +++ b/hunting/linux/docs/excessive_ssh_network_activity_unique_destinations.md @@ -0,0 +1,40 @@ +# Excessive SSH Network Activity to Unique Destinations + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies excessive SSH network activity to unique destinations on Linux systems. It monitors network connections over TCP to port 22 (SSH) and counts the number of unique destination IP addresses. A high number of unique destinations could indicate suspicious activity such as discovery or lateral movement. + +- **UUID:** `223f812c-a962-4d58-961d-134d8f8b15da` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and network.transport == "tcp" and destination.port == 22 and source.port >= 49152 +| keep destination.ip, host.id, user.name +| stats count_unique_dst = count_distinct(destination.ip) by host.id, user.name +// Alter this threshold to make sense for your environment +| where count_unique_dst >= 10 +| limit 100 +| sort user.name asc +``` + +## Notes + +- Monitors network connections to port 22 (SSH) and counts the number of unique destination IP addresses per host and user. +- A high number of unique destinations can indicate suspicious activity such as discovery or lateral movement. +- The threshold of 10 unique destinations can be adjusted to suit the environment's baseline activity. +## MITRE ATT&CK Techniques + +- [T1021.004](https://attack.mitre.org/techniques/T1021/004) +- [T1078.003](https://attack.mitre.org/techniques/T1078/003) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/execution_uncommon_process_execution_from_suspicious_directory.md b/hunting/linux/docs/execution_uncommon_process_execution_from_suspicious_directory.md new file mode 100644 index 00000000000..10ef50e2241 --- /dev/null +++ b/hunting/linux/docs/execution_uncommon_process_execution_from_suspicious_directory.md @@ -0,0 +1,59 @@ +# Uncommon Process Execution from Suspicious Directory + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies uncommon process executions from suspicious directories on Linux systems. It looks for processes executed from directories that are often associated with malicious activity, such as /dev/shm, /var/www, /boot, /srv, /tmp, /var/tmp, /run, and /var/run. The goal is to detect potentially malicious processes while excluding common, benign ones. + +- **UUID:** `0ea47044-b161-4785-ba99-e11f46d6ac51` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( +// Add paths to monitor from your environment here + process.executable like "/dev/shm/*" or + process.executable like "/var/www/*" or + process.executable like "/boot/*" or + process.executable like "/srv/*" or + process.executable rlike "/tmp/[^/]+" or + process.executable rlike "/var/tmp/[^/]+" or + process.executable rlike "/run/[^/]+" or + process.executable rlike "/var/run/[^/]+" +) and not ( + // Exclude noisy (parent) processes, users or directories from your environment here + process.parent.executable in ("/usr/sbin/dpkg-preconfigure") or + // Exclude /tmp and /var/tmp instances starting or ending with digits (usually benign files) + process.executable rlike "/tmp/[0-9].*" or + process.executable rlike "/tmp/.*[0-9]/?" or + process.executable rlike "/var/tmp/[0-9].*" or + process.executable rlike "/var/tmp/.*[0-9]/?" +) +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| sort cc asc +| limit 100 +``` + +## Notes + +- Excluded /tmp, /var/tmp, /run, /var/run subdirectories to reduce noise. +- Excluded /tmp, /var/tmp files starting or ending with digits to exclude real temporary files. +- Included a process or parent process count of <= 3, and a host count of <= 3 to eliminate common processes across different hosts. +## MITRE ATT&CK Techniques + +- [T1036.004](https://attack.mitre.org/techniques/T1036/004) +- [T1049](https://attack.mitre.org/techniques/T1049) +- [T1059](https://attack.mitre.org/techniques/T1059) +- [T1059.004](https://attack.mitre.org/techniques/T1059/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/login_activity_by_source_address.md b/hunting/linux/docs/login_activity_by_source_address.md new file mode 100644 index 00000000000..ce4d6bc875a --- /dev/null +++ b/hunting/linux/docs/login_activity_by_source_address.md @@ -0,0 +1,39 @@ +# Logon Activity by Source IP + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies unusual logon activity by source IP on Linux systems. It monitors authentication events, focusing on failed logon attempts from specific IP addresses. A high number of failed logon attempts combined with a low number of successful logons and multiple distinct usernames can indicate a potential brute force or credential stuffing attack. + +- **UUID:** `95c1467d-d566-4645-b5f1-37a4b0093bb6` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-system.auth-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "authentication" and event.action in ("ssh_login", "user_login") and + event.outcome == "failure" and source.ip IS NOT null and not CIDR_MATCH(source.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") +| eval failed = case(event.outcome == "failure", source.ip, null), success = case(event.outcome == "success", source.ip, null) +| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(user.name) by source.ip + /* below threshold should be adjusted to your env logon patterns */ +| where count_failed >= 100 and count_success <= 10 and count_user >= 20 +``` + +## Notes + +- Monitors authentication events and counts failed and successful logon attempts by source IP address. +- A high number of failed logon attempts combined with a low number of successful logons and multiple distinct usernames can indicate a potential brute force or credential stuffing attack. +- The thresholds for failed attempts, successful logons, and distinct usernames should be adjusted based on the environment's normal logon patterns. +## MITRE ATT&CK Techniques + +- [T1110](https://attack.mitre.org/techniques/T1110) +- [T1078](https://attack.mitre.org/techniques/T1078) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/low_volume_external_network_connections_from_process.md b/hunting/linux/docs/low_volume_external_network_connections_from_process.md new file mode 100644 index 00000000000..4abb311deb8 --- /dev/null +++ b/hunting/linux/docs/low_volume_external_network_connections_from_process.md @@ -0,0 +1,50 @@ +# Low Volume External Network Connections from Process by Unique Agent + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies low volume external network connections initiated by processes on Linux systems. It focuses on connections attempted by processes that have been seen infrequently (five or fewer connections) and by unique agents. This can help identify potentially suspicious activity that might be missed due to low volume. + +- **UUID:** `12526f14-5e35-4f5f-884c-96c6a353a544` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and event.type == "start" and event.action == "connection_attempted" and not process.name is null and + not CIDR_MATCH(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", "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", "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", "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", "FF00::/8") +| stats connection_count = count(*), unique_agent_count = count_distinct(agent.id) by process.name +| where connection_count <= 5 and unique_agent_count == 1 +| limit 100 +| sort connection_count, unique_agent_count asc +``` + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and event.type == "start" and event.action == "connection_attempted" and user.id == "0" and not process.name is null and + not CIDR_MATCH(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", "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", "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", "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", "FF00::/8") +| stats connection_count = count(*), unique_agent_count = count_distinct(agent.id) by process.name +| where connection_count <= 5 and unique_agent_count == 1 +| limit 100 +| sort connection_count, unique_agent_count asc +``` + +## Notes + +- Monitors for network connections attempted by processes that have a low occurrence frequency (five or fewer connections) and are seen by a unique agent. +- Excludes common internal IP ranges to minimize false positives. +- A separate query is included to specifically monitor low volume network connections initiated by the root user, as these can be particularly indicative of malicious activity. +## MITRE ATT&CK Techniques + +- [T1071.001](https://attack.mitre.org/techniques/T1071/001) +- [T1071.004](https://attack.mitre.org/techniques/T1071/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/low_volume_gtfobins_external_network_connections.md b/hunting/linux/docs/low_volume_gtfobins_external_network_connections.md new file mode 100644 index 00000000000..3dea88c2c22 --- /dev/null +++ b/hunting/linux/docs/low_volume_gtfobins_external_network_connections.md @@ -0,0 +1,46 @@ +# Low Volume GTFOBins External Network Connections + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies low volume external network connections initiated by GTFOBins on Linux systems. GTFOBins are Unix binaries that can be exploited by attackers to bypass local security restrictions. The hunt focuses on network connections made by these binaries, excluding common internal IP ranges, to detect potentially malicious activity. + +- **UUID:** `783d6091-b98d-45a8-a880-a07f112a8aa2` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and process.name in ( + "ab", "aria2c", "bash", "cpan", "curl", "easy_install", "finger", "ftp", + "gdb", "gimp", "irb", "jjs", "jrunscript", "julia", "ksh", "lua", "lwp-download", + "nc", "nmap", "node", "openssl", "php", "pip", "python", "ruby", "rview", "rvim", + "scp", "sftp", "smbclient", "socat", "ssh", "tar", "tftp", "view", "vim", "vimdiff", + "wget", "whois", "yum" +) and +destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| keep process.name, destination.port, destination.ip, user.name, host.name +| stats cc = count(*) by destination.port, process.name +| where cc <= 5 +| sort cc asc, destination.port +``` + +## Notes + +- Monitors for external network connections initiated by known GTFOBins such as bash, curl, nc, wget, and others. +- Excludes common internal IP ranges to minimize false positives. +- Counts the occurrences of these connections by process name and limits to those seen infrequently (five or fewer connections). +- This can help identify potentially malicious activity involving the exploitation of GTFOBins. +## MITRE ATT&CK Techniques + +- [T1219](https://attack.mitre.org/techniques/T1219) +- [T1071.001](https://attack.mitre.org/techniques/T1071/001) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/low_volume_modifications_to_critical_system_binaries.md b/hunting/linux/docs/low_volume_modifications_to_critical_system_binaries.md new file mode 100644 index 00000000000..388ceeac15d --- /dev/null +++ b/hunting/linux/docs/low_volume_modifications_to_critical_system_binaries.md @@ -0,0 +1,49 @@ +# Low Volume Modifications to Critical System Binaries by Unique Host + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies low volume modifications to critical system binaries on Linux systems. It monitors file modification events in critical directories such as /bin, /usr/bin, /sbin, and /usr/sbin. The hunt focuses on modifications made by unique hosts, excluding expected update processes like package managers. This can help detect unauthorized or suspicious modifications to system binaries. + +- **UUID:** `c7044817-d9a5-4755-abab-9059e50dab24` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and + (file.path like "/bin/*" or file.path like "/usr/bin/*" or file.path like "/sbin/*" or file.path like "/usr/sbin/*") and + not ( + + // Exclude expected update processes, e.g., package managers + process.executable in ("/usr/bin/apt", "/usr/bin/dpkg", "/usr/bin/yum", "/usr/bin/rpm", "/usr/bin/pacman", + "/usr/bin/pamac-daemon", "/usr/bin/update-alternatives", "/usr/bin/dockerd", "/usr/bin/microdnf", "/sbin/apk") or + + // Exclude certain benign or expected modification patterns, if applicable + file.path like "/usr/bin/gzip*" // Example exclusion, adjust based on your environment +) +| stats modification_count = count(file.path), unique_files_modified = count_distinct(file.path), host_count = count_distinct(host.name) by process.executable +| where modification_count >= 1 and host_count == 1 +| sort modification_count asc +| limit 100 +``` + +## Notes + +- Monitors for file modifications in critical directories like /bin, /usr/bin, /sbin, and /usr/sbin. +- Excludes modifications made by expected update processes such as package managers to reduce false positives. +- Counts the number of unique files modified by each host and the number of modifications made. +- Focuses on modifications made by unique hosts to detect unauthorized or suspicious changes. +## MITRE ATT&CK Techniques + +- [T1070.004](https://attack.mitre.org/techniques/T1070/004) +- [T1569.002](https://attack.mitre.org/techniques/T1569/002) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/low_volume_process_injection_syscalls_by_executable.md b/hunting/linux/docs/low_volume_process_injection_syscalls_by_executable.md new file mode 100644 index 00000000000..c3977a40de1 --- /dev/null +++ b/hunting/linux/docs/low_volume_process_injection_syscalls_by_executable.md @@ -0,0 +1,38 @@ +# Low Volume Process Injection-Related Syscalls by Process Executable + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies low volume process injection-related syscalls on Linux systems. It monitors audit logs for syscalls related to process injection, such as ptrace and memfd_create. The hunt focuses on processes that make these syscalls infrequently, which can indicate potential malicious activity. + +- **UUID:** `c9931736-d5ec-4c89-b4d2-d71dcf5ca12a` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-auditd_manager.auditd-*, logs-auditd.log-*, auditbeat-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and auditd.data.syscall in ("ptrace", "memfd_create") +| stats cc = count(*) by process.executable, auditd.data.syscall +| where cc <= 10 +| limit 100 +| sort cc asc +``` + +## Notes + +- Monitors for process injection-related syscalls such as ptrace and memfd_create. +- Counts the occurrences of these syscalls by process executable to identify processes that make these syscalls infrequently. +- Focuses on low volume occurrences to detect potential malicious activity related to process injection. +## MITRE ATT&CK Techniques + +- [T1055.001](https://attack.mitre.org/techniques/T1055/001) +- [T1055.009](https://attack.mitre.org/techniques/T1055/009) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_reverse_bind_shells.md b/hunting/linux/docs/persistence_reverse_bind_shells.md new file mode 100644 index 00000000000..cad0ab53f2d --- /dev/null +++ b/hunting/linux/docs/persistence_reverse_bind_shells.md @@ -0,0 +1,58 @@ +# Persistence Through Reverse/Bind Shells + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt provides several OSQuery queries that can aid in the detection of reverse/bind shells. Reverse shells are a type of shell in which the target machine communicates back to the attacking machine. Bind shells are a type of shell in which the target machine opens a communication port on the victim machine and waits for an attacker to connect to it. These shells can be used by attackers to gain remote access to a system. + +- **UUID:** `7422faf1-ba51-49c3-b8ba-13759e6bcec4` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[SQL]` + +## Query + +```sql +SELECT ( + CASE family + WHEN 2 THEN 'IP4' + WHEN 10 THEN 'IP6' + ELSE family END +) AS family, ( + CASE protocol + WHEN 6 THEN 'TCP' + WHEN 17 THEN 'UDP' + ELSE protocol END +) AS protocol, local_address, local_port, + remote_address, remote_port +FROM process_open_sockets +WHERE family IN (2, 10) +AND protocol IN (6, 17) +``` + +```sql +SELECT cmdline, name, path, pid, state, threads, total_size +FROM processes +WHERE cmdline != '' +``` + +```sql +SELECT pid, address, port, socket, protocol, path FROM listening_ports +``` + +## Notes + +- The hunt provides OSQuery queries to detect reverse/bind shells on Linux systems. +- The first hunt query retrieves information about open sockets on the system. +- The second hunt query retrieves information about running processes on the system. +- The third hunt query retrieves information about listening ports on the system. +- Investigate strange or unexpected open sockets, processes, or listening ports on the system. +- Use the information from each hunt to pivot and investigate further for potential reverse/bind shells. +## MITRE ATT&CK Techniques + +- [T1059.004](https://attack.mitre.org/techniques/T1059/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_cron.md b/hunting/linux/docs/persistence_via_cron.md new file mode 100644 index 00000000000..f833a5568bc --- /dev/null +++ b/hunting/linux/docs/persistence_via_cron.md @@ -0,0 +1,111 @@ +# Persistence via Cron + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via cron on Linux systems. It monitors for file creation or modification events related to cron configurations and processes spawned by cron, fcron, or atd. These activities can indicate attempts to establish persistence through scheduled tasks. + +- **UUID:** `e1cffb7c-4acf-4e7a-8d72-b8b7657cf7b8` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path in ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") or + file.path like "/etc/cron.*/*" or + file.path like "/var/spool/cron/crontabs/*" or + file.path like "/var/spool/anacron/*" or + file.path like "/var/spool/cron/atjobs/*" or + file.path like "/var/spool/fcron/*" or + file.path like "/home/*/.tsp/*" +) and not ( + process.name in ("dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "anacron") or + file.extension in ("dpkg-remove", "swx", "swp") or + file.name like "tmp.*" +) +| eval persistence = case( + file.path in ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") or + file.path like "/etc/cron.*/*" or + file.path like "/var/spool/cron/crontabs/*" or + file.path like "/var/spool/anacron/*" or + file.path like "/var/spool/cron/atjobs/*" or + file.path like "/var/spool/fcron/*" or + file.path like "/home/*/.tsp/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 3 +| sort pers_count asc +| limit 100 +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("cron", "fcron", "atd") +| stats cc = count(), host_count = count_distinct(host.id) by process.command_line +| where host_count <= 3 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path IN ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") + OR f.path LIKE "/etc/cron.%/*" + OR f.path LIKE "/var/spool/cron/crontabs/%" + OR f.path LIKE "/var/spool/anacron/%" + OR f.path LIKE "/var/spool/cron/atjobs/%" + OR f.path LIKE "/var/spool/fcron/%" + OR f.path LIKE "/home/%/.tsp/%" + OR f.path LIKE "/etc/cron.allow.d/%" + OR f.path LIKE "/etc/cron.d/%" + OR f.path LIKE "/etc/cron.hourly/%" + OR f.path LIKE "/etc/cron.daily/%" + OR f.path LIKE "/etc/cron.weekly/%" + OR f.path LIKE "/etc/cron.monthly/%" +``` + +```sql +SELECT * FROM crontab +``` + +## Notes + +- This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via cron on Linux systems. +- Detects file creation or modification events in directories and files associated with cron configurations, such as /etc/cron.allow, /etc/cron.deny, /etc/crontab, all /etc/cron.* directories and various /var/spool directories. +- Excludes common legitimate processes and file types to minimize false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by cron, fcron, or atd to detect potential persistence mechanisms. +- OSQuery queries are provided to complement the detection by retrieving detailed file information and crontab entries. +## MITRE ATT&CK Techniques + +- [T1053.003](https://attack.mitre.org/techniques/T1053/003) +- [T1053.005](https://attack.mitre.org/techniques/T1053/005) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_driver_load_with_low_occurrence_frequency.md b/hunting/linux/docs/persistence_via_driver_load_with_low_occurrence_frequency.md new file mode 100644 index 00000000000..50646d11a8f --- /dev/null +++ b/hunting/linux/docs/persistence_via_driver_load_with_low_occurrence_frequency.md @@ -0,0 +1,39 @@ +# Drivers Load with Low Occurrence Frequency + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies drivers loaded with low occurrence frequency on Linux systems. It monitors for the loading of kernel modules (drivers) that have only been seen once across a single host within a year. Such activity can indicate the presence of rare or potentially malicious drivers. + +- **UUID:** `e1f59c9a-7a2a-4eb8-a524-97b16a041a4a` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-auditd_manager.auditd-*, logs-auditd.log-*, auditbeat-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.category == "driver" and event.action == "loaded-kernel-module" and auditd.data.syscall in ("init_module", "finit_module") +| stats host_count = count_distinct(host.id), total_count = count(*) by auditd.data.name, process.executable, process.name +// Alter this threshold to make sense for your environment +| where host_count == 1 and total_count == 1 +| limit 100 +| sort auditd.data.name asc +``` + +## Notes + +- Monitors for kernel modules loaded with syscall 'init_module' or 'finit_module', indicating driver load events. +- Counts the occurrence of each driver across all hosts and identifies those seen only once on a single host within the past year. +- Such rare driver loads can indicate potentially malicious activity or the presence of uncommon drivers. +## MITRE ATT&CK Techniques + +- [T1547.006](https://attack.mitre.org/techniques/T1547/006) +- [T1069.002](https://attack.mitre.org/techniques/T1069/002) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_git_hook_pager.md b/hunting/linux/docs/persistence_via_git_hook_pager.md new file mode 100644 index 00000000000..b4b7d6effea --- /dev/null +++ b/hunting/linux/docs/persistence_via_git_hook_pager.md @@ -0,0 +1,90 @@ +# Git Hook/Pager Persistence + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via Git hooks and configurations on Linux systems. It monitors file creation or modification events in Git configuration and hook directories, as well as processes started by Git hooks. These activities can indicate attempts to establish persistence through Git configurations. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `2d7bb29d-d53f-47ab-a0b4-1818adb91423` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path == "/etc/gitconfig" or + file.path like "*/.git/config" or + file.path like "/home/*/.gitconfig" or + file.path like "*/.git/hooks/*" +) and process.name != "git" +| eval persistence = case( + file.path == "/etc/gitconfig" or + file.path like "*/.git/config" or + file.path like "/home/*/.gitconfig" or + file.path like "*/.git/hooks/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 4 +| sort pers_count asc +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.executable like "*.git/hooks/*" +| stats cc = count(), host_count = count_distinct(host.name) by process.parent.executable, process.executable +| where cc < 50 and host_count <= 5 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change time, + datetime(f.btime, 'unixepoch') AS file created time, + f.size AS size bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path == '/etc/gitconfig' + OR f.path LIKE '/%%/.git/config' + OR f.path LIKE '/home/%/.gitconfig' + OR f.path LIKE '/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/%%/%%/.git/hooks/%' +``` + +## Notes + +- Monitors for file creation or modification events in Git configuration and hook directories such as /etc/gitconfig, .git/config, /home/*/.gitconfig, and .git/hooks/. +- Excludes modifications made by the Git process itself to reduce false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by Git hooks to detect suspicious activity related to Git configurations. +- OSQuery query is provided to retrieve detailed file information related to Git configurations and hooks. +- OSQuery has limited support for wildcard queries, therefore the query includes multiple LIKE conditions for directories. These can be increased and decreased based on the environment's Git configuration paths. +## MITRE ATT&CK Techniques + +- [T1546.004](https://attack.mitre.org/techniques/T1546/004) +- [T1059.004](https://attack.mitre.org/techniques/T1059/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_message_of_the_day.md b/hunting/linux/docs/persistence_via_message_of_the_day.md new file mode 100644 index 00000000000..92186d46311 --- /dev/null +++ b/hunting/linux/docs/persistence_via_message_of_the_day.md @@ -0,0 +1,80 @@ +# Persistence via Message-of-the-Day + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via the message-of-the-day (motd) on Linux systems. It monitors for file creation or modification events in the /etc/update-motd.d directory and processes started by these motd scripts. These scripts launch on SSH/terminal connection events, and execute the scripts as root. These activities can indicate attempts to establish persistence through motd modifications. + +- **UUID:** `5984a354-d76c-43e6-bdd9-228456f1b371` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and file.path like "/etc/update-motd.d/*" and +not process.name in ("dpkg", "dockerd", "yum", "dnf", "snapd", "pacman") +| eval persistence = case(file.path like "/etc/update-motd.d/*", process.name, null) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 5 +| sort pers_count asc +| limit 100 +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.executable like "/etc/update-motd.d/*" and +not process.args like "/tmp/tmp.*" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable +| where host_count <= 5 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ('/etc/update-motd.d/') +ORDER BY + f.mtime DESC; +``` + +## Notes + +- This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via the message-of-the-day (motd) on Linux systems. +- Detects file creation or modification events in the /etc/update-motd.d directory, which is used for message-of-the-day scripts. +- Excludes common legitimate processes to minimize false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by motd scripts to detect potential persistence mechanisms. +- OSQuery query is provided to complement the detection by retrieving detailed file information related to motd scripts. +## MITRE ATT&CK Techniques + +- [T1036.005](https://attack.mitre.org/techniques/T1036/005) +- [T1546.003](https://attack.mitre.org/techniques/T1546/003) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_package_manager.md b/hunting/linux/docs/persistence_via_package_manager.md new file mode 100644 index 00000000000..06291d88fe6 --- /dev/null +++ b/hunting/linux/docs/persistence_via_package_manager.md @@ -0,0 +1,100 @@ +# Persistence via Packager Manager + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via package manager configurations on Linux systems. It monitors file creation or modification events in directories related to APT, YUM, and DNF package managers. Additionally, it monitors processes started by these package managers. These activities can indicate attempts to establish persistence through package manager configurations. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `2d01a413-8d97-407a-8698-02dfc7119c97` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path like "/etc/apt/apt.conf.d/*" or + file.path like "/usr/lib/python*/site-packages/dnf-plugins/*" or + file.path like "/etc/dnf/plugins/*" or + file.path like "/usr/lib/yum-plugins/*" or + file.path like "/etc/yum/pluginconf.d/*" +) and not process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "microdnf", "podman", "apk", "yumBackend.py" +) +| eval persistence = case( + file.path like "/etc/apt/apt.conf.d/*" or + file.path like "/usr/lib/python*/site-packages/dnf-plugins/*" or + file.path like "/etc/dnf/plugins/*" or + file.path like "/usr/lib/yum-plugins/*" or + file.path like "/etc/yum/pluginconf.d/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 4 +| sort pers_count asc +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("apt", "yum", "dnf") +| stats cc = count(), host_count = count_distinct(host.name) by process.executable +| where host_count <= 5 and cc < 50 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group owner, + datetime(f.atime, 'unixepoch') AS file_last_access time, + datetime(f.mtime, 'unixepoch') AS file last_modified time, + datetime(f.ctime, 'unixepoch') AS file last_status change time, + datetime(f.btime, 'unixepoch') AS file created time, + f.size AS size bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE '/etc/apt/apt.conf.d/%' + OR f.path LIKE '/usr/lib/python%/site-packages/dnf-plugins/%' + OR f.path LIKE '/etc/dnf/plugins/%' + OR f.path LIKE '/usr/lib/yum-plugins/%' + OR f.path LIKE '/etc/yum/pluginconf.d/%' +``` + +```sql +SELECT * FROM apt_sources +``` + +```sql +SELECT * FROM yum_sources +``` + +## Notes + +- Monitors for file creation or modification events in directories related to APT, YUM, and DNF package managers such as /etc/apt/apt.conf.d/, /etc/dnf/plugins/, /usr/lib/yum-plugins/, and others. +- Excludes modifications made by expected update processes such as package managers to reduce false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by package managers to detect suspicious activity related to package manager configurations. +- OSQuery queries are provided to retrieve detailed file information related to package manager configurations, as well as sources for APT and YUM. +## MITRE ATT&CK Techniques + +- [T1546.004](https://attack.mitre.org/techniques/T1546/004) +- [T1059.004](https://attack.mitre.org/techniques/T1059/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_rc_local.md b/hunting/linux/docs/persistence_via_rc_local.md new file mode 100644 index 00000000000..c5a2933e3f8 --- /dev/null +++ b/hunting/linux/docs/persistence_via_rc_local.md @@ -0,0 +1,81 @@ +# Persistence via rc.local/rc.common + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via rc.local and rc.common on Linux systems. RC scripts are used to start custom applications, services, scripts or commands during start-up. RC scripts have mostly been replaced by Systemd. However, through the "systemd-rc-local-generator", these files can be converted to services that run at boot. The query monitors for file creation or modification events in the /etc/rc.local and /etc/rc.common files, as well as processes started by these scripts. These activities can indicate attempts to establish persistence through rc.local modifications. + +- **UUID:** `a95f778f-2193-4a3d-bbbe-7b02d5740638` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [system](https://docs.elastic.co/integrations/system) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and (file.path == "/etc/rc.local" or file.path == "/etc/rc.common") +| eval persistence = case(file.path == "/etc/rc.local" or file.path == "/etc/rc.common", process.name, null) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable +| where pers_count > 0 and pers_count <= 3 and agent_count <= 3 +| sort pers_count asc +| limit 100 +``` + +```sql +from logs-system.syslog-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and process.name in ("rc.local", "rc.common") +| stats cc = count(), host_count = count_distinct(host.name) by message +| where host_count <= 3 and cc < 10 +| sort cc asc +| limit 100 +``` + +```sql +SELECT * FROM systemd_units WHERE id = "rc-local.service" +``` + +```sql +SELECT * FROM startup_items WHERE name = "rc-local.service" +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path in ('/etc/rc.local', '/etc/rc.common') +``` + +## Notes + +- This hunt includes multiple ES|QL and OSQuery queries to detect potential persistence mechanisms via rc.local on Linux systems. +- Detects file creation or modification events in the /etc/rc.local and /etc/rc.common files, which are used for system initialization scripts. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by rc.local and rc.common scripts to detect potential persistence mechanisms. +- Syslog hunting query is provided to complement the detection by analyzing syslog entries related to rc.local and rc.common processes. +- OSQuery queries are provided to retrieve systemd unit states, startup items, and detailed file information related to rc.local and rc.common. +## MITRE ATT&CK Techniques + +- [T1037.004](https://attack.mitre.org/techniques/T1037/004) +- [T1546.003](https://attack.mitre.org/techniques/T1546/003) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_shell_modification_persistence.md b/hunting/linux/docs/persistence_via_shell_modification_persistence.md new file mode 100644 index 00000000000..f8106640c2f --- /dev/null +++ b/hunting/linux/docs/persistence_via_shell_modification_persistence.md @@ -0,0 +1,110 @@ +# Shell Modification Persistence + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via modifications to shell profile files on Linux systems. It monitors file creation or modification events in system-wide and user-specific profile files, which can indicate attempts to establish persistence through shell modifications. It also monitors processes started by SSH daemons to detect suspicious activity related to SSH logins. + +- **UUID:** `20a02fad-2a09-44c0-a8ce-ce4502859c8a` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide profile files + file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or + file.path like "/etc/profile.d/*" or + + // User-specific profile files + file.path like "/home/*/.profile" or + file.path like "/home/*/.bash_profile" or + file.path like "/home/*/.bash_login" or + file.path like "/home/*/.bash_logout" or + file.path like "/home/*/.bashrc" +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "microdnf", "podman", "apk" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + // System-wide profile files + file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or + file.path like "/etc/profile.d/*" or + + // User-specific profile files + file.path like "/home/*/.profile" or + file.path like "/home/*/.bash_profile" or + file.path like "/home/*/.bash_login" or + file.path like "/home/*/.bash_logout" or + file.path like "/home/*/.bashrc", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.parent.name == "sshd" +| stats cc = count(*) by process.command_line +| where cc <= 20 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path IN ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") + OR f.path LIKE "/etc/profile.d/%" + OR f.path LIKE "/home/%/.profile" + OR f.path LIKE "/home/%/.bash_profile" + OR f.path LIKE "/home/%/.bash_login" + OR f.path LIKE "/home/%/.bash_logout" + OR f.path LIKE "/home/%/.bashrc" +``` + +## Notes + +- Monitors for file creation or modification events in system-wide and user-specific profile files, such as /etc/profile, /etc/bash.bashrc, /home/*/.bashrc, and others. +- Excludes modifications made by expected update processes such as package managers to reduce false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by SSH daemons (sshd) to detect suspicious activity related to SSH logins. +- OSQuery query is provided to retrieve detailed file information related to profile files. +## MITRE ATT&CK Techniques + +- [T1546.004](https://attack.mitre.org/techniques/T1546/004) +- [T1053.005](https://attack.mitre.org/techniques/T1053/005) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_ssh_configurations_and_keys.md b/hunting/linux/docs/persistence_via_ssh_configurations_and_keys.md new file mode 100644 index 00000000000..7ce2580a3ed --- /dev/null +++ b/hunting/linux/docs/persistence_via_ssh_configurations_and_keys.md @@ -0,0 +1,68 @@ +# Persistence via SSH Configurations and/or Keys + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential SSH persistence mechanisms on Linux systems using OSQuery. It monitors SSH keys, authorized_keys files, SSH configuration files, and SSH file information to detect unauthorized access or persistence techniques. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `aa759db0-4499-42f2-9f2f-be3e00fdebfa` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[SQL]` + +## Query + +```sql +SELECT * FROM user_ssh_keys +``` + +```sql +SELECT authorized_keys.* +FROM users +JOIN authorized_keys +USING(uid) +``` + +```sql +SELECT * FROM ssh_configs +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE "/root/.ssh/%" + OR f.path LIKE "/home/%/.ssh/%" + OR f.path LIKE "/etc/ssh/%" + OR f.path LIKE "/etc/ssh/sshd_config.d/%" + OR f.path LIKE "/etc/ssh/ssh_config.d/%" +``` + +## Notes + +- Monitors SSH keys, authorized_keys files, and SSH configuration files using OSQuery to detect potential unauthorized access or persistence techniques. +- Lists detailed information about SSH files, including paths, owners, and permissions. +- Requires additional data analysis and investigation into results to identify malicious or unauthorized SSH configurations and keys. +## MITRE ATT&CK Techniques + +- [T1098.004](https://attack.mitre.org/techniques/T1098/004) +- [T1563.001](https://attack.mitre.org/techniques/T1563/001) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_systemd_timers.md b/hunting/linux/docs/persistence_via_systemd_timers.md new file mode 100644 index 00000000000..4fa8ef0eaed --- /dev/null +++ b/hunting/linux/docs/persistence_via_systemd_timers.md @@ -0,0 +1,202 @@ +# Persistence via Systemd (Timers) + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via systemd (timers) on Linux systems. It monitors for file creation or modification events related to systemd service and timer configurations, as well as generators, which can indicate attempts to establish persistence through scheduled tasks. + +- **UUID:** `d2d24ad6-a315-4e05-a3f9-e205eb805df4` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide/user-specific services/timers (root permissions required) + file.path like "/run/systemd/system/*" or + file.path like "/etc/systemd/system/*" or + file.path like "/etc/systemd/user/*" or + file.path like "/usr/local/lib/systemd/system/*" or + file.path like "/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/user/*" or + + // user-specific services/timers (user permissions required) + file.path like "/home/*/.config/systemd/user/*" or + file.path like "/home/*/.local/share/systemd/user/*" or + + // System-wide generators (root permissions required) + file.path like "/etc/systemd/system-generators/*" or + file.path like "/usr/local/lib/systemd/system-generators/*" or + file.path like "/lib/systemd/system-generators/*" or + file.path like "/etc/systemd/user-generators/*" or + file.path like "/usr/local/lib/systemd/user-generators/*" or + file.path like "/usr/lib/systemd/user-generators/*" + +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "netplan", "systemd", "generate" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + + // System-wide/user-specific services/timers (root permissions required) + file.path like "/run/systemd/system/*" or + file.path like "/etc/systemd/system/*" or + file.path like "/etc/systemd/user/*" or + file.path like "/usr/local/lib/systemd/system/*" or + file.path like "/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/user/*" or + + // user-specific services/timers (user permissions required) + file.path like "/home/*/.config/systemd/user/*" or + file.path like "/home/*/.local/share/systemd/user/*" or + + // System-wide generators (root permissions required) + file.path like "/etc/systemd/system-generators/*" or + file.path like "/usr/local/lib/systemd/system-generators/*" or + file.path like "/lib/systemd/system-generators/*" or + file.path like "/etc/systemd/user-generators/*" or + file.path like "/usr/local/lib/systemd/user-generators/*" or + file.path like "/usr/lib/systemd/user-generators/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + (f.path LIKE "/run/systemd/system/%" + OR f.path LIKE "/etc/systemd/system/%" + OR f.path LIKE "/etc/systemd/user/%" + OR f.path LIKE "/usr/local/lib/systemd/system/%" + OR f.path LIKE "/lib/systemd/system/%" + OR f.path LIKE "/usr/lib/systemd/system/%" + OR f.path LIKE "/usr/lib/systemd/user/%" + OR f.path LIKE "/home/%/.config/systemd/user/%" + OR f.path LIKE "/home/%/.local/share/systemd/user/%") + AND f.filename LIKE "%.service" +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/run/systemd/system', + '/etc/systemd/system', + '/etc/systemd/user', + '/usr/local/lib/systemd/system', + '/lib/systemd/system', + '/usr/lib/systemd/system', + '/usr/lib/systemd/user', + '/home/.config/systemd/user', + '/home/.local/share/systemd/user' + ) + AND f.filename LIKE "%.timer" +ORDER BY + f.mtime DESC; +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/etc/systemd/system-generators/', + '/usr/local/lib/systemd/system-generators/', + '/lib/systemd/system-generators/', + '/etc/systemd/user-generators/', + '/usr/local/lib/systemd/user-generators/', + '/usr/lib/systemd/user-generators/' + ) +ORDER BY + f.mtime DESC; +``` + +```sql +SELECT name, path, source, status, type FROM startup_items +WHERE type == "systemd unit" AND status == "active" AND +name LIKE "%.service" OR name LIKE "%.timer" +``` + +## Notes + +- This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via systemd timers on Linux systems. +- Detects file creation or modification events in directories and files associated with systemd services, timers, and generators, such as /run/systemd/system, /etc/systemd/system, /etc/systemd/user, and various /usr/lib/systemd directories. +- Excludes common legitimate processes and file types to minimize false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- OSQuery queries are provided to complement the detection by retrieving detailed file information and entries related to systemd services, timers, and generators. +## MITRE ATT&CK Techniques + +- [T1053.005](https://attack.mitre.org/techniques/T1053/005) +- [T1546.002](https://attack.mitre.org/techniques/T1546/002) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_udev.md b/hunting/linux/docs/persistence_via_udev.md new file mode 100644 index 00000000000..eeee34ed74d --- /dev/null +++ b/hunting/linux/docs/persistence_via_udev.md @@ -0,0 +1,99 @@ +# Persistence via Udev + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via Udev rules on Linux systems. Udev is a device manager for the Linux kernel that manages device nodes in /dev. Udev is responsible for creating and removing device nodes in /dev when devices are added or removed from the system. Udev executes scripts when devices are added or removed from the system. This query monitors file creation or modification events in Udev rule directories and processes started by Udevadm. These activities can indicate attempts to establish persistence through Udev configurations. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `8d42a644-5b60-4165-a8f1-84d5bcdd4ade` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path like "/etc/udev/rules.d/*" or + file.path like "/run/udev/rules.d/*" or + file.path like "/usr/lib/udev/rules.d/*" or + file.path like "/lib/udev/*" +) and not process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "microdnf", "podman", "apk", "netplan", "generate" +) +| eval persistence = case( + file.path like "/etc/udev/rules.d/*" or + file.path like "/run/udev/rules.d/*" or + file.path like "/usr/lib/udev/rules.d/*" or + file.path like "/lib/udev/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name == "udevadm" and +// Excluding these because this is typical udev behavior. +// If you suspect Udev persistence, remove this exclusion in order to do a more elaborate search +not (process.executable like "/lib/*" or process.executable like "/usr/lib/*") +| stats cc = count(), host_count = count_distinct(host.name) by process.executable +// Tweak the process/host count if you suspect Udev persistence +| where host_count <= 5 and cc < 50 +| sort cc asc +| limit 100 +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/etc/udev/rules.d/', + '/run/udev/rules.d/', + '/usr/lib/udev/rules.d/', + '/lib/udev/' + ) +ORDER BY + f.mtime DESC; +``` + +## Notes + +- Monitors for file creation or modification events in Udev rule directories such as /etc/udev/rules.d/, /run/udev/rules.d/, /usr/lib/udev/rules.d/, and /lib/udev/. +- Excludes modifications made by expected update processes such as package managers to reduce false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by Udevadm to detect suspicious activity related to Udev rules. +- OSQuery query is provided to retrieve detailed file information related to Udev rules. +## MITRE ATT&CK Techniques + +- [T1547.010](https://attack.mitre.org/techniques/T1547/010) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_unusual_system_binary_parent.md b/hunting/linux/docs/persistence_via_unusual_system_binary_parent.md new file mode 100644 index 00000000000..f2ded333279 --- /dev/null +++ b/hunting/linux/docs/persistence_via_unusual_system_binary_parent.md @@ -0,0 +1,39 @@ +# Unusual System Binary Parent (Potential System Binary Hijacking Attempt) + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential system binary hijacking attempts on Linux systems. It monitors process execution events where common system binaries such as ls, cat, mkdir, touch, mv, and cp are the parent processes. These activities can indicate attempts to hijack system binaries for malicious purposes. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `d22cbe8f-c84d-4811-aa6d-f1ee00c806b2` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("ls", "cat", "mkdir", "touch", "mv", "cp") +| stats cc = count(), host_count = count_distinct(host.name) by process.parent.executable, process.executable +| where host_count <= 5 +| sort cc asc +| limit 100 +``` + +## Notes + +- Monitors process execution events where common system binaries such as ls, cat, mkdir, touch, mv, and cp are the parent processes. +- Focuses on identifying unusual or suspicious child processes spawned by these common system binaries. +- Uses stats to count occurrences and identify unusual activity by looking at the number of unique hosts and processes involved. +- Requires additional data analysis and investigation into results to identify malicious or unauthorized use of system binaries. +## MITRE ATT&CK Techniques + +- [T1546.004](https://attack.mitre.org/techniques/T1546/004) +- [T1059.004](https://attack.mitre.org/techniques/T1059/004) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_user_group_creation_modification.md b/hunting/linux/docs/persistence_via_user_group_creation_modification.md new file mode 100644 index 00000000000..b5b00b6cbd5 --- /dev/null +++ b/hunting/linux/docs/persistence_via_user_group_creation_modification.md @@ -0,0 +1,55 @@ +# Privilege Escalation/Persistence via User/Group Creation and/or Modification + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies user and group creation or modification activities on Linux systems using OSQuery. It monitors changes to the shadow file, user and group information, and user processes. These activities can indicate potential unauthorized access or privilege escalation attempts. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `f00c9757-d21b-432c-90a6-8372f18075d0` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[SQL]` + +## Query + +```sql +SELECT * FROM shadow +``` + +```sql +SELECT * FROM shadow +WHERE password_status != "locked" +``` + +```sql +SELECT username, gid, uid, shell, description FROM users +WHERE username != 'root' AND uid LIKE "0" +``` + +```sql +SELECT * FROM users WHERE username = "newuser" +``` + +```sql +SELECT * FROM logged_in_users WHERE user = "newuser" +``` + +```sql +SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username +``` + +## Notes + +- Monitors changes to the shadow file and user/group information using OSQuery to detect potentially unauthorized access or privilege escalation attempts. +- Lists detailed information about users, including authentication status and running processes. +- Requires additional data analysis and investigation into results to identify malicious or unauthorized user and group modifications. +## MITRE ATT&CK Techniques + +- [T1136](https://attack.mitre.org/techniques/T1136) +- [T1136.001](https://attack.mitre.org/techniques/T1136/001) +- [T1136.002](https://attack.mitre.org/techniques/T1136/002) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/persistence_via_xdg_autostart_modifications.md b/hunting/linux/docs/persistence_via_xdg_autostart_modifications.md new file mode 100644 index 00000000000..1cc36fca27b --- /dev/null +++ b/hunting/linux/docs/persistence_via_xdg_autostart_modifications.md @@ -0,0 +1,134 @@ +# XDG Persistence + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies potential persistence mechanisms via modifications to XDG autostart directories on Linux systems. XDG Autostart entries can be used to execute arbitrary commands or scripts when a user logs in. It monitors file creation or modification events in system-wide, user-specific, and root-specific autostart directories. Additionally, it monitors processes started by common Linux desktop session managers to detect suspicious activity related to autostart entries. + +- **UUID:** `8dcc2161-65e0-4448-a03a-1c4e0cbc9330` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL, SQL]` + +## Query + +```sql +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide autostart directories + file.path like "/etc/xdg/autostart/*" or + file.path like "/usr/share/autostart/*" or + + // User-specific autostart directories + file.path like "/home/*/.config/autostart/*" or + file.path like "/home/*/.local/share/autostart/*" or + file.path like "/home/*/.config/autostart-scripts/*" or + + // Root-specific autostart directories + file.path like "/root/.config/autostart/*" or + file.path like "/root/.local/share/autostart/*" or + file.path like "/root/.config/autostart-scripts/*" +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "microdnf", "podman", "apk" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + // System-wide autostart directories + file.path like "/etc/xdg/autostart/*" or + file.path like "/usr/share/autostart/*" or + + // User-specific autostart directories + file.path like "/home/*/.config/autostart/*" or + file.path like "/home/*/.local/share/autostart/*" or + file.path like "/home/*/.config/autostart-scripts/*" or + + // Root-specific autostart directories + file.path like "/root/.config/autostart/*" or + file.path like "/root/.local/share/autostart/*" or + file.path like "/root/.config/autostart-scripts/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.parent.name in ( + "plasmashell", "gnome-session", "xfce4-session", "gnome-session-binary", "mate-session", "cinnamon-session", + "lxsession", "lxqt-session", "unity-session", "pantheon-session", "enlightenment_start" +) +| stats cc = count(*) by process.command_line, process.parent.executable +| where cc <= 20 +| sort cc asc +| limit 100 +``` + +```sql +SELECT name, path, source, status, type FROM startup_items +WHERE type == "Startup Item" AND status == "enabled" AND ( + source LIKE "/etc/xdg/autostart/%" + OR source LIKE "/usr/share/autostart/%" + OR source LIKE "/home/%/.config/autostart/%" + OR source LIKE "/home/%/.local/share/autostart/%" + OR source LIKE "/home/%/.config/autostart-scripts/%" + OR source LIKE "/root/.config/autostart/%" + OR source LIKE "/root/.local/share/autostart/%" + OR source LIKE "/root/.config/autostart-scripts/%" +) +``` + +```sql +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE "/etc/xdg/autostart/%" + OR f.path LIKE "/usr/share/autostart/%" + OR f.path LIKE "/home/%/.config/autostart/%" + OR f.path LIKE "/home/%/.local/share/autostart/%" + OR f.path LIKE "/home/%/.config/autostart-scripts/%" + OR f.path LIKE "/root/.config/autostart/%" + OR f.path LIKE "/root/.local/share/autostart/%" + OR f.path LIKE "/root/.config/autostart-scripts/%" +``` + +## Notes + +- Monitors for file creation or modification events in system-wide, user-specific, and root-specific XDG autostart directories. +- Excludes modifications made by expected update processes such as package managers to reduce false positives. +- Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity. +- Monitors processes started by common Linux desktop session managers to detect suspicious activity related to autostart entries. +- OSQuery queries are provided to retrieve enabled XDG startup items and detailed file information related to autostart directories. +## MITRE ATT&CK Techniques + +- [T1547.001](https://attack.mitre.org/techniques/T1547/001) +- [T1053.005](https://attack.mitre.org/techniques/T1053/005) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/privilege_escalation_via_existing_sudoers.md b/hunting/linux/docs/privilege_escalation_via_existing_sudoers.md new file mode 100644 index 00000000000..4cf374db503 --- /dev/null +++ b/hunting/linux/docs/privilege_escalation_via_existing_sudoers.md @@ -0,0 +1,31 @@ +# Privilege Escalation Identification via Existing Sudoers File + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies entries in the sudoers file on Linux systems using OSQuery. The sudoers file controls which users have administrative privileges and can be a target for attackers seeking to escalate their privileges. This hunt lists all sudoers rules for further analysis. + +- **UUID:** `6e57e6a6-f150-405d-b8be-e4e666a3a86d` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[SQL]` + +## Query + +```sql +SELECT * FROM sudoers +``` + +## Notes + +- Lists all entries in the sudoers file using OSQuery to detect potentially unauthorized or suspicious rules. +- Requires additional data analysis and investigation into results to identify malicious or misconfigured sudoers entries. +- Focuses on monitoring and analyzing administrative privileges granted through the sudoers file. +## MITRE ATT&CK Techniques + +- [T1548.003](https://attack.mitre.org/techniques/T1548/003) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/privilege_escalation_via_process_capabilities.md b/hunting/linux/docs/privilege_escalation_via_process_capabilities.md new file mode 100644 index 00000000000..7384115d961 --- /dev/null +++ b/hunting/linux/docs/privilege_escalation_via_process_capabilities.md @@ -0,0 +1,59 @@ +# Process Capability Hunting + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies processes on Linux systems with specific capabilities set. It monitors process execution events where processes have effective or permitted capabilities, which can be indicative of elevated privileges. The hunt focuses on non-root users to detect potential privilege escalation attempts. The hunt lists detailed information for further analysis and investigation. + +- **UUID:** `6f67704d-e5b1-4613-912c-e2965660fe17` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and (process.thread.capabilities.effective is not null or process.thread.capabilities.permitted is not null) and user.id != "0" and +not ( + // Remove these if you expect persistence through capabilities + process.executable like "/var/lib/docker/*" or + process.name == "gnome-keyring-daemon" or + process.thread.capabilities.permitted == "CAP_WAKE_ALARM" +) +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.thread.capabilities.effective, process.thread.capabilities.permitted +| where host_count <= 3 and cc < 5 +| sort cc asc +| limit 100 +``` + +```sql +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and ( + process.thread.capabilities.effective in ("CAP_SYS_MODULE", "CAP_SYS_PTRACE", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_SETUID", "CAP_SETGID", "CAP_SYS_ADMIN") or + process.thread.capabilities.permitted in ("CAP_SYS_MODULE", "CAP_SYS_PTRACE", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_SETUID", "CAP_SETGID", "CAP_SYS_ADMIN") +) and user.id != "0" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.thread.capabilities.effective, process.thread.capabilities.permitted +| where host_count <= 3 and cc < 5 +| sort cc asc +| limit 100 +``` + +## Notes + +- Monitors process execution events where processes have specific capabilities set, such as CAP_SYS_MODULE, CAP_SYS_PTRACE, and others. +- Excludes certain processes and capabilities to reduce false positives, but these can be adjusted based on your environment. +- Uses EVAL to tag potential privilege escalation events and counts occurrences to identify unusual activity. +- Focuses on non-root users to detect potential privilege escalation attempts. +- Requires additional data analysis and investigation into results to identify malicious or unauthorized use of process capabilities. +## MITRE ATT&CK Techniques + +- [T1548.001](https://attack.mitre.org/techniques/T1548/001) +- [T1548.003](https://attack.mitre.org/techniques/T1548/003) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/privilege_escalation_via_segmentation_fault_and_buffer_overflow.md b/hunting/linux/docs/privilege_escalation_via_segmentation_fault_and_buffer_overflow.md new file mode 100644 index 00000000000..7dd06a4301f --- /dev/null +++ b/hunting/linux/docs/privilege_escalation_via_segmentation_fault_and_buffer_overflow.md @@ -0,0 +1,51 @@ +# Segmentation Fault & Potential Buffer Overflow Hunting + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies segmentation faults (segfaults) and potential buffer overflow attacks on Linux systems by parsing syslog messages related to segfaults. It captures details about the crashing process, shared object file, and other relevant information to help identify and investigate potential exploitation attempts. + +- **UUID:** `3f3fd2b9-940c-4310-adb1-d8b7d726e281` +- **Integration:** [system](https://docs.elastic.co/integrations/system) +- **Language:** `[ES|QL]` + +## Query + +```sql +from logs-system.syslog* +| where @timestamp > now() - 12 hour +| where host.os.type == "linux" and process.name == "kernel" and message like "*segfault*" +| grok message "\\[%{NUMBER:timestamp}\\] %{WORD:process}\\[%{NUMBER:pid}\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\[%{BASE16NUM:so_base_address}\\+%{BASE16NUM:so_offset}\\]" +| keep timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset +``` + +```sql +from logs-system.syslog* +| where host.os.type == "linux" and process.name == "kernel" and message like "*segfault*" +| where @timestamp > now() - 12 hour +| grok message "\\[%{DATA:timestamp}\\] %{WORD:process}\\[%{NUMBER:pid}\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_name}\\[%{BASE16NUM:so_base_address}\\+%{BASE16NUM:so_offset}\\] likely on CPU %{NUMBER:cpu} \\(core %{NUMBER:core}, socket %{NUMBER:socket}\\)" +| eval timestamp = REPLACE(timestamp, "\\s+", "") +| keep timestamp, process, pid, segfault_address, instruction_pointer, stack_pointer, error_code, so_name, so_base_address, so_offset, cpu, core, socket +| stats cc = count() by process, so_name +// Alter this threshold to make sense for your environment +| where cc > 100 +| limit 10 +``` + +## Notes + +- Detects segfaults and parses syslog messages related to segfaults to identify the crashing process and shared object file along with additional crash details. +- Uses GROK to extract relevant fields from syslog messages. +- Counts occurrences of segfaults within a plain text message field to potentially detect buffer overflow attacks and unsuccessful process injection attempts. +- Removes prepending spaces from syslog messages using EVAL to ensure consistent parsing. +- Depending on the Syslog configuration, additional parsing may be required to extract the necessary fields from the message. +## MITRE ATT&CK Techniques + +- [T1203](https://attack.mitre.org/techniques/T1203) +- [T1068](https://attack.mitre.org/techniques/T1068) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/docs/privilege_escalation_via_suid_binaries.md b/hunting/linux/docs/privilege_escalation_via_suid_binaries.md new file mode 100644 index 00000000000..8ea86f6bed7 --- /dev/null +++ b/hunting/linux/docs/privilege_escalation_via_suid_binaries.md @@ -0,0 +1,66 @@ +# OSQuery SUID Hunting + +--- + +## Metadata + +- **Author:** Elastic +- **Description:** This hunt identifies SUID binaries on Linux systems using OSQuery. SUID binaries can be exploited by attackers to gain elevated privileges. The hunt includes queries to list all SUID binaries and detailed information about these files, focusing on regular files owned by root with SUID or SGID bits set. + +- **UUID:** `2db642d2-621a-4183-88b5-b2659dc2c940` +- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) +- **Language:** `[SQL]` + +## Query + +```sql +SELECT * FROM suid_bin +``` + +```sql +SELECT + f.filename, + f.path, + f.mode, + f.uid, + f.gid, + f.type, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE +f.type == "regular" AND +(f.uid == 0 or f.gid == 0) AND +(f.mode LIKE "2%" OR f.mode LIKE "4%") AND +( + f.path LIKE "/%%" OR + f.path LIKE "/%%/%%" OR + f.path LIKE "/%%/%%/%%" OR + f.path LIKE "/%%/%%/%%/%%" +) +``` + +## Notes + +- Identifies SUID binaries using OSQuery to detect potentially exploitable files with SUID or SGID bits set. +- Lists all SUID binaries and provides detailed information about these files, including their paths, owners, and permissions. +- Focuses on regular files owned by root with SUID or SGID bits set to identify potential privilege escalation vectors. +- OSQuery has limited support for wildcard queries, therefore the query includes multiple LIKE conditions for directories. These can be increased and decreased, based on the environment +## MITRE ATT&CK Techniques + +- [T1548.001](https://attack.mitre.org/techniques/T1548/001) +- [T1574.002](https://attack.mitre.org/techniques/T1574/002) + +## License + +- `Elastic License v2` diff --git a/hunting/linux/queries/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.toml b/hunting/linux/queries/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.toml new file mode 100644 index 00000000000..627926600b8 --- /dev/null +++ b/hunting/linux/queries/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.toml @@ -0,0 +1,66 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies network connections with low occurrence frequency for unique agent IDs on Linux systems. It monitors network connection attempts and acceptances, focusing on those initiated by processes that are rarely seen in the environment. By accounting for known low-frequency legitimate binaries (LoLBins) and suspicious directories, this hunt aims to detect unusual network activity that may indicate malicious behavior. +""" +integration = ["endpoint"] +uuid = "ecd84bc7-32ae-474b-93a8-d1d9736c3464" +name = "Network Connections with Low Occurrence Frequency for Unique Agent ID" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for network connections initiated by processes that have low occurrence frequency, focusing on unique agent IDs.", + "Excludes common internal IP ranges to minimize false positives.", + "Accounts for known low-frequency legitimate binaries (LoLBins) to reduce noise.", + "Identifies suspicious directories where processes are executed from, which can indicate malicious activity." +] +mitre = ["T1071.001", "T1071.004"] + +query = [ +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.executable +| where agent_count == 1 and cc > 0 and cc <= 3 +| limit 100 +| sort cc asc +''', +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and ( + process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "socat", "java", "awk", "gawk", "mawk", "nawk", "openssl", "nc", "ncat", "netcat", "nc.openbsd", "telnet") or + process.name like "python*" or + process.name like "perl*" or + process.name like "ruby*" or + process.name like "lua*" or + process.name like "php*" +) and +destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.name +| where agent_count <= 3 and cc > 0 and cc <= 5 +| limit 100 +| sort cc asc +''', +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and ( + process.executable like "./*" or + process.executable like "/dev/shm/*" or + process.executable like "/var/www/*" or + process.executable like "/boot/*" or + process.executable like "/srv/*" or + process.executable rlike "/tmp/[^/]+" or + process.executable rlike "/var/tmp/[^/]+" or + process.executable rlike "/run/[^/]+" or + process.executable rlike "/var/run/[^/]+" +) and +destination.ip IS NOT null and not CIDR_MATCH(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") +| stats cc = count(), agent_count = count_distinct(agent.id) by process.executable +| where agent_count <= 3 and cc > 0 and cc <= 5 +| limit 100 +| sort cc asc +''' +] diff --git a/hunting/linux/queries/command_and_control_via_unusual_file_downloads_from_source_addresses.toml b/hunting/linux/queries/command_and_control_via_unusual_file_downloads_from_source_addresses.toml new file mode 100644 index 00000000000..28d01887ef4 --- /dev/null +++ b/hunting/linux/queries/command_and_control_via_unusual_file_downloads_from_source_addresses.toml @@ -0,0 +1,29 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies unusual file download activities on Linux systems. It detects instances where commonly used download utilities such as curl and wget are executed with command lines that contain IP addresses, which can indicate potentially suspicious file downloads. +""" +integration = ["endpoint"] +uuid = "0d061fad-cf35-43a6-b9b7-986c348bf182" +name = "Unusual File Downloads from Source Addresses" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Detects instances where download utilities like curl and wget are used with IP addresses in their command lines.", + "Monitors for potentially suspicious file downloads, which are often seen in malicious activities.", + "Uses process command line counting in conjunction with host counting to minimize false positives caused by legitimate downloads.", + "The process command line count threshold is set to <= 10, and the host count threshold is set to <= 5 to balance detection and noise." +] +mitre = ["T1071.001", "T1071.004"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and process.name in ("curl", "wget") and process.command_line rlike """.*[0-9]{1,3}(\.[0-9]{1,3}){3}.*""" +| stats cc = count(), host_count = count_distinct(host.id) by process.command_line, process.executable +| where cc <= 10 and host_count <= 5 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/defense_evasion_via_capitalized_process_execution.toml b/hunting/linux/queries/defense_evasion_via_capitalized_process_execution.toml new file mode 100644 index 00000000000..407a6de036a --- /dev/null +++ b/hunting/linux/queries/defense_evasion_via_capitalized_process_execution.toml @@ -0,0 +1,31 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential defense evasion techniques via capitalized process execution on Linux systems. It detects processes that have two or more consecutive capital letters within their names, which can indicate an attempt to evade detection. Such naming conventions are often used in malicious payloads to blend in with legitimate processes. +""" +integration = ["endpoint"] +uuid = "9d485892-1ca2-464b-9e4e-6b21ab379b9a" +name = "Defense Evasion via Capitalized Process Execution" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Detects processes that have two or more consecutive capital letters within their names, with optional digits.", + "This technique is often used in malicious payloads, such as Metasploit payloads, to evade detection.", + "Included a process count of <= 3 and a host count of <= 3 to eliminate common processes across different hosts." +] +mitre = ["T1036.004", "T1070"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 10 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( + (process.name rlike """[A-Z]{2,}[a-z]{1,}[0-9]{0,}""") or + (process.name rlike """[A-Z]{1,}[0-9]{0,}""") +) +| stats cc = count(), host_count = count_distinct(host.name) by process.name +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| limit 100 +''' +] diff --git a/hunting/linux/queries/defense_evasion_via_hidden_process_execution.toml b/hunting/linux/queries/defense_evasion_via_hidden_process_execution.toml new file mode 100644 index 00000000000..6604d3f6ccc --- /dev/null +++ b/hunting/linux/queries/defense_evasion_via_hidden_process_execution.toml @@ -0,0 +1,29 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies hidden process executions on Linux systems. It detects processes executed from hidden files, which are often used by malicious actors to conceal their activities. By focusing on hidden files rather than directories, this hunt aims to catch stealthy processes while minimizing noise. +""" +integration = ["endpoint"] +uuid = "00461198-9a2d-4823-b4cc-f3d1b5c17935" +name = "Hidden Process Execution" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Included only hidden files, excluding hidden directories, as hidden directories are common in Unix.", + "Included a process or parent process count of <= 3, and a host count of <= 3 to eliminate common processes across different hosts.", +] +mitre = ["T1036.004", "T1059"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and + process.executable rlike "/[^/]+/\\.[^/]+" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable, user.id +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/defense_evasion_via_multi_dot_process_execution.toml b/hunting/linux/queries/defense_evasion_via_multi_dot_process_execution.toml new file mode 100644 index 00000000000..b2d4c335e1f --- /dev/null +++ b/hunting/linux/queries/defense_evasion_via_multi_dot_process_execution.toml @@ -0,0 +1,28 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential defense evasion techniques via multi-dot process execution on Linux systems. It looks for processes with executables that contain three or more consecutive dots in their names. Such naming conventions can be used by malicious actors to evade detection and blend in with legitimate processes. +""" +integration = ["endpoint"] +uuid = "11810497-8ce3-4960-9777-9d0e97052682" +name = "Potential Defense Evasion via Multi-Dot Process Execution" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "This query identifies processes with executables containing three or more consecutive dots in their names.", + "The process count threshold of <= 10 can be adjusted based on the environment's baseline activity." +] +mitre = ["T1036.004", "T1070"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.executable rlike """.*\.{3,}.*""" +| stats cc = count() by process.executable +// Alter this threshold to make sense for your environment +| where cc <= 10 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/excessive_ssh_network_activity_unique_destinations.toml b/hunting/linux/queries/excessive_ssh_network_activity_unique_destinations.toml new file mode 100644 index 00000000000..3fcda1fdda7 --- /dev/null +++ b/hunting/linux/queries/excessive_ssh_network_activity_unique_destinations.toml @@ -0,0 +1,30 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies excessive SSH network activity to unique destinations on Linux systems. It monitors network connections over TCP to port 22 (SSH) and counts the number of unique destination IP addresses. A high number of unique destinations could indicate suspicious activity such as discovery or lateral movement. +""" +integration = ["endpoint"] +uuid = "223f812c-a962-4d58-961d-134d8f8b15da" +name = "Excessive SSH Network Activity to Unique Destinations" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors network connections to port 22 (SSH) and counts the number of unique destination IP addresses per host and user.", + "A high number of unique destinations can indicate suspicious activity such as discovery or lateral movement.", + "The threshold of 10 unique destinations can be adjusted to suit the environment's baseline activity." +] +mitre = ["T1021.004", "T1078.003"] + +query = [ +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and network.transport == "tcp" and destination.port == 22 and source.port >= 49152 +| keep destination.ip, host.id, user.name +| stats count_unique_dst = count_distinct(destination.ip) by host.id, user.name +// Alter this threshold to make sense for your environment +| where count_unique_dst >= 10 +| limit 100 +| sort user.name asc +''' +] diff --git a/hunting/linux/queries/execution_uncommon_process_execution_from_suspicious_directory.toml b/hunting/linux/queries/execution_uncommon_process_execution_from_suspicious_directory.toml new file mode 100644 index 00000000000..e9b1d90e111 --- /dev/null +++ b/hunting/linux/queries/execution_uncommon_process_execution_from_suspicious_directory.toml @@ -0,0 +1,47 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies uncommon process executions from suspicious directories on Linux systems. It looks for processes executed from directories that are often associated with malicious activity, such as /dev/shm, /var/www, /boot, /srv, /tmp, /var/tmp, /run, and /var/run. The goal is to detect potentially malicious processes while excluding common, benign ones. +""" +integration = ["endpoint"] +uuid = "0ea47044-b161-4785-ba99-e11f46d6ac51" +name = "Uncommon Process Execution from Suspicious Directory" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Excluded /tmp, /var/tmp, /run, /var/run subdirectories to reduce noise.", + "Excluded /tmp, /var/tmp files starting or ending with digits to exclude real temporary files.", + "Included a process or parent process count of <= 3, and a host count of <= 3 to eliminate common processes across different hosts.", +] +mitre = ["T1036.004", "T1049", "T1059", "T1059.004"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and ( +// Add paths to monitor from your environment here + process.executable like "/dev/shm/*" or + process.executable like "/var/www/*" or + process.executable like "/boot/*" or + process.executable like "/srv/*" or + process.executable rlike "/tmp/[^/]+" or + process.executable rlike "/var/tmp/[^/]+" or + process.executable rlike "/run/[^/]+" or + process.executable rlike "/var/run/[^/]+" +) and not ( + // Exclude noisy (parent) processes, users or directories from your environment here + process.parent.executable in ("/usr/sbin/dpkg-preconfigure") or + // Exclude /tmp and /var/tmp instances starting or ending with digits (usually benign files) + process.executable rlike "/tmp/[0-9].*" or + process.executable rlike "/tmp/.*[0-9]/?" or + process.executable rlike "/var/tmp/[0-9].*" or + process.executable rlike "/var/tmp/.*[0-9]/?" +) +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable +// Alter this threshold to make sense for your environment +| where cc <= 3 and host_count <= 3 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/login_activity_by_source_address.toml b/hunting/linux/queries/login_activity_by_source_address.toml new file mode 100644 index 00000000000..5000dd3075f --- /dev/null +++ b/hunting/linux/queries/login_activity_by_source_address.toml @@ -0,0 +1,29 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies unusual logon activity by source IP on Linux systems. It monitors authentication events, focusing on failed logon attempts from specific IP addresses. A high number of failed logon attempts combined with a low number of successful logons and multiple distinct usernames can indicate a potential brute force or credential stuffing attack. +""" +integration = ["endpoint"] +uuid = "95c1467d-d566-4645-b5f1-37a4b0093bb6" +name = "Logon Activity by Source IP" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors authentication events and counts failed and successful logon attempts by source IP address.", + "A high number of failed logon attempts combined with a low number of successful logons and multiple distinct usernames can indicate a potential brute force or credential stuffing attack.", + "The thresholds for failed attempts, successful logons, and distinct usernames should be adjusted based on the environment's normal logon patterns." +] +mitre = ["T1110", "T1078"] + +query = [ +''' +from logs-system.auth-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "authentication" and event.action in ("ssh_login", "user_login") and + event.outcome == "failure" and source.ip IS NOT null and not CIDR_MATCH(source.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") +| eval failed = case(event.outcome == "failure", source.ip, null), success = case(event.outcome == "success", source.ip, null) +| stats count_failed = count(failed), count_success = count(success), count_user = count_distinct(user.name) by source.ip + /* below threshold should be adjusted to your env logon patterns */ +| where count_failed >= 100 and count_success <= 10 and count_user >= 20 +''' +] diff --git a/hunting/linux/queries/low_volume_external_network_connections_from_process.toml b/hunting/linux/queries/low_volume_external_network_connections_from_process.toml new file mode 100644 index 00000000000..46db763c7b5 --- /dev/null +++ b/hunting/linux/queries/low_volume_external_network_connections_from_process.toml @@ -0,0 +1,39 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies low volume external network connections initiated by processes on Linux systems. It focuses on connections attempted by processes that have been seen infrequently (five or fewer connections) and by unique agents. This can help identify potentially suspicious activity that might be missed due to low volume. +""" +integration = ["endpoint"] +uuid = "12526f14-5e35-4f5f-884c-96c6a353a544" +name = "Low Volume External Network Connections from Process by Unique Agent" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for network connections attempted by processes that have a low occurrence frequency (five or fewer connections) and are seen by a unique agent.", + "Excludes common internal IP ranges to minimize false positives.", + "A separate query is included to specifically monitor low volume network connections initiated by the root user, as these can be particularly indicative of malicious activity." +] +mitre = ["T1071.001", "T1071.004"] + +query = [ +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and event.type == "start" and event.action == "connection_attempted" and not process.name is null and + not CIDR_MATCH(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", "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", "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", "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", "FF00::/8") +| stats connection_count = count(*), unique_agent_count = count_distinct(agent.id) by process.name +| where connection_count <= 5 and unique_agent_count == 1 +| limit 100 +| sort connection_count, unique_agent_count asc +''', +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.category == "network" and event.type == "start" and event.action == "connection_attempted" and user.id == "0" and not process.name is null and + not CIDR_MATCH(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", "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", "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", "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", "FF00::/8") +| stats connection_count = count(*), unique_agent_count = count_distinct(agent.id) by process.name +| where connection_count <= 5 and unique_agent_count == 1 +| limit 100 +| sort connection_count, unique_agent_count asc +''' +] diff --git a/hunting/linux/queries/low_volume_gtfobins_external_network_connections.toml b/hunting/linux/queries/low_volume_gtfobins_external_network_connections.toml new file mode 100644 index 00000000000..dbf8cfece5d --- /dev/null +++ b/hunting/linux/queries/low_volume_gtfobins_external_network_connections.toml @@ -0,0 +1,36 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies low volume external network connections initiated by GTFOBins on Linux systems. GTFOBins are Unix binaries that can be exploited by attackers to bypass local security restrictions. The hunt focuses on network connections made by these binaries, excluding common internal IP ranges, to detect potentially malicious activity. +""" +integration = ["endpoint"] +uuid = "783d6091-b98d-45a8-a880-a07f112a8aa2" +name = "Low Volume GTFOBins External Network Connections" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for external network connections initiated by known GTFOBins such as bash, curl, nc, wget, and others.", + "Excludes common internal IP ranges to minimize false positives.", + "Counts the occurrences of these connections by process name and limits to those seen infrequently (five or fewer connections).", + "This can help identify potentially malicious activity involving the exploitation of GTFOBins." +] +mitre = ["T1219", "T1071.001"] + +query = [ +''' +from logs-endpoint.events.network-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and event.type == "start" and process.name in ( + "ab", "aria2c", "bash", "cpan", "curl", "easy_install", "finger", "ftp", + "gdb", "gimp", "irb", "jjs", "jrunscript", "julia", "ksh", "lua", "lwp-download", + "nc", "nmap", "node", "openssl", "php", "pip", "python", "ruby", "rview", "rvim", + "scp", "sftp", "smbclient", "socat", "ssh", "tar", "tftp", "view", "vim", "vimdiff", + "wget", "whois", "yum" +) and +destination.ip IS NOT null and not CIDR_MATCH(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", "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", "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", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4", "::1","FE80::/10", "FF00::/8") +| keep process.name, destination.port, destination.ip, user.name, host.name +| stats cc = count(*) by destination.port, process.name +| where cc <= 5 +| sort cc asc, destination.port +''' +] diff --git a/hunting/linux/queries/low_volume_modifications_to_critical_system_binaries.toml b/hunting/linux/queries/low_volume_modifications_to_critical_system_binaries.toml new file mode 100644 index 00000000000..b4b0742d21e --- /dev/null +++ b/hunting/linux/queries/low_volume_modifications_to_critical_system_binaries.toml @@ -0,0 +1,39 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies low volume modifications to critical system binaries on Linux systems. It monitors file modification events in critical directories such as /bin, /usr/bin, /sbin, and /usr/sbin. The hunt focuses on modifications made by unique hosts, excluding expected update processes like package managers. This can help detect unauthorized or suspicious modifications to system binaries. +""" +integration = ["endpoint"] +uuid = "c7044817-d9a5-4755-abab-9059e50dab24" +name = "Low Volume Modifications to Critical System Binaries by Unique Host" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for file modifications in critical directories like /bin, /usr/bin, /sbin, and /usr/sbin.", + "Excludes modifications made by expected update processes such as package managers to reduce false positives.", + "Counts the number of unique files modified by each host and the number of modifications made.", + "Focuses on modifications made by unique hosts to detect unauthorized or suspicious changes." +] +mitre = ["T1070.004", "T1569.002"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 7 day +| where host.os.type == "linux" and + (file.path like "/bin/*" or file.path like "/usr/bin/*" or file.path like "/sbin/*" or file.path like "/usr/sbin/*") and + not ( + + // Exclude expected update processes, e.g., package managers + process.executable in ("/usr/bin/apt", "/usr/bin/dpkg", "/usr/bin/yum", "/usr/bin/rpm", "/usr/bin/pacman", + "/usr/bin/pamac-daemon", "/usr/bin/update-alternatives", "/usr/bin/dockerd", "/usr/bin/microdnf", "/sbin/apk") or + + // Exclude certain benign or expected modification patterns, if applicable + file.path like "/usr/bin/gzip*" // Example exclusion, adjust based on your environment +) +| stats modification_count = count(file.path), unique_files_modified = count_distinct(file.path), host_count = count_distinct(host.name) by process.executable +| where modification_count >= 1 and host_count == 1 +| sort modification_count asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/low_volume_process_injection_syscalls_by_executable.toml b/hunting/linux/queries/low_volume_process_injection_syscalls_by_executable.toml new file mode 100644 index 00000000000..022d5893950 --- /dev/null +++ b/hunting/linux/queries/low_volume_process_injection_syscalls_by_executable.toml @@ -0,0 +1,28 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies low volume process injection-related syscalls on Linux systems. It monitors audit logs for syscalls related to process injection, such as ptrace and memfd_create. The hunt focuses on processes that make these syscalls infrequently, which can indicate potential malicious activity. +""" +integration = ["endpoint"] +uuid = "c9931736-d5ec-4c89-b4d2-d71dcf5ca12a" +name = "Low Volume Process Injection-Related Syscalls by Process Executable" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for process injection-related syscalls such as ptrace and memfd_create.", + "Counts the occurrences of these syscalls by process executable to identify processes that make these syscalls infrequently.", + "Focuses on low volume occurrences to detect potential malicious activity related to process injection." +] +mitre = ["T1055.001", "T1055.009"] + +query = [ +''' +from logs-auditd_manager.auditd-*, logs-auditd.log-*, auditbeat-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and auditd.data.syscall in ("ptrace", "memfd_create") +| stats cc = count(*) by process.executable, auditd.data.syscall +| where cc <= 10 +| limit 100 +| sort cc asc +''' +] diff --git a/hunting/linux/queries/persistence_reverse_bind_shells.toml b/hunting/linux/queries/persistence_reverse_bind_shells.toml new file mode 100644 index 00000000000..ad54193bc4b --- /dev/null +++ b/hunting/linux/queries/persistence_reverse_bind_shells.toml @@ -0,0 +1,47 @@ +[hunt] +author = "Elastic" +description = """ +This hunt provides several OSQuery queries that can aid in the detection of reverse/bind shells. Reverse shells are a type of shell in which the target machine communicates back to the attacking machine. Bind shells are a type of shell in which the target machine opens a communication port on the victim machine and waits for an attacker to connect to it. These shells can be used by attackers to gain remote access to a system. +""" +integration = ["endpoint"] +uuid = "7422faf1-ba51-49c3-b8ba-13759e6bcec4" +name = "Persistence Through Reverse/Bind Shells" +language = ["SQL"] +license = "Elastic License v2" +notes = [ + "The hunt provides OSQuery queries to detect reverse/bind shells on Linux systems.", + "The first hunt query retrieves information about open sockets on the system.", + "The second hunt query retrieves information about running processes on the system.", + "The third hunt query retrieves information about listening ports on the system.", + "Investigate strange or unexpected open sockets, processes, or listening ports on the system.", + "Use the information from each hunt to pivot and investigate further for potential reverse/bind shells." +] +mitre = ["T1059.004"] + +query = [ +''' +SELECT ( + CASE family + WHEN 2 THEN 'IP4' + WHEN 10 THEN 'IP6' + ELSE family END +) AS family, ( + CASE protocol + WHEN 6 THEN 'TCP' + WHEN 17 THEN 'UDP' + ELSE protocol END +) AS protocol, local_address, local_port, + remote_address, remote_port +FROM process_open_sockets +WHERE family IN (2, 10) +AND protocol IN (6, 17) +''', +''' +SELECT cmdline, name, path, pid, state, threads, total_size +FROM processes +WHERE cmdline != '' +''', +''' +SELECT pid, address, port, socket, protocol, path FROM listening_ports +''' +] diff --git a/hunting/linux/queries/persistence_via_cron.toml b/hunting/linux/queries/persistence_via_cron.toml new file mode 100644 index 00000000000..3308efa3215 --- /dev/null +++ b/hunting/linux/queries/persistence_via_cron.toml @@ -0,0 +1,98 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via cron on Linux systems. It monitors for file creation or modification events related to cron configurations and processes spawned by cron, fcron, or atd. These activities can indicate attempts to establish persistence through scheduled tasks. +""" +integration = ["endpoint"] +uuid = "e1cffb7c-4acf-4e7a-8d72-b8b7657cf7b8" +name = "Persistence via Cron" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via cron on Linux systems.", + "Detects file creation or modification events in directories and files associated with cron configurations, such as /etc/cron.allow, /etc/cron.deny, /etc/crontab, all /etc/cron.* directories and various /var/spool directories.", + "Excludes common legitimate processes and file types to minimize false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by cron, fcron, or atd to detect potential persistence mechanisms.", + "OSQuery queries are provided to complement the detection by retrieving detailed file information and crontab entries." +] +mitre = ["T1053.003", "T1053.005"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path in ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") or + file.path like "/etc/cron.*/*" or + file.path like "/var/spool/cron/crontabs/*" or + file.path like "/var/spool/anacron/*" or + file.path like "/var/spool/cron/atjobs/*" or + file.path like "/var/spool/fcron/*" or + file.path like "/home/*/.tsp/*" +) and not ( + process.name in ("dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "anacron") or + file.extension in ("dpkg-remove", "swx", "swp") or + file.name like "tmp.*" +) +| eval persistence = case( + file.path in ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") or + file.path like "/etc/cron.*/*" or + file.path like "/var/spool/cron/crontabs/*" or + file.path like "/var/spool/anacron/*" or + file.path like "/var/spool/cron/atjobs/*" or + file.path like "/var/spool/fcron/*" or + file.path like "/home/*/.tsp/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 3 +| sort pers_count asc +| limit 100 +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("cron", "fcron", "atd") +| stats cc = count(), host_count = count_distinct(host.id) by process.command_line +| where host_count <= 3 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path IN ("/etc/cron.allow", "/etc/cron.deny", "/etc/crontab") + OR f.path LIKE "/etc/cron.%/*" + OR f.path LIKE "/var/spool/cron/crontabs/%" + OR f.path LIKE "/var/spool/anacron/%" + OR f.path LIKE "/var/spool/cron/atjobs/%" + OR f.path LIKE "/var/spool/fcron/%" + OR f.path LIKE "/home/%/.tsp/%" + OR f.path LIKE "/etc/cron.allow.d/%" + OR f.path LIKE "/etc/cron.d/%" + OR f.path LIKE "/etc/cron.hourly/%" + OR f.path LIKE "/etc/cron.daily/%" + OR f.path LIKE "/etc/cron.weekly/%" + OR f.path LIKE "/etc/cron.monthly/%" +''', +''' +SELECT * FROM crontab +''' +] diff --git a/hunting/linux/queries/persistence_via_driver_load_with_low_occurrence_frequency.toml b/hunting/linux/queries/persistence_via_driver_load_with_low_occurrence_frequency.toml new file mode 100644 index 00000000000..7ec92830c66 --- /dev/null +++ b/hunting/linux/queries/persistence_via_driver_load_with_low_occurrence_frequency.toml @@ -0,0 +1,29 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies drivers loaded with low occurrence frequency on Linux systems. It monitors for the loading of kernel modules (drivers) that have only been seen once across a single host within a year. Such activity can indicate the presence of rare or potentially malicious drivers. +""" +integration = ["endpoint"] +uuid = "e1f59c9a-7a2a-4eb8-a524-97b16a041a4a" +name = "Drivers Load with Low Occurrence Frequency" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors for kernel modules loaded with syscall 'init_module' or 'finit_module', indicating driver load events.", + "Counts the occurrence of each driver across all hosts and identifies those seen only once on a single host within the past year.", + "Such rare driver loads can indicate potentially malicious activity or the presence of uncommon drivers." +] +mitre = ["T1547.006", "T1069.002"] + +query = [ +''' +from logs-auditd_manager.auditd-*, logs-auditd.log-*, auditbeat-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.category == "driver" and event.action == "loaded-kernel-module" and auditd.data.syscall in ("init_module", "finit_module") +| stats host_count = count_distinct(host.id), total_count = count(*) by auditd.data.name, process.executable, process.name +// Alter this threshold to make sense for your environment +| where host_count == 1 and total_count == 1 +| limit 100 +| sort auditd.data.name asc +''' +] diff --git a/hunting/linux/queries/persistence_via_git_hook_pager.toml b/hunting/linux/queries/persistence_via_git_hook_pager.toml new file mode 100644 index 00000000000..3398582a7f4 --- /dev/null +++ b/hunting/linux/queries/persistence_via_git_hook_pager.toml @@ -0,0 +1,78 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via Git hooks and configurations on Linux systems. It monitors file creation or modification events in Git configuration and hook directories, as well as processes started by Git hooks. These activities can indicate attempts to establish persistence through Git configurations. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "2d7bb29d-d53f-47ab-a0b4-1818adb91423" +name = "Git Hook/Pager Persistence" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "Monitors for file creation or modification events in Git configuration and hook directories such as /etc/gitconfig, .git/config, /home/*/.gitconfig, and .git/hooks/.", + "Excludes modifications made by the Git process itself to reduce false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by Git hooks to detect suspicious activity related to Git configurations.", + "OSQuery query is provided to retrieve detailed file information related to Git configurations and hooks.", + "OSQuery has limited support for wildcard queries, therefore the query includes multiple LIKE conditions for directories. These can be increased and decreased based on the environment's Git configuration paths." +] +mitre = ["T1546.004", "T1059.004"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path == "/etc/gitconfig" or + file.path like "*/.git/config" or + file.path like "/home/*/.gitconfig" or + file.path like "*/.git/hooks/*" +) and process.name != "git" +| eval persistence = case( + file.path == "/etc/gitconfig" or + file.path like "*/.git/config" or + file.path like "/home/*/.gitconfig" or + file.path like "*/.git/hooks/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 4 +| sort pers_count asc +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.executable like "*.git/hooks/*" +| stats cc = count(), host_count = count_distinct(host.name) by process.parent.executable, process.executable +| where cc < 50 and host_count <= 5 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change time, + datetime(f.btime, 'unixepoch') AS file created time, + f.size AS size bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path == '/etc/gitconfig' + OR f.path LIKE '/%%/.git/config' + OR f.path LIKE '/home/%/.gitconfig' + OR f.path LIKE '/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/%%/.git/hooks/%' + OR f.path LIKE '/%%/%%/%%/%%/.git/hooks/%' +''' +] diff --git a/hunting/linux/queries/persistence_via_message_of_the_day.toml b/hunting/linux/queries/persistence_via_message_of_the_day.toml new file mode 100644 index 00000000000..77178e41e6c --- /dev/null +++ b/hunting/linux/queries/persistence_via_message_of_the_day.toml @@ -0,0 +1,68 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via the message-of-the-day (motd) on Linux systems. It monitors for file creation or modification events in the /etc/update-motd.d directory and processes started by these motd scripts. These scripts launch on SSH/terminal connection events, and execute the scripts as root. These activities can indicate attempts to establish persistence through motd modifications. +""" +integration = ["endpoint"] +uuid = "5984a354-d76c-43e6-bdd9-228456f1b371" +name = "Persistence via Message-of-the-Day" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via the message-of-the-day (motd) on Linux systems.", + "Detects file creation or modification events in the /etc/update-motd.d directory, which is used for message-of-the-day scripts.", + "Excludes common legitimate processes to minimize false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by motd scripts to detect potential persistence mechanisms.", + "OSQuery query is provided to complement the detection by retrieving detailed file information related to motd scripts." +] +mitre = ["T1036.005", "T1546.003"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and file.path like "/etc/update-motd.d/*" and +not process.name in ("dpkg", "dockerd", "yum", "dnf", "snapd", "pacman") +| eval persistence = case(file.path like "/etc/update-motd.d/*", process.name, null) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 5 +| sort pers_count asc +| limit 100 +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.executable like "/etc/update-motd.d/*" and +not process.args like "/tmp/tmp.*" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.parent.executable +| where host_count <= 5 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ('/etc/update-motd.d/') +ORDER BY + f.mtime DESC; +''' +] diff --git a/hunting/linux/queries/persistence_via_package_manager.toml b/hunting/linux/queries/persistence_via_package_manager.toml new file mode 100644 index 00000000000..69916b7e4e3 --- /dev/null +++ b/hunting/linux/queries/persistence_via_package_manager.toml @@ -0,0 +1,86 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via package manager configurations on Linux systems. It monitors file creation or modification events in directories related to APT, YUM, and DNF package managers. Additionally, it monitors processes started by these package managers. These activities can indicate attempts to establish persistence through package manager configurations. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "2d01a413-8d97-407a-8698-02dfc7119c97" +name = "Persistence via Packager Manager" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "Monitors for file creation or modification events in directories related to APT, YUM, and DNF package managers such as /etc/apt/apt.conf.d/, /etc/dnf/plugins/, /usr/lib/yum-plugins/, and others.", + "Excludes modifications made by expected update processes such as package managers to reduce false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by package managers to detect suspicious activity related to package manager configurations.", + "OSQuery queries are provided to retrieve detailed file information related to package manager configurations, as well as sources for APT and YUM." +] +mitre = ["T1546.004", "T1059.004"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path like "/etc/apt/apt.conf.d/*" or + file.path like "/usr/lib/python*/site-packages/dnf-plugins/*" or + file.path like "/etc/dnf/plugins/*" or + file.path like "/usr/lib/yum-plugins/*" or + file.path like "/etc/yum/pluginconf.d/*" +) and not process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "microdnf", "podman", "apk", "yumBackend.py" +) +| eval persistence = case( + file.path like "/etc/apt/apt.conf.d/*" or + file.path like "/usr/lib/python*/site-packages/dnf-plugins/*" or + file.path like "/etc/dnf/plugins/*" or + file.path like "/usr/lib/yum-plugins/*" or + file.path like "/etc/yum/pluginconf.d/*", + process.name, + null +) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 and agent_count <= 4 +| sort pers_count asc +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("apt", "yum", "dnf") +| stats cc = count(), host_count = count_distinct(host.name) by process.executable +| where host_count <= 5 and cc < 50 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group owner, + datetime(f.atime, 'unixepoch') AS file_last_access time, + datetime(f.mtime, 'unixepoch') AS file last_modified time, + datetime(f.ctime, 'unixepoch') AS file last_status change time, + datetime(f.btime, 'unixepoch') AS file created time, + f.size AS size bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE '/etc/apt/apt.conf.d/%' + OR f.path LIKE '/usr/lib/python%/site-packages/dnf-plugins/%' + OR f.path LIKE '/etc/dnf/plugins/%' + OR f.path LIKE '/usr/lib/yum-plugins/%' + OR f.path LIKE '/etc/yum/pluginconf.d/%' +''', +''' +SELECT * FROM apt_sources +''', +''' +SELECT * FROM yum_sources +''' +] diff --git a/hunting/linux/queries/persistence_via_rc_local.toml b/hunting/linux/queries/persistence_via_rc_local.toml new file mode 100644 index 00000000000..a793afc941c --- /dev/null +++ b/hunting/linux/queries/persistence_via_rc_local.toml @@ -0,0 +1,67 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via rc.local and rc.common on Linux systems. RC scripts are used to start custom applications, services, scripts or commands during start-up. RC scripts have mostly been replaced by Systemd. However, through the "systemd-rc-local-generator", these files can be converted to services that run at boot. The query monitors for file creation or modification events in the /etc/rc.local and /etc/rc.common files, as well as processes started by these scripts. These activities can indicate attempts to establish persistence through rc.local modifications. +""" +integration = ["endpoint", "system"] +uuid = "a95f778f-2193-4a3d-bbbe-7b02d5740638" +name = "Persistence via rc.local/rc.common" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "This hunt includes multiple ES|QL and OSQuery queries to detect potential persistence mechanisms via rc.local on Linux systems.", + "Detects file creation or modification events in the /etc/rc.local and /etc/rc.common files, which are used for system initialization scripts.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by rc.local and rc.common scripts to detect potential persistence mechanisms.", + "Syslog hunting query is provided to complement the detection by analyzing syslog entries related to rc.local and rc.common processes.", + "OSQuery queries are provided to retrieve systemd unit states, startup items, and detailed file information related to rc.local and rc.common." +] +mitre = ["T1037.004", "T1546.003"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and (file.path == "/etc/rc.local" or file.path == "/etc/rc.common") +| eval persistence = case(file.path == "/etc/rc.local" or file.path == "/etc/rc.common", process.name, null) +| stats pers_count = count(persistence), agent_count = count_distinct(agent.id) by process.executable +| where pers_count > 0 and pers_count <= 3 and agent_count <= 3 +| sort pers_count asc +| limit 100 +''', +''' +from logs-system.syslog-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and process.name in ("rc.local", "rc.common") +| stats cc = count(), host_count = count_distinct(host.name) by message +| where host_count <= 3 and cc < 10 +| sort cc asc +| limit 100 +''', +''' +SELECT * FROM systemd_units WHERE id = "rc-local.service" +''', +''' +SELECT * FROM startup_items WHERE name = "rc-local.service" +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path in ('/etc/rc.local', '/etc/rc.common') +''' +] diff --git a/hunting/linux/queries/persistence_via_shell_modification_persistence.toml b/hunting/linux/queries/persistence_via_shell_modification_persistence.toml new file mode 100644 index 00000000000..a42a6a14b55 --- /dev/null +++ b/hunting/linux/queries/persistence_via_shell_modification_persistence.toml @@ -0,0 +1,98 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via modifications to shell profile files on Linux systems. It monitors file creation or modification events in system-wide and user-specific profile files, which can indicate attempts to establish persistence through shell modifications. It also monitors processes started by SSH daemons to detect suspicious activity related to SSH logins. +""" +integration = ["endpoint"] +uuid = "20a02fad-2a09-44c0-a8ce-ce4502859c8a" +name = "Shell Modification Persistence" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "Monitors for file creation or modification events in system-wide and user-specific profile files, such as /etc/profile, /etc/bash.bashrc, /home/*/.bashrc, and others.", + "Excludes modifications made by expected update processes such as package managers to reduce false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by SSH daemons (sshd) to detect suspicious activity related to SSH logins.", + "OSQuery query is provided to retrieve detailed file information related to profile files." +] +mitre = ["T1546.004", "T1053.005"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide profile files + file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or + file.path like "/etc/profile.d/*" or + + // User-specific profile files + file.path like "/home/*/.profile" or + file.path like "/home/*/.bash_profile" or + file.path like "/home/*/.bash_login" or + file.path like "/home/*/.bash_logout" or + file.path like "/home/*/.bashrc" +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "microdnf", "podman", "apk" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + // System-wide profile files + file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or + file.path like "/etc/profile.d/*" or + + // User-specific profile files + file.path like "/home/*/.profile" or + file.path like "/home/*/.bash_profile" or + file.path like "/home/*/.bash_login" or + file.path like "/home/*/.bash_logout" or + file.path like "/home/*/.bashrc", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.parent.name == "sshd" +| stats cc = count(*) by process.command_line +| where cc <= 20 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path IN ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") + OR f.path LIKE "/etc/profile.d/%" + OR f.path LIKE "/home/%/.profile" + OR f.path LIKE "/home/%/.bash_profile" + OR f.path LIKE "/home/%/.bash_login" + OR f.path LIKE "/home/%/.bash_logout" + OR f.path LIKE "/home/%/.bashrc" +''' +] diff --git a/hunting/linux/queries/persistence_via_ssh_configurations_and_keys.toml b/hunting/linux/queries/persistence_via_ssh_configurations_and_keys.toml new file mode 100644 index 00000000000..c35bf930be7 --- /dev/null +++ b/hunting/linux/queries/persistence_via_ssh_configurations_and_keys.toml @@ -0,0 +1,55 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential SSH persistence mechanisms on Linux systems using OSQuery. It monitors SSH keys, authorized_keys files, SSH configuration files, and SSH file information to detect unauthorized access or persistence techniques. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "aa759db0-4499-42f2-9f2f-be3e00fdebfa" +name = "Persistence via SSH Configurations and/or Keys" +language = ["SQL"] +license = "Elastic License v2" +notes = [ + "Monitors SSH keys, authorized_keys files, and SSH configuration files using OSQuery to detect potential unauthorized access or persistence techniques.", + "Lists detailed information about SSH files, including paths, owners, and permissions.", + "Requires additional data analysis and investigation into results to identify malicious or unauthorized SSH configurations and keys." +] +mitre = ["T1098.004", "T1563.001"] + +query = [ +''' +SELECT * FROM user_ssh_keys +''', +''' +SELECT authorized_keys.* +FROM users +JOIN authorized_keys +USING(uid) +''', +''' +SELECT * FROM ssh_configs +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE "/root/.ssh/%" + OR f.path LIKE "/home/%/.ssh/%" + OR f.path LIKE "/etc/ssh/%" + OR f.path LIKE "/etc/ssh/sshd_config.d/%" + OR f.path LIKE "/etc/ssh/ssh_config.d/%" +''' +] diff --git a/hunting/linux/queries/persistence_via_systemd_timers.toml b/hunting/linux/queries/persistence_via_systemd_timers.toml new file mode 100644 index 00000000000..16baf99a548 --- /dev/null +++ b/hunting/linux/queries/persistence_via_systemd_timers.toml @@ -0,0 +1,188 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via systemd (timers) on Linux systems. It monitors for file creation or modification events related to systemd service and timer configurations, as well as generators, which can indicate attempts to establish persistence through scheduled tasks. +""" +integration = ["endpoint"] +uuid = "d2d24ad6-a315-4e05-a3f9-e205eb805df4" +name = "Persistence via Systemd (Timers)" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via systemd timers on Linux systems.", + "Detects file creation or modification events in directories and files associated with systemd services, timers, and generators, such as /run/systemd/system, /etc/systemd/system, /etc/systemd/user, and various /usr/lib/systemd directories.", + "Excludes common legitimate processes and file types to minimize false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "OSQuery queries are provided to complement the detection by retrieving detailed file information and entries related to systemd services, timers, and generators." +] +mitre = ["T1053.005", "T1546.002"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide/user-specific services/timers (root permissions required) + file.path like "/run/systemd/system/*" or + file.path like "/etc/systemd/system/*" or + file.path like "/etc/systemd/user/*" or + file.path like "/usr/local/lib/systemd/system/*" or + file.path like "/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/user/*" or + + // user-specific services/timers (user permissions required) + file.path like "/home/*/.config/systemd/user/*" or + file.path like "/home/*/.local/share/systemd/user/*" or + + // System-wide generators (root permissions required) + file.path like "/etc/systemd/system-generators/*" or + file.path like "/usr/local/lib/systemd/system-generators/*" or + file.path like "/lib/systemd/system-generators/*" or + file.path like "/etc/systemd/user-generators/*" or + file.path like "/usr/local/lib/systemd/user-generators/*" or + file.path like "/usr/lib/systemd/user-generators/*" + +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "netplan", "systemd", "generate" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + + // System-wide/user-specific services/timers (root permissions required) + file.path like "/run/systemd/system/*" or + file.path like "/etc/systemd/system/*" or + file.path like "/etc/systemd/user/*" or + file.path like "/usr/local/lib/systemd/system/*" or + file.path like "/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/system/*" or + file.path like "/usr/lib/systemd/user/*" or + + // user-specific services/timers (user permissions required) + file.path like "/home/*/.config/systemd/user/*" or + file.path like "/home/*/.local/share/systemd/user/*" or + + // System-wide generators (root permissions required) + file.path like "/etc/systemd/system-generators/*" or + file.path like "/usr/local/lib/systemd/system-generators/*" or + file.path like "/lib/systemd/system-generators/*" or + file.path like "/etc/systemd/user-generators/*" or + file.path like "/usr/local/lib/systemd/user-generators/*" or + file.path like "/usr/lib/systemd/user-generators/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + (f.path LIKE "/run/systemd/system/%" + OR f.path LIKE "/etc/systemd/system/%" + OR f.path LIKE "/etc/systemd/user/%" + OR f.path LIKE "/usr/local/lib/systemd/system/%" + OR f.path LIKE "/lib/systemd/system/%" + OR f.path LIKE "/usr/lib/systemd/system/%" + OR f.path LIKE "/usr/lib/systemd/user/%" + OR f.path LIKE "/home/%/.config/systemd/user/%" + OR f.path LIKE "/home/%/.local/share/systemd/user/%") + AND f.filename LIKE "%.service" +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/run/systemd/system', + '/etc/systemd/system', + '/etc/systemd/user', + '/usr/local/lib/systemd/system', + '/lib/systemd/system', + '/usr/lib/systemd/system', + '/usr/lib/systemd/user', + '/home/.config/systemd/user', + '/home/.local/share/systemd/user' + ) + AND f.filename LIKE "%.timer" +ORDER BY + f.mtime DESC; +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/etc/systemd/system-generators/', + '/usr/local/lib/systemd/system-generators/', + '/lib/systemd/system-generators/', + '/etc/systemd/user-generators/', + '/usr/local/lib/systemd/user-generators/', + '/usr/lib/systemd/user-generators/' + ) +ORDER BY + f.mtime DESC; +''', +''' +SELECT name, path, source, status, type FROM startup_items +WHERE type == "systemd unit" AND status == "active" AND +name LIKE "%.service" OR name LIKE "%.timer" +''' +] diff --git a/hunting/linux/queries/persistence_via_udev.toml b/hunting/linux/queries/persistence_via_udev.toml new file mode 100644 index 00000000000..df27a0b8d91 --- /dev/null +++ b/hunting/linux/queries/persistence_via_udev.toml @@ -0,0 +1,88 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via Udev rules on Linux systems. Udev is a device manager for the Linux kernel that manages device nodes in /dev. Udev is responsible for creating and removing device nodes in /dev when devices are added or removed from the system. Udev executes scripts when devices are added or removed from the system. This query monitors file creation or modification events in Udev rule directories and processes started by Udevadm. These activities can indicate attempts to establish persistence through Udev configurations. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "8d42a644-5b60-4165-a8f1-84d5bcdd4ade" +name = "Persistence via Udev" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "Monitors for file creation or modification events in Udev rule directories such as /etc/udev/rules.d/, /run/udev/rules.d/, /usr/lib/udev/rules.d/, and /lib/udev/.", + "Excludes modifications made by expected update processes such as package managers to reduce false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by Udevadm to detect suspicious activity related to Udev rules.", + "OSQuery query is provided to retrieve detailed file information related to Udev rules." +] +mitre = ["T1547.010"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + file.path like "/etc/udev/rules.d/*" or + file.path like "/run/udev/rules.d/*" or + file.path like "/usr/lib/udev/rules.d/*" or + file.path like "/lib/udev/*" +) and not process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", + "microdnf", "podman", "apk", "netplan", "generate" +) +| eval persistence = case( + file.path like "/etc/udev/rules.d/*" or + file.path like "/run/udev/rules.d/*" or + file.path like "/usr/lib/udev/rules.d/*" or + file.path like "/lib/udev/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name == "udevadm" and +// Excluding these because this is typical udev behavior. +// If you suspect Udev persistence, remove this exclusion in order to do a more elaborate search +not (process.executable like "/lib/*" or process.executable like "/usr/lib/*") +| stats cc = count(), host_count = count_distinct(host.name) by process.executable +// Tweak the process/host count if you suspect Udev persistence +| where host_count <= 5 and cc < 50 +| sort cc asc +| limit 100 +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size bytes, + h.md5 +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +LEFT JOIN + hash h ON f.path = h.path +WHERE + f.directory IN ( + '/etc/udev/rules.d/', + '/run/udev/rules.d/', + '/usr/lib/udev/rules.d/', + '/lib/udev/' + ) +ORDER BY + f.mtime DESC; +''' +] diff --git a/hunting/linux/queries/persistence_via_unusual_system_binary_parent.toml b/hunting/linux/queries/persistence_via_unusual_system_binary_parent.toml new file mode 100644 index 00000000000..ed42b534e13 --- /dev/null +++ b/hunting/linux/queries/persistence_via_unusual_system_binary_parent.toml @@ -0,0 +1,29 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential system binary hijacking attempts on Linux systems. It monitors process execution events where common system binaries such as ls, cat, mkdir, touch, mv, and cp are the parent processes. These activities can indicate attempts to hijack system binaries for malicious purposes. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "d22cbe8f-c84d-4811-aa6d-f1ee00c806b2" +name = "Unusual System Binary Parent (Potential System Binary Hijacking Attempt)" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors process execution events where common system binaries such as ls, cat, mkdir, touch, mv, and cp are the parent processes.", + "Focuses on identifying unusual or suspicious child processes spawned by these common system binaries.", + "Uses stats to count occurrences and identify unusual activity by looking at the number of unique hosts and processes involved.", + "Requires additional data analysis and investigation into results to identify malicious or unauthorized use of system binaries." +] +mitre = ["T1546.004", "T1059.004"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and process.parent.name in ("ls", "cat", "mkdir", "touch", "mv", "cp") +| stats cc = count(), host_count = count_distinct(host.name) by process.parent.executable, process.executable +| where host_count <= 5 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/persistence_via_user_group_creation_modification.toml b/hunting/linux/queries/persistence_via_user_group_creation_modification.toml new file mode 100644 index 00000000000..8411040129c --- /dev/null +++ b/hunting/linux/queries/persistence_via_user_group_creation_modification.toml @@ -0,0 +1,39 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies user and group creation or modification activities on Linux systems using OSQuery. It monitors changes to the shadow file, user and group information, and user processes. These activities can indicate potential unauthorized access or privilege escalation attempts. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "f00c9757-d21b-432c-90a6-8372f18075d0" +name = "Privilege Escalation/Persistence via User/Group Creation and/or Modification" +language = ["SQL"] +license = "Elastic License v2" +notes = [ + "Monitors changes to the shadow file and user/group information using OSQuery to detect potentially unauthorized access or privilege escalation attempts.", + "Lists detailed information about users, including authentication status and running processes.", + "Requires additional data analysis and investigation into results to identify malicious or unauthorized user and group modifications." +] +mitre = ["T1136", "T1136.001", "T1136.002"] + +query = [ +''' +SELECT * FROM shadow +''', +''' +SELECT * FROM shadow +WHERE password_status != "locked" +''', +''' +SELECT username, gid, uid, shell, description FROM users +WHERE username != 'root' AND uid LIKE "0" +''', +''' +SELECT * FROM users WHERE username = "newuser" +''', +''' +SELECT * FROM logged_in_users WHERE user = "newuser" +''', +''' +SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username +''' +] diff --git a/hunting/linux/queries/persistence_via_xdg_autostart_modifications.toml b/hunting/linux/queries/persistence_via_xdg_autostart_modifications.toml new file mode 100644 index 00000000000..045a92afdf5 --- /dev/null +++ b/hunting/linux/queries/persistence_via_xdg_autostart_modifications.toml @@ -0,0 +1,121 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies potential persistence mechanisms via modifications to XDG autostart directories on Linux systems. XDG Autostart entries can be used to execute arbitrary commands or scripts when a user logs in. It monitors file creation or modification events in system-wide, user-specific, and root-specific autostart directories. Additionally, it monitors processes started by common Linux desktop session managers to detect suspicious activity related to autostart entries. +""" +integration = ["endpoint"] +uuid = "8dcc2161-65e0-4448-a03a-1c4e0cbc9330" +name = "XDG Persistence" +language = ["ES|QL", "SQL"] +license = "Elastic License v2" +notes = [ + "Monitors for file creation or modification events in system-wide, user-specific, and root-specific XDG autostart directories.", + "Excludes modifications made by expected update processes such as package managers to reduce false positives.", + "Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.", + "Monitors processes started by common Linux desktop session managers to detect suspicious activity related to autostart entries.", + "OSQuery queries are provided to retrieve enabled XDG startup items and detailed file information related to autostart directories." +] +mitre = ["T1547.001", "T1053.005"] + +query = [ +''' +from logs-endpoint.events.file-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type in ("creation", "change") and ( + + // System-wide autostart directories + file.path like "/etc/xdg/autostart/*" or + file.path like "/usr/share/autostart/*" or + + // User-specific autostart directories + file.path like "/home/*/.config/autostart/*" or + file.path like "/home/*/.local/share/autostart/*" or + file.path like "/home/*/.config/autostart-scripts/*" or + + // Root-specific autostart directories + file.path like "/root/.config/autostart/*" or + file.path like "/root/.local/share/autostart/*" or + file.path like "/root/.config/autostart-scripts/*" +) and not ( + process.name in ( + "dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "microdnf", "podman", "apk" + ) or + process.executable == "/proc/self/exe" or + process.executable like "/dev/fd/*" or + file.extension in ("dpkg-remove", "swx", "swp") +) +| eval persistence = case( + // System-wide autostart directories + file.path like "/etc/xdg/autostart/*" or + file.path like "/usr/share/autostart/*" or + + // User-specific autostart directories + file.path like "/home/*/.config/autostart/*" or + file.path like "/home/*/.local/share/autostart/*" or + file.path like "/home/*/.config/autostart-scripts/*" or + + // Root-specific autostart directories + file.path like "/root/.config/autostart/*" or + file.path like "/root/.local/share/autostart/*" or + file.path like "/root/.config/autostart-scripts/*", + process.name, + null +) +| stats pers_count = count(persistence) by process.executable, file.path +| where pers_count > 0 and pers_count <= 20 +| sort pers_count asc +| limit 100 +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.parent.name in ( + "plasmashell", "gnome-session", "xfce4-session", "gnome-session-binary", "mate-session", "cinnamon-session", + "lxsession", "lxqt-session", "unity-session", "pantheon-session", "enlightenment_start" +) +| stats cc = count(*) by process.command_line, process.parent.executable +| where cc <= 20 +| sort cc asc +| limit 100 +''', +''' +SELECT name, path, source, status, type FROM startup_items +WHERE type == "Startup Item" AND status == "enabled" AND ( + source LIKE "/etc/xdg/autostart/%" + OR source LIKE "/usr/share/autostart/%" + OR source LIKE "/home/%/.config/autostart/%" + OR source LIKE "/home/%/.local/share/autostart/%" + OR source LIKE "/home/%/.config/autostart-scripts/%" + OR source LIKE "/root/.config/autostart/%" + OR source LIKE "/root/.local/share/autostart/%" + OR source LIKE "/root/.config/autostart-scripts/%" +) +''', +''' +SELECT + f.filename, + f.path, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE + f.path LIKE "/etc/xdg/autostart/%" + OR f.path LIKE "/usr/share/autostart/%" + OR f.path LIKE "/home/%/.config/autostart/%" + OR f.path LIKE "/home/%/.local/share/autostart/%" + OR f.path LIKE "/home/%/.config/autostart-scripts/%" + OR f.path LIKE "/root/.config/autostart/%" + OR f.path LIKE "/root/.local/share/autostart/%" + OR f.path LIKE "/root/.config/autostart-scripts/%" +''' +] diff --git a/hunting/linux/queries/privilege_escalation_via_existing_sudoers.toml b/hunting/linux/queries/privilege_escalation_via_existing_sudoers.toml new file mode 100644 index 00000000000..9098f45c6f5 --- /dev/null +++ b/hunting/linux/queries/privilege_escalation_via_existing_sudoers.toml @@ -0,0 +1,22 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies entries in the sudoers file on Linux systems using OSQuery. The sudoers file controls which users have administrative privileges and can be a target for attackers seeking to escalate their privileges. This hunt lists all sudoers rules for further analysis. +""" +integration = ["endpoint"] +uuid = "6e57e6a6-f150-405d-b8be-e4e666a3a86d" +name = "Privilege Escalation Identification via Existing Sudoers File" +language = ["SQL"] +license = "Elastic License v2" +notes = [ + "Lists all entries in the sudoers file using OSQuery to detect potentially unauthorized or suspicious rules.", + "Requires additional data analysis and investigation into results to identify malicious or misconfigured sudoers entries.", + "Focuses on monitoring and analyzing administrative privileges granted through the sudoers file." +] +mitre = ["T1548.003"] + +query = [ +''' +SELECT * FROM sudoers +''' +] diff --git a/hunting/linux/queries/privilege_escalation_via_process_capabilities.toml b/hunting/linux/queries/privilege_escalation_via_process_capabilities.toml new file mode 100644 index 00000000000..c34539cddec --- /dev/null +++ b/hunting/linux/queries/privilege_escalation_via_process_capabilities.toml @@ -0,0 +1,48 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies processes on Linux systems with specific capabilities set. It monitors process execution events where processes have effective or permitted capabilities, which can be indicative of elevated privileges. The hunt focuses on non-root users to detect potential privilege escalation attempts. The hunt lists detailed information for further analysis and investigation. +""" +integration = ["endpoint"] +uuid = "6f67704d-e5b1-4613-912c-e2965660fe17" +name = "Process Capability Hunting" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Monitors process execution events where processes have specific capabilities set, such as CAP_SYS_MODULE, CAP_SYS_PTRACE, and others.", + "Excludes certain processes and capabilities to reduce false positives, but these can be adjusted based on your environment.", + "Uses EVAL to tag potential privilege escalation events and counts occurrences to identify unusual activity.", + "Focuses on non-root users to detect potential privilege escalation attempts.", + "Requires additional data analysis and investigation into results to identify malicious or unauthorized use of process capabilities." +] +mitre = ["T1548.001", "T1548.003"] + +query = [ +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and (process.thread.capabilities.effective is not null or process.thread.capabilities.permitted is not null) and user.id != "0" and +not ( + // Remove these if you expect persistence through capabilities + process.executable like "/var/lib/docker/*" or + process.name == "gnome-keyring-daemon" or + process.thread.capabilities.permitted == "CAP_WAKE_ALARM" +) +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.thread.capabilities.effective, process.thread.capabilities.permitted +| where host_count <= 3 and cc < 5 +| sort cc asc +| limit 100 +''', +''' +from logs-endpoint.events.process-* +| where @timestamp > now() - 30 day +| where host.os.type == "linux" and event.action == "exec" and event.type == "start" and ( + process.thread.capabilities.effective in ("CAP_SYS_MODULE", "CAP_SYS_PTRACE", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_SETUID", "CAP_SETGID", "CAP_SYS_ADMIN") or + process.thread.capabilities.permitted in ("CAP_SYS_MODULE", "CAP_SYS_PTRACE", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_SETUID", "CAP_SETGID", "CAP_SYS_ADMIN") +) and user.id != "0" +| stats cc = count(), host_count = count_distinct(host.name) by process.executable, process.thread.capabilities.effective, process.thread.capabilities.permitted +| where host_count <= 3 and cc < 5 +| sort cc asc +| limit 100 +''' +] diff --git a/hunting/linux/queries/privilege_escalation_via_segmentation_fault_and_buffer_overflow.toml b/hunting/linux/queries/privilege_escalation_via_segmentation_fault_and_buffer_overflow.toml new file mode 100644 index 00000000000..a4f0acadb9d --- /dev/null +++ b/hunting/linux/queries/privilege_escalation_via_segmentation_fault_and_buffer_overflow.toml @@ -0,0 +1,40 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies segmentation faults (segfaults) and potential buffer overflow attacks on Linux systems by parsing syslog messages related to segfaults. It captures details about the crashing process, shared object file, and other relevant information to help identify and investigate potential exploitation attempts. +""" +integration = ["system"] +uuid = "3f3fd2b9-940c-4310-adb1-d8b7d726e281" +name = "Segmentation Fault & Potential Buffer Overflow Hunting" +language = ["ES|QL"] +license = "Elastic License v2" +notes = [ + "Detects segfaults and parses syslog messages related to segfaults to identify the crashing process and shared object file along with additional crash details.", + "Uses GROK to extract relevant fields from syslog messages.", + "Counts occurrences of segfaults within a plain text message field to potentially detect buffer overflow attacks and unsuccessful process injection attempts.", + "Removes prepending spaces from syslog messages using EVAL to ensure consistent parsing.", + "Depending on the Syslog configuration, additional parsing may be required to extract the necessary fields from the message." +] +mitre = ["T1203", "T1068"] + +query = [ +''' +from logs-system.syslog* +| where @timestamp > now() - 12 hour +| where host.os.type == "linux" and process.name == "kernel" and message like "*segfault*" +| grok message "\\[%{NUMBER:timestamp}\\] %{WORD:process}\\[%{NUMBER:pid}\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_file}\\[%{BASE16NUM:so_base_address}\\+%{BASE16NUM:so_offset}\\]" +| keep timestamp, process, pid, so_file, segfault_address, instruction_pointer, stack_pointer, error_code, so_base_address, so_offset +''', +''' +from logs-system.syslog* +| where host.os.type == "linux" and process.name == "kernel" and message like "*segfault*" +| where @timestamp > now() - 12 hour +| grok message "\\[%{DATA:timestamp}\\] %{WORD:process}\\[%{NUMBER:pid}\\]: segfault at %{BASE16NUM:segfault_address} ip %{BASE16NUM:instruction_pointer} sp %{BASE16NUM:stack_pointer} error %{NUMBER:error_code} in %{DATA:so_name}\\[%{BASE16NUM:so_base_address}\\+%{BASE16NUM:so_offset}\\] likely on CPU %{NUMBER:cpu} \\(core %{NUMBER:core}, socket %{NUMBER:socket}\\)" +| eval timestamp = REPLACE(timestamp, "\\s+", "") +| keep timestamp, process, pid, segfault_address, instruction_pointer, stack_pointer, error_code, so_name, so_base_address, so_offset, cpu, core, socket +| stats cc = count() by process, so_name +// Alter this threshold to make sense for your environment +| where cc > 100 +| limit 10 +''' +] diff --git a/hunting/linux/queries/privilege_escalation_via_suid_binaries.toml b/hunting/linux/queries/privilege_escalation_via_suid_binaries.toml new file mode 100644 index 00000000000..5b207d2f426 --- /dev/null +++ b/hunting/linux/queries/privilege_escalation_via_suid_binaries.toml @@ -0,0 +1,55 @@ +[hunt] +author = "Elastic" +description = """ +This hunt identifies SUID binaries on Linux systems using OSQuery. SUID binaries can be exploited by attackers to gain elevated privileges. The hunt includes queries to list all SUID binaries and detailed information about these files, focusing on regular files owned by root with SUID or SGID bits set. +""" +integration = ["endpoint"] +uuid = "2db642d2-621a-4183-88b5-b2659dc2c940" +name = "OSQuery SUID Hunting" +language = ["SQL"] +license = "Elastic License v2" +notes = [ + "Identifies SUID binaries using OSQuery to detect potentially exploitable files with SUID or SGID bits set.", + "Lists all SUID binaries and provides detailed information about these files, including their paths, owners, and permissions.", + "Focuses on regular files owned by root with SUID or SGID bits set to identify potential privilege escalation vectors.", + "OSQuery has limited support for wildcard queries, therefore the query includes multiple LIKE conditions for directories. These can be increased and decreased, based on the environment" +] +mitre = ["T1548.001", "T1574.002"] + +query = [ +''' +SELECT * FROM suid_bin +''', +''' +SELECT + f.filename, + f.path, + f.mode, + f.uid, + f.gid, + f.type, + u.username AS file_owner, + g.groupname AS group_owner, + datetime(f.atime, 'unixepoch') AS file_last_access_time, + datetime(f.mtime, 'unixepoch') AS file_last_modified_time, + datetime(f.ctime, 'unixepoch') AS file_last_status_change_time, + datetime(f.btime, 'unixepoch') AS file_created_time, + f.size AS size_bytes +FROM + file f +LEFT JOIN + users u ON f.uid = u.uid +LEFT JOIN + groups g ON f.gid = g.gid +WHERE +f.type == "regular" AND +(f.uid == 0 or f.gid == 0) AND +(f.mode LIKE "2%" OR f.mode LIKE "4%") AND +( + f.path LIKE "/%%" OR + f.path LIKE "/%%/%%" OR + f.path LIKE "/%%/%%/%%" OR + f.path LIKE "/%%/%%/%%/%%" +) +''' +] diff --git a/hunting/llm/docs/aws_bedrock_dos_resource_exhaustion_detection.md b/hunting/llm/docs/aws_bedrock_dos_resource_exhaustion_detection.md index 0f373c33cbb..05fdf5e0396 100644 --- a/hunting/llm/docs/aws_bedrock_dos_resource_exhaustion_detection.md +++ b/hunting/llm/docs/aws_bedrock_dos_resource_exhaustion_detection.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunting query identifies unusual spikes in token usage that may indicate malicious attempts to disrupt services. High token usage can strain system resources and degrade performance, aligning with tactics observed in DoS attacks. -- **UUID:** `dc181967-c32c-46c9-b84b-ec4c8811c6a0` +- **UUID:** `00023411-192e-4472-90aa-da7562bc3f2a` - **Integration:** [aws_bedrock.invocation](https://docs.elastic.co/integrations/aws_bedrock) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/llm/docs/aws_bedrock_latency_anomalies_detection.md b/hunting/llm/docs/aws_bedrock_latency_anomalies_detection.md index 8c3c9b791a7..16c866a2a19 100644 --- a/hunting/llm/docs/aws_bedrock_latency_anomalies_detection.md +++ b/hunting/llm/docs/aws_bedrock_latency_anomalies_detection.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This analytic helps identify delays in LLM responses that are outside expected performance parameters, possibly due to malicious disruptions like DDoS attacks or from operational inefficiencies. -- **UUID:** `3708787b-811b-43b1-b2e7-c7276b8db48c` +- **UUID:** `991b55c3-6327-4af6-8e0c-5d4870748369` - **Integration:** [aws_bedrock.invocation](https://docs.elastic.co/integrations/aws_bedrock) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/llm/docs/aws_bedrock_sensitive_content_refusal_detection.md b/hunting/llm/docs/aws_bedrock_sensitive_content_refusal_detection.md index 4def0245222..dd94f37ff37 100644 --- a/hunting/llm/docs/aws_bedrock_sensitive_content_refusal_detection.md +++ b/hunting/llm/docs/aws_bedrock_sensitive_content_refusal_detection.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** This analytic flags multiple instances of LLM refusals to respond to sensitive prompts, helping to maintain ethical guidelines and compliance standards. -- **UUID:** `8fabae86-7ed2-4006-9623-5db28164f374` +- **UUID:** `11e33a8f-805b-4394-bee0-08ae8d78b025` - **Integration:** [aws_bedrock.invocation](https://docs.elastic.co/integrations/aws_bedrock) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/llm/queries/aws_bedrock_dos_resource_exhaustion_detection.toml b/hunting/llm/queries/aws_bedrock_dos_resource_exhaustion_detection.toml index 1288ca5f0a5..c05895f7721 100644 --- a/hunting/llm/queries/aws_bedrock_dos_resource_exhaustion_detection.toml +++ b/hunting/llm/queries/aws_bedrock_dos_resource_exhaustion_detection.toml @@ -4,9 +4,9 @@ description = """ This hunting query identifies unusual spikes in token usage that may indicate malicious attempts to disrupt services. High token usage can strain system resources and degrade performance, aligning with tactics observed in DoS attacks. """ integration = ["aws_bedrock.invocation"] -uuid = "dc181967-c32c-46c9-b84b-ec4c8811c6a0" +uuid = "00023411-192e-4472-90aa-da7562bc3f2a" name = "AWS Bedrock LLM Denial-of-Service or Resource Exhaustion" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [ ''' diff --git a/hunting/llm/queries/aws_bedrock_latency_anomalies_detection.toml b/hunting/llm/queries/aws_bedrock_latency_anomalies_detection.toml index 52ef8b35674..58d24d6dc89 100644 --- a/hunting/llm/queries/aws_bedrock_latency_anomalies_detection.toml +++ b/hunting/llm/queries/aws_bedrock_latency_anomalies_detection.toml @@ -4,9 +4,9 @@ description = """ This analytic helps identify delays in LLM responses that are outside expected performance parameters, possibly due to malicious disruptions like DDoS attacks or from operational inefficiencies. """ integration = ["aws_bedrock.invocation"] -uuid = "3708787b-811b-43b1-b2e7-c7276b8db48c" +uuid = "991b55c3-6327-4af6-8e0c-5d4870748369" name = "AWS Bedrock LLM Latency Anomalies" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [ ''' diff --git a/hunting/llm/queries/aws_bedrock_sensitive_content_refusal_detection.toml b/hunting/llm/queries/aws_bedrock_sensitive_content_refusal_detection.toml index ed5c16deca7..c6386e5717a 100644 --- a/hunting/llm/queries/aws_bedrock_sensitive_content_refusal_detection.toml +++ b/hunting/llm/queries/aws_bedrock_sensitive_content_refusal_detection.toml @@ -2,9 +2,9 @@ author = "Elastic" description = "This analytic flags multiple instances of LLM refusals to respond to sensitive prompts, helping to maintain ethical guidelines and compliance standards." integration = ["aws_bedrock.invocation"] -uuid = "8fabae86-7ed2-4006-9623-5db28164f374" +uuid = "11e33a8f-805b-4394-bee0-08ae8d78b025" name = "AWS Bedrock LLM Sensitive Content Refusals" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [ ''' diff --git a/hunting/macos/docs/suspicious_network_connections_by_unsigned_macho.md b/hunting/macos/docs/suspicious_network_connections_by_unsigned_macho.md index 1296c555893..622d5a9b9db 100644 --- a/hunting/macos/docs/suspicious_network_connections_by_unsigned_macho.md +++ b/hunting/macos/docs/suspicious_network_connections_by_unsigned_macho.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt aggregates by process ID and destination IP by the number of connections per hour over a period of time greater than a defined threshold. This may indicate suspicious network connections by unsigned Mach-O binaries. -- **UUID:** `44aff0e3-e0d7-4dca-a94f-2dd0b96f18bd` +- **UUID:** `dc04d70a-80aa-4c3f-ad02-2b18d54af6d4` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/macos/queries/suspicious_network_connections_by_unsigned_macho.toml b/hunting/macos/queries/suspicious_network_connections_by_unsigned_macho.toml index 1335175eb9c..c9c5a6ba612 100644 --- a/hunting/macos/queries/suspicious_network_connections_by_unsigned_macho.toml +++ b/hunting/macos/queries/suspicious_network_connections_by_unsigned_macho.toml @@ -4,9 +4,9 @@ description = """ This hunt aggregates by process ID and destination IP by the number of connections per hour over a period of time greater than a defined threshold. This may indicate suspicious network connections by unsigned Mach-O binaries. """ integration = ["endpoint"] -uuid = "44aff0e3-e0d7-4dca-a94f-2dd0b96f18bd" +uuid = "dc04d70a-80aa-4c3f-ad02-2b18d54af6d4" name = "Suspicious Network Connections by Unsigned Mach-O" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt returns a list of processes by entity_id and name that have a high number of connections per hour over a period of time greater than a defined threshold.", diff --git a/hunting/windows/docs/createremotethread_by_source_process_with_low_occurrence.md b/hunting/windows/docs/createremotethread_by_source_process_with_low_occurrence.md index f2972c3a436..1bc31251eef 100644 --- a/hunting/windows/docs/createremotethread_by_source_process_with_low_occurrence.md +++ b/hunting/windows/docs/createremotethread_by_source_process_with_low_occurrence.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** This hunt attempts to identify remote process injection by aggregating Sysmon `CreateRemoteThread` events by source process and returns the ones that we observed in only one unique host. -- **UUID:** `0545f23f-84a7-4b88-9b5b-b8cfcfdc9276` +- **UUID:** `4f878255-53b8-4914-9a7d-4b668bd2ea6a` - **Integration:** [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.md b/hunting/windows/docs/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.md index 554a41cdbd4..09373a77a8c 100644 --- a/hunting/windows/docs/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.md +++ b/hunting/windows/docs/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** This hunt identifies when a process loads a DLL normally located in `System32` or `SysWOW64` folders from an unusual path. Adversaries may execute their own malicious payloads by side-loading malicious DLLs. The host count also should help exclude false-positives by looking at low occurrences when this abnormal behavior is limited to unique agents. -- **UUID:** `87c97865-fdaa-48b2-bfa6-67bed7cf56ef` +- **UUID:** `d06bc067-6174-412f-b1c9-bf8f15149519` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/detect_masquerading_attempts_as_native_windows_binaries.md b/hunting/windows/docs/detect_masquerading_attempts_as_native_windows_binaries.md index 0060613108e..79a4e7d406a 100644 --- a/hunting/windows/docs/detect_masquerading_attempts_as_native_windows_binaries.md +++ b/hunting/windows/docs/detect_masquerading_attempts_as_native_windows_binaries.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** This hunt detects processes named as legit Microsoft native binaries located in the system32 folder. Adversaries may attempt to manipulate features of their artifacts to make them appear legitimate or benign to users and/or security tools. Masquerading occurs when the name or location of an object, legitimate or malicious, is manipulated or abused for the sake of evading defenses and observation. -- **UUID:** `93a72542-a1f7-4407-9175-8f066343db60` +- **UUID:** `a2006c66-d6ab-43ee-871e-d650e38f7972` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/detect_rare_dll_sideload_by_occurrence.md b/hunting/windows/docs/detect_rare_dll_sideload_by_occurrence.md index af1dc7fbfcd..d10eace0cea 100644 --- a/hunting/windows/docs/detect_rare_dll_sideload_by_occurrence.md +++ b/hunting/windows/docs/detect_rare_dll_sideload_by_occurrence.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** This hunt identifies instances where a signed Windows process attempts to load an unsigned DLL from the same process folder. Matches are limited to a unique host with low library load occurrence. Adversaries may execute their own malicious payloads by side-loading malicious DLLs. -- **UUID:** `bcdb7c29-1312-4974-8f2e-10ddeb09cf5c` +- **UUID:** `34a7aadb-fb0f-45ea-9260-830f39c3343b` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/detect_rare_lsass_process_access_attempts.md b/hunting/windows/docs/detect_rare_lsass_process_access_attempts.md index f00621d8408..0d93e5eef50 100644 --- a/hunting/windows/docs/detect_rare_lsass_process_access_attempts.md +++ b/hunting/windows/docs/detect_rare_lsass_process_access_attempts.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt identifies instances where a process attempts to open the Local Security Authority Subsystem Service (LSASS) memory and where the number of occurences is limited to one unique agent and a low number of attempts. This may indicate either a rare legitimate condition or a malicious process attempting to obtain credentials or inject code into the LSASS. -- **UUID:** `3978e183-0b70-4e1c-8c40-24e367f6db5a` +- **UUID:** `d0aed6f5-f84c-4da8-bb2a-b5ca0fbb55e0` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.md b/hunting/windows/docs/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.md index 9ca5fde9043..e428ee89105 100644 --- a/hunting/windows/docs/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.md +++ b/hunting/windows/docs/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for DNS queries performed by commonly abused Microsoft binaries that perform remote file transfer or binary proxy execution. Aggregations for the number of occurrences is limited to one host to reduce the number of potentially legitimate hits. -- **UUID:** `ebf8eb13-c98a-4d2c-8bdb-3f72a3a3961b` +- **UUID:** `1c7be6db-12eb-4281-878d-b6abe0454f36` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/drivers_load_with_low_occurrence_frequency.md b/hunting/windows/docs/drivers_load_with_low_occurrence_frequency.md index 8167a99d2a8..92546cae0bc 100644 --- a/hunting/windows/docs/drivers_load_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/drivers_load_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt helps identify drivers loaded once on a unique host and with a unique hash over a 15 day period of time. Advanced adversaries may leverage legit vulnerable driver to tamper with existing defences or execute code in Kernel mode. -- **UUID:** `99818ad6-c242-4da7-a41a-df64fe7314d6` +- **UUID:** `cebfbb4d-5b2a-44d8-b763-5512b654fb26` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/excessive_rdp_network_activity_by_source_host_and_user.md b/hunting/windows/docs/excessive_rdp_network_activity_by_source_host_and_user.md index 8fb9f6ab98b..a8ef814acd3 100644 --- a/hunting/windows/docs/excessive_rdp_network_activity_by_source_host_and_user.md +++ b/hunting/windows/docs/excessive_rdp_network_activity_by_source_host_and_user.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for a high occurrence of remote desktop connections from the same host and user. The number of unique destination IP addresses is compared to a defined threshold. This could be a sign of discovery or lateral movement via the Remote Desktop Protocol (RDP). -- **UUID:** `fe01a8a5-6367-4c4c-a57b-be513ab80e42` +- **UUID:** `f7d2054f-b571-4cd0-b39e-a779576e9398` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/excessive_smb_network_activity_by_process_id.md b/hunting/windows/docs/excessive_smb_network_activity_by_process_id.md index 27b6f75bfb7..959c015bcb1 100644 --- a/hunting/windows/docs/excessive_smb_network_activity_by_process_id.md +++ b/hunting/windows/docs/excessive_smb_network_activity_by_process_id.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for a high occurrence of SMB connections from the same process by unique destination IP addresses. The number of unique destination IP addresses is compared to a defined threshold. This could be a sign of SMB scanning or lateral movement via remote services that depend on the SMB protocol. -- **UUID:** `6949135b-76d7-47a3-ae95-ef482508fb7c` +- **UUID:** `8a95f552-f149-4c71-888e-f2690f5add15` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/executable_file_creation_by_an_unusual_microsoft_binary.md b/hunting/windows/docs/executable_file_creation_by_an_unusual_microsoft_binary.md index 60e64eddaed..db20ed901f2 100644 --- a/hunting/windows/docs/executable_file_creation_by_an_unusual_microsoft_binary.md +++ b/hunting/windows/docs/executable_file_creation_by_an_unusual_microsoft_binary.md @@ -8,9 +8,9 @@ - **Description:** This hunt identifies executable file creation by an unusual Microsoft native binary. This could be the result of code injection or some other form of exploitation for defense evasion. -- **UUID:** `3b2900fe-74d9-4c49-b3df-cbeceb02e841` +- **UUID:** `b786bcd7-b119-4ff7-b839-3927c2ff7f1f` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.md b/hunting/windows/docs/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.md index 818f73aea8d..10cc5d87ff3 100644 --- a/hunting/windows/docs/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.md +++ b/hunting/windows/docs/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt aggregates process execution and remote network logons by source address, account name and process hash. It then limits the results by unique host within a 7 day period. This may indicate lateral movement via remote services. -- **UUID:** `ae07c580-290e-4421-add8-d6ca30509b6a` +- **UUID:** `24108755-4d1f-4d7a-ad5f-04c2ca55e9a3` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/execution_via_remote_services_by_client_address.md b/hunting/windows/docs/execution_via_remote_services_by_client_address.md index 94dc4e1dd54..8659abfe2a8 100644 --- a/hunting/windows/docs/execution_via_remote_services_by_client_address.md +++ b/hunting/windows/docs/execution_via_remote_services_by_client_address.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt aggregates process execution via remote network logon by source address, account name and where the parent process is related to remote services such as WMI, WinRM, DCOM and remote PowerShell. This may indicate lateral movement via remote services. -- **UUID:** `e6e54717-2676-4785-a4a6-503577bfb0ea` +- **UUID:** `5fd5da54-0515-4d6b-b8d7-30fd05f5be33` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/execution_via_startup_with_low_occurrence_frequency.md b/hunting/windows/docs/execution_via_startup_with_low_occurrence_frequency.md index 845b308f98f..ee6cc2ba951 100644 --- a/hunting/windows/docs/execution_via_startup_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/execution_via_startup_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt identifies programs started shortly after user logon and presence limited to a unique host. Run registry key and Startup folder cause programs to run each time that a user logs on and are often abused by malwares to maintain persistence on an endpoint. -- **UUID:** `a447df80-d3d5-48b3-a175-a864264ec487` +- **UUID:** `52a958e8-0368-4e74-bd4b-a64faf397bf4` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.md b/hunting/windows/docs/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.md index 7df963b1f81..e26c6b34839 100644 --- a/hunting/windows/docs/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.md +++ b/hunting/windows/docs/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for unique process execution via Windows Management Instrumentation (WMI) by removing random patterns from `process.command_line` and aggregating execution by count of agents with the same command line to limit results to unique ones. -- **UUID:** `b5efeb92-9b51-45b9-839f-be4cdc054ef4` +- **UUID:** `a95e69af-22ad-4ab7-919e-794501f10c95` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query @@ -28,7 +28,7 @@ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-sys | where @timestamp > now() - 7 day and host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation", "created-process") and - process.parent.name.caseless == "wmiprvse.exe" + to_lower(process.parent.name) == "wmiprvse.exe" | keep process.command_line, host.id | eval cmdline = replace(process.command_line, """[cC]:\\[uU][sS][eE][rR][sS]\\[a-zA-Z0-9\.\-\_\$~ ]+\\""", "C:\\\\users\\\\user\\\\") | eval cmdline = replace(cmdline, """([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,})""", "") @@ -40,7 +40,7 @@ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-sys from logs-endpoint.events.process-*, logs-windows.sysmon_operational-* | where @timestamp > now() - 7 day and host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation") and - process.parent.name.caseless == "wmiprvse.exe" and (process.code_signature.exists == false or process.code_signature.trusted == false) + to_lower(process.parent.name) == "wmiprvse.exe" and (process.code_signature.exists == false or process.code_signature.trusted == false) | keep process.hash.sha256, host.id, process.name | stats agents = count_distinct(host.id) by process.hash.sha256 | where agents == 1 diff --git a/hunting/windows/docs/execution_via_windows_scheduled_task_with_low_occurrence_frequency.md b/hunting/windows/docs/execution_via_windows_scheduled_task_with_low_occurrence_frequency.md index 88d56835902..ecaf2c7b52e 100644 --- a/hunting/windows/docs/execution_via_windows_scheduled_task_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/execution_via_windows_scheduled_task_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** Aggregating by paths/hash, this hunt identifies rare instances where a program executes as a child process of the Tasks Scheduler service. This could be the result of persistence as a Windows Scheduled Task. -- **UUID:** `96d5afc8-1f25-4265-8a0e-9998091a2e1f` +- **UUID:** `0d960760-8a40-49c1-bbdd-4deb32c7fd67` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/execution_via_windows_services_with_low_occurrence_frequency.md b/hunting/windows/docs/execution_via_windows_services_with_low_occurrence_frequency.md index 37878a0a063..f93de4ee388 100644 --- a/hunting/windows/docs/execution_via_windows_services_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/execution_via_windows_services_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for a low occurrence of process execution via the Windows Services Control Manager by unique agent. The Services Control Manager is responsible for starting, stopping, and interacting with system services. This could be a sign of persistence as a Windows service. -- **UUID:** `858b7022-b587-4b95-afd6-8ce597bedce3` +- **UUID:** `a0a84a86-115f-42f9-90a5-4cb7ceeef981` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/high_count_of_network_connection_over_extended_period_by_process.md b/hunting/windows/docs/high_count_of_network_connection_over_extended_period_by_process.md index ed98002ee6d..2b4357cbc30 100644 --- a/hunting/windows/docs/high_count_of_network_connection_over_extended_period_by_process.md +++ b/hunting/windows/docs/high_count_of_network_connection_over_extended_period_by_process.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt identifies browser or svchost instances performing a considerable number of connections per hour over an extended period of hours to a specific destination address, limited to a unique host of the monitored agents. Browsers and svchost are both good targets for masquerading network traffic on the endpoint. -- **UUID:** `ed254a22-e7bb-4a36-9291-196b77762dd8` +- **UUID:** `5e5aa9c2-96a8-4d5b-bbca-ff2ec8fefa5b` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/libraries_loaded_by_svchost_with_low_occurrence_frequency.md b/hunting/windows/docs/libraries_loaded_by_svchost_with_low_occurrence_frequency.md index db39a5dfe9c..bccdb2fcc31 100644 --- a/hunting/windows/docs/libraries_loaded_by_svchost_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/libraries_loaded_by_svchost_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt returns the SHA256 hash and the `dll.path` of unsigned libraries loaded by svchost where the presence of unique path/hash is limited to a unique host. Adversaries may use Windows service DLLs to maintain persistence or run with System privileges. -- **UUID:** `e37fe0b9-1b70-4800-8989-58bac5a0a9bb` +- **UUID:** `c00f1afe-4f25-4542-8cc9-277b23581121` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/microsoft_office_child_processes_with_low_occurrence_frequency.md b/hunting/windows/docs/microsoft_office_child_processes_with_low_occurrence_frequency.md index 16074a0d3cd..08ebad93a7c 100644 --- a/hunting/windows/docs/microsoft_office_child_processes_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/microsoft_office_child_processes_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for Microsoft Office child processes with low occurrence frequency. This could be a normal rare behavior as well as potential execution via a malicious document. Adversaries may use Microsoft Office applications to execute malicious code, such as macros, scripts, or other payloads. -- **UUID:** `74b2e54b-7002-4201-83d6-7fd9bd5dcf0f` +- **UUID:** `f1b8519a-4dae-475f-965a-f53559233eab` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/network_discovery_via_sensitive_ports_by_unusual_process.md b/hunting/windows/docs/network_discovery_via_sensitive_ports_by_unusual_process.md index 0fc9f746203..8aaa3fe6606 100644 --- a/hunting/windows/docs/network_discovery_via_sensitive_ports_by_unusual_process.md +++ b/hunting/windows/docs/network_discovery_via_sensitive_ports_by_unusual_process.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for either processes connecting to multiple sensitive TCP ports (SMB, RDP, LDAP, Kerberos and ADWS), a high number of SMB/RDP connections to unique destinations or the same process connecting to both RDP and SMB (should be rare). -- **UUID:** `e0acab7d-30bd-4be0-9682-5c3457bbeb4f` +- **UUID:** `386f9cec-bb44-4dd2-8368-45e6fa0a425b` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/pe_file_transfer_via_smb_admin_shares_by_agent.md b/hunting/windows/docs/pe_file_transfer_via_smb_admin_shares_by_agent.md index 7652222b096..8caf033181b 100644 --- a/hunting/windows/docs/pe_file_transfer_via_smb_admin_shares_by_agent.md +++ b/hunting/windows/docs/pe_file_transfer_via_smb_admin_shares_by_agent.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for a high number of executable file transfers via the SMB protocol by the same user or agent to more than a defined maxium threshold of targets. This could be a sign of lateral movement via the Windows Admin Shares. -- **UUID:** `3e66fc1a-2ea0-43a6-ba51-0280c693d152` +- **UUID:** `814894a4-c951-4f33-ab0b-09354e1cb957` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/persistence_via_run_key_with_low_occurrence_frequency.md b/hunting/windows/docs/persistence_via_run_key_with_low_occurrence_frequency.md index 3131f94a0a0..85b743bd2fe 100644 --- a/hunting/windows/docs/persistence_via_run_key_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/persistence_via_run_key_with_low_occurrence_frequency.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** Leveraging frequency based analysis and random values normalization, this hunt identifies instances where a program adds a persistence entry with rare values or are imited to unique hosts. Run registry key cause programs to run each time that a user logs on and are often abused by adversaries to maintain persistence on an endpoint. -- **UUID:** `1078e906-0485-482e-bcf3-7ee939e07020` +- **UUID:** `df4ee961-254d-4ad1-af15-c65c3b65abcd` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/persistence_via_startup_with_low_occurrence_frequency.md b/hunting/windows/docs/persistence_via_startup_with_low_occurrence_frequency.md index 962e473921f..a8dac4cc443 100644 --- a/hunting/windows/docs/persistence_via_startup_with_low_occurrence_frequency.md +++ b/hunting/windows/docs/persistence_via_startup_with_low_occurrence_frequency.md @@ -6,9 +6,9 @@ - **Author:** Elastic - **Description:** Leveraging frequency based analysis and path normalization, this hunt identifies rare instances where a program adds a Startup persistence via file creation. Startup entries cause programs to run each time that a user logs on and are often abused by adversaries to maintain persistence on an endpoint. -- **UUID:** `9d8c79fd-0006-4988-8aaa-d5f9b9a7df8e` +- **UUID:** `ea950361-33e4-4045-96a5-d36ca28fbc91` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.md b/hunting/windows/docs/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.md index 51661b8cfb1..e992b8233a9 100644 --- a/hunting/windows/docs/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.md +++ b/hunting/windows/docs/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for persistence via Launch agent or daemon where the distribution is limited to one unique host. -- **UUID:** `a7dcd1a1-2860-491e-8802-31169a607167` +- **UUID:** `69fc4f40-8fb1-4652-99b7-52755cd370fe` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/potential_exfiltration_by_process_total_egress_bytes.md b/hunting/windows/docs/potential_exfiltration_by_process_total_egress_bytes.md index ea5970208be..a6dae90a4e4 100644 --- a/hunting/windows/docs/potential_exfiltration_by_process_total_egress_bytes.md +++ b/hunting/windows/docs/potential_exfiltration_by_process_total_egress_bytes.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** Using aggregation and the ES|QL `SUM` function, this hunt identifies processes that performed egress connections with total bytes greater or equal to a defined maximum threshold. This may indicate exfiltration or long term command and control activity. -- **UUID:** `977d77f9-86e0-4df6-bdc7-aed87c048290` +- **UUID:** `24925575-defd-4581-bfda-a8753dcfb46e` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/rundll32_execution_aggregated_by_cmdline.md b/hunting/windows/docs/rundll32_execution_aggregated_by_cmdline.md index 6c7a77c7097..7e452066bd8 100644 --- a/hunting/windows/docs/rundll32_execution_aggregated_by_cmdline.md +++ b/hunting/windows/docs/rundll32_execution_aggregated_by_cmdline.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt aggregate Rundll32 execution by normalized `process.command_line` and returns instances that are unique by frequency. Rundll32 is one of the most abused binaries to proxy execution of malicious commands and modules. -- **UUID:** `30f37cd2-c1d8-4554-bb4a-ed76de9e6857` +- **UUID:** `44e6adc6-e183-4bfa-b06d-db41669641fa` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/scheduled_task_creation_by_action_via_registry.md b/hunting/windows/docs/scheduled_task_creation_by_action_via_registry.md index 7e5f3769c62..2446f14e468 100644 --- a/hunting/windows/docs/scheduled_task_creation_by_action_via_registry.md +++ b/hunting/windows/docs/scheduled_task_creation_by_action_via_registry.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for scheduled tasks creation by action using registry events. Scheduled tasks actions are saved under the TaskCache registry key in base64 encoded blob. Malware often abuse LOLBins to proxy execution or run executables from unusual paths, you can add more patterns to the query. -- **UUID:** `344c0690-ebc3-4794-b123-272a5c09c57b` +- **UUID:** `df50f65e-e820-47f4-a039-671611582f51` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/scheduled_tasks_creation_for_unique_hosts_by_task_command.md b/hunting/windows/docs/scheduled_tasks_creation_for_unique_hosts_by_task_command.md index 685fcae5eb2..d353a26080b 100644 --- a/hunting/windows/docs/scheduled_tasks_creation_for_unique_hosts_by_task_command.md +++ b/hunting/windows/docs/scheduled_tasks_creation_for_unique_hosts_by_task_command.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** Using aggregation and strings extraction, this hunt identifies instances where a scheduled task is created and set to run a command unique to a specific host. This could be the result of persistence as a Windows Scheduled Task. -- **UUID:** `75804319-122c-4bdc-976e-d6355bca0d78` +- **UUID:** `44223fd6-8241-4c21-9d54-21201fa15b12` - **Integration:** [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/suspicious_base64_encoded_powershell_commands.md b/hunting/windows/docs/suspicious_base64_encoded_powershell_commands.md index eb3ed872e2e..a71617ab916 100644 --- a/hunting/windows/docs/suspicious_base64_encoded_powershell_commands.md +++ b/hunting/windows/docs/suspicious_base64_encoded_powershell_commands.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt identifies base64 encoded powershell commands in process start events and filters ones with suspicious keywords like downloaders and evasion related commands. -- **UUID:** `8bf800de-b3a2-4b36-9484-7d9dae2a1992` +- **UUID:** `2e583d3c-7ad6-4544-a0db-c685b2066493` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/suspicious_dns_txt_record_lookups_by_process.md b/hunting/windows/docs/suspicious_dns_txt_record_lookups_by_process.md index 77291923421..2037edd1125 100644 --- a/hunting/windows/docs/suspicious_dns_txt_record_lookups_by_process.md +++ b/hunting/windows/docs/suspicious_dns_txt_record_lookups_by_process.md @@ -8,9 +8,9 @@ - **Description:** Leveraging aggregation by process executable entities, this hunt identifies identifies a high number of DNS TXT record queries from same process. Adversaries may leverage DNS TXT queries to stage malicious content or exfiltrate data. -- **UUID:** `0b7343f7-2d16-43c7-af28-9d1f012b1093` +- **UUID:** `7a2c8397-d219-47ad-a8e2-93562e568d08` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/unique_windows_services_creation_by_servicefilename.md b/hunting/windows/docs/unique_windows_services_creation_by_servicefilename.md index 3a98c902341..54600eab2d5 100644 --- a/hunting/windows/docs/unique_windows_services_creation_by_servicefilename.md +++ b/hunting/windows/docs/unique_windows_services_creation_by_servicefilename.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt aggregates created Windows services by service file name and distribution limited to unique hosts. Using the ES|QL `Replace` command we can also further remove random patterns to reduce results to interesting events. More investigation can be conducted on instance that looks suspicious based on service file path, names and LOLBins. -- **UUID:** `ebf79207-16dc-44f8-b10c-317d4a034bad` +- **UUID:** `48b75e53-3c73-40bd-873d-569dd8d7d925` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/windows_command_and_scripting_interpreter_from_unusual_parent.md b/hunting/windows/docs/windows_command_and_scripting_interpreter_from_unusual_parent.md index bd5755a4943..dc4b925ad9f 100644 --- a/hunting/windows/docs/windows_command_and_scripting_interpreter_from_unusual_parent.md +++ b/hunting/windows/docs/windows_command_and_scripting_interpreter_from_unusual_parent.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt looks for unusual Microsoft native processes spawning `cmd.exe`, `powershell.exe` or `conhost.exe` and limited to a unique host. This could be normal rare behavior as well as an interactive shell activity from an injected parent process to execute system commands. -- **UUID:** `de929347-c04a-4a94-8be2-cbe87b25bb25` +- **UUID:** `aca4877f-d284-4bdb-8e18-b1414d3a7c20` - **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint), [windows](https://docs.elastic.co/integrations/windows), [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/docs/windows_logon_activity_by_source_ip.md b/hunting/windows/docs/windows_logon_activity_by_source_ip.md index 5c71659eeca..d95de178f17 100644 --- a/hunting/windows/docs/windows_logon_activity_by_source_ip.md +++ b/hunting/windows/docs/windows_logon_activity_by_source_ip.md @@ -7,9 +7,9 @@ - **Author:** Elastic - **Description:** This hunt returns a summary of network logon activity by `source.ip` using Windows event IDs 4624 and 4625. The higher the number of failures, low success and multiple accounts the more suspicious the behavior is. -- **UUID:** `7bdea198-eb09-4eca-ae3d-bfc3b52c89a9` +- **UUID:** `441fba85-47a9-4f1f-aab4-569bbfdc548b` - **Integration:** [system](https://docs.elastic.co/integrations/system) -- **Language:** `ES|QL` +- **Language:** `[ES|QL]` ## Query diff --git a/hunting/windows/queries/createremotethread_by_source_process_with_low_occurrence.toml b/hunting/windows/queries/createremotethread_by_source_process_with_low_occurrence.toml index 4fea380c3ba..1b6cb5a2e48 100644 --- a/hunting/windows/queries/createremotethread_by_source_process_with_low_occurrence.toml +++ b/hunting/windows/queries/createremotethread_by_source_process_with_low_occurrence.toml @@ -2,9 +2,9 @@ author = "Elastic" description = "This hunt attempts to identify remote process injection by aggregating Sysmon `CreateRemoteThread` events by source process and returns the ones that we observed in only one unique host." integration = ["windows"] -uuid = "0545f23f-84a7-4b88-9b5b-b8cfcfdc9276" +uuid = "4f878255-53b8-4914-9a7d-4b668bd2ea6a" name = "Low Occurrence Rate of CreateRemoteThread by Source Process" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Adding `winlog.event_data.TargetImage` to the aggregation clause can be beneficial but may introduce more false-positives.", diff --git a/hunting/windows/queries/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.toml b/hunting/windows/queries/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.toml index cdbfab8145e..c758229bf3b 100644 --- a/hunting/windows/queries/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.toml +++ b/hunting/windows/queries/detect_dll_hijack_via_masquerading_as_microsoft_native_libraries.toml @@ -2,9 +2,9 @@ author = "Elastic" description = "This hunt identifies when a process loads a DLL normally located in `System32` or `SysWOW64` folders from an unusual path. Adversaries may execute their own malicious payloads by side-loading malicious DLLs. The host count also should help exclude false-positives by looking at low occurrences when this abnormal behavior is limited to unique agents." integration = ["endpoint", "windows"] -uuid = "87c97865-fdaa-48b2-bfa6-67bed7cf56ef" +uuid = "d06bc067-6174-412f-b1c9-bf8f15149519" name = "DLL Hijack via Masquerading as Microsoft Native Libraries" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" mitre = ["T1574", "T1574.001"] notes = [ diff --git a/hunting/windows/queries/detect_masquerading_attempts_as_native_windows_binaries.toml b/hunting/windows/queries/detect_masquerading_attempts_as_native_windows_binaries.toml index 96f9ef336ce..1f65a7229f2 100644 --- a/hunting/windows/queries/detect_masquerading_attempts_as_native_windows_binaries.toml +++ b/hunting/windows/queries/detect_masquerading_attempts_as_native_windows_binaries.toml @@ -2,10 +2,10 @@ author = "Elastic" description = "This hunt detects processes named as legit Microsoft native binaries located in the system32 folder. Adversaries may attempt to manipulate features of their artifacts to make them appear legitimate or benign to users and/or security tools. Masquerading occurs when the name or location of an object, legitimate or malicious, is manipulated or abused for the sake of evading defenses and observation. " integration = ["endpoint"] -uuid = "93a72542-a1f7-4407-9175-8f066343db60" +uuid = "a2006c66-d6ab-43ee-871e-d650e38f7972" mitre = ["T1036"] name = "Masquerading Attempts as Native Windows Binaries" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [''' from logs-endpoint.events.process-* diff --git a/hunting/windows/queries/detect_rare_dll_sideload_by_occurrence.toml b/hunting/windows/queries/detect_rare_dll_sideload_by_occurrence.toml index 9374520bda0..76697de350b 100644 --- a/hunting/windows/queries/detect_rare_dll_sideload_by_occurrence.toml +++ b/hunting/windows/queries/detect_rare_dll_sideload_by_occurrence.toml @@ -2,9 +2,9 @@ author = "Elastic" description = """This hunt identifies instances where a signed Windows process attempts to load an unsigned DLL from the same process folder. Matches are limited to a unique host with low library load occurrence. Adversaries may execute their own malicious payloads by side-loading malicious DLLs.""" integration = ["endpoint", "windows"] -uuid = "bcdb7c29-1312-4974-8f2e-10ddeb09cf5c" +uuid = "34a7aadb-fb0f-45ea-9260-830f39c3343b" name = "Rare DLL Side-Loading by Occurrence" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [ ''' diff --git a/hunting/windows/queries/detect_rare_lsass_process_access_attempts.toml b/hunting/windows/queries/detect_rare_lsass_process_access_attempts.toml index 60e6a54b734..a4505180db3 100644 --- a/hunting/windows/queries/detect_rare_lsass_process_access_attempts.toml +++ b/hunting/windows/queries/detect_rare_lsass_process_access_attempts.toml @@ -4,9 +4,9 @@ description = """ This hunt identifies instances where a process attempts to open the Local Security Authority Subsystem Service (LSASS) memory and where the number of occurences is limited to one unique agent and a low number of attempts. This may indicate either a rare legitimate condition or a malicious process attempting to obtain credentials or inject code into the LSASS. """ integration = ["endpoint", "windows"] -uuid = "3978e183-0b70-4e1c-8c40-24e367f6db5a" +uuid = "d0aed6f5-f84c-4da8-bb2a-b5ca0fbb55e0" name = "Rare LSASS Process Access Attempts" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" query = [ ''' diff --git a/hunting/windows/queries/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.toml b/hunting/windows/queries/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.toml index d14755d19d5..c7473153f59 100644 --- a/hunting/windows/queries/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.toml +++ b/hunting/windows/queries/domain_names_queried_via_lolbins_and_with_low_occurence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for DNS queries performed by commonly abused Microsoft binaries that perform remote file transfer or binary proxy execution. Aggregations for the number of occurrences is limited to one host to reduce the number of potentially legitimate hits. """ integration = ["endpoint", "windows"] -uuid = "ebf8eb13-c98a-4d2c-8bdb-3f72a3a3961b" +uuid = "1c7be6db-12eb-4281-878d-b6abe0454f36" name = "DNS Queries via LOLBins with Low Occurence Frequency" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Utilities like curl and SSL verification for web services are noisy, while others are rare such as scripting utilities and are worth further investigation.", diff --git a/hunting/windows/queries/drivers_load_with_low_occurrence_frequency.toml b/hunting/windows/queries/drivers_load_with_low_occurrence_frequency.toml index e4c7d0a2346..9c497027bb2 100644 --- a/hunting/windows/queries/drivers_load_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/drivers_load_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt helps identify drivers loaded once on a unique host and with a unique hash over a 15 day period of time. Advanced adversaries may leverage legit vulnerable driver to tamper with existing defences or execute code in Kernel mode. """ integration = ["endpoint", "windows", "system"] -uuid = "99818ad6-c242-4da7-a41a-df64fe7314d6" +uuid = "cebfbb4d-5b2a-44d8-b763-5512b654fb26" name = "Low Occurrence of Drivers Loaded on Unique Hosts" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt has three optional queries, one for Elastic Defend data, another for Sysmon data and the last one for Windows 7045 events.", diff --git a/hunting/windows/queries/excessive_rdp_network_activity_by_source_host_and_user.toml b/hunting/windows/queries/excessive_rdp_network_activity_by_source_host_and_user.toml index 607fc20fa45..2dce1e1c7f7 100644 --- a/hunting/windows/queries/excessive_rdp_network_activity_by_source_host_and_user.toml +++ b/hunting/windows/queries/excessive_rdp_network_activity_by_source_host_and_user.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for a high occurrence of remote desktop connections from the same host and user. The number of unique destination IP addresses is compared to a defined threshold. This could be a sign of discovery or lateral movement via the Remote Desktop Protocol (RDP). """ integration = ["endpoint", "windows"] -uuid = "fe01a8a5-6367-4c4c-a57b-be513ab80e42" +uuid = "f7d2054f-b571-4cd0-b39e-a779576e9398" name = "Excessive RDP Network Activity by Host and User" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Further investigation can done pivoting by `host.id` and `user.name`.", diff --git a/hunting/windows/queries/excessive_smb_network_activity_by_process_id.toml b/hunting/windows/queries/excessive_smb_network_activity_by_process_id.toml index 8292137ebd3..16b8bde2525 100644 --- a/hunting/windows/queries/excessive_smb_network_activity_by_process_id.toml +++ b/hunting/windows/queries/excessive_smb_network_activity_by_process_id.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for a high occurrence of SMB connections from the same process by unique destination IP addresses. The number of unique destination IP addresses is compared to a defined threshold. This could be a sign of SMB scanning or lateral movement via remote services that depend on the SMB protocol. """ integration = ["endpoint", "windows"] -uuid = "6949135b-76d7-47a3-ae95-ef482508fb7c" +uuid = "8a95f552-f149-4c71-888e-f2690f5add15" name = "Excessive SMB Network Activity by Process ID" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Further investigation can done pivoting by `process.entity_id` and `host.id.`", diff --git a/hunting/windows/queries/executable_file_creation_by_an_unusual_microsoft_binary.toml b/hunting/windows/queries/executable_file_creation_by_an_unusual_microsoft_binary.toml index 94df6676a50..4a3cb454e8f 100644 --- a/hunting/windows/queries/executable_file_creation_by_an_unusual_microsoft_binary.toml +++ b/hunting/windows/queries/executable_file_creation_by_an_unusual_microsoft_binary.toml @@ -5,9 +5,9 @@ This hunt identifies executable file creation by an unusual Microsoft native bin code injection or some other form of exploitation for defense evasion. """ integration = ["endpoint", "windows"] -uuid = "3b2900fe-74d9-4c49-b3df-cbeceb02e841" +uuid = "b786bcd7-b119-4ff7-b839-3927c2ff7f1f" name = "Executable File Creation by an Unusual Microsoft Binary" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt includes two optional queries, one for Elastic Defend data and another for Sysmon data.", diff --git a/hunting/windows/queries/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.toml b/hunting/windows/queries/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.toml index 0f05183e689..8d44e729b11 100644 --- a/hunting/windows/queries/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.toml +++ b/hunting/windows/queries/execution_via_network_logon_by_occurrence_frequency_by_top_source_ip.toml @@ -4,9 +4,9 @@ description = """ This hunt aggregates process execution and remote network logons by source address, account name and process hash. It then limits the results by unique host within a 7 day period. This may indicate lateral movement via remote services. """ integration = ["endpoint"] -uuid = "ae07c580-290e-4421-add8-d6ca30509b6a" +uuid = "24108755-4d1f-4d7a-ad5f-04c2ca55e9a3" name = "Frequency of Process Execution via Network Logon by Source Address" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "The second query highest occurrence of source addresses/accounts performing remote process execution", diff --git a/hunting/windows/queries/execution_via_remote_services_by_client_address.toml b/hunting/windows/queries/execution_via_remote_services_by_client_address.toml index b84ccd6668f..44d441c6480 100644 --- a/hunting/windows/queries/execution_via_remote_services_by_client_address.toml +++ b/hunting/windows/queries/execution_via_remote_services_by_client_address.toml @@ -4,9 +4,9 @@ description = """ This hunt aggregates process execution via remote network logon by source address, account name and where the parent process is related to remote services such as WMI, WinRM, DCOM and remote PowerShell. This may indicate lateral movement via remote services. """ integration = ["endpoint"] -uuid = "e6e54717-2676-4785-a4a6-503577bfb0ea" +uuid = "5fd5da54-0515-4d6b-b8d7-30fd05f5be33" name = "Execution via Remote Services by Client Address" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "`process.Ext.session_info.*` is populated for Elastic Defend versions 8.6.0+.", diff --git a/hunting/windows/queries/execution_via_startup_with_low_occurrence_frequency.toml b/hunting/windows/queries/execution_via_startup_with_low_occurrence_frequency.toml index f31fe0239e2..c462d79030d 100644 --- a/hunting/windows/queries/execution_via_startup_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/execution_via_startup_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt identifies programs started shortly after user logon and presence limited to a unique host. Run registry key and Startup folder cause programs to run each time that a user logs on and are often abused by malwares to maintain persistence on an endpoint. """ integration = ["endpoint"] -uuid = "a447df80-d3d5-48b3-a175-a864264ec487" +uuid = "52a958e8-0368-4e74-bd4b-a64faf397bf4" name = "Startup Execution with Low Occurrence Frequency by Unique Host" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Items set to persist via Startup such as Run keys and Startup folder will be executed by `Explorer.exe` shortly after user logon (`process.Ext.session_info.relative_logon_time` helps us to capture that time difference).", diff --git a/hunting/windows/queries/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.toml b/hunting/windows/queries/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.toml index 41aa38bf7d9..87914f6c4c3 100644 --- a/hunting/windows/queries/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.toml +++ b/hunting/windows/queries/execution_via_windows_management_instrumentation_by_occurrence_frequency_by_unique_agent.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for unique process execution via Windows Management Instrumentation (WMI) by removing random patterns from `process.command_line` and aggregating execution by count of agents with the same command line to limit results to unique ones. """ integration = ["endpoint", "windows", "system"] -uuid = "b5efeb92-9b51-45b9-839f-be4cdc054ef4" +uuid = "a95e69af-22ad-4ab7-919e-794501f10c95" name = "Low Frequency of Process Execution via WMI by Unique Agent" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt contains three queries for Elastic Defend, Sysmon, and Windows Security event 4688."] @@ -16,7 +16,7 @@ query = [ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-* | where @timestamp > now() - 7 day and host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation") and - process.parent.name == "WmiPrvSE.exe" and starts_with(process.code_signature.subject_name, "Microsoft") + to_lower(process.parent.name) == "wmiprvse.exe" and starts_with(process.code_signature.subject_name, "Microsoft") | keep process.hash.sha256, host.id, process.name | stats agents = count_distinct(host.id) by process.name | where agents == 1 @@ -26,7 +26,7 @@ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-sys | where @timestamp > now() - 7 day and host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation", "created-process") and - to_lower(process.parent.name) == "wmiprvse.exe" + to_lower(process.parent.name) == "wmiprvse.exe" | keep process.command_line, host.id | eval cmdline = replace(process.command_line, """[cC]:\\[uU][sS][eE][rR][sS]\\[a-zA-Z0-9\.\-\_\$~ ]+\\""", "C:\\\\users\\\\user\\\\") | eval cmdline = replace(cmdline, """([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,})""", "") @@ -37,7 +37,7 @@ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-sys from logs-endpoint.events.process-*, logs-windows.sysmon_operational-* | where @timestamp > now() - 7 day and host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation") and - process.parent.name.caseless == "wmiprvse.exe" and (process.code_signature.exists == false or process.code_signature.trusted == false) + to_lower(process.parent.name) == "wmiprvse.exe" and (process.code_signature.exists == false or process.code_signature.trusted == false) | keep process.hash.sha256, host.id, process.name | stats agents = count_distinct(host.id) by process.hash.sha256 | where agents == 1 diff --git a/hunting/windows/queries/execution_via_windows_scheduled_task_with_low_occurrence_frequency.toml b/hunting/windows/queries/execution_via_windows_scheduled_task_with_low_occurrence_frequency.toml index edd5db88e09..4ba24de83f3 100644 --- a/hunting/windows/queries/execution_via_windows_scheduled_task_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/execution_via_windows_scheduled_task_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ Aggregating by paths/hash, this hunt identifies rare instances where a program executes as a child process of the Tasks Scheduler service. This could be the result of persistence as a Windows Scheduled Task. """ integration = ["endpoint", "windows"] -uuid = "96d5afc8-1f25-4265-8a0e-9998091a2e1f" +uuid = "0d960760-8a40-49c1-bbdd-4deb32c7fd67" name = "Low Frequency of Process Execution via Windows Scheduled Task by Unique Agent" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Windows security event 4688 lacks `process.parent.command_line` needed for this hunt to identify the Schedule `svchost` instance.", diff --git a/hunting/windows/queries/execution_via_windows_services_with_low_occurrence_frequency.toml b/hunting/windows/queries/execution_via_windows_services_with_low_occurrence_frequency.toml index bad8e38a795..4872553e995 100644 --- a/hunting/windows/queries/execution_via_windows_services_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/execution_via_windows_services_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for a low occurrence of process execution via the Windows Services Control Manager by unique agent. The Services Control Manager is responsible for starting, stopping, and interacting with system services. This could be a sign of persistence as a Windows service. """ integration = ["endpoint", "windows", "system"] -uuid = "858b7022-b587-4b95-afd6-8ce597bedce3" +uuid = "a0a84a86-115f-42f9-90a5-4cb7ceeef981" name = "Low Occurence of Process Execution via Windows Services with Unique Agent" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt contains two queries for Elastic Defend and Windows Security event 4688.", diff --git a/hunting/windows/queries/high_count_of_network_connection_over_extended_period_by_process.toml b/hunting/windows/queries/high_count_of_network_connection_over_extended_period_by_process.toml index 44ae0c42423..9387a23de10 100644 --- a/hunting/windows/queries/high_count_of_network_connection_over_extended_period_by_process.toml +++ b/hunting/windows/queries/high_count_of_network_connection_over_extended_period_by_process.toml @@ -4,9 +4,9 @@ description = """ This hunt identifies browser or svchost instances performing a considerable number of connections per hour over an extended period of hours to a specific destination address, limited to a unique host of the monitored agents. Browsers and svchost are both good targets for masquerading network traffic on the endpoint. """ integration = ["endpoint", "windows"] -uuid = "ed254a22-e7bb-4a36-9291-196b77762dd8" +uuid = "5e5aa9c2-96a8-4d5b-bbca-ff2ec8fefa5b" name = "High Count of Network Connection Over Extended Period by Process" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt includes three queries for Elastic Defend and Sysmon data sources.", diff --git a/hunting/windows/queries/libraries_loaded_by_svchost_with_low_occurrence_frequency.toml b/hunting/windows/queries/libraries_loaded_by_svchost_with_low_occurrence_frequency.toml index 7858e90607f..512f2b2aaa2 100644 --- a/hunting/windows/queries/libraries_loaded_by_svchost_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/libraries_loaded_by_svchost_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt returns the SHA256 hash and the `dll.path` of unsigned libraries loaded by svchost where the presence of unique path/hash is limited to a unique host. Adversaries may use Windows service DLLs to maintain persistence or run with System privileges. """ integration = ["endpoint", "windows"] -uuid = "e37fe0b9-1b70-4800-8989-58bac5a0a9bb" +uuid = "c00f1afe-4f25-4542-8cc9-277b23581121" name = "Libraries Loaded by svchost with Low Occurrence Frequency" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt includes two queries to cover both Sysmon and Elastic Defend data sources.", diff --git a/hunting/windows/queries/microsoft_office_child_processes_with_low_occurrence_frequency.toml b/hunting/windows/queries/microsoft_office_child_processes_with_low_occurrence_frequency.toml index fe1709bbe9b..b7c1717dfae 100644 --- a/hunting/windows/queries/microsoft_office_child_processes_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/microsoft_office_child_processes_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for Microsoft Office child processes with low occurrence frequency. This could be a normal rare behavior as well as potential execution via a malicious document. Adversaries may use Microsoft Office applications to execute malicious code, such as macros, scripts, or other payloads. """ integration = ["endpoint", "windows", "system"] -uuid = "74b2e54b-7002-4201-83d6-7fd9bd5dcf0f" +uuid = "f1b8519a-4dae-475f-965a-f53559233eab" name = "Microsoft Office Child Processes with Low Occurrence Frequency by Unique Agent" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Certain processes like `WerFault.exe`, `dw20.exe` and `dwwin.exe` are often related to application crash.", @@ -18,9 +18,9 @@ query = [ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-* | where host.os.family == "windows" and @timestamp > NOW() - 15 day and event.category == "process" and event.action in ("start", "Process creation", "created-process") and - process.parent.name.caseless in ("winword.exe", "excel.exe", "powerpnt.exe") and not starts_with(process.executable, "C:\\Program Files") + to_lower(process.parent.name) in ("winword.exe", "excel.exe", "powerpnt.exe") and not starts_with(process.executable, "C:\\Program Files") // normalize user home profile paths -| eval process_path = replace(process.executable.caseless, """[c]:\\[u][s][e][r][s]\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\") +| eval process_path = replace(to_lower(process.executable), """[c]:\\[u][s][e][r][s]\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\") | stats occurrences = count(*), agents = count_distinct(agent.id) by process_path, process.parent.name | where occurrences == 1 and agents == 1 ''' diff --git a/hunting/windows/queries/network_discovery_via_sensitive_ports_by_unusual_process.toml b/hunting/windows/queries/network_discovery_via_sensitive_ports_by_unusual_process.toml index 5f80401f4d2..4ac8d98f419 100644 --- a/hunting/windows/queries/network_discovery_via_sensitive_ports_by_unusual_process.toml +++ b/hunting/windows/queries/network_discovery_via_sensitive_ports_by_unusual_process.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for either processes connecting to multiple sensitive TCP ports (SMB, RDP, LDAP, Kerberos and ADWS), a high number of SMB/RDP connections to unique destinations or the same process connecting to both RDP and SMB (should be rare). """ integration = ["endpoint", "windows"] -uuid = "e0acab7d-30bd-4be0-9682-5c3457bbeb4f" +uuid = "386f9cec-bb44-4dd2-8368-45e6fa0a425b" name = "Network Discovery via Sensitive Ports by Unusual Process" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "The query thresholds for SMB or RDP need to be adjusted to your environment.", diff --git a/hunting/windows/queries/pe_file_transfer_via_smb_admin_shares_by_agent.toml b/hunting/windows/queries/pe_file_transfer_via_smb_admin_shares_by_agent.toml index 39a2bc1d874..056615c8e78 100644 --- a/hunting/windows/queries/pe_file_transfer_via_smb_admin_shares_by_agent.toml +++ b/hunting/windows/queries/pe_file_transfer_via_smb_admin_shares_by_agent.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for a high number of executable file transfers via the SMB protocol by the same user or agent to more than a defined maxium threshold of targets. This could be a sign of lateral movement via the Windows Admin Shares. """ integration = ["endpoint"] -uuid = "3e66fc1a-2ea0-43a6-ba51-0280c693d152" +uuid = "814894a4-c951-4f33-ab0b-09354e1cb957" name = "PE File Transfer via SMB_Admin Shares by Agent or User" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Further investigation can done pivoting by `host.id` and `user.name`.", diff --git a/hunting/windows/queries/persistence_via_run_key_with_low_occurrence_frequency.toml b/hunting/windows/queries/persistence_via_run_key_with_low_occurrence_frequency.toml index 28cdf428567..8ea924acfb6 100644 --- a/hunting/windows/queries/persistence_via_run_key_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/persistence_via_run_key_with_low_occurrence_frequency.toml @@ -4,9 +4,9 @@ description = """ Leveraging frequency based analysis and random values normalization, this hunt identifies instances where a program adds a persistence entry with rare values or are imited to unique hosts. Run registry key cause programs to run each time that a user logs on and are often abused by adversaries to maintain persistence on an endpoint. """ integration = ["endpoint", "windows"] -uuid = "1078e906-0485-482e-bcf3-7ee939e07020" +uuid = "df4ee961-254d-4ad1-af15-c65c3b65abcd" name = "Persistence via Run Key with Low Occurrence Frequency" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt includes two queries to cover both Sysmon and Elastic Defend data sources.", diff --git a/hunting/windows/queries/persistence_via_startup_with_low_occurrence_frequency.toml b/hunting/windows/queries/persistence_via_startup_with_low_occurrence_frequency.toml index 65e1ed4704f..4ca6d14235b 100644 --- a/hunting/windows/queries/persistence_via_startup_with_low_occurrence_frequency.toml +++ b/hunting/windows/queries/persistence_via_startup_with_low_occurrence_frequency.toml @@ -2,9 +2,9 @@ author = "Elastic" description = "Leveraging frequency based analysis and path normalization, this hunt identifies rare instances where a program adds a Startup persistence via file creation. Startup entries cause programs to run each time that a user logs on and are often abused by adversaries to maintain persistence on an endpoint." integration = ["endpoint", "windows"] -uuid = "9d8c79fd-0006-4988-8aaa-d5f9b9a7df8e" +uuid = "ea950361-33e4-4045-96a5-d36ca28fbc91" name = "Persistence via Startup with Low Occurrence Frequency by Unique Host" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Elastic Defend file event captures the `process.code_signature` information, this can be added to the hunt to limit to unsigned and Microsoft signed programs.", diff --git a/hunting/windows/queries/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.toml b/hunting/windows/queries/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.toml index 2e6cb02440d..ecc32d41a2a 100644 --- a/hunting/windows/queries/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.toml +++ b/hunting/windows/queries/persistence_via_suspicious_launch_agent_or_launch_daemon_with_low_occurrence.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for persistence via Launch agent or daemon where the distribution is limited to one unique host. """ integration = ["endpoint"] -uuid = "a7dcd1a1-2860-491e-8802-31169a607167" +uuid = "69fc4f40-8fb1-4652-99b7-52755cd370fe" name = "Low Occurrence of Suspicious Launch Agent or Launch Daemon" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Further investigation can done pivoting by `Persistence.name` and `args`.", diff --git a/hunting/windows/queries/potential_exfiltration_by_process_total_egress_bytes.toml b/hunting/windows/queries/potential_exfiltration_by_process_total_egress_bytes.toml index 48f192b0f2b..d12c03743d5 100644 --- a/hunting/windows/queries/potential_exfiltration_by_process_total_egress_bytes.toml +++ b/hunting/windows/queries/potential_exfiltration_by_process_total_egress_bytes.toml @@ -4,9 +4,9 @@ description = """ Using aggregation and the ES|QL `SUM` function, this hunt identifies processes that performed egress connections with total bytes greater or equal to a defined maximum threshold. This may indicate exfiltration or long term command and control activity. """ integration = ["endpoint"] -uuid = "977d77f9-86e0-4df6-bdc7-aed87c048290" +uuid = "24925575-defd-4581-bfda-a8753dcfb46e" name = "Egress Network Connections with Total Bytes Greater than Threshold" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt is not compatible with Sysmon event 3 (Network connection) and Windows security event 5156 as both don't log `source.bytes`.", diff --git a/hunting/windows/queries/rundll32_execution_aggregated_by_cmdline.toml b/hunting/windows/queries/rundll32_execution_aggregated_by_cmdline.toml index c266a04ebf4..cbd259bee79 100644 --- a/hunting/windows/queries/rundll32_execution_aggregated_by_cmdline.toml +++ b/hunting/windows/queries/rundll32_execution_aggregated_by_cmdline.toml @@ -4,9 +4,9 @@ description = """ This hunt aggregate Rundll32 execution by normalized `process.command_line` and returns instances that are unique by frequency. Rundll32 is one of the most abused binaries to proxy execution of malicious commands and modules. """ integration = ["endpoint", "windows", "system"] -uuid = "30f37cd2-c1d8-4554-bb4a-ed76de9e6857" +uuid = "44e6adc6-e183-4bfa-b06d-db41669641fa" name = "Rundll32 Execution Aggregated by Command Line" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Execution of DLLs from suspicious paths or with suspicious export function names or from suspicious parent should be further reviewed.", @@ -18,7 +18,7 @@ query = [ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-* | where @timestamp > now() - 7 day | where host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation", "created-process") and - process.name.caseless == "rundll32.exe" and + to_lower(process.name) == "rundll32.exe" and not process.command_line rlike """.*(zzzzInvokeManagedCustomActionOutOfProc|GeneralTel.dll,RunInUserCxt|ShOpenVerbApplication|davclnt.dll,DavSetCookie|FileProtocolHandler|EDGEHTML.dll|FirewallControlPanel.dll,ShowNotificationDialog|printui.dll,PrintUIEntryDPIAware|Program Files|SHCreateLocalServerRunDll|ImageView_Fullscreen|StatusMonitorEntryPoint|Control_RunDLL|HotPlugSafeRemovalDriveNotification|AppxDeploymentClient.dll|acproxy.dll,PerformAutochkOperations|CapabilityAccessManagerDoStoreMaintenance|dfshim.dll|display.dll,ShowAdapterSettings|ForceProxyDetectionOnNextRun|PfSvWsSwapAssessmentTask|acmigration.dll,ApplyMigrationShims|LenovoBatteryGaugePackage.dll|-localserver|DriverStore|CnmDxPEntryPoint|DeferredDelete|DeviceProperties_RunDLL|AppxDeploymentClient.dll|spool\\DRIVERS|printui.dll,PrintUIEntry|DfdGetDefaultPolicyAndSMART|cryptext.dll,CryptExt|WininetPlugin.dll|ClearMyTracksByProcess|SusRunTask|OpenURL|CleanupTemporaryState).*""" | keep process.parent.name, process.command_line, host.id | eval cmdline = replace(process.command_line, """[cC]:\\[uU][sS][eE][rR][sS]\\[a-zA-Z0-9\.\-\_\$~ ]+\\""", "C:\\\\users\\\\user\\\\") diff --git a/hunting/windows/queries/scheduled_task_creation_by_action_via_registry.toml b/hunting/windows/queries/scheduled_task_creation_by_action_via_registry.toml index f473169b0dd..1f9a9930c0b 100644 --- a/hunting/windows/queries/scheduled_task_creation_by_action_via_registry.toml +++ b/hunting/windows/queries/scheduled_task_creation_by_action_via_registry.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for scheduled tasks creation by action using registry events. Scheduled tasks actions are saved under the TaskCache registry key in base64 encoded blob. Malware often abuse LOLBins to proxy execution or run executables from unusual paths, you can add more patterns to the query. """ integration = ["endpoint"] -uuid = "344c0690-ebc3-4794-b123-272a5c09c57b" +uuid = "df50f65e-e820-47f4-a039-671611582f51" name = "Scheduled tasks Creation by Action via Registry" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Malware often abuse LOLBins to proxy execution or run executables from unusual paths, you can add more patterns to the query.", diff --git a/hunting/windows/queries/scheduled_tasks_creation_for_unique_hosts_by_task_command.toml b/hunting/windows/queries/scheduled_tasks_creation_for_unique_hosts_by_task_command.toml index 8d236b4c9be..1a748c6b227 100644 --- a/hunting/windows/queries/scheduled_tasks_creation_for_unique_hosts_by_task_command.toml +++ b/hunting/windows/queries/scheduled_tasks_creation_for_unique_hosts_by_task_command.toml @@ -4,9 +4,9 @@ description = """ Using aggregation and strings extraction, this hunt identifies instances where a scheduled task is created and set to run a command unique to a specific host. This could be the result of persistence as a Windows Scheduled Task. """ integration = ["system"] -uuid = "75804319-122c-4bdc-976e-d6355bca0d78" +uuid = "44223fd6-8241-4c21-9d54-21201fa15b12" name = "Scheduled Tasks Creation for Unique Hosts by Task Command" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt returns the aggregation of created tasks by task name, command to execute and number of hosts where this task is present.", diff --git a/hunting/windows/queries/suspicious_base64_encoded_powershell_commands.toml b/hunting/windows/queries/suspicious_base64_encoded_powershell_commands.toml index 88e89486a6e..414ca602af3 100644 --- a/hunting/windows/queries/suspicious_base64_encoded_powershell_commands.toml +++ b/hunting/windows/queries/suspicious_base64_encoded_powershell_commands.toml @@ -4,9 +4,9 @@ description = """ This hunt identifies base64 encoded powershell commands in process start events and filters ones with suspicious keywords like downloaders and evasion related commands. """ integration = ["endpoint", "windows", "system"] -uuid = "8bf800de-b3a2-4b36-9484-7d9dae2a1992" +uuid = "2e583d3c-7ad6-4544-a0db-c685b2066493" name = "Suspicious Base64 Encoded Powershell Command" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt can be expanded to include more evasion techniques and downloaders.", diff --git a/hunting/windows/queries/suspicious_dns_txt_record_lookups_by_process.toml b/hunting/windows/queries/suspicious_dns_txt_record_lookups_by_process.toml index 344f9675a43..386a29084cc 100644 --- a/hunting/windows/queries/suspicious_dns_txt_record_lookups_by_process.toml +++ b/hunting/windows/queries/suspicious_dns_txt_record_lookups_by_process.toml @@ -5,9 +5,9 @@ Leveraging aggregation by process executable entities, this hunt identifies iden Adversaries may leverage DNS TXT queries to stage malicious content or exfiltrate data. """ integration = ["endpoint", "windows"] -uuid = "0b7343f7-2d16-43c7-af28-9d1f012b1093" +uuid = "7a2c8397-d219-47ad-a8e2-93562e568d08" name = "Suspicious DNS TXT Record Lookups by Process" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt returns a list of processes unique pids and executable paths that performs a high number of DNS TXT lookups.", diff --git a/hunting/windows/queries/unique_windows_services_creation_by_servicefilename.toml b/hunting/windows/queries/unique_windows_services_creation_by_servicefilename.toml index 8bc916f296f..4ac5238e9b7 100644 --- a/hunting/windows/queries/unique_windows_services_creation_by_servicefilename.toml +++ b/hunting/windows/queries/unique_windows_services_creation_by_servicefilename.toml @@ -4,9 +4,9 @@ description = """ This hunt aggregates created Windows services by service file name and distribution limited to unique hosts. Using the ES|QL `Replace` command we can also further remove random patterns to reduce results to interesting events. More investigation can be conducted on instance that looks suspicious based on service file path, names and LOLBins. """ integration = ["endpoint", "windows", "system"] -uuid = "ebf79207-16dc-44f8-b10c-317d4a034bad" +uuid = "48b75e53-3c73-40bd-873d-569dd8d7d925" name = "Unique Windows Services Creation by Service File Name" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "This hunt also identifies services registry modification by unusual process based on number of hosts and occurrences history.", diff --git a/hunting/windows/queries/windows_command_and_scripting_interpreter_from_unusual_parent.toml b/hunting/windows/queries/windows_command_and_scripting_interpreter_from_unusual_parent.toml index a4d0d9a8c56..d15ffde7f4e 100644 --- a/hunting/windows/queries/windows_command_and_scripting_interpreter_from_unusual_parent.toml +++ b/hunting/windows/queries/windows_command_and_scripting_interpreter_from_unusual_parent.toml @@ -4,9 +4,9 @@ description = """ This hunt looks for unusual Microsoft native processes spawning `cmd.exe`, `powershell.exe` or `conhost.exe` and limited to a unique host. This could be normal rare behavior as well as an interactive shell activity from an injected parent process to execute system commands. """ integration = ["endpoint", "windows", "system"] -uuid = "de929347-c04a-4a94-8be2-cbe87b25bb25" +uuid = "aca4877f-d284-4bdb-8e18-b1414d3a7c20" name = "Windows Command and Scripting Interpreter from Unusual Parent Process" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Further pivoting can be done via `process.parent.name`.", @@ -18,8 +18,8 @@ query = [ from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-* | where @timestamp > now() - 7 day | where host.os.family == "windows" and event.category == "process" and event.action in ("start", "Process creation", "created-process") and - process.name.caseless in ("cmd.exe", "powershell.exe", "conhost.exe") and - (starts_with(process.parent.executable.caseless, "c:\\windows\\system32") or starts_with(process.parent.executable.caseless, "c:\\windows\\syswow64")) + to_lower(process.name) in ("cmd.exe", "powershell.exe", "conhost.exe") and + (starts_with(to_lower(process.parent.executable), "c:\\windows\\system32") or starts_with(to_lower(process.parent.executable), "c:\\windows\\syswow64")) | keep process.name, process.parent.name, host.id | stats hosts = count_distinct(host.id), cc = count(*) by process.parent.name | where cc <= 10 and hosts == 1 diff --git a/hunting/windows/queries/windows_logon_activity_by_source_ip.toml b/hunting/windows/queries/windows_logon_activity_by_source_ip.toml index 4547241284f..3647b68d90b 100644 --- a/hunting/windows/queries/windows_logon_activity_by_source_ip.toml +++ b/hunting/windows/queries/windows_logon_activity_by_source_ip.toml @@ -4,9 +4,9 @@ description = """ This hunt returns a summary of network logon activity by `source.ip` using Windows event IDs 4624 and 4625. The higher the number of failures, low success and multiple accounts the more suspicious the behavior is. """ integration = ["system"] -uuid = "7bdea198-eb09-4eca-ae3d-bfc3b52c89a9" +uuid = "441fba85-47a9-4f1f-aab4-569bbfdc548b" name = "Windows Logon Activity by Source IP" -language = "ES|QL" +language = ["ES|QL"] license = "Elastic License v2" notes = [ "Pay close attention to IP address sources with a high number of failed connections associated with low success attempts and high number of user accounts.",