Detection rules › Elastic

Elastic rules: 2k

AWS Sign-In Root Password Recovery Requested

#
Status
production
Severity
high
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a password recovery request for the AWS account root user. In AWS, the PasswordRecoveryRequested event from signin.amazonaws.com applies to the root user’s “Forgot your password?” flow. Other identity types, like IAM and federated users, do not generate this event. This alert indicates that someone initiated the root password reset workflow for this account. Verify whether this was an expected action and review identity provider notifications/email to confirm legitimacy.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/07/02"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies a password recovery request for the AWS account root user.
In AWS, the PasswordRecoveryRequested event from signin.amazonaws.com applies to the root user’s “Forgot your password?” flow. Other identity types, like IAM and federated users, do not generate this event. 
This alert indicates that someone initiated the root password reset workflow for this account. Verify whether this was an expected action and review identity provider notifications/email to confirm legitimacy.
"""
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Sign-In Root Password Recovery Requested"
note = """## Triage and analysis

### Investigating AWS Sign-In Root Password Recovery Requested

In AWS, a `PasswordRecoveryRequested` event from `signin.amazonaws.com` is only generated for the root user during the “Forgot your password?” workflow. Other identity types (IAM or federated users) do not trigger this event. A root password recovery request is a critical identity security event that could indicate a legitimate recovery by the account owner or a malicious attempt to gain full administrative access.

### Possible investigation steps

- **Verify the event details.**  
  Review the alert fields (`source.ip`, `user_agent.original`, `cloud.region`, and `@timestamp`) to confirm when and from where the request originated.

- **Confirm legitimacy.**  
  Contact the account owner or credential custodian to verify whether they initiated the password recovery.  
  AWS will also send an email notification to the root account email address, check whether the owner received and acknowledged this.

- **Check CloudTrail for related events.**  
  Search for any subsequent `ConsoleLogin` events for the root user, or IAM changes (for example, `CreateAccessKey`, `CreateUser`, or `AttachUserPolicy`) shortly after the recovery request.

- **Assess IP reputation and location.**  
  Validate whether the `source.ip` aligns with known admin networks or expected geographies.  
  Suspicious indicators include foreign IPs, anonymization services, or unfamiliar user agents.

- **Correlate with other alerts.**  
  Review other AWS security detections (for example, root logins, MFA disablement, or IAM policy changes) around the same timeframe.

### False positive analysis

- **Expected maintenance activity.**  
  If the root account owner confirms that the password reset was intentional (for example, for account recovery or planned credential rotation), the alert may be safely dismissed.  
- **Testing or account verification.**  
  Security or compliance teams occasionally test password recovery flows. Confirm via ticketing or planned maintenance documentation.

### Response and remediation

**Immediate actions**
- **If confirmed legitimate:**  
  - Ensure that MFA is enabled and operational for the root account.  
  - Encourage rotation of the root password if not recently updated.  
- **If unconfirmed or suspicious:**  
  - Immediately reset the root password using the legitimate AWS recovery email link.  
  - Review the AWS account’s email for password-recovery notifications and secure that inbox (change its password, enable MFA).  
  - Check for new successful root logins or unexpected IAM changes since the recovery attempt.  

**Evidence preservation**
- Export the `PasswordRecoveryRequested` event from CloudTrail (±30 minutes).  
- Preserve all `signin.amazonaws.com` and root `ConsoleLogin` events for the next 24 hours.  
- Store this evidence in a restricted S3 bucket with Object Lock enabled.

**Scoping and investigation**
- Review all root-level activities within the past 24–48 hours.  
  Focus on administrative actions such as `CreateAccessKey`, `UpdateAccountPasswordPolicy`, or `DisableMFA`.  
- Correlate with GuardDuty findings and AWS Config change history for any unauthorized modifications.

**Recovery and hardening**
- Confirm MFA is enforced on the root account.  
- Rotate all root credentials and ensure no access keys exist for the root user (root keys should never be active).  
- Secure the associated email account (password reset notifications are sent there).  
- Enable Cloudtrail, GuardDuty, Security Hub, and AWS Config across all regions.  
- Review account recovery procedures to ensure multiple custodians are aware of the legitimate process.

### Additional information

- **AWS Incident Response Playbooks:**    
  and [`IRP-Credential-Compromise.md`](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/IRP-CredCompromise.md) for procedures related to root account credential recovery and unauthorized access attempts.  
- **AWS Customer Playbook Framework:**  
  See [`Compromised_IAM_Credentials.md`](https://github.com/aws-samples/aws-customer-playbook-framework/blob/a8c7b313636b406a375952ac00b2d68e89a991f2/docs/Compromised_IAM_Credentials.md) for guidance on containment, evidence collection, and recovery validation.  
- **AWS Documentation:** [AWS account root user best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/root-user-best-practices.html).  
- **Security Best Practices:** [AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/).  
"""

references = ["https://web.archive.org/web/20230930161727/https://www.cadosecurity.com/an-ongoing-aws-phishing-campaign/"]
risk_score = 73
rule_id = "69c420e8-6c9e-4d28-86c0-8a2be2d1e78c"
severity = "high"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS Sign-In",
    "Use Case: Identity and Access Audit",
    "Tactic: Initial Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:aws.cloudtrail and 
event.provider:signin.amazonaws.com and 
event.action:PasswordRecoveryRequested and 
event.outcome:success
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.response_elements"
]

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"

[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

Stages and Predicates

Stage 1: query

data_stream.dataset:aws.cloudtrail and 
event.provider:signin.amazonaws.com and 
event.action:PasswordRecoveryRequested and 
event.outcome:success

Indicators

These rows show field, operator, and value matches.

Boot File Copy

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects the process of copying or moving files from or to the "/boot" directory on Linux systems. The "/boot" directory contains files that are essential for the system to boot, such as the kernel and initramfs images. Attackers may copy or move files to the "/boot" directory to modify the boot process, which can be leveraged to maintain access to the system.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/01/16"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2025/12/22"

[rule]
author = ["Elastic"]
description = """
This rule detects the process of copying or moving files from or to the "/boot" directory on Linux systems. The "/boot"
directory contains files that are essential for the system to boot, such as the kernel and initramfs images. Attackers
may copy or move files to the "/boot" directory to modify the boot process, which can be leveraged to maintain access to
the system.
"""
from = "now-9m"
index = [
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Boot File Copy"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Boot File Copy
The `/boot` directory in Linux systems is crucial for storing files necessary for booting, such as the kernel. Adversaries may exploit this by copying or moving files to alter the boot process, potentially gaining persistent access. The 'Boot File Copy' detection rule identifies suspicious file operations in this directory, excluding legitimate processes, to flag potential unauthorized modifications.

### Possible investigation steps

- Review the process details to identify the specific file operation by examining the process name and arguments, particularly focusing on the use of 'cp' or 'mv' commands with paths involving '/boot/*'.
- Investigate the parent process executable and name to determine if the operation was initiated by a known legitimate process or script, ensuring it is not one of the excluded processes like 'update-initramfs' or 'grub-mkconfig'.
- Check the user account associated with the process to assess whether it is a privileged account and if the activity aligns with typical user behavior.
- Analyze recent system logs and audit records for any other suspicious activities or anomalies around the time of the alert to identify potential patterns or related events.
- Verify the integrity and authenticity of the files in the /boot directory to ensure no unauthorized modifications have been made, focusing on critical files like the kernel and initramfs images.
- If possible, correlate the alert with other data sources such as Elastic Endgame or Crowdstrike to gather additional context and confirm whether this is part of a broader attack pattern.

### False positive analysis

- System updates and maintenance tasks often involve legitimate processes that interact with the /boot directory. Processes like update-initramfs, dracut, and grub-mkconfig are common during these operations. Users can exclude these processes by adding them to the exception list in the detection rule.
- Custom scripts or administrative tasks that require copying or moving files to the /boot directory may trigger false positives. Identify these scripts and add their parent process names or paths to the exclusion criteria.
- Package management operations, such as those involving dpkg or rpm, may also interact with the /boot directory. Exclude paths like /var/lib/dpkg/info/* and /var/tmp/rpm-tmp.* to prevent these from being flagged.
- Temporary system recovery or installation processes might use directories like /tmp/newroot. Exclude these paths to avoid unnecessary alerts during legitimate recovery operations.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or potential lateral movement by the adversary.
- Terminate any suspicious processes identified by the detection rule, specifically those involving unauthorized 'cp' or 'mv' operations in the /boot directory.
- Conduct a thorough review of the /boot directory to identify and remove any unauthorized files or modifications. Restore any altered files from a known good backup if necessary.
- Check for any unauthorized changes to boot configuration files, such as GRUB or LILO, and restore them to their original state.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected.
- Implement additional monitoring on the affected system and similar systems to detect any further unauthorized access attempts or modifications.
- Review and update access controls and permissions for the /boot directory to ensure only authorized processes and users can make changes."""
risk_score = 21
rule_id = "5bda8597-69a6-4b9e-87a2-69a7c963ea83"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start") and
process.name in ("cp", "mv") and process.parent.executable != null and process.args like~ "/boot/*" and not (
  process.parent.name in ("update-initramfs", "dracut", "grub-mkconfig", "shim-install", "sudo", "activate-theme", "update-grub-gfxpayload", "grub-pc.postinst") or
  process.parent.executable like~ ("/usr/lib/kernel/install.d/*", "/tmp/newroot/*", "/var/lib/dpkg/info/*") or
  process.parent.args like~ ("/usr/bin/mkinitcpio", "/var/tmp/rpm-tmp.*", "/var/lib/dpkg/info/*") or
  process.parent.executable in (
    "/var/lib/aws-replication-agent/migration_scripts/suse_to_aws.bash", "/usr/sbin/flash-kernel", "/usr/sbin/weak-modules",
    "/etc/cron.hourly/check_mau", "/usr/bin/update-microcode-initrd", "/bin/run-parts", "/usr/sbin/mkinitramfs", "/usr/sbin/grub2-mkconfig",
    "/usr/bin/supermin5", "/sbin/weak-modules", "/usr/sbin/nv-update-initrd", "/usr/libexec/platform-python", "/bin/kernel-install",
    "/usr/bin/oracle-database-preinstall-19c-verify", "/usr/libexec/grubby/prune_debug"
  ) or
  process.command_line == "/bin/cp /usr/local/ASR/Vx/scripts/vCon//Configuration.info /boot/" or
  ?process.working_directory in ("/var/lib/aws-replication-agent", "/opt/sentinelone/bin", "/tmp/MobilityAgentAutoUpgrade/package") or
  (
    process.name == "cp" and
    process.parent.args in (
      "/etc/kernel/postrm.d/zz-proxmox-boot", "/etc/kernel/postinst.d/zz-proxmox-boot", "/usr/lib/kernel/install.d/20-grub.install",
      "/usr/bin/dracut", "/bin/dracut", "/usr/sbin/shim-install", "/sbin/dracut", "/opt/McAfee/ens/esp/scripts/modversion-check.sh",
      "//opt/McAfee/ens/esp/scripts//modversion-check.sh", "/usr/sbin/update-grub-legacy-ec2", "/usr/bin/foreman-generate-bootloaders",
      "/usr/share/grub2/themes/SLE/activate-theme", "/usr/sbin/dracut", "/usr/sbin/flash-kernel", "/usr/lib/kernel/install.d/20-grubby.install"
    ) 
  ) or
  (process.name == "mv" and process.args == "-f" and process.parent.args == "/usr/sbin/update-initramfs") or
  (
    process.name == "mv" and
    process.parent.args in (
      "/usr/sbin/flash-kernel", "/usr/bin/update-microcode-initrd", "/usr/sbin/update-grub-gfxpayload",
      "/usr/sbin/weak-modules", "/usr/bin/dracut"
    )
  )
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1542"
name = "Pre-OS Boot"
reference = "https://attack.mitre.org/techniques/T1542/"

[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"

[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start") and
process.name in ("cp", "mv") and process.parent.executable != null and process.args like~ "/boot/*" and not (
  process.parent.name in ("update-initramfs", "dracut", "grub-mkconfig", "shim-install", "sudo", "activate-theme", "update-grub-gfxpayload", "grub-pc.postinst") or
  process.parent.executable like~ ("/usr/lib/kernel/install.d/*", "/tmp/newroot/*", "/var/lib/dpkg/info/*") or
  process.parent.args like~ ("/usr/bin/mkinitcpio", "/var/tmp/rpm-tmp.*", "/var/lib/dpkg/info/*") or
  process.parent.executable in (
    "/var/lib/aws-replication-agent/migration_scripts/suse_to_aws.bash", "/usr/sbin/flash-kernel", "/usr/sbin/weak-modules",
    "/etc/cron.hourly/check_mau", "/usr/bin/update-microcode-initrd", "/bin/run-parts", "/usr/sbin/mkinitramfs", "/usr/sbin/grub2-mkconfig",
    "/usr/bin/supermin5", "/sbin/weak-modules", "/usr/sbin/nv-update-initrd", "/usr/libexec/platform-python", "/bin/kernel-install",
    "/usr/bin/oracle-database-preinstall-19c-verify", "/usr/libexec/grubby/prune_debug"
  ) or
  process.command_line == "/bin/cp /usr/local/ASR/Vx/scripts/vCon//Configuration.info /boot/" or
  ?process.working_directory in ("/var/lib/aws-replication-agent", "/opt/sentinelone/bin", "/tmp/MobilityAgentAutoUpgrade/package") or
  (
    process.name == "cp" and
    process.parent.args in (
      "/etc/kernel/postrm.d/zz-proxmox-boot", "/etc/kernel/postinst.d/zz-proxmox-boot", "/usr/lib/kernel/install.d/20-grub.install",
      "/usr/bin/dracut", "/bin/dracut", "/usr/sbin/shim-install", "/sbin/dracut", "/opt/McAfee/ens/esp/scripts/modversion-check.sh",
      "//opt/McAfee/ens/esp/scripts//modversion-check.sh", "/usr/sbin/update-grub-legacy-ec2", "/usr/bin/foreman-generate-bootloaders",
      "/usr/share/grub2/themes/SLE/activate-theme", "/usr/sbin/dracut", "/usr/sbin/flash-kernel", "/usr/lib/kernel/install.d/20-grubby.install"
    ) 
  ) or
  (process.name == "mv" and process.args == "-f" and process.parent.args == "/usr/sbin/update-initramfs") or
  (
    process.name == "mv" and
    process.parent.args in (
      "/usr/sbin/flash-kernel", "/usr/bin/update-microcode-initrd", "/usr/sbin/update-grub-gfxpayload",
      "/usr/sbin/weak-modules", "/usr/bin/dracut"
    )
  )
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq-fexcludes:process.args field:"process.args" value:"-f"
process.nameeqmvexcludes:process.name field:"process.name" value:"mv"
process.parent.argseq/usr/sbin/update-initramfsexcludes:process.parent.args field:"process.parent.args" value:"/usr/sbin/update-initramfs"
process.nameeqcpexcludes:process.name field:"process.name" value:"cp"
process.parent.argsin//opt/McAfee/ens/esp/scripts//modversion-check.sh, /bin/dracut, /etc/kernel/postinst.d/zz-proxmox-boot, /etc/kernel/postrm.d/zz-proxmox-boot, /opt/McAfee/ens/esp/scripts/modversion-check.sh, /sbin/dracut, /usr/bin/dracut, /usr/bin/foreman-generate-bootloaders, /usr/lib/kernel/install.d/20-grub.install, /usr/lib/kernel/install.d/20-grubby.install, /usr/sbin/dracut, /usr/sbin/flash-kernel, /usr/sbin/shim-install, /usr/sbin/update-grub-legacy-ec2, /usr/share/grub2/themes/SLE/activate-themeexcludes:process.parent.args
process.parent.argsin/usr/bin/dracut, /usr/bin/update-microcode-initrd, /usr/sbin/flash-kernel, /usr/sbin/update-grub-gfxpayload, /usr/sbin/weak-modulesexcludes:process.parent.args
process.command_lineeq/bin/cp /usr/local/ASR/Vx/scripts/vCon//Configuration.info /boot/excludes:process.command_line field:"process.command_line" value:"/bin/cp /usr/local/ASR/Vx/scripts/vCon//Configuration.info /boot/"
process.parent.argswildcard/usr/bin/mkinitcpio, /var/tmp/rpm-tmp.*, /var/lib/dpkg/info/*excludes:process.parent.args field:"process.parent.args" value:"/usr/bin/mkinitcpio" field:"process.parent.args" value:"/var/tmp/rpm-tmp.*" field:"process.parent.args" value:"/var/lib/dpkg/info/*"
process.parent.executablein/bin/kernel-install, /bin/run-parts, /etc/cron.hourly/check_mau, /sbin/weak-modules, /usr/bin/oracle-database-preinstall-19c-verify, /usr/bin/supermin5, /usr/bin/update-microcode-initrd, /usr/libexec/grubby/prune_debug, /usr/libexec/platform-python, /usr/sbin/flash-kernel, /usr/sbin/grub2-mkconfig, /usr/sbin/mkinitramfs, /usr/sbin/nv-update-initrd, /usr/sbin/weak-modules, /var/lib/aws-replication-agent/migration_scripts/suse_to_aws.bashexcludes:process.parent.executable
process.parent.executablestarts_with/usr/lib/kernel/install.d/, /tmp/newroot/, /var/lib/dpkg/info/excludes:process.parent.executable field:"process.parent.executable" value:"/usr/lib/kernel/install.d/" field:"process.parent.executable" value:"/tmp/newroot/" field:"process.parent.executable" value:"/var/lib/dpkg/info/"
process.parent.nameinactivate-theme, dracut, grub-mkconfig, grub-pc.postinst, shim-install, sudo, update-grub-gfxpayload, update-initramfsexcludes:process.parent.name
process.working_directoryin/opt/sentinelone/bin, /tmp/MobilityAgentAutoUpgrade/package, /var/lib/aws-replication-agentexcludes:process.working_directory field:"process.working_directory" value:"/opt/sentinelone/bin" field:"process.working_directory" value:"/tmp/MobilityAgentAutoUpgrade/package" field:"process.working_directory" value:"/var/lib/aws-replication-agent"

Command and Scripting Interpreter from Suspicious Parent

#
Time window
1m
Sequence by
process.entity_id, process.parent.entity_id
Source
github.com/elastic/protections-artifacts

Identifies when a script interpreter is executed with a long command line and from an unsigned parent executable.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = "Identifies when a script interpreter is executed with a long command line and from an unsigned parent executable."
id = "61b8b978-847b-4b1f-9771-b646cde53a9a"
license = "Elastic License v2"
name = "Command and Scripting Interpreter from Suspicious Parent"
os_list = ["windows"]
version = "1.0.6"

query = '''
sequence with maxspan=1m
 [process where event.action == "start" and not user.id : "S-1-5-18" and 
  (
   (process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk", "USB *") and
    not process.executable : "C:\\*") or

   ((process.Ext.relative_file_creation_time <= 900 or process.Ext.relative_file_name_modify_time <= 900) and
     not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
     not process.executable : ("?:\\Program Files (x86)\\*", "?:\\Program Files\\*")) or

   (process.executable :
	        ("?:\\Users\\*\\AppData\\*",
	         "?:\\Users\\*\\Downloads\\*",
	         "?:\\Users\\*\\Desktop\\*",
	         "?:\\Users\\Public\\*") and not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*"))
   ) and
  not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\VsDebugConsole.exe"
  ] by process.entity_id
 [process where event.action == "start" and process.name : ("cmd.exe", "powershell.exe") and
  length(process.command_line) >= 200 and not process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and 
  not (process.args : "-InputFormat" and process.args : "-command") and 
  not process.args : "UwB0AGEAcgB0ACAAIgBoAHQAdABw*" and 
  process.command_line : ("*New-ScheduledTaskAction*", "*New-ItemProperty*", "*WScript.Shell*", "*schtasks* /create*", 
                          "*\\Start Menu\\Programs\\*", "*CurrentVersion\\Run*", "*.Invoke(*", "*MpPreference*", 
			  "*-EncodedCommand*", "*Get-Content*", "*Windows Defender*", "*powershell* -e *", "*setZeroData*", 
                          "*Get-Clipboard*", "*http* -xf *", "*dns-query?name=*")
 ] by process.parent.entity_id
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

[[threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.

Stage 1: process

[process where event.action == "start" and not user.id : "S-1-5-18" and 
  (
   (process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk", "USB *") and
    not process.executable : "C:\\*") or

   ((process.Ext.relative_file_creation_time <= 900 or process.Ext.relative_file_name_modify_time <= 900) and
     not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
     not process.executable : ("?:\\Program Files (x86)\\*", "?:\\Program Files\\*")) or

   (process.executable :
	        ("?:\\Users\\*\\AppData\\*",
	         "?:\\Users\\*\\Downloads\\*",
	         "?:\\Users\\*\\Desktop\\*",
	         "?:\\Users\\Public\\*") and not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*"))
   ) and
  not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\VsDebugConsole.exe"
  ] by process.entity_id

Stage 2: process

[process where event.action == "start" and process.name : ("cmd.exe", "powershell.exe") and
  length(process.command_line) >= 200 and not process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and 
  not (process.args : "-InputFormat" and process.args : "-command") and 
  not process.args : "UwB0AGEAcgB0ACAAIgBoAHQAdABw*" and 
  process.command_line : ("*New-ScheduledTaskAction*", "*New-ItemProperty*", "*WScript.Shell*", "*schtasks* /create*", 
                          "*\\Start Menu\\Programs\\*", "*CurrentVersion\\Run*", "*.Invoke(*", "*MpPreference*", 
			  "*-EncodedCommand*", "*Get-Content*", "*Windows Defender*", "*powershell* -e *", "*setZeroData*", 
                          "*Get-Clipboard*", "*http* -xf *", "*dns-query?name=*")
 ] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.device.product_idwildcard
  • USB * corpus 6 (elastic 6)
  • Virtual DVD-ROM corpus 7 (elastic 7)
  • Virtual Disk corpus 7 (elastic 7)
field:"process.Ext.device.product_id" kind:wildcard
process.Ext.relative_file_creation_timele
  • 900 transforms: number corpus 7 (elastic 7)
field:"process.Ext.relative_file_creation_time" kind:le value:"900"
process.Ext.relative_file_name_modify_timele
  • 900 transforms: number corpus 6 (elastic 6)
field:"process.Ext.relative_file_name_modify_time" kind:le value:"900"
process.command_linewildcard
  • *-EncodedCommand* corpus 2 (elastic 2)
  • *.Invoke(*
  • *CurrentVersion\Run* corpus 2 (elastic 2)
  • *Get-Clipboard*
  • *Get-Content*
  • *MpPreference*
  • *New-ItemProperty*
  • *New-ScheduledTaskAction*
  • *WScript.Shell* corpus 3 (elastic 3)
  • *Windows Defender*
  • *\Start Menu\Programs\*
  • *dns-query?name=*
  • *http* -xf *
  • *powershell* -e *
  • *schtasks* /create*
  • *setZeroData*
field:"CommandLine" kind:wildcard
process.executablewildcard
  • ?:\Users\*\AppData\* corpus 12 (elastic 12)
  • ?:\Users\*\Desktop\* corpus 3 (elastic 3)
  • ?:\Users\*\Downloads\* corpus 12 (elastic 12)
  • ?:\Users\Public\* corpus 22 (elastic 22)
field:"Image" kind:wildcard
process.namewildcard
  • cmd.exe corpus 122 (elastic 93, splunk 29)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

Command Shell Activity Started via RunDLL32

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies command shell activity started via RunDLL32, which is commonly abused by attackers to host malicious code.

Known False Positives

  • Microsoft Windows installers leveraging RunDLL32 for installation.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/10/19"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Elastic"]
description = "Identifies command shell activity started via RunDLL32, which is commonly abused by attackers to host malicious code."
false_positives = ["Microsoft Windows installers leveraging RunDLL32 for installation."]
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.process-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Command Shell Activity Started via RunDLL32"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Command Shell Activity Started via RunDLL32

RunDLL32 is a legitimate Windows utility used to execute functions in DLLs, often leveraged by attackers to run malicious code stealthily. Adversaries exploit it to launch command shells like cmd.exe or PowerShell, bypassing security controls. The detection rule identifies such abuse by monitoring for command shells initiated by RunDLL32, excluding known benign patterns, thus highlighting potential threats.

### Possible investigation steps

- Review the process details to confirm the parent-child relationship between rundll32.exe and the command shell (cmd.exe or powershell.exe) to ensure the alert is not a false positive.
- Examine the command line arguments of rundll32.exe to identify any suspicious or unusual DLLs or functions being executed, excluding known benign patterns.
- Check the user account associated with the process to determine if it aligns with expected behavior or if it indicates potential compromise.
- Investigate the source and destination network connections associated with the process to identify any suspicious or unauthorized communication.
- Correlate the event with other security alerts or logs from the same host or user to identify any patterns or additional indicators of compromise.
- Review recent changes or activities on the host, such as software installations or updates, that might explain the execution of rundll32.exe with command shells.

### False positive analysis

- Known false positives include command shells initiated by RunDLL32 for legitimate administrative tasks or software installations.
- Exclude command lines that match common benign patterns, such as those involving SHELL32.dll or temporary files used by trusted applications.
- Regularly update the list of exceptions to include new benign patterns identified through monitoring and analysis.
- Collaborate with IT and security teams to identify and document legitimate use cases of RunDLL32 in your environment.
- Use process monitoring tools to verify the legitimacy of command shells started by RunDLL32, ensuring they align with expected behavior.

### Response and remediation

- Isolate the affected system from the network to prevent further malicious activity and lateral movement.
- Terminate any suspicious processes identified as cmd.exe or powershell.exe that were initiated by rundll32.exe to halt potential malicious actions.
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any malicious files or remnants.
- Review and analyze the rundll32.exe command line arguments to understand the scope and intent of the activity, and identify any additional compromised systems or accounts.
- Reset credentials for any user accounts that were active on the affected system during the time of the alert to prevent unauthorized access.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring and logging for rundll32.exe and related processes to detect similar activities in the future and improve response times."""
risk_score = 21
rule_id = "9ccf3ce0-0057-440a-91f5-870c6ad39093"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Tactic: Credential Access",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
 process.name : ("cmd.exe", "powershell.exe") and
  process.parent.name : "rundll32.exe" and process.parent.command_line != null and
  /* common FPs can be added here */
  not process.parent.args : ("C:\\Windows\\System32\\SHELL32.dll,RunAsNewUser_RunDLL",
                             "C:\\WINDOWS\\*.tmp,zzzzInvokeManagedCustomActionOutOfProc")
'''

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend

### Additional data sources

This rule also supports the following third-party data sources. For setup instructions, refer to the links below:

- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
"""


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"



[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"


[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"



[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
 process.name : ("cmd.exe", "powershell.exe") and
  process.parent.name : "rundll32.exe" and process.parent.command_line != null and
  not process.parent.args : ("C:\\Windows\\System32\\SHELL32.dll,RunAsNewUser_RunDLL",
                             "C:\\WINDOWS\\*.tmp,zzzzInvokeManagedCustomActionOutOfProc")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namewildcard
  • cmd.exe corpus 122 (elastic 93, splunk 29)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
field:"process_basename" kind:wildcard
process.parent.command_lineis_not_null
  • (no value, null check)
field:"ParentCommandLine" kind:is_not_null
process.parent.namewildcard
  • rundll32.exe corpus 20 (elastic 20)
field:"parent_process_basename" kind:wildcard value:"rundll32.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.argswildcardC:\Windows\System32\SHELL32.dll,RunAsNewUser_RunDLL, C:\WINDOWS\*.tmp,zzzzInvokeManagedCustomActionOutOfProcexcludes:process.parent.args field:"process.parent.args" value:"C:\Windows\System32\SHELL32.dll,RunAsNewUser_RunDLL" field:"process.parent.args" value:"C:\WINDOWS\*.tmp,zzzzInvokeManagedCustomActionOutOfProc"

Dynwrapx Image Load via Windows Scripts

#
Time window
1m
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Identifies when a Windows script interpreter loads an external library that allow to call Windows API functions from scripts in JScript and VBScript. Malware may abuse this legit capability to interact further with the Operating System.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies when a Windows script interpreter loads an external library that allow to call Windows API functions from
scripts in JScript and VBScript. Malware may abuse this legit capability to interact further with the Operating System.
"""
id = "4cd6f758-0057-4e8a-9701-20b6116c2118"
license = "Elastic License v2"
name = "Dynwrapx Image Load via Windows Scripts"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/Hunting-for-Suspicious-Windows-Libraries-for-Execution-and-Evasion",
    "https://www.script-coding.com/dynwrapx_eng.html",
    "https://www.splunk.com/en_us/blog/security/detecting-malware-script-loaders-using-remcos-threat-research-release-december-2021.html",
]
version = "1.0.29"

query = '''
sequence by process.entity_id with maxspan=1m
 [process where event.type == "start" and
  process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "wmic.exe", "cmstp.exe", "msxsl.exe")]
 [library where dll.pe.original_file_name : "dynwrapx.dll"]
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and
  process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "wmic.exe", "cmstp.exe", "msxsl.exe")]

Stage 2: library

[library where dll.pe.original_file_name : "dynwrapx.dll"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.pe.original_file_namewildcard
  • dynwrapx.dll
field:"dll.pe.original_file_name" kind:wildcard value:"dynwrapx.dll"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namewildcard
  • cmstp.exe corpus 25 (elastic 25)
  • cscript.exe corpus 68 (elastic 66, splunk 2)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • msxsl.exe corpus 22 (elastic 22)
  • wmic.exe corpus 66 (elastic 39, splunk 27)
  • wscript.exe corpus 84 (elastic 82, splunk 1, kusto 1)
field:"process_basename" kind:wildcard

Entra ID ROPC Authentication with Unknown Client ID

#
Status
production
Severity
medium
Time window
9m
Group by
azure.signinlogs.properties.app_id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies potential OAuth client ID spoofing in Microsoft Entra ID sign-in logs. Adversaries submit fabricated or non-existent application identifiers (client IDs) in Resource Owner Password Credentials (ROPC) authentication requests to the token endpoint. Because Entra ID validates the submitted credential before rejecting the request on application resolution, the resulting error code acts as a credential- and account-validity oracle while never producing a successful sign-in. By fragmenting attempts across many fictional application identifiers, adversaries evade per-application detections, rate limiting, and application-scoped Conditional Access. This rule detects a ROPC authentication that fails with error code 700016 (application not found in the directory) where no application display name resolves, which is characteristic of a spoofed client ID used for stealthy user enumeration and password spraying.

Known False Positives

  • A legitimate application that has been deleted from the tenant while a client continues to authenticate against its former client ID via ROPC can generate error code 700016. A misconfigured legacy client submitting an incorrect client ID is also possible. In both cases the client ID is typically stable and low-volume, unlike the many distinct or randomized identifiers seen in spoofing. Verify the application identifier, the source infrastructure, and whether the same principal is targeted by many different unresolved client IDs.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/07/15"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/15"

[rule]
author = ["Elastic"]
description = """
Identifies potential OAuth client ID spoofing in Microsoft Entra ID sign-in logs. Adversaries submit fabricated or
non-existent application identifiers (client IDs) in Resource Owner Password Credentials (ROPC) authentication requests
to the token endpoint. Because Entra ID validates the submitted credential before rejecting the request on application
resolution, the resulting error code acts as a credential- and account-validity oracle while never producing a
successful sign-in. By fragmenting attempts across many fictional application identifiers, adversaries evade
per-application detections, rate limiting, and application-scoped Conditional Access. This rule detects a ROPC
authentication that fails with error code 700016 (application not found in the directory) where no application display
name resolves, which is characteristic of a spoofed client ID used for stealthy user enumeration and password spraying.
"""
false_positives = [
    """
    A legitimate application that has been deleted from the tenant while a client continues to authenticate against its
    former client ID via ROPC can generate error code 700016. A misconfigured legacy client submitting an incorrect
    client ID is also possible. In both cases the client ID is typically stable and low-volume, unlike the many distinct
    or randomized identifiers seen in spoofing. Verify the application identifier, the source infrastructure, and
    whether the same principal is targeted by many different unresolved client IDs.
    """,
]
from = "now-9m"
index = ["logs-azure.signinlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID ROPC Authentication with Unknown Client ID"
note = """## Triage and analysis

### Investigating Entra ID ROPC Authentication with Unknown Client ID

Adversaries submit fabricated application identifiers (client IDs) in ROPC authentication requests to Microsoft's token endpoint. Entra ID validates the supplied username and password before rejecting the request because the application does not exist, so the returned error code reveals whether the credential and account are valid without ever producing a successful sign-in. A valid credential paired with a spoofed client ID returns `AADSTS700016` (application not found), an invalid password returns `AADSTS50126`, and a non-existent user returns `AADSTS50034`. Because the application never resolves, application-scoped Conditional Access is bypassed, and fragmenting requests across many random client IDs defeats per-application correlation and rate limiting. This behavior is used for stealthy user enumeration and password spraying (for example, the campaigns Proofpoint tracks as UNK_pyreq2323 and UNK_OutFlareAZ).

This rule detects a ROPC authentication (`authentication_protocol: ropc`) that fails with `status.error_code: 700016` and carries no resolved `app_display_name`, the signature of a spoofed or non-existent client ID. This is a New Terms rule that triggers only when the application identifier (`app_id`) has not been observed in the tenant's sign-in logs in the previous 10 days, so each newly introduced spoofed client ID surfaces once rather than on every attempt.

### Possible investigation steps

- Review `azure.signinlogs.properties.app_id`: the value is a client ID that does not resolve to any registered application in the tenant. Determine whether the same principal or source is presenting many distinct or randomized client IDs (fragmentation) versus a single stable identifier (possible deleted app).
- Assess `azure.signinlogs.properties.user_principal_name`: a valid user account produces a sign-in log for this activity, so the targeted principal exists in the directory and its credentials are being probed. Prioritize privileged or high-value accounts.
- Correlate `azure.signinlogs.properties.status.error_code` for the same user and source over time. A shift from `50126` (invalid password) to `700016` (application not found) for the same account indicates the adversary has confirmed a valid credential, because the request advanced past credential validation.
- Review `source.ip`, `source.as.organization.name`, and `source.geo.country_name`: enumeration commonly originates from hosting providers, VPNs, or proxy infrastructure rather than corporate ranges.
- Inspect `user_agent.original` and `azure.signinlogs.properties.client_app_used`: scripted enumeration frequently uses generic HTTP libraries and logs `client_app_used` as `Unknown`.
- Pivot on the source IP or ASN to determine how many distinct user principals are being probed, which distinguishes targeted probing from broad spraying.

### False positive analysis

- A legitimate application deleted from the tenant while a client keeps authenticating against its former client ID via ROPC can produce `700016`. Such activity is typically a single, stable client ID at low volume, unlike the many distinct or randomized identifiers seen in spoofing.
- A misconfigured legacy client submitting an incorrect client ID may also trigger this rule. Confirm the client ID, the source, and whether the same principal is targeted by multiple unresolved client IDs before dismissing.

### Response and remediation

- If enumeration is confirmed, treat the targeted accounts as credential-probing targets: force password resets and revoke refresh tokens for any account where the error code progressed to `700016` (credential likely validated).
- Block the offending source IPs or ASNs at the firewall, proxy, or via Conditional Access named locations.
- Ensure MFA and Conditional Access are enforced for all user types, and disable legacy and ROPC authentication where not required, since ROPC cannot satisfy MFA.
- Audit targeted accounts for credential reuse across services and monitor for follow-on interactive or non-interactive sign-in success from the same source.
- Notify your identity security team and correlate with any concurrent brute-force or password-spray detections.
"""
references = [
    "https://www.proofpoint.com/us/blog/threat-insight/oauth-client-id-spoofing-why-fake-client-ids-are-gaining-traction-stealthy",
    "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes",
    "https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc",
]
risk_score = 47
rule_id = "a222b46e-eba8-492f-a376-b7f5f397a34f"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Entra ID",
    "Data Source: Entra ID Sign-in Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "azure.signinlogs"
    and event.category: "authentication"
    and azure.signinlogs.properties.authentication_protocol: "ropc"
    and azure.signinlogs.properties.status.error_code: 700016
    and not azure.signinlogs.properties.app_display_name: *
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"



[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[rule.threat.technique.subtechnique]]
id = "T1087.004"
name = "Cloud Account"
reference = "https://attack.mitre.org/techniques/T1087/004/"



[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "azure.signinlogs.properties.user_principal_name",
    "azure.signinlogs.properties.app_id",
    "azure.signinlogs.properties.app_display_name",
    "azure.signinlogs.properties.status.error_code",
    "azure.signinlogs.properties.authentication_protocol",
    "azure.signinlogs.properties.client_app_used",
    "azure.signinlogs.category",
    "source.ip",
    "source.as.organization.name",
    "source.geo.country_name",
    "user_agent.original",
    "event.outcome",
]

[rule.new_terms]
field = "new_terms_fields"
value = ["azure.signinlogs.properties.app_id"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-10d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "azure.signinlogs"
    and event.category: "authentication"
    and azure.signinlogs.properties.authentication_protocol: "ropc"
    and azure.signinlogs.properties.status.error_code: 700016
    and not azure.signinlogs.properties.app_display_name: *

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
azure.signinlogs.properties.app_display_nameis_not_null(no value, null check)excludes:azure.signinlogs.properties.app_display_name

Exfiltration Data Staging in Temporary Directory via Osascript

#
Time window
10s
Sequence by
Effective_process.entity_id, process.parent.entity_id
Source
github.com/elastic/protections-artifacts

Detects when a directory gets created within a temporary directory and a file is created immediately after. This is a technique that has been observed being used by the most recent Atomic stealer samples in order to organize their data collection prior to exfiltration.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when a directory gets created within a temporary directory and a file is created immediately after. This is a
technique that has been observed being used by the most recent Atomic stealer samples in order to organize their data
collection prior to exfiltration.
"""
id = "802d1796-7d9e-4e3c-911b-22281fdfea03"
license = "Elastic License v2"
name = "Exfiltration Data Staging in Temporary Directory via Osascript"
os_list = ["macos"]
version = "1.0.7"

query = '''
sequence with maxspan=10s
[process where event.type == "start" and event.action == "exec" and process.name == "mkdir" and process.args == "-p" and
  process.args like ("/tmp/*", "/private/tmp/*") and
  process.parent.name == "osascript"] by process.parent.entity_id
[file where event.action == "modification" and process.name == "osascript" and file.path like ("/tmp/*", "/private/tmp/*")] by Effective_process.entity_id
'''

min_endpoint_version = "8.11.1"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1119"
name = "Automated Collection"
reference = "https://attack.mitre.org/techniques/T1119/"


[threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"

[internal]
min_endpoint_version = "8.11.1"

Stages and Predicates

Ordered sequence: each step below must occur in order within 10s, correlated by Effective_process.entity_id, process.parent.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name == "mkdir" and process.args == "-p" and
  process.args like ("/tmp/*", "/private/tmp/*") and
  process.parent.name == "osascript"] by process.parent.entity_id

Stage 2: file

[file where event.action == "modification" and process.name == "osascript" and file.path like ("/tmp/*", "/private/tmp/*")] by Effective_process.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
  • modification corpus 72 (elastic 72)
field:"EventType" kind:eq
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
file.pathwildcard
  • /private/tmp/* corpus 11 (elastic 11)
  • /tmp/* corpus 15 (elastic 15)
field:"TargetFilename" kind:wildcard
process.argseq
  • -p corpus 3 (elastic 3)
field:"process.args" kind:eq value:"-p"
process.argswildcard
  • /private/tmp/* corpus 7 (elastic 7)
  • /tmp/* corpus 11 (elastic 11)
field:"process.args" kind:wildcard
process.nameeq
  • mkdir corpus 3 (elastic 3)
  • osascript corpus 41 (elastic 41)
field:"process_basename" kind:eq
process.parent.nameeq
  • osascript corpus 11 (elastic 11)
field:"parent_process_basename" kind:eq value:"osascript"

GCP IAM Role Deletion

#
Status
production
Severity
low
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies an Identity and Access Management (IAM) role deletion in Google Cloud Platform (GCP). A role contains a set of permissions that allows you to perform specific actions on Google Cloud resources. An adversary may delete an IAM role to inhibit access to accounts utilized by legitimate users.

Known False Positives

  • Role deletions may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Role deletions by unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/09/22"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies an Identity and Access Management (IAM) role deletion in Google Cloud Platform (GCP). A role contains a set
of permissions that allows you to perform specific actions on Google Cloud resources. An adversary may delete an IAM
role to inhibit access to accounts utilized by legitimate users.
"""
false_positives = [
    """
    Role deletions may be done by a system or network administrator. Verify whether the user email, resource name,
    and/or hostname should be making changes in your environment. Role deletions by unfamiliar users or hosts should be
    investigated. If known behavior is causing false positives, it can be exempted from the rule.
    """,
]
index = ["filebeat-*", "logs-gcp*"]
language = "kuery"
license = "Elastic License v2"
name = "GCP IAM Role Deletion"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating GCP IAM Role Deletion

Google Cloud Platform's IAM roles define permissions for actions on resources, crucial for managing access. Adversaries might delete roles to disrupt legitimate user access, hindering operations. The detection rule monitors audit logs for successful role deletions, signaling potential unauthorized access removal, thus aiding in identifying and mitigating such security threats.

### Possible investigation steps

- Review the audit logs for the specific event.action:google.iam.admin.v*.DeleteRole to identify the exact role that was deleted and the associated project or resource.
- Identify the user or service account responsible for the deletion by examining the actor information in the audit logs.
- Check the event.timestamp to determine when the role deletion occurred and correlate it with any other suspicious activities around the same time.
- Investigate the event.outcome:success to confirm that the role deletion was completed successfully and assess the potential impact on access and operations.
- Analyze the context of the deletion by reviewing recent changes or activities in the project or organization to understand if the deletion was part of a legitimate change or an unauthorized action.
- Contact the user or team responsible for the project to verify if the role deletion was intentional and authorized, and gather additional context if needed.

### False positive analysis

- Routine administrative actions may trigger alerts when roles are deleted as part of regular maintenance or restructuring. To manage this, create exceptions for known administrative accounts or scheduled maintenance windows.
- Automated scripts or tools that manage IAM roles might cause false positives if they delete roles as part of their operation. Identify these scripts and exclude their actions from triggering alerts by using specific service accounts or tags.
- Deletion of temporary or test roles used in development environments can be mistaken for malicious activity. Implement filters to exclude actions within designated development projects or environments.
- Changes in organizational structure or policy might necessitate role deletions, which could be misinterpreted as threats. Document and communicate these changes to the security team to adjust monitoring rules accordingly.
- Third-party integrations or services that manage IAM roles could inadvertently cause false positives. Ensure these services are properly documented and their actions are whitelisted if deemed non-threatening.

### Response and remediation

- Immediately revoke any active sessions and credentials associated with the deleted IAM role to prevent unauthorized access.
- Restore the deleted IAM role from a backup or recreate it with the same permissions to ensure legitimate users regain access.
- Conduct a thorough review of recent IAM activity logs to identify any unauthorized changes or suspicious activities related to IAM roles.
- Notify the security team and relevant stakeholders about the incident for awareness and further investigation.
- Implement additional monitoring on IAM role changes to detect and alert on any future unauthorized deletions promptly.
- Review and tighten IAM role permissions to ensure the principle of least privilege is enforced, reducing the risk of similar incidents.
- Consider enabling additional security features such as multi-factor authentication (MFA) for accounts with permissions to modify IAM roles.

## Setup

The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://cloud.google.com/iam/docs/understanding-roles"]
risk_score = 21
rule_id = "e2fb5b18-e33c-4270-851e-c3d675c9afcd"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: GCP",
    "Data Source: Google Cloud Platform",
    "Use Case: Identity and Access Audit",
    "Tactic: Impact",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.DeleteRole and event.outcome:success
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1531"
name = "Account Access Removal"
reference = "https://attack.mitre.org/techniques/T1531/"


[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.DeleteRole and event.outcome:success

Indicators

These rows show field, operator, and value matches.

GKE Pod Exec Cloud Instance Metadata Access

#
Status
production
Severity
high
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects successful GKE pod exec sessions whose command references Google Cloud instance metadata endpoints, including metadata.google.internal, computeMetadata/v1, or the link-local metadata IP 169.254.169.254. Workloads that reach the GKE metadata service from an exec session are often attempting to harvest short-lived credentials or instance attributes from the node or workload identity boundary. That behavior is high risk because it can expose cloud credentials to code running inside a container. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.

Known False Positives

  • Break-glass debugging from platform engineers may include curl to the metadata IP or hostname.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/07/15"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/15"

[rule]
author = ["Elastic"]
description = """
Detects successful GKE pod exec sessions whose command references Google Cloud instance metadata endpoints, including
metadata.google.internal, computeMetadata/v1, or the link-local metadata IP 169.254.169.254. Workloads that reach the
GKE metadata service from an exec session are often attempting to harvest short-lived credentials or instance attributes
from the node or workload identity boundary. That behavior is high risk because it can expose cloud credentials to code
running inside a container. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command
is passed to exec.
"""
false_positives = [
    """
    Break-glass debugging from platform engineers may include curl to the metadata IP or hostname.
    """,
]
from = "now-6m"
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Pod Exec Cloud Instance Metadata Access"
note = """## Triage and analysis

### Investigating GKE Pod Exec Cloud Instance Metadata Access

This alert fires when a successful pods/exec API call includes a command targeting GKE/GCP instance metadata.
Review `gcp.audit.labels.command.gke.io/command` for the full command string.

### Possible investigation steps

- Confirm the actor (`client.user.email`), source IP, and user agent that performed exec.
- Map `gcp.audit.resource_name` to the target pod/namespace and determine whether the workload should ever call metadata.
- Correlate with GCP audit logs for token issuance or IAM activity around the same time from the node or workload identity.
- Hunt adjacent activity from the same identity: secret reads, additional execs, or RBAC changes.

### False positive analysis

- Approved platform tooling or bootstrap scripts may query metadata during startup; baseline those images and identities.
- Break-glass egress/metadata connectivity tests can match; document and allowlist those principals.

### Response and remediation

- If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that
  could have been read, and tighten pods/exec RBAC plus network policies that deny link-local metadata from pods.
"""
setup = "The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."
references = [
    "https://cloud.google.com/kubernetes-engine/docs/concepts/protecting-cluster-metadata",
]
risk_score = 73
rule_id = "c8bf56cc-c648-4f88-bb4f-9e504d0779d1"
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Data Source: GCP",
    "Data Source: GCP Audit Logs",
    "Data Source: Google Cloud Platform",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Execution",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and service.name:"k8s.io" and
event.outcome:success and event.type:start and
event.action:("io.k8s.core.v1.pods.exec.create" or "io.k8s.core.v1.pods.exec.get") and
gcp.audit.labels.command.gke.io/command:(
  *169.254.169.254* or *metadata.google.internal* or *computeMetadata/v1*
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"

[[rule.threat.technique.subtechnique]]
id = "T1552.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "client.user.email",
    "source.ip",
    "user_agent.original",
    "event.action",
    "event.outcome",
    "event.type",
    "gcp.audit.labels.command.gke.io/command",
    "gcp.audit.resource_name",
    "data_stream.namespace",
]

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and service.name:"k8s.io" and
event.outcome:success and event.type:start and
event.action:("io.k8s.core.v1.pods.exec.create" or "io.k8s.core.v1.pods.exec.get") and
gcp.audit.labels.command.gke.io/command:(
  *169.254.169.254* or *metadata.google.internal* or *computeMetadata/v1*
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • gcp.audit corpus 60 (elastic 60)
field:"data_stream.dataset" kind:eq value:"gcp.audit"
event.actionin
  • io.k8s.core.v1.pods.exec.create corpus 5 (elastic 5)
  • io.k8s.core.v1.pods.exec.get corpus 5 (elastic 5)
field:"EventType" kind:in
event.outcomeeq
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:eq value:"success"
event.typeeq
  • start corpus 67 (elastic 67)
field:"event.type" kind:eq value:"start"
gcp.audit.labels.command.gke.io/commandwildcard
  • *169.254.169.254*
  • *computeMetadata/v1*
  • *metadata.google.internal*
field:"gcp.audit.labels.command.gke.io/command" kind:wildcard
service.nameeq
  • k8s.io corpus 28 (elastic 28)
field:"ServiceName" kind:eq value:"k8s.io"

Google Calendar C2 via Script Interpreter

#
Status
production
Severity
high
Time window
20s
Sequence by
process.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Detects a two-stage Google Calendar C2 pattern where a scripting runtime (Node.js, Python, osascript) first connects to calendar.app.google to retrieve a hidden C2 address, then initiates a secondary connection to the decoded C2 host. This sequence is characteristic of packages using Unicode steganography in Google Calendar events to stage dynamic command-and-control endpoints.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Detects a two-stage Google Calendar C2 pattern where a scripting runtime (Node.js, Python, osascript) first 
connects to calendar.app.google to retrieve a hidden C2 address, then initiates a secondary connection to the 
decoded C2 host. This sequence is characteristic of packages using Unicode steganography in Google Calendar 
events to stage dynamic command-and-control endpoints.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "Google Calendar C2 via Script Interpreter"
references = [
    "https://www.veracode.com/resources/sophisticated-npm-attack-leveraging-unicode-steganography-and-google-calendar-c2",
    "https://www.koi.ai/blog/glassworm-first-self-propagating-worm-using-invisible-code-hits-openvsx-marketplace"
]
risk_score = 73
rule_id = "abc7a2be-479e-428b-b0b3-1d22bda46dd9"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Tactic: Execution",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide"
]
type = "eql"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Google Calendar C2 via Script Interpreter

Threat actors increasingly abuse legitimate cloud services to establish covert command and control channels that blend with normal traffic and bypass traditional network security controls. Google Calendar has been weaponized as a C2 mechanism where attackers store encoded commands in calendar event descriptions, which malware then polls and executes. This detection rule identifies script interpreters connecting to Google Calendar API endpoints, which may indicate this living-off-the-land technique.

### Possible investigation steps

- Review the process.name and process.executable fields to identify which script interpreter is making the Google Calendar API connection and assess whether it is expected for the user or application context.
- Examine the process.command_line and process.args fields to understand what script or code is being executed that initiated the calendar connection.
- Check the process.parent.executable and process.parent.command_line to trace the process lineage and identify how the script interpreter was launched.
- Investigate the Google Workspace audit logs for the associated user account to review calendar events that may contain encoded commands or suspicious content.
- Review network connection details including dns.question.name and destination.ip to understand the specific Google API endpoints being accessed.
- Correlate with authentication events to identify which user account or service account OAuth tokens are being used for the calendar access.
- Search for similar activity across other endpoints to determine if this is an isolated incident or part of a broader campaign.

### False positive analysis

- Legitimate productivity applications may integrate with Google Calendar for scheduling and automation purposes. Verify the application's purpose and whether it is approved by IT.
- Custom automation scripts built by employees may access Google Calendar API for workflow automation. Review with the script owner to confirm legitimacy.
- Development and testing environments may trigger this detection when building calendar integrations. Document known development activities and create targeted exceptions.
- Third-party calendar sync applications may use script interpreters to interface with Google Calendar. Verify these are sanctioned applications.

### Response and remediation

- Immediately terminate the suspicious script interpreter process to stop any ongoing C2 communication.
- Revoke OAuth tokens and API credentials associated with the compromised Google account to prevent further unauthorized access.
- Review Google Workspace admin console for any unauthorized calendar events or modifications that may contain malicious content.
- Isolate the affected macOS system from the network while conducting forensic analysis.
- Perform a comprehensive scan for additional malware, persistence mechanisms, or lateral movement indicators.
- Reset the affected user's credentials and enable multi-factor authentication if not already in place.
- Implement application allowlisting to prevent unauthorized script interpreters from executing.
- Escalate to the security operations team for further investigation into potential data exfiltration or broader compromise.
"""
query = '''
sequence by process.entity_id with maxspan=20s
  [network where host.os.type == "macos" and event.type == "start" and
    (process.name in ("node", "osascript") or process.name like "python*" or
     process.code_signature.trusted == false or process.code_signature.exists == false) and
    destination.domain like "calendar.app.google*"]
  [network where host.os.type == "macos" and event.type == "start" and destination.domain == null]
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1102"
name = "Web Service"
reference = "https://attack.mitre.org/techniques/T1102/"

[[rule.threat.technique.subtechnique]]
id = "T1102.001"
name = "Dead Drop Resolver"
reference = "https://attack.mitre.org/techniques/T1102/001/"

[[rule.threat.technique.subtechnique]]
id = "T1102.002"
name = "Bidirectional Communication"
reference = "https://attack.mitre.org/techniques/T1102/002/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.002"
name = "AppleScript"
reference = "https://attack.mitre.org/techniques/T1059/002/"

[[rule.threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"

[[rule.threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 20s, correlated by process.entity_id.

Stage 1: network

[network where host.os.type == "macos" and event.type == "start" and
    (process.name in ("node", "osascript") or process.name like "python*" or
     process.code_signature.trusted == false or process.code_signature.exists == false) and
    destination.domain like "calendar.app.google*"]

Stage 2: network

[network where host.os.type == "macos" and event.type == "start" and destination.domain == null]

Indicators

These rows show field, operator, and value matches.

Google Workspace Device Registration Burst for Single User

#
Status
production
Severity
medium
Time window
9m
Group by
Esql.bucket_minute, user.email, user.id, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects bursts of Google Workspace device registration events for the same user, where three or more distinct "google_workspace.device.id" values are emitted in a one-minute window. Although "DEVICE_REGISTER_UNREGISTER_EVENT" fires routinely on session/sync registration and is not a true physical device enrollment, legitimate user activity typically produces fewer than three distinct device IDs in a single minute. A high-cardinality burst is the fingerprint behavior of AiTM phishing-kit relays (Tycoon2FA Google variant, EvilGinx phishlets) and stolen-OAuth-token replay tooling, both of which mint a new session attestation per relay or replay attempt.

Known False Positives

  • A user simultaneously enrolling multiple Workspace-aware apps on a new device (e.g., first-time setup of Gmail, Drive, Calendar, and Meet on a new laptop in a short window) may produce three or more distinct device IDs in a minute. Validate by checking whether the burst is tied to a fresh device or onboarding event.
  • Major OS upgrades or Workspace client refreshes that re-attest several apps concurrently may also produce a burst. Cross-reference against the user's known device OS transitions.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/05/15"
integration = ["google_workspace"]
maturity = "production"
updated_date = "2026/05/15"

[rule]
author = ["Elastic"]
description = """
Detects bursts of Google Workspace device registration events for the same user, where three or more distinct
"google_workspace.device.id" values are emitted in a one-minute window. Although "DEVICE_REGISTER_UNREGISTER_EVENT"
fires routinely on session/sync registration and is not a true physical device enrollment, legitimate user activity
typically produces fewer than three distinct device IDs in a single minute. A high-cardinality burst is the fingerprint
behavior of AiTM phishing-kit relays (Tycoon2FA Google variant, EvilGinx phishlets) and stolen-OAuth-token replay
tooling, both of which mint a new session attestation per relay or replay attempt.
"""
false_positives = [
    """
    A user simultaneously enrolling multiple Workspace-aware apps on a new device (e.g., first-time setup of Gmail,
    Drive, Calendar, and Meet on a new laptop in a short window) may produce three or more distinct device IDs in a
    minute. Validate by checking whether the burst is tied to a fresh device or onboarding event.
    """,
    """
    Major OS upgrades or Workspace client refreshes that re-attest several apps concurrently may also produce a burst.
    Cross-reference against the user's known device OS transitions.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Google Workspace Device Registration Burst for Single User"
note = """## Triage and analysis

### Investigating Google Workspace Device Registration Burst for Single User

`DEVICE_REGISTER_UNREGISTER_EVENT` from the Google Workspace `mobile` provider does not represent a one-time physical device enrollment. The Reports API emits a fresh `google_workspace.device.id` on every session/sync registration, and a single physical device can produce multiple events per day as Workspace-aware apps independently attest. Legitimate activity, however, very rarely concentrates three or more distinct device IDs into a one-minute window for a single user. A burst of that shape is the fingerprint of either:

- An AiTM phishing-kit relay session: the kit completes the victim's sign-in against Google, then attests one or more device contexts of its own, all from the same kit infrastructure within seconds.
- Token-replay tooling driving multiple sessions in quick succession against a stolen OAuth refresh token.

In both cases the device fingerprint (OS, model) typically converges on a single value distinct from the victim's baseline (e.g., all "Windows" attestations for a known macOS user), and the burst events fire within a few seconds of each other rather than spread across minutes.

### Possible investigation steps

- Identify the user (`user.email`, `user.id`) and inspect `Esql.host_os_version_values`, `Esql.device_type_values`, `Esql.device_model_values`. A homogeneous fingerprint (single OS, single model) across multiple device IDs in the burst window is highly suspicious.
- Cross-reference `logs-google_workspace.login` for `event.action: "login_success"` events from the same `user.email` in the 30 minutes preceding the burst. The kit-relay sign-ins should appear there. Inspect each sign-in's `source.geo.country_name`, `source.as.organization.name`, and `user_agent.original` for divergence from the user's baseline. Hosting-provider ASNs (Clouvider, Host Telecom, OVH, Alibaba, Vultr, DigitalOcean, M247) for interactive sign-ins are high-fidelity suspicious.
- Cross-reference `logs-google_workspace.token` for `event.action: "authorize"` events for the same user near the burst window. Each kit relay normally fires a corresponding OAuth grant within seconds, often to Google Chrome (`77185425430.apps.googleusercontent.com`) or another long-lived first-party client.
- Pull all `logs-google_workspace.device` events for the user across the 24 hours preceding the burst to characterize the user's normal device-event rate. A user who typically produces less than 1 event per hour suddenly emitting 3+ in a minute is a strong anomaly even before considering device fingerprints.
- Confirm with the user whether they were performing a new device setup, OS upgrade, or onboarding activity during the burst window.

### False positive analysis

- New device setup where a user simultaneously enrolls multiple Workspace-aware apps (Gmail, Drive, Calendar, Meet) on first boot can produce a burst. Validate by checking whether the burst coincides with a known device refresh or onboarding event.
- Major OS upgrades that re-attest several apps concurrently can also produce a burst. The host OS version values will reflect the upgrade transition.
- Bulk MDM rollouts or fleet refreshes may produce bursts across many users at the same time. Consider rule suppression during planned rollouts.

### Response and remediation

- Treat as likely AiTM compromise or token-replay activity until proven otherwise. Suspend the user, revoke all OAuth tokens (`DELETE /admin/directory/v1/users/<email>/tokens/<clientId>`), reset the password, clear recovery email/phone, sign out all sessions.
- Audit `logs-google_workspace.token: authorize` events for kit-issued or replay-issued OAuth grants. Each grant maps to an independently replayable refresh token; revoking via the consent removes them all at once.
- Audit the device IDs surfaced in the burst via the Admin SDK Directory API and remove any that are confirmed adversary-controlled.
- If the tenant exposes GCP resources to the user, cross-check `logs-gcp.audit-*` for `authenticationInfo.principalEmail` matching the user from a non-baseline `callerIp` in the same window; token theft frequently extends to cross-cloud access.
"""
references = [
    "https://developers.google.com/workspace/admin/reports/v1/appendix/activity/mobile",
    "https://any.run/malware-trends/tycoon/",
    "https://www.elastic.co/security-labs/google-workspace-attack-surface-part-one",
]
risk_score = 47
rule_id = "bea0589d-c7a4-4dc6-a931-9fecaa8689fb"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Google Workspace",
    "Data Source: Google Workspace Device Logs",
    "Use Case: Threat Detection",
    "Use Case: Identity and Access Audit",
    "Tactic: Persistence",
    "Tactic: Initial Access",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-google_workspace.device-*
| where event.dataset == "google_workspace.device"
    and event.action == "DEVICE_REGISTER_UNREGISTER_EVENT"
    and google_workspace.device.account_state == "REGISTERED"
    and user.email is not null
    and google_workspace.device.id is not null

| eval Esql.bucket_minute = date_trunc(1 minute, @timestamp)

| stats
        Esql.count_distinct_device_id = count_distinct(google_workspace.device.id),
        Esql.device_id_values = values(google_workspace.device.id),
        Esql.device_resource_id_values = values(google_workspace.device.resource.id),
        Esql.device_type_values = values(google_workspace.device.type),
        Esql.device_model_values = values(google_workspace.device.model),
        Esql.device_account_state_values = values(google_workspace.device.account_state),
        Esql.host_os_version_values = values(host.os.version),
        Esql.event_provider_values = values(event.provider),
        Esql.event_id_values = values(event.id),
        Esql.google_workspace_actor_type_values = values(google_workspace.actor.type),
        Esql.google_workspace_event_type_values = values(google_workspace.event.type),
        Esql.organization_id_values = values(organization.id),
        Esql.user_domain_values = values(user.domain),
        Esql.timestamp_first_seen = min(@timestamp),
        Esql.timestamp_last_seen = max(@timestamp),
        Esql.event_count = count(*)
    by user.id, user.email, user.name, Esql.bucket_minute

| where Esql.count_distinct_device_id >= 3

| keep user.id,
        user.email,
        user.name,
        Esql.bucket_minute,
        Esql.timestamp_first_seen,
        Esql.timestamp_last_seen,
        Esql.count_distinct_device_id,
        Esql.event_count,
        Esql.device_id_values,
        Esql.device_resource_id_values,
        Esql.device_type_values,
        Esql.device_model_values,
        Esql.device_account_state_values,
        Esql.host_os_version_values,
        Esql.event_provider_values,
        Esql.event_id_values,
        Esql.google_workspace_actor_type_values,
        Esql.google_workspace_event_type_values,
        Esql.organization_id_values,
        Esql.user_domain_values
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.005"
name = "Device Registration"
reference = "https://attack.mitre.org/techniques/T1098/005/"



[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"



[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"


[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[rule.investigation_fields]
field_names = ["@timestamp", "user.email", "user.id", "user.name"]

Stages and Predicates

Stage 1: from

from logs-google_workspace.device-*

Stage 2: where

| where event.dataset == "google_workspace.device"
    and event.action == "DEVICE_REGISTER_UNREGISTER_EVENT"
    and google_workspace.device.account_state == "REGISTERED"
    and user.email is not null
    and google_workspace.device.id is not null

Stage 3: eval

| eval Esql.bucket_minute = date_trunc(1 minute, @timestamp)

Stage 4: stats

| stats
        Esql.count_distinct_device_id = count_distinct(google_workspace.device.id),
        Esql.device_id_values = values(google_workspace.device.id),
        Esql.device_resource_id_values = values(google_workspace.device.resource.id),
        Esql.device_type_values = values(google_workspace.device.type),
        Esql.device_model_values = values(google_workspace.device.model),
        Esql.device_account_state_values = values(google_workspace.device.account_state),
        Esql.host_os_version_values = values(host.os.version),
        Esql.event_provider_values = values(event.provider),
        Esql.event_id_values = values(event.id),
        Esql.google_workspace_actor_type_values = values(google_workspace.actor.type),
        Esql.google_workspace_event_type_values = values(google_workspace.event.type),
        Esql.organization_id_values = values(organization.id),
        Esql.user_domain_values = values(user.domain),
        Esql.timestamp_first_seen = min(@timestamp),
        Esql.timestamp_last_seen = max(@timestamp),
        Esql.event_count = count(*)
    by user.id, user.email, user.name, Esql.bucket_minute

Stage 5: where

| where Esql.count_distinct_device_id >= 3

Stage 6: keep

| keep user.id,
        user.email,
        user.name,
        Esql.bucket_minute,
        Esql.timestamp_first_seen,
        Esql.timestamp_last_seen,
        Esql.count_distinct_device_id,
        Esql.event_count,
        Esql.device_id_values,
        Esql.device_resource_id_values,
        Esql.device_type_values,
        Esql.device_model_values,
        Esql.device_account_state_values,
        Esql.host_os_version_values,
        Esql.event_provider_values,
        Esql.event_id_values,
        Esql.google_workspace_actor_type_values,
        Esql.google_workspace_event_type_values,
        Esql.organization_id_values,
        Esql.user_domain_values

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
user.idKEEP user.id
user.emailKEEP user.email
user.nameKEEP user.name
Esql.bucket_minuteKEEP Esql.bucket_minute
Esql.timestamp_first_seenKEEP Esql.timestamp_first_seen
Esql.timestamp_last_seenKEEP Esql.timestamp_last_seen
Esql.count_distinct_device_idKEEP Esql.count_distinct_device_id
Esql.event_countKEEP Esql.event_count
Esql.device_id_valuesKEEP Esql.device_id_values
Esql.device_resource_id_valuesKEEP Esql.device_resource_id_values
Esql.device_type_valuesKEEP Esql.device_type_values
Esql.device_model_valuesKEEP Esql.device_model_values
Esql.device_account_state_valuesKEEP Esql.device_account_state_values
Esql.host_os_version_valuesKEEP Esql.host_os_version_values
Esql.event_provider_valuesKEEP Esql.event_provider_values
Esql.event_id_valuesKEEP Esql.event_id_values
Esql.google_workspace_actor_type_valuesKEEP Esql.google_workspace_actor_type_values
Esql.google_workspace_event_type_valuesKEEP Esql.google_workspace_event_type_values
Esql.organization_id_valuesKEEP Esql.organization_id_values
Esql.user_domain_valuesKEEP Esql.user_domain_values

Hosts File Modified

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

The hosts file on endpoints is used to control manual IP address to hostname resolutions. The hosts file is the first point of lookup for DNS hostname resolution so if adversaries can modify the endpoint hosts file, they can route traffic to malicious infrastructure. This rule detects modifications to the hosts file on Microsoft Windows, Linux (Ubuntu or RHEL) and macOS systems.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/07/07"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2026/02/02"

[rule]
author = ["Elastic"]
description = """
The hosts file on endpoints is used to control manual IP address to hostname resolutions. The hosts file is the first
point of lookup for DNS hostname resolution so if adversaries can modify the endpoint hosts file, they can route traffic
to malicious infrastructure. This rule detects modifications to the hosts file on Microsoft Windows, Linux (Ubuntu or
RHEL) and macOS systems.
"""
from = "now-9m"
index = ["auditbeat-*", "winlogbeat-*", "logs-endpoint.events.*", "logs-windows.*"]
language = "eql"
license = "Elastic License v2"
name = "Hosts File Modified"
note = """## Triage and analysis

### Investigating Hosts File Modified

Operating systems use the hosts file to map a connection between an IP address and domain names before going to domain name servers. Attackers can abuse this mechanism to route traffic to malicious infrastructure or disrupt security that depends on server communications. For example, Russian threat actors modified this file on a domain controller to redirect Duo MFA calls to localhost instead of the Duo server, which prevented the MFA service from contacting its server to validate MFA login. This effectively disabled MFA for active domain accounts because the default policy of Duo for Windows is to "Fail open" if the MFA server is unreachable. This can happen in any MFA implementation and is not exclusive to Duo. Find more details in this [CISA Alert](https://www.cisa.gov/uscert/ncas/alerts/aa22-074a).

This rule identifies modifications in the hosts file across multiple operating systems using process creation events for Linux and file events in Windows and macOS.

#### Possible investigation steps

- Identify the specifics of the involved assets, such as role, criticality, and associated users.
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Examine the changes to the hosts file by comparing it against file backups, volume shadow copies, and other restoration mechanisms.

### False positive analysis

- This mechanism can be used legitimately. Analysts can dismiss the alert if the administrator is aware of the activity and the configuration was justified.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Consider isolating the involved host to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Review the privileges of the administrator account that performed the action.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/beats/auditbeat/current/auditbeat-reference-yml.html"]
risk_score = 47
rule_id = "9c260313-c811-4ec8-ab89-8f6530e0246c"
setup = """## Setup

For Windows systems using Auditbeat, this rule requires adding `C:/Windows/System32/drivers/etc` as an additional path in the 'file_integrity' module of auditbeat.yml.

If enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2,
events will not define `event.ingested` and default fallback for EQL rules was not added until version 8.2.
Hence for this rule to work effectively, users will need to add a custom ingest pipeline to populate
`event.ingested` to @timestamp.
For more details on adding a custom ingest pipeline refer - https://www.elastic.co/guide/en/fleet/current/data-streams-pipeline-tutorial.html
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "OS: Windows",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Impact",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timeline_id = "4d4c0b59-ea83-483f-b8c1-8c360ee53c5c"
timeline_title = "Comprehensive File Timeline"
timestamp_override = "event.ingested"
type = "eql"

query = '''
any where process.executable != null and

  /* file events for creation; file change events are not captured by some of the included sources for linux and so may
     miss this, which is the purpose of the process + command line args logic below */
  (
   event.category == "file" and event.type in ("change", "creation") and event.action != "rename" and
     file.path : ("/private/etc/hosts", "/etc/hosts", "?:\\Windows\\System32\\drivers\\etc\\hosts") and 
     not process.name in ("dockerd", "rootlesskit", "podman", "crio") and
     not process.executable : ("C:\\Program Files\\Fortinet\\FortiClient\\FCDBLog.exe",
                               "C:\\Program Files\\Fortinet\\FortiClient\\FortiWF.exe",
                               "C:\\Program Files\\Fortinet\\FortiClient\\fmon.exe",
                               "C:\\Program Files\\Seqrite\\Seqrite\\SCANNER.EXE",
                               "C:\\Windows\\System32\\SearchProtocolHost.exe",
                               "C:\\Windows\\Temp\\*.ins\\inst.exe",
                               "C:\\Windows\\System32\\svchost.exe",
                               "C:\\Program Files\\NordVPN\\nordvpn-service.exe",
                               "C:\\Program Files\\Tailscale\\tailscaled.exe",
                               "C:\\Program Files\\Docker\\Docker\\com.docker.service",
                               "C:\\Program Files\\Docker\\Docker\\InstallerCli.exe",
                               "C:\\Program Files\\Quick Heal\\Quick Heal AntiVirus Pro\\scanner.exe",
                               "C:\\Program Files (x86)\\Quick Heal AntiVirus Pro\\SCANNER.EXE",
                               "C:\\Program Files\\Quick Heal\\Quick Heal Internet Security\\scanner.exe",
                               "C:\\Program Files (x86)\\Cisco\\Cisco AnyConnect Secure Mobility Client\\vpnagent.exe",
                               "/Applications/Parallels Desktop.app/Contents/MacOS/prl_naptd",
                               "/opt/IBM/InformationServer/Server/DSEngine/bin/uvsh",
                               "/usr/local/demisto/server", 
                               "/usr/local/bin/defender")
  )
  or

  /* process events for change targeting linux only */
  (
   event.category == "process" and event.type in ("start") and
     process.name in ("nano", "vim", "vi", "emacs", "echo", "sed") and
     (process.args : ("/etc/hosts") or (process.working_directory == "/etc" and process.args == "hosts")) and 
     not process.parent.name in ("dhclient-script", "google_set_hostname") and
     not process.command_line == "sed -i /Added by Google/d /etc/hosts"
  )
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1565"
name = "Data Manipulation"
reference = "https://attack.mitre.org/techniques/T1565/"
[[rule.threat.technique.subtechnique]]
id = "T1565.001"
name = "Stored Data Manipulation"
reference = "https://attack.mitre.org/techniques/T1565/001/"



[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"

Stages and Predicates

Stage 1: any

any where process.executable != null and
  /* file events for creation; file change events are not captured by some of the included sources for linux and so may
     miss this, which is the purpose of the process + command line args logic below */
  (
   event.category == "file" and event.type in ("change", "creation") and event.action != "rename" and
     file.path : ("/private/etc/hosts", "/etc/hosts", "?:\\Windows\\System32\\drivers\\etc\\hosts") and
     not process.name in ("dockerd", "rootlesskit", "podman", "crio") and
     not process.executable : ("C:\\Program Files\\Fortinet\\FortiClient\\FCDBLog.exe",
                               "C:\\Program Files\\Fortinet\\FortiClient\\FortiWF.exe",
                               "C:\\Program Files\\Fortinet\\FortiClient\\fmon.exe",
                               "C:\\Program Files\\Seqrite\\Seqrite\\SCANNER.EXE",
                               "C:\\Windows\\System32\\SearchProtocolHost.exe",
                               "C:\\Windows\\Temp\\*.ins\\inst.exe",
                               "C:\\Windows\\System32\\svchost.exe",
                               "C:\\Program Files\\NordVPN\\nordvpn-service.exe",
                               "C:\\Program Files\\Tailscale\\tailscaled.exe",
                               "C:\\Program Files\\Docker\\Docker\\com.docker.service",
                               "C:\\Program Files\\Docker\\Docker\\InstallerCli.exe",
                               "C:\\Program Files\\Quick Heal\\Quick Heal AntiVirus Pro\\scanner.exe",
                               "C:\\Program Files (x86)\\Quick Heal AntiVirus Pro\\SCANNER.EXE",
                               "C:\\Program Files\\Quick Heal\\Quick Heal Internet Security\\scanner.exe",
                               "C:\\Program Files (x86)\\Cisco\\Cisco AnyConnect Secure Mobility Client\\vpnagent.exe",
                               "/Applications/Parallels Desktop.app/Contents/MacOS/prl_naptd",
                               "/opt/IBM/InformationServer/Server/DSEngine/bin/uvsh",
                               "/usr/local/demisto/server",
                               "/usr/local/bin/defender")
  )
  or
  (
   event.category == "process" and event.type in ("start") and
     process.name in ("nano", "vim", "vi", "emacs", "echo", "sed") and
     (process.args : ("/etc/hosts") or (process.working_directory == "/etc" and process.args == "hosts")) and
     not process.parent.name in ("dhclient-script", "google_set_hostname") and
     not process.command_line == "sed -i /Added by Google/d /etc/hosts"
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionne
  • rename
field:"EventType" kind:ne value:"rename"
event.categoryeq
  • file corpus 14 (elastic 14)
  • process corpus 38 (elastic 38)
field:"event.category" kind:eq
event.typein
  • change corpus 18 (elastic 18)
  • creation corpus 17 (elastic 17)
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:in
file.pathwildcard
  • /etc/hosts
  • /private/etc/hosts
  • ?:\Windows\System32\drivers\etc\hosts
field:"TargetFilename" kind:wildcard
process.argseq
  • hosts corpus 2 (elastic 2)
field:"process.args" kind:eq value:"hosts"
process.argswildcard
  • /etc/hosts corpus 2 (elastic 2)
field:"process.args" kind:wildcard value:"/etc/hosts"
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
process.namein
  • echo corpus 6 (elastic 6)
  • emacs corpus 5 (elastic 5)
  • nano corpus 4 (elastic 4)
  • sed corpus 15 (elastic 15)
  • vi corpus 7 (elastic 7)
  • vim corpus 14 (elastic 14)
field:"process_basename" kind:in
process.working_directoryeq
  • /etc corpus 2 (elastic 2)
field:"CurrentDirectory" kind:eq value:"/etc"

Potential Computer Account NTLM Relay Activity

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies potential relay activities against a Computer account by identifying authentication events using the computer account coming from from hosts other than the server that owns the account. Attackers may relay the computer account hash after capturing it using forced authentication.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2024/07/24"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/08/10"

[rule]
author = ["Elastic"]
description = """
Identifies potential relay activities against a Computer account by identifying authentication events using the computer
account coming from from hosts other than the server that owns the account. Attackers may relay the computer account
hash after capturing it using forced authentication.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Computer Account NTLM Relay Activity"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Potential Computer Account NTLM Relay Activity

### Possible investigation steps

- Compare the source.ip to the target server host.ip addresses to make sure it's indeed a remote use of the machine account.
- Examine the source.ip activities as this is the attacker IP address used to relay.
- Review all relevant activities such as services creation, file and process events on the target server within the same period.
- Verify the machine account names that end with a dollar sign ($) to ensure they match the expected hostnames, and investigate any discrepancies.
- Check the network logon types to confirm if they align with typical usage patterns for the identified machine accounts.
- Investigate the context of the source IP addresses that do not match the host IP, looking for any signs of unauthorized access or unusual network activity.
- Correlate the findings with other security logs and alerts to identify any patterns or additional indicators of compromise related to the potential relay attack.

### False positive analysis

- Machine accounts performing legitimate network logons from different IP addresses can trigger false positives. To manage this, identify and whitelist known IP addresses associated with legitimate administrative tasks or automated processes.
- Scheduled tasks or automated scripts that use machine accounts for network operations may be flagged. Review and document these tasks, then create exceptions for their associated IP addresses and hostnames.
- Load balancers or proxy servers that alter the source IP address of legitimate authentication requests can cause false alerts. Ensure these devices are accounted for in the network architecture and exclude their IP addresses from the rule.
- Temporary network reconfigurations or migrations might result in machine accounts appearing to log in from unexpected hosts. During such events, temporarily adjust the rule parameters or disable the rule to prevent unnecessary alerts.
- Regularly review and update the list of exceptions to ensure they reflect current network configurations and operational practices, minimizing the risk of overlooking genuine threats.

### Response and Remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
    - If the involved server is a Domain Controller, coordinate the isolation of the server with infrastructure and identity teams to contain the threat while preserving service availability and forensic evidence. Prioritize this step if active compromise or attacker persistence is confirmed.
- Reset the domain controller's machine account password, along with any accounts suspected to be compromised or exposed. Ensure strong, unique credentials are used and apply tiered credential hygiene where applicable.
- Analyze recent authentication logs, event logs, and network traffic, focusing on suspicious activity and the source IPs referenced in the alert. Correlate findings to identify any lateral movement or additional compromised systems.
- Strengthen network segmentation, especially between domain controllers, administrative workstations, and critical infrastructure. This limits the attack surface and impedes credential relay or reuse across systems.
- Escalate the incident to the SOC or incident response team to coordinate a full investigation, containment, and recovery plan. Ensure stakeholders are kept informed throughout the response.
- Enhance detection mechanisms by tuning alerts and deploying additional telemetry focused on credential relay patterns, anomalous authentication, and NTLM-related activity.
- Conduct a structured post-incident review, documenting findings, identifying control gaps, and updating playbooks, configurations, or security policies to reduce the likelihood of similar incidents in the future.
"""

setup = """## Setup

Audit Logon must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-logon
"""

references = [
    "https://github.com/p0dalirius/windows-coerced-authentication-methods",
    "https://www.thehacker.recipes/a-d/movement/mitm-and-coerced-authentications",
    "https://attack.mitre.org/techniques/T1187/",
]
risk_score = 47
rule_id = "263481c8-1e9b-492e-912d-d1760707f810"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Active Directory",
    "Use Case: Active Directory Monitoring",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
 winlog.logon.type == "Network" and winlog.event_data.AuthenticationPackageName == "NTLM" and
 endswith~(user.name, "$") and user.name != "$" and
 source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1" and

 /* Filter for a machine account that matches the hostname */
 startswith~(host.name, substring(user.name, 0, -1)) and

 /* Verify the machine account matches the full hostname, not just a prefix substring */
 (startswith~(substring(user.name, 0, -1), host.name) or startswith~(host.name, concat(substring(user.name, 0, -1), "."))) and

 /* Verify if the Source IP belongs to the host */
 not endswith(string(source.ip), string(host.ip)) and
 indexOf(string(host.ip), string(source.ip)) == null and

 /* Exclude self-authentication from multi-homed hosts where the NTLM workstation name matches the machine account */
 not (source.domain != null and
      startswith~(user.name, source.domain) and
      startswith~(source.domain, substring(user.name, 0, -1)))
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1187"
name = "Forced Authentication"
reference = "https://attack.mitre.org/techniques/T1187/"

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"
[[rule.threat.technique.subtechnique]]
id = "T1557.001"
name = "LLMNR/NBT-NS Poisoning and SMB Relay"
reference = "https://attack.mitre.org/techniques/T1557/001/"



[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Stage 1: authentication

authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
 winlog.logon.type == "Network" and winlog.event_data.AuthenticationPackageName == "NTLM" and
 endswith~(user.name, "$") and user.name != "$" and
 source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1" and
 startswith~(host.name, substring(user.name, 0, -1)) and
 (startswith~(substring(user.name, 0, -1), host.name) or startswith~(host.name, concat(substring(user.name, 0, -1), "."))) and
 not endswith(string(source.ip), string(host.ip)) and
 indexOf(string(host.ip), string(source.ip)) == null and
 not (source.domain != null and
      startswith~(user.name, source.domain) and
      startswith~(source.domain, substring(user.name, 0, -1)))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codein
  • 4624 corpus 6 (elastic 3, kusto 3)
  • 4625 corpus 6 (elastic 3, kusto 3)
field:"EventID" kind:in
host.namestarts_with
  • concat(substring(user.name, 0, (-1)), ".") (expression)
  • substring(user.name, 0, (-1)) (expression)
field:"Computer" kind:starts_with
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null
source.ipne
  • 127.0.0.1 corpus 22 (elastic 22)
  • ::1 corpus 20 (elastic 20)
field:"src_ip" kind:ne
user.nameends_with
  • $ corpus 5 (elastic 4, kusto 1)
field:"user" kind:ends_with value:"$"
user.namene
  • $
field:"user" kind:ne value:"$"
winlog.event_data.AuthenticationPackageNameeq
  • NTLM
field:"AuthenticationPackageName" kind:eq value:"NTLM"
winlog.logon.typeeq
  • Network corpus 4 (elastic 4)
field:"LogonType" kind:eq value:"Network"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
source.domainis_not_null(no value, null check)excludes:source.domain
source.domainstarts_withsubstring(user.name, 0, (-1))excludes:source.domain field:"source.domain" value:"substring(user.name, 0, (-1))"
user.namestarts_withsource.domainexcludes:user.name field:"user.name" value:"source.domain"
source.ipends_withstring(host.ip)excludes:source.ip field:"source.ip" value:"string(host.ip)"

Potential Kerberos Relay Attack against a Computer Account

#
Status
production
Severity
high
Time window
5s
Sequence by
source.ip, winlog.computer_name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects potential relay attacks by identifying coercion attempts followed by authentication events using a target server's computer account, originating from a different host. This may indicate that an attacker has captured and relayed Kerberos authentication material for the server's computer account to execute code on behalf of the compromised system.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/06/18"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/04/22"

[rule]
author = ["Elastic"]
description = """
Detects potential relay attacks by identifying coercion attempts followed by authentication events using a target
server's computer account, originating from a different host. This may indicate that an attacker has captured and
relayed Kerberos authentication material for the server's computer account to execute code on behalf of the
compromised system.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Kerberos Relay Attack against a Computer Account"
references = [
    "https://github.com/p0dalirius/windows-coerced-authentication-methods",
    "https://www.thehacker.recipes/a-d/movement/mitm-and-coerced-authentications",
    "https://www.synacktiv.com/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025",
    "https://blog.redteam-pentesting.de/2025/reflective-kerberos-relay-attack/",
    "https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html",
    "https://github.com/CICADA8-Research/RemoteKrbRelay/blob/main/README.md",
    "https://github.com/Orange-Cyberdefense/ocd-mindmaps/blob/main/excalimap/mindmap/ad/authenticated.md",
]
risk_score = 73
rule_id = "2d58f67c-156e-480a-a6eb-a698fd8197ff"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Active Directory",
    "Use Case: Active Directory Monitoring",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
sequence by winlog.computer_name, source.ip with maxspan=5s

/* Filter for an event that indicates coercion against known abused named pipes using an account that is not the host */
[file where host.os.type == "windows" and event.code : "5145" and 
    not startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    file.name : (
        "Spoolss", "netdfs", "lsarpc", "lsass", "netlogon", "samr", "efsrpc", "FssagentRpc",
        "eventlog", "winreg", "srvsvc", "dnsserver", "dhcpserver", "WinsPipe"
    )]

/* Detects a logon attempt using the Kerberos protocol resulting from the coercion coming from the same IP address */
[authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
    endswith~(user.name, "$") and winlog.logon.type : "network" and
    winlog.event_data.AuthenticationPackageName : "Kerberos" and

    /* Filter for a machine account that matches the hostname */
    startswith~(winlog.computer_name, substring(user.name, 0, -1)) and

    /* Verify if the Source IP belongs to the host */
    not endswith(string(source.ip), string(host.ip)) and
    source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1"]
'''

note = """## Triage and analysis

### Investigating Potential Kerberos Relay Attack against a Computer Account

#### Possible investigation steps

- What do the recovered source events prove about the relay sequence?
  - Why: Kerberos relay can reuse a coerced machine-account ticket when SPN selection or service protections allow it; reflective variants keep the same triage anchors: recovered pipe, `source.ip`, target dollar account, and Kerberos network auth.
  - Hint: Open Investigate in Timeline before interpreting the grouped alert; filter the alert window to `event.code` 5145 and 4624/4625 with the same `winlog.computer_name` and `source.ip`. In this step, read `file.name` from the recovered 5145 source event. If endpoint file telemetry is available for this host and time window, recover the matching `file.*` evidence before using it for interpretation or remediation. Treat it as optional corroboration, not the alert source.
  - Focus: recovered 5145 and 4624/4625 source events scoped by `winlog.computer_name`, `source.ip`, and `@timestamp`; in the 5145 event read `file.name` as the named-pipe value, then in the auth event read `winlog.event_data.AuthenticationPackageName`, `winlog.logon.type`, and `host.ip`.
  - Implication: escalate when a known coercion pipe such as Spoolss, netdfs, lsarpc, efsrpc, netlogon, srvsvc, or winreg is followed within seconds by a Kerberos network logon from the same non-target `source.ip`; lower suspicion only when the recovered pipe/auth outcome recurs for the same source, server, and machine account and outside topology or owner evidence verifies that exact infrastructure role.

- Does the authenticated machine account belong to the target server?
  - Focus: `winlog.event_data.TargetUserName` dollar-account prefix and `winlog.event_data.TargetDomainName` from the auth source event compared with `winlog.computer_name`.
  - Implication: escalate when the target account is the target server's dollar account and the source is not the server itself; if the account does not map to the target server, resolve whether the sequence paired unrelated events before using the alert for closure or escalation.

- Did the Kerberos authentication create a usable session or only a failed attempt?
  - Focus: auth source-event `event.code`, `winlog.event_data.Status`, `winlog.event_data.SubStatus`, `winlog.event_data.TargetLogonId`, and `source.ip`.
  - Implication: prioritize confirmed compromise review when a 4624 produces a `winlog.event_data.TargetLogonId`; keep failed-only 4625 sequences suspicious when the source or pipe is unexplained, but lower urgency when the status pattern is a recurring, bounded failure from recognized infrastructure.

- Does the source IP fit recognized infrastructure or relay-characteristic behavior?
  - Focus: surrounding Windows Security authentication events for `source.ip` and `winlog.computer_name`, reading `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, `winlog.logon.type`, `winlog.event_data.Status`, and `winlog.event_data.SubStatus`.
  - Hint: use same-source authentication events to see whether the source targets multiple machine accounts or alternates Kerberos successes and failures around the alert. $investigate_2
  - Implication: escalate when the source is rare for this server, targets multiple machine accounts, or alternates Kerberos successes and failures outside a verified infrastructure role; missing surrounding authentication telemetry is unresolved, not benign. Lower suspicion only when the same bounded source/server/account/outcome pattern recurs and outside topology or owner evidence verifies the exact role.

- If local evidence is suspicious or unresolved, is this part of broader relay activity?
  - Focus: related alerts for `source.ip` that show additional coercion or machine-account Kerberos relay. $investigate_0
  - Hint: pivot target-server related alerts for service creation, persistence, or remote execution only when the source pivot is suspicious; missing related alerts narrows existing-alert scope only, not host activity. $investigate_1
  - Hint: for raw Windows Security scoping after a 4624, review follow-on Windows Security events on the same `winlog.computer_name` where `winlog.event_data.SubjectLogonId` matches the recovered `winlog.event_data.TargetLogonId`; filter within results for service creation, task creation, share access, or persistence if the result set is large. Missing follow-on events is unresolved unless that event coverage is confirmed. $investigate_3
  - Implication: expand scope when source history shows other coercion or machine-account Kerberos relay, or when target history shows follow-on service, persistence, or remote-execution alerts; keep containment local only when related alerts stay limited to the same explained infrastructure tuple.

- Based on the recovered evidence, what disposition is supported?
  - Focus: sequence integrity, target dollar-account identity, Kerberos outcome, source-fit tuple, and related-alert results.
  - Implication: escalate when the sequence is intact and unexplained, when successful machine-account Kerberos comes from an unrecognized source, or when related-alert evidence shows follow-on abuse; close only when recovered source events and supported recovery bind one exact recognized infrastructure workflow with no contradictory evidence; preserve and escalate when evidence conflicts or visibility is missing.

### False positive analysis

- Validated infrastructure peers or authorized relay/coercion testing are the narrow benign paths. Confirm by verifying the recovered source events align on the same `source.ip`, `winlog.computer_name`, target machine account in `winlog.event_data.TargetUserName`, Kerberos `winlog.event_data.AuthenticationPackageName`, network `winlog.logon.type`, bounded `winlog.event_data.Status`/`winlog.event_data.SubStatus`, and recovered pipe evidence for the same server/account/pipe/outcome tuple. If telemetry cannot explain the specific pipe, account, and outcome, do not close as benign.
- Use topology, owner, or test-plan confirmation only to verify the exact recovered tuple after source-event recovery. Before creating an exception, validate recurrence across prior alerts from this rule for the same source/server/account/pipe/outcome pattern. If this is the first confirmed benign occurrence, document it as a candidate exception and monitor before suppressing. Build exceptions from the full confirmed workflow pattern; avoid exceptions on `source.ip`, `winlog.computer_name`, or machine-account name alone.

### Response and remediation

- If confirmed benign, reverse any temporary containment and document the evidence that proved the workflow: `source.ip`, `winlog.computer_name`, target machine account, Kerberos network auth, bounded `winlog.event_data.Status`/`winlog.event_data.SubStatus`, and recovered pipe evidence. Create an exception only after the same full pattern recurs across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the alert export, Timeline source events, recovered pipe evidence, target machine-account identity, auth outcome, session identifier when present, and related-alert results before containment. Use reversible containment first: temporarily restrict SMB/RPC between `source.ip` and the affected server, or isolate the source host when its role tolerates isolation. Escalate to broader host or account action only if follow-on service, persistence, execution, or wider relay evidence appears.
- If confirmed malicious, preserve the same alert export, Timeline source events, recovered pipe evidence, target machine-account identity, auth outcome, session identifier when present, and related-alert results before action. Then contain the source host and restrict access to the affected `winlog.computer_name`; if direct containment is unavailable, hand off the preserved evidence set to the team that can act. Remove the coercion route, block the offending source path, and eradicate only services, scheduled tasks, dropped tools, or configuration changes confirmed during response.
- Rotate the affected computer-account secret and review adjacent delegated, service, or administrative credentials that could have been exposed through the relay path. Coordinate disruptive credential or host actions with identity and infrastructure owners when the target is a domain controller, cluster node, or other critical service.
- After containment, audit other servers reached from the same `source.ip` and retain Windows Security source events needed to reconstruct each source/server/account/pipe sequence.
- Post-incident hardening: before releasing containment for a reflective Kerberos relay path, validate the relevant CVE-2025-33073 fixes and SMB signing or service-specific signing/sealing/channel binding on the affected service tier. Restrict coercion-prone RPC and named-pipe exposure, then document the confirmed source/server/account/pipe pattern for future analysts and control owners.
"""

setup = """## Setup

The following Windows audit policies must be enabled to generate the events used by this rule:
- [Audit Logon](https://ela.st/audit-logon)
- [Audit Detailed File Share](https://ela.st/audit-detailed-file-share)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.code",
    "winlog.computer_name",
    "source.ip",
    "host.ip",
    "user.name",
    "file.name",
    "winlog.event_data.TargetUserName",
    "winlog.event_data.TargetDomainName",
    "winlog.event_data.AuthenticationPackageName",
    "winlog.logon.type",
    "winlog.event_data.Status",
    "winlog.event_data.SubStatus",
    "winlog.event_data.TargetLogonId",
    "winlog.event_data.SubjectLogonId",
]

[[transform.investigate]]
label = "Alerts associated with this source IP"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with this target server"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Authentication events from this source to this target"
description = ""
providers = [
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" },
    { excluded = false, field = "winlog.event_data.AuthenticationPackageName", queryType = "phrase", value = "Kerberos", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" },
    { excluded = false, field = "winlog.event_data.AuthenticationPackageName", queryType = "phrase", value = "Kerberos", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Follow-on Windows Security events for the Kerberos logon session"
description = ""
providers = [
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.TargetLogonId}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1187"
name = "Forced Authentication"
reference = "https://attack.mitre.org/techniques/T1187/"

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"

[[rule.threat.technique.subtechnique]]
id = "T1557.001"
name = "LLMNR/NBT-NS Poisoning and SMB Relay"
reference = "https://attack.mitre.org/techniques/T1557/001/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5s, correlated by source.ip, winlog.computer_name.

Stage 1: file

[file where host.os.type == "windows" and event.code : "5145" and
    not startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    file.name : (
        "Spoolss", "netdfs", "lsarpc", "lsass", "netlogon", "samr", "efsrpc", "FssagentRpc",
        "eventlog", "winreg", "srvsvc", "dnsserver", "dhcpserver", "WinsPipe"
    )]

Stage 2: authentication

[authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
    endswith~(user.name, "$") and winlog.logon.type : "network" and
    winlog.event_data.AuthenticationPackageName : "Kerberos" and
    startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    not endswith(string(source.ip), string(host.ip)) and
    source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codein
  • 4624 corpus 6 (elastic 3, kusto 3)
  • 4625 corpus 6 (elastic 3, kusto 3)
field:"EventID" kind:in
event.codewildcard
  • 5145 corpus 19 (splunk 17, elastic 2)
field:"EventID" kind:wildcard value:"5145"
file.namewildcard
  • FssagentRpc corpus 3 (elastic 3)
  • Spoolss corpus 3 (elastic 3)
  • WinsPipe corpus 2 (elastic 2)
  • dhcpserver corpus 2 (elastic 2)
  • dnsserver corpus 2 (elastic 2)
  • efsrpc corpus 3 (elastic 3)
  • eventlog corpus 2 (elastic 2)
  • lsarpc corpus 3 (elastic 3)
  • lsass corpus 3 (elastic 3)
  • netdfs corpus 3 (elastic 3)
  • netlogon corpus 3 (elastic 3)
  • samr corpus 3 (elastic 3)
  • srvsvc corpus 2 (elastic 2)
  • winreg corpus 2 (elastic 2)
field:"file.name" kind:wildcard
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null
source.ipne
  • 127.0.0.1 corpus 22 (elastic 22)
  • ::1 corpus 20 (elastic 20)
field:"src_ip" kind:ne
user.nameends_with
  • $ corpus 5 (elastic 4, kusto 1)
field:"user" kind:ends_with value:"$"
winlog.computer_namestarts_with
  • substring(user.name, 0, (-1)) (expression)
field:"computer_name" kind:starts_with value:"substring(user.name, 0, (-1))"
winlog.event_data.AuthenticationPackageNamewildcard
  • Kerberos corpus 5 (sigma 2, elastic 2, splunk 1)
field:"AuthenticationPackageName" kind:wildcard value:"Kerberos"
winlog.logon.typewildcard
  • network corpus 30 (splunk 13, sigma 12, elastic 5)
field:"LogonType" kind:wildcard value:"network"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
winlog.computer_namestarts_withsubstring(user.name, 0, (-1))excludes:winlog.computer_name field:"winlog.computer_name" value:"substring(user.name, 0, (-1))"
source.ipends_withstring(host.ip)excludes:source.ip field:"source.ip" value:"string(host.ip)"

Potential Persistence via Emond

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of a suspicious child process of the Event Monitor Daemon (emond). Adversaries may abuse this service by writing a rule to execute commands when a defined event occurs, such as system start up or user authentication.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a suspicious child process of the Event Monitor Daemon (emond). Adversaries may abuse this
service by writing a rule to execute commands when a defined event occurs, such as system start up or user
authentication.
"""
id = "1cd247d8-00e8-4c62-b9ee-90cd1811460b"
license = "Elastic License v2"
name = "Potential Persistence via Emond"
os_list = ["macos"]
reference = [
    "https://www.elastic.co/security-labs/handy-elastic-tools-for-the-enthusiastic-detection-engineer",
    "https://www.xorrior.com/emond-persistence/",
]
version = "1.0.31"

query = '''
process where event.type == "start" and
 process.parent.name == "emond" and
 process.name like~ (
   "bash",
   "dash",
   "sh",
   "tcsh",
   "csh",
   "zsh",
   "ksh",
   "fish",
   "Python",
   "python*",
   "perl*",
   "php*",
   "osascript",
   "pwsh",
   "curl",
   "nscurl",
   "wget",
   "cp",
   "mv",
   "touch",
   "echo",
   "base64",
   "launchctl",
   "ruby*",
   "node*",
   "tcl*")
'''

min_endpoint_version = "8.10.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.014"
name = "Emond"
reference = "https://attack.mitre.org/techniques/T1546/014/"



[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[internal]
min_endpoint_version = "8.10.2"

Stages and Predicates

Stage 1: process

process where event.type == "start" and
 process.parent.name == "emond" and
 process.name like~ (
   "bash",
   "dash",
   "sh",
   "tcsh",
   "csh",
   "zsh",
   "ksh",
   "fish",
   "Python",
   "python*",
   "perl*",
   "php*",
   "osascript",
   "pwsh",
   "curl",
   "nscurl",
   "wget",
   "cp",
   "mv",
   "touch",
   "echo",
   "base64",
   "launchctl",
   "ruby*",
   "node*",
   "tcl*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.namewildcard
  • Python
  • base64
  • bash
  • cp
  • csh
  • curl
  • dash
  • echo
  • fish
  • ksh
  • launchctl
  • mv
  • node*
  • nscurl
  • osascript
  • perl*
  • php*
  • pwsh
  • python*
  • ruby*
  • sh
  • tcl*
  • tcsh
  • touch
  • wget
  • zsh
field:"process_basename" kind:wildcard
process.parent.nameeq
  • emond
field:"parent_process_basename" kind:eq value:"emond"

Potential Redis CONFIG SET SSH Authorized Key Injection

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects attempts to abuse Redis CONFIG SET commands to inject SSH authorized keys on Linux hosts. Attackers targeting unauthenticated Redis instances issue CONFIG SET dir to an SSH directory such as /root/.ssh, set the filename to authorized_keys via CONFIG SET dbfilename, write an attacker-controlled public key via SET, and call BGSAVE to flush it to disk, establishing persistent SSH access as root.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/06/11"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/06/11"

[rule]
author = ["Elastic"]
description = """
This rule detects attempts to abuse Redis CONFIG SET commands to inject SSH authorized keys on Linux hosts.
Attackers targeting unauthenticated Redis instances issue CONFIG SET dir to an SSH directory such as
/root/.ssh, set the filename to authorized_keys via CONFIG SET dbfilename, write an attacker-controlled
public key via SET, and call BGSAVE to flush it to disk, establishing persistent SSH access as root.
"""
from = "now-9m"
index = ["logs-network_traffic.redis*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Redis CONFIG SET SSH Authorized Key Injection"
note = """## Triage and analysis

### Investigating Potential Redis CONFIG SET SSH Authorized Key Injection

Redis's CONFIG SET command allows runtime reconfiguration of the server, including the working directory (`dir`) and database filename (`dbfilename`). Attackers targeting unauthenticated Redis instances exploit this to redirect BGSAVE output into `/root/.ssh/authorized_keys`, injecting their own SSH public key and establishing persistent root shell access without credentials.

The full attack chain is:
1. `CONFIG SET dir /root/.ssh` — redirects the save path to the SSH directory
2. `CONFIG SET dbfilename authorized_keys` — sets the output filename
3. `SET key "\n\nssh-rsa ATTACKER_KEY\n\n"` — writes the public key with surrounding newlines
4. `BGSAVE` — flushes the in-memory dataset (including the injected key) to disk

A related variant targets cron persistence (`CONFIG SET dir /etc/cron.d`) for cryptominer deployment, as used by the RedisRaider campaign.

### Possible investigation steps

- Identify the source IP and determine whether it is an expected Redis client or an external/unknown address. Any external IP issuing CONFIG SET to an SSH directory should be treated as malicious.
- Check whether the destination Redis instance requires authentication (`requirepass` or ACL). Unauthenticated instances are the prerequisite for this attack.
- Review subsequent Redis commands from the same source IP for `SET` (key write) and `BGSAVE` (flush to disk), which complete the injection chain.
- Examine `/root/.ssh/authorized_keys` and other user SSH directories on the Redis host for unexpected or recently modified entries at or after the alert time.
- Check SSH login events on the Redis host for successful logins from unknown keys or source IPs shortly after the alert.
- Review outbound connections from the Redis host for lateral movement or C2 activity following a successful key injection.

### False positive analysis

- `CONFIG SET dir` is a legitimate administrative command, but pointing it to any `/.ssh` directory has no legitimate use case. A match on this pattern has an extremely low false positive rate.
- `CONFIG SET dbfilename authorized_keys` has no legitimate operational use. Any match should be investigated immediately.
- Automated deployment tooling (Ansible, Chef, Puppet) will never target SSH directories via Redis CONFIG SET — this combination is exclusively malicious.

### Response and remediation

- Immediately inspect `/root/.ssh/authorized_keys` and all user `~/.ssh/authorized_keys` files on the Redis host for unauthorized entries and remove them.
- Rotate SSH host keys and audit all active SSH sessions on the affected host.
- Require authentication on all Redis instances (`requirepass` or ACL). Unauthenticated Redis reachable from any network is the root cause.
- Restrict `CONFIG SET` permissions using Redis ACLs: `ACL SETUSER <user> -config`.
- Block inbound access to Redis port 6379 from untrusted networks at the host firewall or perimeter.
- Consider enabling Redis's protected mode, which rejects connections from non-loopback addresses when no authentication is configured.
"""
references = [
    "https://redis.io/docs/latest/operate/oss_and_stack/management/security/",
    "https://attack.mitre.org/techniques/T1098/004/",
    "https://attack.mitre.org/techniques/T1190/",
]
risk_score = 73
rule_id = "39ab0f66-efa0-4649-9c9c-8c64682f5fdd"
setup = """## Setup

This rule requires the Elastic **network_traffic** integration (Packetbeat via Elastic Agent) with the Redis
protocol module enabled.

### Enabling the Redis module

In the Elastic Agent `network_traffic` integration policy:
1. Add or confirm **Redis** in the protocols list with `enabled: true`.
2. Set **ports** to include `6379` (or the custom port your Redis instances listen on).
3. Deploy the sensor on the Redis host, on a SPAN/mirror port, or on a gateway that receives Redis traffic.

### TLS limitation

This rule requires unencrypted Redis traffic. Redis uses plaintext by default (port 6379). If TLS is configured,
Packetbeat cannot inspect the payload without TLS decryption.
"""
severity = "high"
tags = [
    "Domain: Network",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Initial Access",
    "Data Source: Network Packet Capture",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
network where data_stream.dataset == "network_traffic.redis" and
  (
    (
      network_traffic.redis.query like~ "*CONFIG SET dir*" and
      network_traffic.redis.query like~ "*/.ssh*"
    ) or
    (
      network_traffic.redis.query like~ "*CONFIG SET dbfilename*" and
      network_traffic.redis.query like~ "*authorized_keys*"
    )
  )
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.004"
name = "SSH Authorized Keys"
reference = "https://attack.mitre.org/techniques/T1098/004/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"

[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

Stages and Predicates

Stage 1: network

network where data_stream.dataset == "network_traffic.redis" and
  (
    (
      network_traffic.redis.query like~ "*CONFIG SET dir*" and
      network_traffic.redis.query like~ "*/.ssh*"
    ) or
    (
      network_traffic.redis.query like~ "*CONFIG SET dbfilename*" and
      network_traffic.redis.query like~ "*authorized_keys*"
    )
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • network_traffic.redis
field:"data_stream.dataset" kind:eq value:"network_traffic.redis"
network_traffic.redis.querywildcard
  • */.ssh*
  • *CONFIG SET dbfilename*
  • *CONFIG SET dir*
  • *authorized_keys*
field:"network_traffic.redis.query" kind:wildcard

Potential Reverse Shell via UDP

#
Status
production
Severity
medium
Sequence by
host.id, process.parent.pid, process.pid
Author
Elastic
Source
github.com/elastic/detection-rules

This detection rule identifies suspicious network traffic patterns associated with UDP reverse shell activity. This activity consists of a sample of an execve, socket and connect syscall executed by the same process, where the auditd.data.a0-1 indicate a UDP connection, ending with an egress connection event. An attacker may establish a Linux UDP reverse shell to bypass traditional firewall restrictions and gain remote access to a target system covertly.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/07/04"
integration = ["auditd_manager"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This detection rule identifies suspicious network traffic patterns associated with UDP reverse shell activity. This
activity consists of a sample of an execve, socket and connect syscall executed by the same process, where the
auditd.data.a0-1 indicate a UDP connection, ending with an egress connection event. An attacker may establish a Linux
UDP reverse shell to bypass traditional firewall restrictions and gain remote access to a target system covertly.
"""
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Reverse Shell via UDP"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Potential Reverse Shell via UDP

Reverse shells over UDP can be exploited by attackers to bypass firewalls and gain unauthorized access to systems. This technique leverages UDP's connectionless nature, making it harder to detect. Adversaries may use scripting languages or network tools to initiate these connections. The detection rule identifies suspicious processes executing network-related syscalls and egress connections, flagging potential reverse shell activity.

### Possible investigation steps

- Review the process details such as process.pid, process.parent.pid, and process.name to identify the specific process that triggered the alert and its parent process.
- Examine the command line arguments and environment variables associated with the suspicious process to understand its intended function and origin.
- Check the network connection details, including destination.ip and network.direction, to determine the external entity the process attempted to connect to and assess if it is a known malicious IP or domain.
- Investigate the user account associated with the process to determine if it has been compromised or if there are any signs of unauthorized access.
- Analyze historical logs for any previous instances of similar process executions or network connections to identify patterns or repeated attempts.
- Correlate the alert with other security events or alerts from the same host.id to gather additional context and assess the scope of potential compromise.

### False positive analysis

- Legitimate administrative scripts or tools may trigger the rule if they use UDP for valid network operations. Users can create exceptions for specific scripts or processes that are known to perform routine administrative tasks.
- Automated monitoring or network management tools that use UDP for health checks or status updates might be flagged. Identify these tools and exclude their process names or network patterns from the rule.
- Development or testing environments where developers frequently use scripting languages or network tools for legitimate purposes can cause false positives. Consider excluding specific host IDs or process names associated with these environments.
- Custom applications that use UDP for communication, especially if they are developed in-house, may be mistakenly identified. Review these applications and whitelist their process names or network behaviors if they are verified as safe.
- Network scanning or diagnostic tools that use UDP for troubleshooting can be misinterpreted as malicious. Ensure these tools are recognized and excluded from the detection rule if they are part of regular network maintenance activities.

### Response and remediation

- Immediately isolate the affected host from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified by the detection rule, particularly those associated with known reverse shell tools or scripting languages.
- Conduct a forensic analysis of the affected system to identify any additional indicators of compromise, such as unauthorized user accounts or modified system files.
- Review and update firewall rules to block outbound UDP traffic from unauthorized applications or processes, ensuring legitimate traffic is not disrupted.
- Reset credentials for any accounts accessed from the affected host, especially if they have administrative privileges.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if other systems may be affected.
- Implement enhanced monitoring and logging for similar suspicious activities, focusing on the execution of network-related syscalls and egress connections from scripting languages or network tools."""
references = [
    "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md",
    "https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
    "https://www.elastic.co/security-labs/linux-detection-engineering-with-auditd",
]
risk_score = 47
rule_id = "a5eb21b7-13cc-4b94-9fe2-29bb2914e037"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Auditbeat
- Auditd Manager

### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.

#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).

### Auditd Manager Integration Setup
The Auditd Manager Integration receives audit events from the Linux Audit Framework which is a part of the Linux kernel.
Auditd Manager provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system.

#### The following steps should be executed in order to add the Elastic Agent System integration "auditd_manager" on a Linux System:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Auditd Manager” and select the integration to see more details about it.
- Click “Add Auditd Manager”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “auditd manager” to an existing or a new agent policy, and deploy the agent on a Linux system from which auditd log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/auditd_manager).

#### Rule Specific Setup Note
Auditd Manager subscribes to the kernel and receives events as they occur without any additional configuration.
However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
- For this detection rule no additional audit rules are required to be added to the integration.
"""
severity = "medium"
tags = [
    "Data Source: Auditd Manager",
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sample by host.id, process.pid, process.parent.pid
  [process where host.os.type == "linux" and event.type == "start" and event.action == "executed" and process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    ) and
    not process.args in ("/var/www/MISP/app/Console/cake", "/var/www/MISP/app", "/usr/local/bin/wp")]
  [process where host.os.type == "linux" and auditd.data.syscall == "socket" and process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    ) and auditd.data.a1 == "2"]
  [network where host.os.type == "linux" and event.type == "start" and event.action == "connected-to" and
   process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    ) and network.direction == "egress" and destination.ip != null and
   not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")]
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"

[[rule.threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"

[[rule.threat.technique.subtechnique]]
id = "T1059.011"
name = "Lua"
reference = "https://attack.mitre.org/techniques/T1059/011/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"

[[rule.threat.technique]]
id = "T1095"
name = "Non-Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1095/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

Stages and Predicates

Ordered sequence: each step below must occur in order, correlated by host.id, process.parent.pid, process.pid.

Stage 1: process

not process.args in ("/usr/local/bin/wp", "/var/www/MISP/app", "/var/www/MISP/app/Console/cake") and event.action == "executed" and event.type == "start" and host.os.type == "linux" and wildcard~(process.name, "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*", "ruby", "openssl", "awk", "telnet", "lua*", "socat")

Stage 2: process

auditd.data.a1 == "2" and auditd.data.syscall == "socket" and host.os.type == "linux" and wildcard~(process.name, "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*", "ruby", "openssl", "awk", "telnet", "lua*", "socat")

Stage 3: network

not (cidrMatch(destination.ip, "127.0.0.0/8") or cidrMatch(destination.ip, "169.254.0.0/16") or cidrMatch(destination.ip, "224.0.0.0/4") or cidrMatch(destination.ip, "::1")) and destination.ip != null and event.action == "connected-to" and event.type == "start" and host.os.type == "linux" and network.direction == "egress" and wildcard~(process.name, "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*", "ruby", "openssl", "awk", "telnet", "lua*", "socat")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin/usr/local/bin/wp, /var/www/MISP/app, /var/www/MISP/app/Console/cakeexcludes:process.args field:"process.args" value:"/usr/local/bin/wp" field:"process.args" value:"/var/www/MISP/app" field:"process.args" value:"/var/www/MISP/app/Console/cake"
destination.ipcidr_match127.0.0.0/8, 169.254.0.0/16, 224.0.0.0/4, ::1excludes:destination.ip

Privilege Escalation via SUID/SGID

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies instances where a process is executed with user/group ID 0 (root), and a real user/group ID that is not 0. This is indicative of a process that has been granted SUID/SGID permissions, allowing it to run with elevated privileges. Attackers may leverage a misconfiguration for exploitation in order to escalate their privileges to root, or establish a backdoor for persistence.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/06/17"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/07/17"

[rule]
author = ["Elastic"]
description = """
Identifies instances where a process is executed with user/group ID 0 (root), and a real user/group ID that is not 0.
This is indicative of a process that has been granted SUID/SGID permissions, allowing it to run with elevated
privileges. Attackers may leverage a misconfiguration for exploitation in order to escalate their privileges to root, or
establish a backdoor for persistence.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Privilege Escalation via SUID/SGID"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Privilege Escalation via SUID/SGID

SUID/SGID are Unix/Linux permissions that allow users to execute files with the file owner's or group's privileges, often root. Adversaries exploit misconfigured SUID/SGID binaries to gain elevated access or persistence. The detection rule identifies processes running with root privileges but initiated by non-root users, flagging potential misuse of SUID/SGID permissions.

### Possible investigation steps

- Review the process details, including process.name and process.args, to understand the nature of the executed command and its intended function.
- Check the process.real_user.id and process.real_group.id to identify the non-root user or group that initiated the process, and assess whether this user should have access to execute such commands.
- Investigate the parent process (process.parent.name) to determine the origin of the execution and whether it aligns with expected behavior or indicates potential compromise.
- Examine the system logs and user activity around the time of the alert to identify any suspicious actions or patterns that could suggest privilege escalation attempts.
- Verify the SUID/SGID permissions of the flagged binary to ensure they are correctly configured and assess whether they have been altered or misconfigured.
- Cross-reference the process with known vulnerabilities or exploits associated with the specific binary or command to determine if it is being targeted for privilege escalation.

### False positive analysis

- Processes initiated by legitimate system maintenance tasks or scripts may trigger the rule. Review scheduled tasks and scripts to identify benign activities and consider excluding them from the rule.
- Some system utilities or applications may inherently require SUID/SGID permissions for normal operation. Verify the necessity of these permissions and exclude known safe applications from the rule.
- Development or testing environments often run processes with elevated privileges for debugging purposes. Identify these environments and apply exceptions to avoid false positives.
- Administrative tools or scripts executed by system administrators might appear as privilege escalation attempts. Ensure these are documented and excluded if they are part of routine administrative tasks.
- Processes with the parent name "spine" are already excluded, indicating a known benign pattern. Review similar patterns in your environment and apply similar exclusions where applicable.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the attacker.
- Terminate any suspicious processes identified by the detection rule that are running with elevated privileges but were initiated by non-root users.
- Conduct a thorough review of the SUID/SGID binaries on the affected system to identify and remove any unnecessary or misconfigured binaries that could be exploited for privilege escalation.
- Reset credentials and review access permissions for any accounts that may have been compromised or used in the attack to ensure they do not retain unauthorized elevated privileges.
- Apply security patches and updates to the operating system and all installed software to mitigate known vulnerabilities that could be exploited for privilege escalation.
- Implement enhanced monitoring and logging for SUID/SGID execution and privilege escalation attempts to detect and respond to similar threats in the future.
- Escalate the incident to the security operations team for further investigation and to assess the potential impact on other systems within the network."""
references = [
    "https://gtfobins.github.io/#+suid",
    "https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
]
risk_score = 47
rule_id = "28eb3afe-131d-48b0-a8fc-9784f3d54f3c"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Tactic: Persistence",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
  (process.user.id == "0" and process.real_user.id != "0") or
  (process.group.id == "0" and process.real_group.id != "0")
) and (
  process.name in (
    "aa-exec", "ab", "agetty", "alpine", "ar", "arj", "arp", "as", "ascii-xfr", "ash", "aspell",
    "atobm", "awk", "base32", "base64", "basenc", "basez", "bc", "bridge", "busctl",
    "busybox", "bzip2", "cabal", "capsh", "cat", "choom", "chown", "chroot", "clamscan", "cmp",
    "column", "comm", "cp", "cpio", "cpulimit", "csplit", "csvtool", "cupsfilter", "curl",
    "cut", "date", "dd", "debugfs", "dialog", "diff", "dig", "distcc", "dmsetup", "docker",
    "dosbox", "ed", "efax", "elvish", "emacs", "env", "eqn", "espeak", "expand", "expect", "file",
    "fish", "flock", "fmt", "fold", "gawk", "gcore", "gdb", "genie", "genisoimage", "gimp",
    "gtester", "gzip", "hd", "head", "hexdump", "highlight", "hping3", "iconv", "install",
    "ionice", "ispell", "jjs", "join", "jq", "jrunscript", "julia", "ksh", "ksshell", "kubectl",
    "ld.so", "less", "links", "logsave", "look", "lua", "make", "mawk", "minicom", "more",
    "mosquitto", "msgattrib", "msgcat", "msgconv", "msgfilter", "msgmerge", "msguniq", "multitime",
    "nasm", "nawk", "ncftp", "nice", "nl", "nm", "nmap", "node", "nohup", "ntpdate",
    "od", "openssl", "openvpn", "pandoc", "paste", "perf", "perl", "pexec", "pg", "php", "pidstat",
    "pr", "ptx", "python", "rc", "readelf", "restic", "rev", "rlwrap", "rsync", "rtorrent",
    "run-parts", "rview", "rvim", "sash", "scanmem", "sed", "setarch", "setfacl", "setlock", "shuf",
    "soelim", "softlimit", "sort", "sqlite3", "ss", "ssh-agent", "ssh-keygen", "ssh-keyscan",
    "sshpass", "start-stop-daemon", "stdbuf", "strace", "strings", "sysctl", "systemctl", "tac",
    "tail", "taskset", "tbl", "tclsh", "tee", "terraform", "tftp", "tic", "time", "timeout", "troff",
    "ul", "unexpand", "uniq", "unshare", "unsquashfs", "unzip", "update-alternatives", "uudecode",
    "uuencode", "vagrant", "varnishncsa", "view", "vigr", "vim", "vimdiff", "vipw", "w3m", "watch",
    "wc", "wget", "whiptail", "xdotool", "xmodmap", "xmore", "xxd", "xz", "yash", "zsh",
    "zsoelim"
  ) or
  (process.name like ".*" or process.executable like ("/tmp/.*", "/var/tmp/.*", "/dev/shm/.*", "/home/*"))  or 
  (process.name == "ip" and ((process.args == "-force" and process.args in ("-batch", "-b")) or (process.args == "exec"))) or
  (process.name == "find" and process.args in ("-exec", "-execdir")) or
  (process.name in ("bash", "csh", "dash") and process.args in ("-p", "-b")) or
  (process.name == "pkexec" and process.args_count == 1) or
  (process.name == "nft" and process.args in ("-f", "--file")) or
  (process.name == "xargs" and process.args like ("-a", "--arg-file=*"))
) and
not (
  process.parent.name == "spine" or
  (process.name == "sysctl" and process.args == "-n") or
  process.parent.executable in (
    "/usr/NX/bin/nxexec", "/opt/andrisoft/bin/WANmaintenance", "/usr/lib/vmware/bin/vmware-vmx",
    "/usr/bin/pamprivilegechange", "/usr/lib/hyper-v/bin/hv_kvp_daemon"
  ) or
  process.parent.command_line in ("runc init", "/opt/bitdefender-security-tools/bin/auctl") or
  process.args like ("/usr/bin/snmpwalk*", "/usr/bin/snmpbulkwalk*", "/usr/bin/snmpget*") or
  process.executable like ("/home/*/agent/*/bin/job-processor", "/u0?/install/APPS/*/webtier/ohs/bin/.apachectl")
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.001"
name = "Setuid and Setgid"
reference = "https://attack.mitre.org/techniques/T1548/001/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.001"
name = "Setuid and Setgid"
reference = "https://attack.mitre.org/techniques/T1548/001/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
  (process.user.id == "0" and process.real_user.id != "0") or
  (process.group.id == "0" and process.real_group.id != "0")
) and (
  process.name in (
    "aa-exec", "ab", "agetty", "alpine", "ar", "arj", "arp", "as", "ascii-xfr", "ash", "aspell",
    "atobm", "awk", "base32", "base64", "basenc", "basez", "bc", "bridge", "busctl",
    "busybox", "bzip2", "cabal", "capsh", "cat", "choom", "chown", "chroot", "clamscan", "cmp",
    "column", "comm", "cp", "cpio", "cpulimit", "csplit", "csvtool", "cupsfilter", "curl",
    "cut", "date", "dd", "debugfs", "dialog", "diff", "dig", "distcc", "dmsetup", "docker",
    "dosbox", "ed", "efax", "elvish", "emacs", "env", "eqn", "espeak", "expand", "expect", "file",
    "fish", "flock", "fmt", "fold", "gawk", "gcore", "gdb", "genie", "genisoimage", "gimp",
    "gtester", "gzip", "hd", "head", "hexdump", "highlight", "hping3", "iconv", "install",
    "ionice", "ispell", "jjs", "join", "jq", "jrunscript", "julia", "ksh", "ksshell", "kubectl",
    "ld.so", "less", "links", "logsave", "look", "lua", "make", "mawk", "minicom", "more",
    "mosquitto", "msgattrib", "msgcat", "msgconv", "msgfilter", "msgmerge", "msguniq", "multitime",
    "nasm", "nawk", "ncftp", "nice", "nl", "nm", "nmap", "node", "nohup", "ntpdate",
    "od", "openssl", "openvpn", "pandoc", "paste", "perf", "perl", "pexec", "pg", "php", "pidstat",
    "pr", "ptx", "python", "rc", "readelf", "restic", "rev", "rlwrap", "rsync", "rtorrent",
    "run-parts", "rview", "rvim", "sash", "scanmem", "sed", "setarch", "setfacl", "setlock", "shuf",
    "soelim", "softlimit", "sort", "sqlite3", "ss", "ssh-agent", "ssh-keygen", "ssh-keyscan",
    "sshpass", "start-stop-daemon", "stdbuf", "strace", "strings", "sysctl", "systemctl", "tac",
    "tail", "taskset", "tbl", "tclsh", "tee", "terraform", "tftp", "tic", "time", "timeout", "troff",
    "ul", "unexpand", "uniq", "unshare", "unsquashfs", "unzip", "update-alternatives", "uudecode",
    "uuencode", "vagrant", "varnishncsa", "view", "vigr", "vim", "vimdiff", "vipw", "w3m", "watch",
    "wc", "wget", "whiptail", "xdotool", "xmodmap", "xmore", "xxd", "xz", "yash", "zsh",
    "zsoelim"
  ) or
  (process.name like ".*" or process.executable like ("/tmp/.*", "/var/tmp/.*", "/dev/shm/.*", "/home/*"))  or 
  (process.name == "ip" and ((process.args == "-force" and process.args in ("-batch", "-b")) or (process.args == "exec"))) or
  (process.name == "find" and process.args in ("-exec", "-execdir")) or
  (process.name in ("bash", "csh", "dash") and process.args in ("-p", "-b")) or
  (process.name == "pkexec" and process.args_count == 1) or
  (process.name == "nft" and process.args in ("-f", "--file")) or
  (process.name == "xargs" and process.args like ("-a", "--arg-file=*"))
) and
not (
  process.parent.name == "spine" or
  (process.name == "sysctl" and process.args == "-n") or
  process.parent.executable in (
    "/usr/NX/bin/nxexec", "/opt/andrisoft/bin/WANmaintenance", "/usr/lib/vmware/bin/vmware-vmx",
    "/usr/bin/pamprivilegechange", "/usr/lib/hyper-v/bin/hv_kvp_daemon"
  ) or
  process.parent.command_line in ("runc init", "/opt/bitdefender-security-tools/bin/auctl") or
  process.args like ("/usr/bin/snmpwalk*", "/usr/bin/snmpbulkwalk*", "/usr/bin/snmpget*") or
  process.executable like ("/home/*/agent/*/bin/job-processor", "/u0?/install/APPS/*/webtier/ohs/bin/.apachectl")
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq-nexcludes:process.args field:"process.args" value:"-n"
process.nameeqsysctlexcludes:process.name field:"process.name" value:"sysctl"
process.argsstarts_with/usr/bin/snmpwalk, /usr/bin/snmpbulkwalk, /usr/bin/snmpgetexcludes:process.args field:"process.args" value:"/usr/bin/snmpwalk" field:"process.args" value:"/usr/bin/snmpbulkwalk" field:"process.args" value:"/usr/bin/snmpget"
process.executablewildcard/home/*/agent/*/bin/job-processor, /u0?/install/APPS/*/webtier/ohs/bin/.apachectlexcludes:process.executable field:"process.executable" value:"/home/*/agent/*/bin/job-processor" field:"process.executable" value:"/u0?/install/APPS/*/webtier/ohs/bin/.apachectl"
process.parent.command_linein/opt/bitdefender-security-tools/bin/auctl, runc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"/opt/bitdefender-security-tools/bin/auctl" field:"process.parent.command_line" value:"runc init"
process.parent.executablein/opt/andrisoft/bin/WANmaintenance, /usr/NX/bin/nxexec, /usr/bin/pamprivilegechange, /usr/lib/hyper-v/bin/hv_kvp_daemon, /usr/lib/vmware/bin/vmware-vmxexcludes:process.parent.executable
process.parent.nameeqspineexcludes:process.parent.name field:"process.parent.name" value:"spine"

SMTP to the Internet on Port 26/TCP

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects events that may indicate use of SMTP on TCP port 26 from an internal host to an external destination. This port is commonly used by several popular mail transfer agents to deconflict with the default SMTP port 25. This port has also been used by a malware family called BadPatch for command and control of Windows systems. The rule is scoped to outbound traffic (internal source to external destination) to focus on the command and control and exfiltration use cases, rather than benign internal mail relays or unrelated transit traffic observed by the sensor.

Known False Positives

  • Internal hosts that legitimately send mail to external mail transfer agents listening on TCP port 26 may cause false positives. Mail servers or applications with known external SMTP relays can be excluded by source or destination IP address as this is expected behavior.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["network_traffic", "panw", "fortinet_fortigate", "pfsense", "zeek", "corelight"]
maturity = "production"
updated_date = "2026/08/26"

[rule]
author = ["Elastic"]
description = """
This rule detects events that may indicate use of SMTP on TCP port 26 from an internal host to an external destination.
This port is commonly used by several popular mail transfer agents to deconflict with the default SMTP port 25. This
port has also been used by a malware family called BadPatch for command and control of Windows systems. The rule is
scoped to outbound traffic (internal source to external destination) to focus on the command and control and
exfiltration use cases, rather than benign internal mail relays or unrelated transit traffic observed by the sensor.
"""
false_positives = [
    """
    Internal hosts that legitimately send mail to external mail transfer agents listening on TCP port 26 may cause false
    positives. Mail servers or applications with known external SMTP relays can be excluded by source or destination IP
    address as this is expected behavior.
    """,
]
from = "now-9m"
index = ["logs-network_traffic.*", "logs-panw.panos*", "logs-fortinet_fortigate.log-*", "logs-pfsense.log-*", "logs-zeek.*", "logs-corelight.*"]
language = "kuery"
license = "Elastic License v2"
name = "SMTP to the Internet on Port 26/TCP"
references = [
    "https://unit42.paloaltonetworks.com/unit42-badpatch/",
    "https://isc.sans.edu/forums/diary/Next+up+whats+up+with+TCP+port+26/25564/",
]
risk_score = 21
rule_id = "d7e62693-aab9-4f66-a21a-3d79ecdd603d"
severity = "low"
tags = ["Tactic: Command and Control",
        "Tactic: Exfiltration",
        "Domain: Endpoint",
        "Use Case: Threat Detection",
        "Data Source: Corelight",
        "Data Source: Fortinet",
        "Data Source: PAN-OS",
        "Data Source: Network Traffic",
        "Data Source: pfSense",
        "Data Source: Zeek",
        "Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "query"

query = '''
(data_stream.dataset: (fortinet_fortigate.log or network_traffic.flow or zeek.smtp) or event.category:(network or network_traffic)) and
  network.transport:tcp and destination.port:26 and
  source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and
  not destination.ip:(10.0.0.0/8
    or 100.64.0.0/10
    or 127.0.0.0/8
    or 169.254.0.0/16
    or 172.16.0.0/12
    or 192.0.0.0/24
    or 192.0.0.0/29
    or 192.0.0.10/32
    or 192.0.0.170/32
    or 192.0.0.171/32
    or 192.0.0.8/32
    or 192.0.0.9/32
    or 192.0.2.0/24
    or 192.168.0.0/16
    or 192.175.48.0/24
    or 192.31.196.0/24
    or 192.52.193.0/24
    or 192.88.99.0/24
    or 198.18.0.0/15
    or 198.51.100.0/24
    or 203.0.113.0/24
    or 224.0.0.0/4
    or 240.0.0.0/4
    or "::1"
    or "FE80::/10"
    or "FF00::/8")
'''
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating SMTP to the Internet on Port 26/TCP

SMTP, typically operating on port 25, is crucial for email transmission. However, port 26 is often used to avoid conflicts or restrictions on port 25. Adversaries exploit this by using port 26 for covert command and control, as seen with the BadPatch malware. The detection rule identifies suspicious SMTP activity on port 26 originating from an internal host to an external destination, helping to uncover potential command and control or exfiltration while suppressing benign internal mail traffic.

### Possible investigation steps

- Review the network traffic logs to identify any unusual patterns or anomalies associated with TCP port 26, focusing on the event.dataset fields such as network_traffic.flow or zeek.smtp.
- Analyze the source and destination IP addresses involved in the alert to determine if they are known or associated with any previous suspicious activities.
- Check for any additional alerts or logs related to the same source or destination IP addresses to identify potential patterns or repeated attempts of communication on port 26.
- Investigate the context of the communication by examining the payload data, if available, to identify any indicators of compromise or malicious content.
- Correlate the findings with threat intelligence sources to determine if the IP addresses or domains are associated with known threat actors or malware, such as BadPatch.
- Assess the risk and impact on the affected systems by determining if any sensitive data or critical systems are involved in the communication on port 26.

### False positive analysis

- Legitimate mail transfer agents may use port 26 to avoid conflicts with port 25. Identify these agents and create exceptions in the detection rule to prevent unnecessary alerts.
- Some network configurations might reroute SMTP traffic to port 26 for load balancing or security reasons. Verify these configurations and whitelist known IP addresses or domains to reduce false positives.
- Internal testing or development environments might use port 26 for non-malicious purposes. Document these environments and exclude their traffic from triggering alerts.
- Certain email service providers may use port 26 as an alternative to port 25. Confirm these providers and adjust the rule to recognize their traffic as benign.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further command and control communication via port 26.
- Conduct a thorough scan of the isolated system using updated antivirus and anti-malware tools to identify and remove the BadPatch malware or any other malicious software.
- Review and analyze network logs to identify any other systems that may have communicated with the same command and control server, and isolate those systems as well.
- Change all passwords and credentials that may have been compromised or accessed by the affected system to prevent unauthorized access.
- Apply security patches and updates to the affected system and any other vulnerable systems to mitigate exploitation by similar threats.
- Monitor network traffic for any further suspicious activity on port 26 and other non-standard ports, adjusting firewall rules to block unauthorized SMTP traffic.
- Escalate the incident to the security operations center (SOC) or relevant cybersecurity team for further investigation and to ensure comprehensive threat eradication."""


[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"

[[rule.threat.technique.subtechnique]]
id = "T1071.003"
name = "Mail Protocols"
reference = "https://attack.mitre.org/techniques/T1071/003/"

[[rule.threat.technique]]
id = "T1571"
name = "Non-Standard Port"
reference = "https://attack.mitre.org/techniques/T1571/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"

[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"

Stages and Predicates

Stage 1: query

(data_stream.dataset: (fortinet_fortigate.log or network_traffic.flow or zeek.smtp) or event.category:(network or network_traffic)) and
  network.transport:tcp and destination.port:26 and
  source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) and
  not destination.ip:(10.0.0.0/8
    or 100.64.0.0/10
    or 127.0.0.0/8
    or 169.254.0.0/16
    or 172.16.0.0/12
    or 192.0.0.0/24
    or 192.0.0.0/29
    or 192.0.0.10/32
    or 192.0.0.170/32
    or 192.0.0.171/32
    or 192.0.0.8/32
    or 192.0.0.9/32
    or 192.0.2.0/24
    or 192.168.0.0/16
    or 192.175.48.0/24
    or 192.31.196.0/24
    or 192.52.193.0/24
    or 192.88.99.0/24
    or 198.18.0.0/15
    or 198.51.100.0/24
    or 203.0.113.0/24
    or 224.0.0.0/4
    or 240.0.0.0/4
    or "::1"
    or "FE80::/10"
    or "FF00::/8")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipin10.0.0.0/8, 100.64.0.0/10, 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.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.0.8/32, 192.0.0.9/32, 192.0.2.0/24, 192.168.0.0/16, 192.175.48.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.88.99.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::/8excludes:destination.ip

Spike in Network Traffic To a Country

#
Status
production
Severity
low
Author
Elastic
Source
github.com/elastic/detection-rules

A machine learning job detected an unusually large spike in network activity to one destination country in the network logs. This could be due to unusually large amounts of reconnaissance or enumeration traffic. Data exfiltration activity may also produce such a surge in traffic to a destination country that does not normally appear in network traffic or business workflows. Malware instances and persistence mechanisms may communicate with command-and-control (C2) infrastructure in their country of origin, which may be an unusual destination country for the source network.

Known False Positives

  • Business workflows that occur very occasionally, and involve an unusual surge in network traffic to one destination country, can trigger this alert. A new business workflow or a surge in business activity in a particular country may trigger this alert. Business travelers who roam to many countries for brief periods may trigger this alert if they engage in volumetric network activity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2021/04/05"
integration = ["endpoint", "network_traffic"]
maturity = "production"
updated_date = "2026/07/27"

[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job detected an unusually large spike in network activity to one destination country in the network
logs. This could be due to unusually large amounts of reconnaissance or enumeration traffic. Data exfiltration activity
may also produce such a surge in traffic to a destination country that does not normally appear in network traffic or
business workflows. Malware instances and persistence mechanisms may communicate with command-and-control (C2)
infrastructure in their country of origin, which may be an unusual destination country for the source network.
"""
false_positives = [
    """
    Business workflows that occur very occasionally, and involve an unusual surge in network traffic to one destination
    country, can trigger this alert. A new business workflow or a surge in business activity in a particular country may
    trigger this alert. Business travelers who roam to many countries for brief periods may trigger this alert if they
    engage in volumetric network activity.
    """,
]
from = "now-30m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "high_count_by_destination_country"
name = "Spike in Network Traffic To a Country"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Network Packet Capture

### Anomaly Detection Setup

Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

### Network Packet Capture Integration Setup
The Network Packet Capture integration sniffs network packets on a host and dissects known protocols. Monitoring the network traffic is critical to gaining observability and securing your environment — ensuring high levels of performance and security. The Network Packet Capture integration captures the network traffic between your application servers, decodes common application layer protocols and records the interesting fields for each transaction.

#### The following steps should be executed in order to add the Elastic Agent System integration "network_traffic" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Network Packet Capture” and select the integration to see more details about it.
- Click “Add Network Packet Capture”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “network_traffic” to an existing or a new agent policy, and deploy the agent on your system from which network log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/network_traffic).
"""
note = """## Triage and analysis

### Investigating Spike in Network Traffic To a Country

Monitoring network traffic for anomalies is a good methodology for uncovering various potentially suspicious activities. For example, data exfiltration or infected machines may communicate with a command-and-control (C2) server in another country your company doesn't have business with.

This rule uses a machine learning job to detect a significant spike in the network traffic to a country, which can indicate reconnaissance or enumeration activities, an infected machine being used as a bot in a DDoS attack, or potentially data exfiltration.

#### Possible investigation steps

- Identify the specifics of the involved assets, such as role, criticality, and associated users.
- Investigate other alerts associated with the involved assets during the past 48 hours.
- Examine the data available and determine the exact users and processes involved in those connections.
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Consider the time of day. If the user is a human (not a program or script), did the activity occurs during working hours?
- If this activity is suspicious, contact the account owner and confirm whether they are aware of it.

### False positive analysis

- Understand the context of the connections by contacting the asset owners. If this activity is related to a new business process or newly implemented (approved) technology, consider adding exceptions — preferably with a combination of user and source conditions.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
  - Remove and block malicious artifacts identified during triage.
- Consider implementing temporary network border rules to block or alert connections to the target country, if relevant.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "c7db5533-ca2a-41f6-a8b0-ee98abe0f573"
severity = "low"
tags = [
    "Data Source: Elastic Defend",
    "Data Source: Network Packet Capture",
    "Use Case: Threat Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Resources: Investigation Guide",
]
type = "machine_learning"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1041"
name = "Exfiltration Over C2 Channel"
reference = "https://attack.mitre.org/techniques/T1041/"

[[rule.threat.technique]]
id = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"

[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"

[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"

[[rule.threat.technique.subtechnique]]
id = "T1595.001"
name = "Scanning IP Blocks"
reference = "https://attack.mitre.org/techniques/T1595/001/"

[rule.threat.tactic]
id = "TA0043"
name = "Reconnaissance"
reference = "https://attack.mitre.org/tactics/TA0043/"

SSH Key Generated via ssh-keygen

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule identifies the creation of SSH keys using the ssh-keygen tool, which is the standard utility for generating SSH keys. Users often create SSH keys for authentication with remote services. However, threat actors can exploit this tool to move laterally across a network or maintain persistence by generating unauthorized SSH keys, granting them SSH access to systems.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/05/31"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2025/03/20"

[rule]
author = ["Elastic"]
description = """
This rule identifies the creation of SSH keys using the ssh-keygen tool, which is the standard utility for generating
SSH keys. Users often create SSH keys for authentication with remote services. However, threat actors can exploit this
tool to move laterally across a network or maintain persistence by generating unauthorized SSH keys, granting them SSH
access to systems.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*", "endgame-*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "SSH Key Generated via ssh-keygen"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating SSH Key Generated via ssh-keygen

SSH keys, created using the ssh-keygen tool, are essential for secure authentication in Linux environments. While typically used for legitimate access to remote systems, adversaries can exploit this by generating unauthorized keys, enabling lateral movement or persistence. The detection rule identifies suspicious key creation by monitoring specific directories and actions, helping to flag potential misuse by threat actors.

### Possible investigation steps

- Review the alert details to identify the specific file path and name where the SSH key was created, focusing on directories like "/home/*/.ssh/*", "/root/.ssh/*", and "/etc/ssh/*".
- Check the user account associated with the SSH key creation event to determine if the action aligns with expected behavior for that user.
- Investigate the process execution context by examining the process tree and parent processes of "/usr/bin/ssh-keygen" to identify any potentially suspicious activity leading to the key generation.
- Analyze recent login and access logs for the user and system involved to detect any unusual or unauthorized access patterns.
- Correlate the event with other security alerts or logs to identify if there are signs of lateral movement or persistence tactics being employed by a threat actor.
- Verify the legitimacy of the SSH key by consulting with the system owner or user to confirm if the key creation was authorized and necessary.

### False positive analysis

- Routine administrative tasks may trigger the rule when system administrators generate SSH keys for legitimate purposes. To manage this, create exceptions for specific user accounts or directories known to be used by trusted administrators.
- Automated scripts or configuration management tools that regularly generate SSH keys for system provisioning or maintenance can cause false positives. Identify these scripts and exclude their associated processes or file paths from the rule.
- Development environments where developers frequently create SSH keys for testing or deployment purposes might be flagged. Consider excluding directories or user accounts associated with these environments to reduce noise.
- Backup or recovery processes that involve SSH key generation can also trigger alerts. Review these processes and exclude relevant file paths or processes to prevent unnecessary alerts.
- Security tools or monitoring solutions that simulate SSH key generation for testing or validation purposes may be mistakenly flagged. Identify these tools and add exceptions for their activities to avoid false positives.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement.
- Revoke any unauthorized SSH keys found in the monitored directories (/home/*/.ssh/*, /root/.ssh/*, /etc/ssh/*) to cut off access for threat actors.
- Conduct a thorough review of user accounts and SSH key pairs on the affected system to identify and remove any unauthorized accounts or keys.
- Reset passwords and regenerate SSH keys for legitimate users to ensure that compromised credentials are not reused.
- Monitor network traffic and system logs for any signs of further unauthorized access attempts or suspicious activity related to SSH.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine the scope of the breach.
- Implement additional monitoring and alerting for SSH key generation activities across the network to enhance detection of similar threats in the future."""
references = ["https://www.elastic.co/security-labs/primer-on-persistence-mechanisms"]
risk_score = 21
rule_id = "7df3cb8b-5c0c-4228-b772-bb6cd619053c"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Lateral Movement",
    "Tactic: Persistence",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
file where host.os.type == "linux" and event.action in ("creation", "file_create_event") and
process.executable == "/usr/bin/ssh-keygen" and file.path : ("/home/*/.ssh/*", "/root/.ssh/*", "/etc/ssh/*") and
not file.name : "known_hosts.*"
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.004"
name = "SSH Authorized Keys"
reference = "https://attack.mitre.org/techniques/T1098/004/"



[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"
[[rule.threat.technique.subtechnique]]
id = "T1021.004"
name = "SSH"
reference = "https://attack.mitre.org/techniques/T1021/004/"


[[rule.threat.technique]]
id = "T1563"
name = "Remote Service Session Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/"
[[rule.threat.technique.subtechnique]]
id = "T1563.001"
name = "SSH Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/001/"



[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.action in ("creation", "file_create_event") and
process.executable == "/usr/bin/ssh-keygen" and file.path : ("/home/*/.ssh/*", "/root/.ssh/*", "/etc/ssh/*") and
not file.name : "known_hosts.*"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • creation
  • file_create_event
field:"EventType" kind:in
file.pathwildcard
  • /etc/ssh/*
  • /home/*/.ssh/*
  • /root/.ssh/*
field:"TargetFilename" kind:wildcard
process.executableeq
  • /usr/bin/ssh-keygen
field:"Image" kind:eq value:"/usr/bin/ssh-keygen"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.namestarts_withknown_hosts.excludes:file.name field:"file.name" value:"known_hosts."

Suspicious Child Process via Azure VM CustomScript Extension

#
Status
production
Severity
medium
Time window
1m
Sequence by
host.id, process.Ext.ancestry, process.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a suspicious process executing as a descendant of the Azure VM CustomScript extension handler (CustomScriptHandler.exe) on a Windows host. The Azure CustomScript extension runs an attacker-supplied script with high privilege (SYSTEM) via the guest agent, and is a common cloud-to-host code-execution and persistence primitive. Because the extension's resource name is attacker-controlled and absent from on-host telemetry, this rule anchors on the type-bearing handler binary ('Microsoft.Compute.CustomScriptExtension...\CustomScriptHandler.exe') rather than the spoofable extension name, making it resistant to renaming. CustomScript legitimately launches PowerShell and cmd, so the rule fires only when the descendant is an execution-proxy, download, or discovery LOLBin, or PowerShell exhibiting suspicious tradecraft.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/06/17"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/06/17"

[rule]
author = ["Elastic"]
description = """
Identifies a suspicious process executing as a descendant of the Azure VM CustomScript extension handler
(CustomScriptHandler.exe) on a Windows host. The Azure CustomScript extension runs an attacker-supplied script with high
privilege (SYSTEM) via the guest agent, and is a common cloud-to-host code-execution and persistence primitive. Because
the extension's resource name is attacker-controlled and absent from on-host telemetry, this rule anchors on the
type-bearing handler binary ('Microsoft.Compute.CustomScriptExtension\\...\\CustomScriptHandler.exe') rather than the
spoofable extension name, making it resistant to renaming. CustomScript legitimately launches PowerShell and cmd, so the
rule fires only when the descendant is an execution-proxy, download, or discovery LOLBin, or PowerShell exhibiting
suspicious tradecraft.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Child Process via Azure VM CustomScript Extension"
note = """## Triage and analysis

### Investigating Suspicious Child Process via Azure VM CustomScript Extension

The Azure CustomScript extension executes a script as SYSTEM via the guest agent. The extension's resource name is
attacker-controlled and not present on the host, so this rule anchors on the handler binary path
(`Microsoft.Compute.CustomScriptExtension\\...\\CustomScriptHandler.exe`), which is rename-proof, and alerts when a
LOLBin or suspicious PowerShell runs anywhere in its process tree.

### Possible investigation steps

- Review the full process tree from `CustomScriptHandler.exe` to the alerting process, including `process.command_line`
  and `process.args`.
- Identify the descendant: execution proxies (`mshta`, `regsvr32`, `rundll32`, `installutil`, `msbuild`), download tools
  (`certutil`, `bitsadmin`), script hosts (`wscript`, `cscript`), or discovery utilities (`whoami`, `net`, `nltest`,
  `wmic`) are not expected children of a benign CustomScript payload.
- Correlate with the control-plane event: a `MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE` in
  `logs-azure.activitylogs-*` for this host around the same time, and the acting principal/source behind it.
- Retrieve the extension's settings/protectedSettings from the VM (the activity log does not contain the script body) to
  assess intent.
- Pivot on the host for credential access, new local accounts, persistence, or outbound C2 following the execution.
- Review who deployed the extension (Entra sign-in logs and RBAC for the principal in the correlated activity log event).

### False positive analysis

- Infrastructure-as-code and configuration-management scripts deployed via CustomScript may legitimately run discovery
  utilities (`whoami`, `net`, `nltest`, `systeminfo`, `wmic`, `tasklist`, `arp`) for bootstrap or inventory. If the
  activity recurs from known automation, baseline it and exclude by `process.command_line`/`process.args`.
- Software installation and bootstrapping via CustomScript can invoke `msbuild`, `installutil`, `regsvr32`, `regasm`,
  `regsvcs`, `certutil`, or `bitsadmin` to build, register, or download legitimate components. Verify the target
  file/URL and, if benign, scope the exclusion to the specific command or signed binary rather than the whole LOLBin.
- Legitimate setup scripts (DSC bootstrap, agent installers) may use PowerShell download cradles
  (`Invoke-WebRequest`, `DownloadString`, `-EncodedCommand`) against trusted internal or Microsoft endpoints. Confirm
  the destination host and content before excluding, and exclude by the specific command line, not by host.
- A known automation principal deploying the extension from expected corporate egress (corroborated by the correlated
  `MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE` and an approved change) lowers confidence, but still review the
  executed content. Prefer narrow, command- or argument-scoped exclusions over broad host or LOLBin exclusions, since
  the same execution chain is exactly what an attacker abuses.

### Response and remediation

- If unauthorized, remove the extension, isolate the host, rotate credentials reachable from it, and review RBAC on the affected subscription/resource group.
"""
references = [
    "https://blog.pwnedlabs.io/diving-deep-into-azure-vm-attack-vectors",
    "https://www.sysdig.com/blog/the-expendable-extension-name-azure-vmaccess-naming-chaos-password-resets-and-a-detection-gap",
    "https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows",
]
risk_score = 47
rule_id = "b4d4f0fb-908e-4cd1-ac8f-795c0433db0a"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by host.id with maxspan=1m
  /* Azure CustomScript extension handler */
  [process where host.os.type == "windows" and event.type == "start" and
     (process.name : "CustomScriptHandler.exe" or
      process.executable : "?:\\Packages\\Plugins\\*CustomScript*\\*\\CustomScriptHandler.exe")] by process.entity_id
  /* Abused LOLBin / suspicious PowerShell anywhere in its tree */
  [process where host.os.type == "windows" and event.type == "start" and
   (
     process.name : ("mshta.exe", "regsvr32.exe", "rundll32.exe", "installutil.exe", "msbuild.exe", "regasm.exe",
                     "regsvcs.exe", "wscript.exe", "cscript.exe", "bitsadmin.exe", "nltest.exe", "whoami.exe",
                     "net.exe", "net1.exe", "wmic.exe", "systeminfo.exe", "quser.exe", "arp.exe", "tasklist.exe") or
     (process.name : "certutil.exe" and process.args : ("*urlcache*", "*-decode*", "*-encode*")) or
     (process.name : ("powershell.exe", "pwsh.exe") and
      process.command_line : ("*-enc*", "*EncodedCommand*", "*FromBase64String*", "*DownloadString*", "*DownloadFile*",
                              "*Invoke-Expression*", "*IEX *", "*IEX(*", "*|IEX*", "*-w hidden*", "*WindowStyle Hidden*",
                              "*Net.WebClient*", "*Invoke-WebRequest*", "*Start-BitsTransfer*"))
   )] by process.Ext.ancestry
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1651"
name = "Cloud Administration Command"
reference = "https://attack.mitre.org/techniques/T1651/"

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by host.id, process.Ext.ancestry, process.entity_id.

Stage 1: process

[process where host.os.type == "windows" and event.type == "start" and
     (process.name : "CustomScriptHandler.exe" or
      process.executable : "?:\\Packages\\Plugins\\*CustomScript*\\*\\CustomScriptHandler.exe")] by process.entity_id

Stage 2: process

[process where host.os.type == "windows" and event.type == "start" and
   (
     process.name : ("mshta.exe", "regsvr32.exe", "rundll32.exe", "installutil.exe", "msbuild.exe", "regasm.exe",
                     "regsvcs.exe", "wscript.exe", "cscript.exe", "bitsadmin.exe", "nltest.exe", "whoami.exe",
                     "net.exe", "net1.exe", "wmic.exe", "systeminfo.exe", "quser.exe", "arp.exe", "tasklist.exe") or
     (process.name : "certutil.exe" and process.args : ("*urlcache*", "*-decode*", "*-encode*")) or
     (process.name : ("powershell.exe", "pwsh.exe") and
      process.command_line : ("*-enc*", "*EncodedCommand*", "*FromBase64String*", "*DownloadString*", "*DownloadFile*",
                              "*Invoke-Expression*", "*IEX *", "*IEX(*", "*|IEX*", "*-w hidden*", "*WindowStyle Hidden*",
                              "*Net.WebClient*", "*Invoke-WebRequest*", "*Start-BitsTransfer*"))
   )] by process.Ext.ancestry

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argswildcard
  • *-decode*
  • *-encode*
  • *urlcache*
field:"process.args" kind:wildcard
process.command_linewildcard
  • *-enc* corpus 3 (sigma 2, elastic 1)
  • *-w hidden*
  • *DownloadFile* corpus 5 (sigma 4, elastic 1)
  • *DownloadString* corpus 8 (sigma 7, elastic 1)
  • *EncodedCommand* corpus 2 (sigma 1, elastic 1)
  • *FromBase64String* corpus 15 (sigma 9, elastic 4, splunk 2)
  • *IEX * corpus 7 (sigma 6, elastic 1)
  • *IEX(* corpus 4 (sigma 3, elastic 1)
  • *Invoke-Expression* corpus 5 (sigma 4, elastic 1)
  • *Invoke-WebRequest* corpus 13 (sigma 10, elastic 3)
  • *Net.WebClient* corpus 3 (sigma 2, elastic 1)
  • *Start-BitsTransfer* corpus 5 (sigma 3, elastic 1, splunk 1)
  • *WindowStyle Hidden*
  • *|IEX*
field:"CommandLine" kind:wildcard
process.executablewildcard
  • ?:\Packages\Plugins\*CustomScript*\*\CustomScriptHandler.exe
field:"Image" kind:wildcard value:"?:\Packages\Plugins\*CustomScript*\*\CustomScriptHandler.exe"
process.namewildcard
  • CustomScriptHandler.exe corpus 2 (elastic 1, kusto 1)
  • arp.exe corpus 10 (elastic 8, splunk 1, kusto 1)
  • bitsadmin.exe corpus 25 (elastic 22, splunk 2, kusto 1)
  • certutil.exe corpus 45 (elastic 39, splunk 6)
  • cscript.exe corpus 68 (elastic 66, splunk 2)
  • installutil.exe corpus 36 (elastic 32, splunk 4)
  • msbuild.exe corpus 39 (elastic 36, splunk 3)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • net.exe corpus 30 (elastic 27, splunk 2, kusto 1)
  • net1.exe corpus 40 (elastic 21, splunk 19)
  • nltest.exe corpus 12 (elastic 10, splunk 2)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
  • pwsh.exe corpus 78 (elastic 49, splunk 29)
  • quser.exe corpus 10 (elastic 9, splunk 1)
  • regasm.exe corpus 25 (elastic 24, splunk 1)
  • regsvcs.exe corpus 22 (elastic 21, splunk 1)
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
  • systeminfo.exe corpus 10 (elastic 10)
  • tasklist.exe corpus 11 (elastic 11)
  • whoami.exe corpus 14 (elastic 11, splunk 2, kusto 1)
  • wmic.exe corpus 66 (elastic 39, splunk 27)
  • wscript.exe corpus 84 (elastic 82, splunk 1, kusto 1)
field:"process_basename" kind:wildcard

Suspicious MS Office Execution via DCOM

#
Time window
1m
Sequence by
user.id
Source
github.com/elastic/protections-artifacts

Identifies suspicious modification of the Microsoft Office AccessVBOM security setting followed by the execution of another Office process instance via DCOM. This may indicate an attempt to evade detection via suspicious process tree.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access
Persistence
Defense Impairment

Rule Body

[rule]
description = """
Identifies suspicious modification of the Microsoft Office AccessVBOM security setting followed by the execution of
another Office process instance via DCOM. This may indicate an attempt to evade detection via suspicious process tree.
"""
id = "6a714747-2671-4523-b233-744f119949b6"
license = "Elastic License v2"
name = "Suspicious MS Office Execution via DCOM"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/blog/playing-defense-against-gamaredon-group",
    "https://stigviewer.com/stig/microsoft_powerpoint_2007/2014-04-03/finding/V-17522",
]
version = "1.0.31"

query = '''
sequence by user.id with maxspan=1m
   [registry where event.type == "change" and
    registry.path :
          ("HKEY_USERS\\S-1-5-21-*\\SOFTWARE\\Microsoft\\Office\\*\\Security\\AccessVBOM",
           "HKEY_USERS\\S-1-12-1-*\\SOFTWARE\\Microsoft\\Office\\*\\Security\\AccessVBOM") and
    registry.data.strings == "1"]
   [process where event.action == "start" and
    (process.parent.name :("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
     process.parent.args : "-Embedding") and
    not (process.executable : ("?:\\Windows\\System32\\WerFault.exe", "?:\\Windows\\SysWOW64\\WerFault.exe") and process.args : "-u" and process.args : "-p") and
    not (process.pe.original_file_name == "ItSukurti.exe" and process.executable : "?:\\SamExpert\\ItSukurti.exe") and
    not (process.executable : "?:\\WINDOWS\\splwow64.exe" and process.args : "8192") and
    not (process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe") and process.code_signature.trusted == true) and
    not (process.code_signature.subject_name : ("Essential Objects, Inc.", "REFINITIV US LLC") and process.code_signature.trusted == true)]
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"


[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by user.id.

Stage 1: registry

[registry where event.type == "change" and
    registry.path :
          ("HKEY_USERS\\S-1-5-21-*\\SOFTWARE\\Microsoft\\Office\\*\\Security\\AccessVBOM",
           "HKEY_USERS\\S-1-12-1-*\\SOFTWARE\\Microsoft\\Office\\*\\Security\\AccessVBOM") and
    registry.data.strings == "1"]

Stage 2: process

[process where event.action == "start" and
    (process.parent.name :("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
     process.parent.args : "-Embedding") and
    not (process.executable : ("?:\\Windows\\System32\\WerFault.exe", "?:\\Windows\\SysWOW64\\WerFault.exe") and process.args : "-u" and process.args : "-p") and
    not (process.pe.original_file_name == "ItSukurti.exe" and process.executable : "?:\\SamExpert\\ItSukurti.exe") and
    not (process.executable : "?:\\WINDOWS\\splwow64.exe" and process.args : "8192") and
    not (process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe") and process.code_signature.trusted == true) and
    not (process.code_signature.subject_name : ("Essential Objects, Inc.", "REFINITIV US LLC") and process.code_signature.trusted == true)]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
event.typeeq
  • change corpus 89 (elastic 89)
field:"event.type" kind:eq value:"change"
process.parent.argswildcard
  • -Embedding corpus 7 (elastic 7)
field:"process.parent.args" kind:wildcard value:"-Embedding"
process.parent.namewildcard
  • EXCEL.EXE corpus 28 (elastic 27, splunk 1)
  • MSACCESS.EXE corpus 12 (elastic 12)
  • POWERPNT.EXE corpus 23 (elastic 23)
  • WINWORD.EXE corpus 26 (elastic 26)
field:"parent_process_basename" kind:wildcard
registry.data.stringseq
  • 1 corpus 3 (elastic 2, kusto 1)
field:"Details" kind:eq value:"1"
registry.pathwildcard
  • HKEY_USERS\S-1-12-1-*\SOFTWARE\Microsoft\Office\*\Security\AccessVBOM
  • HKEY_USERS\S-1-5-21-*\SOFTWARE\Microsoft\Office\*\Security\AccessVBOM
field:"TargetObject" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq-pexcludes:process.args field:"process.args" value:"-p"
process.argseq-uexcludes:process.args field:"process.args" value:"-u"
process.executableeq?:\Windows\System32\WerFault.exe, ?:\Windows\SysWOW64\WerFault.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\System32\WerFault.exe" field:"process.executable" value:"?:\Windows\SysWOW64\WerFault.exe"
process.argseq8192excludes:process.args field:"process.args" value:"8192"
process.executableeq?:\WINDOWS\splwow64.exeexcludes:process.executable field:"process.executable" value:"?:\WINDOWS\splwow64.exe"
process.code_signature.subject_nameeqEssential Objects, Inc., REFINITIV US LLCexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Essential Objects, Inc." field:"process.code_signature.subject_name" value:"REFINITIV US LLC"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.executablewildcard?:\Program Files (x86)\*.exe, ?:\Program Files\*.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files (x86)\*.exe" field:"process.executable" value:"?:\Program Files\*.exe"
process.executableeq?:\SamExpert\ItSukurti.exeexcludes:process.executable field:"process.executable" value:"?:\SamExpert\ItSukurti.exe"
process.pe.original_file_nameeqItSukurti.exeexcludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"ItSukurti.exe"

Untrusted Document Opened via Microsoft Office

#
Time window
1m
Sequence by
process.entity_id, process.parent.entity_id
Source
github.com/elastic/protections-artifacts

Identifies the execution of Microsoft Office processes to open a document classified by Microsoft SmartScreen as originating from an unknown source followed by Microsoft Office spawning an unusual child process.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

[rule]
description = """
Identifies the execution of Microsoft Office processes to open a document classified by Microsoft SmartScreen as
originating from an unknown source followed by Microsoft Office spawning an unusual child process.
"""
id = "2887ca7c-40b9-4d04-ab9c-65a5c0428ab8"
license = "Elastic License v2"
name = "Untrusted Document Opened via Microsoft Office"
os_list = ["windows"]
reference = [
    "https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-smartscreen/microsoft-defender-smartscreen-overview",
]
version = "1.0.31"

query = '''
sequence with maxspan=1m
 [process where event.action == "start" and
  process.name : ("EXCEL.EXE", "WINWORD.EXE", "POWERPNT.EXE") and

  /* probably unknown or potentially unsafe to smartscreen files classification */
  process.Ext.token.security_attributes : "SMARTLOCKER://SMARTSCREENORIGINCLAIM" and

  /* Docs opened from file shares */
  not process.args : "\\\\*"] by process.entity_id

 [process where event.action == "start" and
  process.parent.name : ("EXCEL.EXE", "WINWORD.EXE", "POWERPNT.EXE") and

  /* unknow office doc spawns an unusual child */
  not process.executable :
              ("?:\\Program Files\\*.exe",
               "?:\\Program Files (x86)\\*.exe",
               "?:\\Windows\\System32\\WerFault.exe",
               "?:\\Windows\\SysWOW64\\WerFault.exe",
               "?:\\Windows\\System32\\wermgr.exe",
               "?:\\windows\\splwow64.exe",
               "?:\\Windows\\system32\\dwwin.exe",
               "?:\\Windows\\SysWOW64\\DWWIN.EXE",
               "?:\\Windows\\Microsoft.NET\\*\\csc.exe",
               "?:\\Windows\\system32\\verclsid.exe",
               "?:\\Windows\\SysWOW64\\verclsid.exe",
               "D:\\Microsoft office 2016\\office2016\\Office16\\*.EXE",
               "D:\\Programs\\Foxit Software\\Foxit PhantomPDF\\Plugins\\Creator\\FoxitProxyServer_Socket_PH.exe",
               "\\\\*",
               "\\Device\\Mup\\*",
               "?:\\Adobe\\Acrobat DC\\Acrobat\\AcroTray.exe") and
  not (process.name : "BrowserSubprocess.exe" and process.command_line : "*--type=gpu-process*--no-sandbox*") and
  not (process.code_signature.subject_name :
          ("Zhuhai Kingsoft Office Software Co., Ltd.",
           "Poll Everywhere, Inc.",
           "Xerox Corporation",
           "Mozilla Corporation",
           "Vivaldi Technologies AS",
           "成都艾斯莱德网络科技有限公司",
           "Tencent Technology(Shenzhen) Company Limited",
           "Beijing Sogou Technology Development Co., Ltd.",
           "Beijing Yundong Zhixiao Network Technology Co. , Ltd.",
           "Dell Incorporated",
           "sli.do s. r. o.",
           "CANON INC.",
           "TEAMDEV LTD.",
           "Canon Inc.",
           "HP Inc.",
           "SEIKO EPSON CORPORATION",
           "FOXIT SOFTWARE INC.",
           "Google LLC",
           "Brave Software, Inc.",
           "Opera Norway AS",
           "Bloomberg LP",
           "Microsoft Windows Hardware Compatibility Publisher",
           "Orpheus Technology Ltd",
           "Foxit Software Incorporated",
           "Samsung Electronics CO., LTD.",
           "REFINITIV US LLC",
           "WEPA, INC.",
           "Wolters Kluwer United States INC.") and
       process.code_signature.trusted == true) and
  not (process.name : "rundll32.exe" and
       process.args :
           ("?:\\WINDOWS\\system32\\spool\\DRIVERS\\x64\\*,MonitorPrintJobStatus",
            "ndfapi.dll,NdfRunDllDiagnoseWithAnswerFile",
            "?:\\windows\\system32\\spool\\DRIVERS\\x64\\3\\*.DLL,CheckDevice",
            "?:\\Program Files\\*",
            "?:\\Program Files (x86)\\*")) and
  not (process.pe.original_file_name : ("msedge.exe", "FileCoAuth.exe") and process.code_signature.trusted == true) and
  not process.hash.sha256 : 
             ("e68d9768f1d1c2ef2e614dec47e5f0719030073373533603f3e9a914b5607d85", 
              "ded86974860dd9802db04d92409c05e2ff8b3de7f172c957c34861bbad6a9af3",
              "4a21f9b556046a31878a3f44e1d210baee7663cc5f9d8e980f67e180a6dd3592",
              "bc1ec9584f749b1d264cf1ce040e98f96de680efd74a1dab2de53e8d481c5b79",
              "b72b18af7ed446db1630a2263c76fc3cbde6c189f88ea7ba4e42ecf61cb0ee8b",
              "28c69f2b353a8df70abef0e5f09e1d390ef88e79b08465bc21c0d9fdb3b61f0d",
              "4a06605651958c56e89a468f600c3322e3fdc97c8143bcfd1d8d1ebadb0920fb",
              "b20dff35c0aabb92f2e72d2236d33e3f0d9f150ad8206db9d56c642825775c25",
              "92fd0ed373796efdba340db4345c619d8fa811b90efdd400384bfbf8857f6d6c",
              "e86df8bba04d1d437eaaf913f8252cdee5f4534eae8e730a49ba22681a37e935",
              "083166e1cab8bceec2730682816fbb41be91356fe92bb45d1c860439ee0e52e6") and
  not (process.pe.original_file_name : ("Teams.exe", "msedgewebview2.exe", "BDEUNLOCK.EXE") and process.code_signature.trusted == true) and
  not (process.executable : "?:\\Windows\\Microsoft.NET\\Framework64\\*\\RegAsm.exe" and process.args : "?:\\Program Files (x86)\\Thomson Reuters\\*") and
  not (process.name : "cmd.exe" and process.command_line : "\"CMD.exe\" /C dotnet --list-runtimes")
  ] by process.parent.entity_id
'''

min_endpoint_version = "8.10.0"
reputation = true
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.

Stage 1: process

[process where event.action == "start" and
  process.name : ("EXCEL.EXE", "WINWORD.EXE", "POWERPNT.EXE") and
  process.Ext.token.security_attributes : "SMARTLOCKER://SMARTSCREENORIGINCLAIM" and
  not process.args : "\\\\*"] by process.entity_id

Stage 2: process

[process where event.action == "start" and
  process.parent.name : ("EXCEL.EXE", "WINWORD.EXE", "POWERPNT.EXE") and
  not process.executable :
              ("?:\\Program Files\\*.exe",
               "?:\\Program Files (x86)\\*.exe",
               "?:\\Windows\\System32\\WerFault.exe",
               "?:\\Windows\\SysWOW64\\WerFault.exe",
               "?:\\Windows\\System32\\wermgr.exe",
               "?:\\windows\\splwow64.exe",
               "?:\\Windows\\system32\\dwwin.exe",
               "?:\\Windows\\SysWOW64\\DWWIN.EXE",
               "?:\\Windows\\Microsoft.NET\\*\\csc.exe",
               "?:\\Windows\\system32\\verclsid.exe",
               "?:\\Windows\\SysWOW64\\verclsid.exe",
               "D:\\Microsoft office 2016\\office2016\\Office16\\*.EXE",
               "D:\\Programs\\Foxit Software\\Foxit PhantomPDF\\Plugins\\Creator\\FoxitProxyServer_Socket_PH.exe",
               "\\\\*",
               "\\Device\\Mup\\*",
               "?:\\Adobe\\Acrobat DC\\Acrobat\\AcroTray.exe") and
  not (process.name : "BrowserSubprocess.exe" and process.command_line : "*--type=gpu-process*--no-sandbox*") and
  not (process.code_signature.subject_name :
          ("Zhuhai Kingsoft Office Software Co., Ltd.",
           "Poll Everywhere, Inc.",
           "Xerox Corporation",
           "Mozilla Corporation",
           "Vivaldi Technologies AS",
           "成都艾斯莱德网络科技有限公司",
           "Tencent Technology(Shenzhen) Company Limited",
           "Beijing Sogou Technology Development Co., Ltd.",
           "Beijing Yundong Zhixiao Network Technology Co. , Ltd.",
           "Dell Incorporated",
           "sli.do s. r. o.",
           "CANON INC.",
           "TEAMDEV LTD.",
           "Canon Inc.",
           "HP Inc.",
           "SEIKO EPSON CORPORATION",
           "FOXIT SOFTWARE INC.",
           "Google LLC",
           "Brave Software, Inc.",
           "Opera Norway AS",
           "Bloomberg LP",
           "Microsoft Windows Hardware Compatibility Publisher",
           "Orpheus Technology Ltd",
           "Foxit Software Incorporated",
           "Samsung Electronics CO., LTD.",
           "REFINITIV US LLC",
           "WEPA, INC.",
           "Wolters Kluwer United States INC.") and
       process.code_signature.trusted == true) and
  not (process.name : "rundll32.exe" and
       process.args :
           ("?:\\WINDOWS\\system32\\spool\\DRIVERS\\x64\\*,MonitorPrintJobStatus",
            "ndfapi.dll,NdfRunDllDiagnoseWithAnswerFile",
            "?:\\windows\\system32\\spool\\DRIVERS\\x64\\3\\*.DLL,CheckDevice",
            "?:\\Program Files\\*",
            "?:\\Program Files (x86)\\*")) and
  not (process.pe.original_file_name : ("msedge.exe", "FileCoAuth.exe") and process.code_signature.trusted == true) and
  not process.hash.sha256 :
             ("e68d9768f1d1c2ef2e614dec47e5f0719030073373533603f3e9a914b5607d85",
              "ded86974860dd9802db04d92409c05e2ff8b3de7f172c957c34861bbad6a9af3",
              "4a21f9b556046a31878a3f44e1d210baee7663cc5f9d8e980f67e180a6dd3592",
              "bc1ec9584f749b1d264cf1ce040e98f96de680efd74a1dab2de53e8d481c5b79",
              "b72b18af7ed446db1630a2263c76fc3cbde6c189f88ea7ba4e42ecf61cb0ee8b",
              "28c69f2b353a8df70abef0e5f09e1d390ef88e79b08465bc21c0d9fdb3b61f0d",
              "4a06605651958c56e89a468f600c3322e3fdc97c8143bcfd1d8d1ebadb0920fb",
              "b20dff35c0aabb92f2e72d2236d33e3f0d9f150ad8206db9d56c642825775c25",
              "92fd0ed373796efdba340db4345c619d8fa811b90efdd400384bfbf8857f6d6c",
              "e86df8bba04d1d437eaaf913f8252cdee5f4534eae8e730a49ba22681a37e935",
              "083166e1cab8bceec2730682816fbb41be91356fe92bb45d1c860439ee0e52e6") and
  not (process.pe.original_file_name : ("Teams.exe", "msedgewebview2.exe", "BDEUNLOCK.EXE") and process.code_signature.trusted == true) and
  not (process.executable : "?:\\Windows\\Microsoft.NET\\Framework64\\*\\RegAsm.exe" and process.args : "?:\\Program Files (x86)\\Thomson Reuters\\*") and
  not (process.name : "cmd.exe" and process.command_line : "\"CMD.exe\" /C dotnet --list-runtimes")
  ] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.token.security_attributeswildcard
  • SMARTLOCKER://SMARTSCREENORIGINCLAIM corpus 2 (elastic 2)
field:"process.Ext.token.security_attributes" kind:wildcard value:"SMARTLOCKER://SMARTSCREENORIGINCLAIM"
process.namewildcard
  • EXCEL.EXE corpus 34 (elastic 34)
  • POWERPNT.EXE corpus 31 (elastic 31)
  • WINWORD.EXE corpus 35 (elastic 35)
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • EXCEL.EXE corpus 28 (elastic 27, splunk 1)
  • POWERPNT.EXE corpus 23 (elastic 23)
  • WINWORD.EXE corpus 26 (elastic 26)
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsstarts_with\\excludes:process.args field:"process.args" value:"\\"
process.argsstarts_with?:\Program Files (x86)\Thomson Reuters\excludes:process.args field:"process.args" value:"?:\Program Files (x86)\Thomson Reuters\"
process.executablewildcard?:\Windows\Microsoft.NET\Framework64\*\RegAsm.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\Microsoft.NET\Framework64\*\RegAsm.exe"
process.argswildcard?:\WINDOWS\system32\spool\DRIVERS\x64\*,MonitorPrintJobStatus, ndfapi.dll,NdfRunDllDiagnoseWithAnswerFile, ?:\windows\system32\spool\DRIVERS\x64\3\*.DLL,CheckDevice, ?:\Program Files\*, ?:\Program Files (x86)\*excludes:process.args
process.nameeqrundll32.exeexcludes:process.name field:"process.name" value:"rundll32.exe"
process.code_signature.subject_nameeqZhuhai Kingsoft Office Software Co., Ltd., Poll Everywhere, Inc., Xerox Corporation, Mozilla Corporation, Vivaldi Technologies AS, 成都艾斯莱德网络科技有限公司, Tencent Technology(Shenzhen) Company Limited, Beijing Sogou Technology Development Co., Ltd., Beijing Yundong Zhixiao Network Technology Co. , Ltd., Dell Incorporated, sli.do s. r. o., CANON INC., TEAMDEV LTD., Canon Inc., HP Inc., SEIKO EPSON CORPORATION, FOXIT SOFTWARE INC., Google LLC, Brave Software, Inc., Opera Norway AS, Bloomberg LP, Microsoft Windows Hardware Compatibility Publisher, Orpheus Technology Ltd, Foxit Software Incorporated, Samsung Electronics CO., LTD., REFINITIV US LLC, WEPA, INC., Wolters Kluwer United States INC.excludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.pe.original_file_nameeqTeams.exe, msedgewebview2.exe, BDEUNLOCK.EXEexcludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"Teams.exe" field:"process.pe.original_file_name" value:"msedgewebview2.exe" field:"process.pe.original_file_name" value:"BDEUNLOCK.EXE"
process.pe.original_file_nameeqmsedge.exe, FileCoAuth.exeexcludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"msedge.exe" field:"process.pe.original_file_name" value:"FileCoAuth.exe"
process.command_lineeq"CMD.exe" /C dotnet --list-runtimesexcludes:process.command_line
process.nameeqcmd.exeexcludes:process.name field:"process.name" value:"cmd.exe"
process.command_linewildcard*--type=gpu-process*--no-sandbox*excludes:process.command_line field:"process.command_line" value:"*--type=gpu-process*--no-sandbox*"
process.nameeqBrowserSubprocess.exeexcludes:process.name field:"process.name" value:"BrowserSubprocess.exe"
process.executablewildcard?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\System32\WerFault.exe, ?:\Windows\SysWOW64\WerFault.exe, ?:\Windows\System32\wermgr.exe, ?:\windows\splwow64.exe, ?:\Windows\system32\dwwin.exe, ?:\Windows\SysWOW64\DWWIN.EXE, ?:\Windows\Microsoft.NET\*\csc.exe, ?:\Windows\system32\verclsid.exe, ?:\Windows\SysWOW64\verclsid.exe, D:\Microsoft office 2016\office2016\Office16\*.EXE, D:\Programs\Foxit Software\Foxit PhantomPDF\Plugins\Creator\FoxitProxyServer_Socket_PH.exe, \\*, \Device\Mup\*, ?:\Adobe\Acrobat DC\Acrobat\AcroTray.exeexcludes:process.executable
process.hash.sha256eqe68d9768f1d1c2ef2e614dec47e5f0719030073373533603f3e9a914b5607d85, ded86974860dd9802db04d92409c05e2ff8b3de7f172c957c34861bbad6a9af3, 4a21f9b556046a31878a3f44e1d210baee7663cc5f9d8e980f67e180a6dd3592, bc1ec9584f749b1d264cf1ce040e98f96de680efd74a1dab2de53e8d481c5b79, b72b18af7ed446db1630a2263c76fc3cbde6c189f88ea7ba4e42ecf61cb0ee8b, 28c69f2b353a8df70abef0e5f09e1d390ef88e79b08465bc21c0d9fdb3b61f0d, 4a06605651958c56e89a468f600c3322e3fdc97c8143bcfd1d8d1ebadb0920fb, b20dff35c0aabb92f2e72d2236d33e3f0d9f150ad8206db9d56c642825775c25, 92fd0ed373796efdba340db4345c619d8fa811b90efdd400384bfbf8857f6d6c, e86df8bba04d1d437eaaf913f8252cdee5f4534eae8e730a49ba22681a37e935, 083166e1cab8bceec2730682816fbb41be91356fe92bb45d1c860439ee0e52e6excludes:process.hash.sha256

Untrusted File Execution via Microsoft Office

#
Time window
1m
Sequence by
file.path, process.executable, user.id
Source
github.com/elastic/protections-artifacts

Identifies the execution of an unsigned file written or modified by Microsoft Office processes.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

[rule]
description = "Identifies the execution of an unsigned file written or modified by Microsoft Office processes."
id = "bb23a662-2d75-4714-837d-4ec9c2e772a5"
license = "Elastic License v2"
name = "Untrusted File Execution via Microsoft Office"
os_list = ["windows"]
version = "1.0.34"

query = '''
sequence by user.id with maxspan=1m
  [file where event.action != "deletion" and
    (file.extension : ("exe", "com", "pif", "scr") or file.Ext.header_bytes : "4d5a*") and
    process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
    not file.path :
            (
              "?:\\Users\\*\\Downloads\\*",
              "?:\\Users\\*\\AppData\\Local\\Temp\\*-*-*-*\\*",
              "?:\\Program Files (x86)\\*",
              "?:\\Program Files\\*"
            )
    ] by file.path
  [process where event.action == "start" and
    process.parent.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
    not process.code_signature.trusted == true] by process.executable
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by file.path, process.executable, user.id.

Stage 1: file

[file where event.action != "deletion" and
    (file.extension : ("exe", "com", "pif", "scr") or file.Ext.header_bytes : "4d5a*") and
    process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
    not file.path :
            (
              "?:\\Users\\*\\Downloads\\*",
              "?:\\Users\\*\\AppData\\Local\\Temp\\*-*-*-*\\*",
              "?:\\Program Files (x86)\\*",
              "?:\\Program Files\\*"
            )
    ] by file.path

Stage 2: process

[process where event.action == "start" and
    process.parent.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
    not process.code_signature.trusted == true] by process.executable

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
event.actionne
  • deletion corpus 90 (elastic 90)
field:"EventType" kind:ne value:"deletion"
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
file.extensionwildcard
  • com corpus 16 (elastic 16)
  • exe corpus 32 (elastic 32)
  • pif corpus 18 (elastic 18)
  • scr corpus 17 (elastic 17)
field:"file.extension" kind:wildcard
process.namewildcard
  • EXCEL.EXE corpus 34 (elastic 34)
  • MSACCESS.EXE corpus 19 (elastic 19)
  • POWERPNT.EXE corpus 31 (elastic 31)
  • WINWORD.EXE corpus 35 (elastic 35)
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • EXCEL.EXE corpus 28 (elastic 27, splunk 1)
  • MSACCESS.EXE corpus 12 (elastic 12)
  • POWERPNT.EXE corpus 23 (elastic 23)
  • WINWORD.EXE corpus 26 (elastic 26)
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathwildcard?:\Users\*\Downloads\*, ?:\Users\*\AppData\Local\Temp\*-*-*-*\*, ?:\Program Files (x86)\*, ?:\Program Files\*excludes:file.path
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"

Back to all Elastic rules