mirror of
https://github.com/elastic/detection-rules
synced 2026-06-08 14:00:08 +00:00
[Rule Tuning] Windows High-Severity Rules Revamp - 10 (#6028)
* [Rule Tuning] Windows High-Severity Rules Revamp - 10
* ++
* Update defense_evasion_untrusted_driver_loaded.toml
* Update defense_evasion_untrusted_driver_loaded.toml
* Apply suggestion from @w0rk3r
(cherry picked from commit 2df45b2a6b)
This commit is contained in:
committed by
tradebot-elastic
parent
75d5364467
commit
bb58cd623f
@@ -2,96 +2,19 @@
|
||||
creation_date = "2023/01/27"
|
||||
integration = ["endpoint"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[transform]
|
||||
[[transform.osquery]]
|
||||
label = "Osquery - Retrieve All Non-Microsoft Drivers with Virustotal Link"
|
||||
query = """
|
||||
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
|
||||
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
|
||||
authenticode.path JOIN hash ON drivers.image = hash.path WHERE NOT (provider == "Microsoft" AND signed == "1")
|
||||
"""
|
||||
|
||||
[[transform.osquery]]
|
||||
label = "Osquery - Retrieve All Unsigned Drivers with Virustotal Link"
|
||||
query = """
|
||||
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
|
||||
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
|
||||
authenticode.path JOIN hash ON drivers.image = hash.path WHERE signed == "0"
|
||||
"""
|
||||
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies attempt to load an untrusted driver. Adversaries may modify code signing policies to enable execution of
|
||||
unsigned or self-signed code.
|
||||
Identifies an untrusted driver loaded by the Windows kernel. Adversaries may modify code signing policies to
|
||||
enable execution of unsigned or self-signed kernel code.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = ["logs-endpoint.events.library-*"]
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Untrusted Driver Loaded"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Untrusted Driver Loaded
|
||||
|
||||
Microsoft created the Windows Driver Signature Enforcement (DSE) security feature to prevent drivers with invalid signatures from loading and executing into the kernel (ring 0). DSE aims to protect systems by blocking attackers from loading malicious drivers on targets.
|
||||
|
||||
This protection is essential for maintaining system security. However, attackers or administrators can disable DSE and load untrusted drivers, which can put the system at risk. Therefore, it's important to keep this feature enabled and only load drivers from trusted sources to ensure system integrity and security.
|
||||
|
||||
This rule identifies an attempt to load an untrusted driver, which effectively means that DSE was disabled or bypassed. This can indicate that the system was compromised.
|
||||
|
||||
> **Note**:
|
||||
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Examine the driver loaded to identify potentially suspicious characteristics. The following actions can help you gain context:
|
||||
- Identify the path that the driver was loaded from. If you're using Elastic Defend, path information can be found in the `dll.path` field.
|
||||
- Examine the file creation and modification timestamps:
|
||||
- On Elastic Defend, those can be found in the `dll.Ext.relative_file_creation_time` and `dll.Ext.relative_file_name_modify_time` fields. The values are in seconds.
|
||||
- Search for file creation events sharing the same file name as the `dll.name` field and identify the process responsible for the operation.
|
||||
- Investigate any other abnormal behavior by the subject process, such as network connections, registry or file modifications, and any spawned child processes.
|
||||
- Use the driver SHA-256 (`dll.hash.sha256` field) hash value to search for the existence and reputation in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
|
||||
- Investigate other alerts associated with the user/host during the past 48 hours.
|
||||
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
|
||||
- Use Osquery to investigate the drivers loaded into the system.
|
||||
- $osquery_0
|
||||
- $osquery_1
|
||||
- Identify the driver's `Device Name` and `Service Name`.
|
||||
- Check for alerts from the rules specified in the `Related Rules` section.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- This activity should not happen legitimately. The security team should address any potential benign true positive (B-TP), as this configuration can put the user and the domain at risk.
|
||||
|
||||
### Related Rules
|
||||
|
||||
- First Time Seen Driver Loaded - df0fd41e-5590-4965-ad5e-cd079ec22fa9
|
||||
- Code Signing Policy Modification Through Registry - da7733b1-fe08-487e-b536-0a04c6d8b0cd
|
||||
- Code Signing Policy Modification Through Built-in tools - b43570de-a908-4f7f-8bdb-b2df6ffd8c80
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate the involved host to prevent further post-compromise behavior.
|
||||
- Disable and uninstall all suspicious drivers found in the system. This can be done via Device Manager. (Note that this step may require you to boot the system into Safe Mode.)
|
||||
- Remove the related services and registry keys found in the system. Note that the service will probably not stop if the driver is still installed.
|
||||
- This can be done via PowerShell `Remove-Service` cmdlet.
|
||||
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
|
||||
- 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.
|
||||
- Ensure that the Driver Signature Enforcement is enabled on the system.
|
||||
- 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.
|
||||
- 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://github.com/hfiref0x/TDL",
|
||||
"https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653559(v=vs.85)?redirectedfrom=MSDN",
|
||||
@@ -113,18 +36,170 @@ type = "eql"
|
||||
query = '''
|
||||
driver where host.os.type == "windows" and process.pid == 4 and
|
||||
(dll.code_signature.trusted == false or dll.code_signature.exists == false) and
|
||||
not dll.code_signature.status : ("errorExpired", "errorRevoked", "errorCode_endpoint:*")
|
||||
/* errorExpired and errorRevoked are handled by d12bac54-ab2a-4159-933f-d7bcefa7b61d */
|
||||
not dll.code_signature.status : ("errorExpired", "errorRevoked", "errorCode_endpoint:*") and
|
||||
|
||||
/* HP DOT4 printer driver family FPs (Dot4.sys, Dot4Prt.sys, Dot4usb.sys, Dot4Scan.sys) */
|
||||
not dll.hash.sha256 : (
|
||||
"f21c1d478180bc5e932bb2c2e4618e3ed463ca87acedeb139682d218435f82f1",
|
||||
"7e2f2a139e897eae56038b920bda9381094bc0ae9e626f6634e6b444b8b0c91f",
|
||||
"12ffdf5f48a79b1b4adbb88ba2cb6c59dd6719554e8ea6beefe99b3e3c66f1ac",
|
||||
"dbc6afaf80141e2480e19878f581edfe9c2b018da2ec527c4025ff04d5587afd"
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Untrusted Driver Loaded
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What exact kernel driver loaded, and what trust failure made it alert?
|
||||
- Focus: `process.pid`, `dll.path`, `dll.code_signature.exists`, `dll.code_signature.trusted`, and `dll.code_signature.status`.
|
||||
- Implication: escalate when System loaded an unsigned or untrusted driver from a non-vendor, user-writable, temp, or renamed path; lower concern only when the trust failure fits a controlled driver-development or hardware-validation host class.
|
||||
|
||||
- Does the driver identity map to a known vulnerable driver, BYOVD chain, or offensive loader?
|
||||
- Why: TDL-style and BYOVD activity may be easier to recognize by stable hash, original PE name, or signer than current file name.
|
||||
- Focus: `dll.hash.sha256`, `dll.pe.original_file_name`, `dll.code_signature.subject_name`, and `dll.code_signature.thumbprint_sha256`.
|
||||
- Implication: escalate when hash, original name, or signer maps to a vulnerable-driver blocklist, signature-bypass loader, or malicious kernel tooling; lower concern only when the same artifact is tied to a controlled lab or validation cohort.
|
||||
|
||||
- Does recency or rename timing show the driver was staged for this load?
|
||||
- Focus: `dll.Ext.relative_file_creation_time`, `dll.Ext.relative_file_name_modify_time`, and `dll.path`; if file-event telemetry is available, use the same `host.id` and path to identify who wrote or renamed it. $investigate_0
|
||||
- Implication: escalate when the driver appeared just before load, was recently renamed, or was written by an unrelated staging process. Missing file-event telemetry leaves provenance unresolved, not benign.
|
||||
|
||||
- What resident service or device identity is tied to the loaded image?
|
||||
- Focus: compare `dll.path`, `dll.hash.sha256`, and `dll.code_signature.subject_name` with current Osquery driver inventory and service output.
|
||||
- Hint: For non-Microsoft drivers by `image`, `service`, `signed`, `subject_name`, and `VtLink`; use it as current-state context, and keep the alert as the historical load record if no matching image exists.
|
||||
- $osquery_0
|
||||
- Hint: For unsigned current drivers when the alert shows missing or untrusted signature metadata; current signed or service values do not prove what existed at `@timestamp`.
|
||||
- $osquery_1
|
||||
- Implication: escalate when current inventory lacks a coherent image or service entry, the service is unexpected for the host, or other unsigned drivers do not fit the host role. Treat osquery as corroboration; do not delay escalation when alert-local identity, trust, or recency evidence is decisive.
|
||||
|
||||
- Did signing or code-integrity control activity make this load possible?
|
||||
- Why: 64-bit Windows normally enforces kernel-mode driver signing, while test-signing, DSE tampering, or vulnerable-driver loaders can open a path for untrusted kernel code.
|
||||
- Focus: same-host process events around the load using `host.id`, `process.name`, `process.executable`, and `process.command_line` for bcdedit test-signing/nointegritychecks changes or known vulnerable-driver loader activity. $investigate_1
|
||||
- Implication: escalate when surrounding process evidence shows test-signing changes, code-integrity bypass tooling, or vulnerable-driver loader execution; absent process evidence weakens this corroborator but does not clear an unexplained untrusted driver load.
|
||||
|
||||
- Does the host cohort and prevalence fit a controlled driver workflow?
|
||||
- Focus: `host.id`, `host.name`, and the smallest stable indicator, usually `dll.hash.sha256`, `dll.path`, or `dll.code_signature.subject_name`.
|
||||
- Hint: broaden only when identity, recency, inventory, or tampering evidence remains suspicious or unresolved. $investigate_2
|
||||
- Implication: escalate when the driver appears on production systems, user-writable paths, unrelated hosts, or outside the expected lab cohort; lower concern only when artifact, path pattern, signer, and host cohort consistently match a controlled validation workflow.
|
||||
|
||||
- Using identity, trust failure, staging/provenance, osquery inventory, signing-control evidence, and host-cohort spread: escalate unauthorized kernel code, BYOVD, or signature-bypass evidence; close only when telemetry binds the load to one controlled driver workflow; preserve artifacts and escalate mixed or incomplete cases.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Controlled driver-development, OEM hardware validation, and authorized security or EDR compatibility testing can load test-signed or unsigned drivers on isolated lab hosts. Confirm first with telemetry: `dll.hash.sha256`, `dll.path`, `dll.code_signature.status` or `dll.code_signature.subject_name`, current osquery image and service output, and `host.id` cohort must align with one workflow. Use build, test, or change records only after telemetry binds the exact artifact and cohort; if unavailable, require prior alerts for the same driver artifact and host cohort before exceptioning. If any evidence dimension contradicts the workflow, do not close as benign.
|
||||
- Build exceptions only from the minimum confirmed pattern, such as `dll.hash.sha256` plus `dll.path` plus bounded `host.id` cohort or service identity. Avoid exceptions on `dll.name`, signer, or generic unsigned-driver conditions alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign:
|
||||
- Reverse temporary containment and document the driver artifact, host cohort, current osquery image and service values, and any corroborating external record. Keep exceptions narrow to the confirmed hash, path, host cohort, or service identity.
|
||||
- If suspicious but unconfirmed:
|
||||
- Preserve the driver file if accessible, the alert event export, osquery driver inventory results, surrounding signing-control process events, and the case timeline before containment or cleanup.
|
||||
- Apply reversible containment first, such as temporary network restriction or heightened monitoring, while scoping the same `dll.hash.sha256` or `dll.path` across other hosts.
|
||||
- Escalate to host isolation before reboot, uninstall, or cleanup only if evidence shows code-integrity tampering, vulnerable-driver loader activity, post-load abuse, or spread outside the expected lab cohort.
|
||||
- If confirmed malicious:
|
||||
- Isolate the host after preserving the driver artifact, service or boot-start context, signing-control evidence, and affected `host.id` or `host.name`. If endpoint response is unavailable, hand off that evidence set to the team that can contain the system.
|
||||
- Scope other hosts for the same `dll.hash.sha256`, `dll.path`, or `dll.code_signature.subject_name` before uninstalling the driver, deleting the file, removing the backing service, or rebooting.
|
||||
- Remove the malicious driver, related service or boot-start entry, and code-signing or DSE changes identified during investigation, then remediate the loader or vulnerable-driver path that introduced it.
|
||||
- Post-incident hardening:
|
||||
- Re-enable or enforce driver-signing and code-integrity controls on the affected host class, block confirmed malicious or vulnerable `dll.hash.sha256` values and `dll.path` locations, and restrict test-signing to isolated lab systems.
|
||||
- Document any BYOVD family, loader service name, or host-cohort pattern uncovered during triage for future response cases.
|
||||
"""
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"process.pid",
|
||||
"dll.path",
|
||||
"dll.name",
|
||||
"dll.hash.sha256",
|
||||
"dll.pe.original_file_name",
|
||||
"dll.code_signature.exists",
|
||||
"dll.code_signature.trusted",
|
||||
"dll.code_signature.status",
|
||||
"dll.code_signature.subject_name",
|
||||
"dll.code_signature.thumbprint_sha256",
|
||||
"dll.Ext.relative_file_creation_time",
|
||||
"dll.Ext.relative_file_name_modify_time",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.osquery]]
|
||||
label = "Osquery - Retrieve All Non-Microsoft Drivers with Virustotal Link"
|
||||
query = """
|
||||
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
|
||||
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
|
||||
authenticode.path JOIN hash ON drivers.image = hash.path WHERE NOT (provider == "Microsoft" AND signed == "1")
|
||||
"""
|
||||
|
||||
[[transform.osquery]]
|
||||
label = "Osquery - Retrieve All Unsigned Drivers with Virustotal Link"
|
||||
query = """
|
||||
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
|
||||
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
|
||||
authenticode.path JOIN hash ON drivers.image = hash.path WHERE signed == "0"
|
||||
"""
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File events for the loaded driver path"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "file.path", queryType = "phrase", value = "{{dll.path}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events on the driver host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the driver identity"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "dll.hash.sha256", queryType = "phrase", value = "{{dll.hash.sha256}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "dll.path", queryType = "phrase", value = "{{dll.path}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1036"
|
||||
name = "Masquerading"
|
||||
reference = "https://attack.mitre.org/techniques/T1036/"
|
||||
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1036.001"
|
||||
name = "Invalid Code Signature"
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
creation_date = "2025/08/20"
|
||||
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "crowdstrike"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/24"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies DNS queries to known public IP address lookup web services. Malwares tend to perform this action to assess potential targets.
|
||||
Identifies DNS queries to known public IP address lookup web services from suspicious Windows processes, which
|
||||
can reveal external IP or internet-connectivity discovery before follow-on activity.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = [
|
||||
@@ -22,35 +23,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "System Public IP Discovery via DNS Query"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating System Public IP Discovery via DNS Query
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Investigate the process execution chain (parent process tree) for unknown processes or malicious scripts.
|
||||
- Verify if the executed process is persistent on the host like common mechanisms Startup folder, task or Run key.
|
||||
- Review any unusual network, files or registry events by the same process.
|
||||
- Investigate other alerts associated with the user/host during the past 48 hours.
|
||||
- Extract this communication's indicators of compromise (IoCs) and use traffic logs to search for other potentially compromised hosts.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Trusted domain from an expected process running in the environment.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate the involved host to prevent further post-compromise behavior.
|
||||
- Immediately block the identified indicators of compromise (IoCs).
|
||||
- Implement any temporary network rules, procedures, and segmentation required to contain the attack.
|
||||
- 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.
|
||||
- Update firewall rules to be more restrictive.
|
||||
- Reimage the host operating system or restore the compromised files to clean versions.
|
||||
- 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://attack.mitre.org/techniques/T1016/"]
|
||||
risk_score = 73
|
||||
rule_id = "642ce354-4252-4d43-80c9-6603f16571c1"
|
||||
@@ -112,7 +84,6 @@ network where host.os.type == "windows" and dns.question.name != null and proces
|
||||
"iplogger.*",
|
||||
"freegeoip.net",
|
||||
"freegeoip.app",
|
||||
"ipinfo.io",
|
||||
"geoplugin.net",
|
||||
"myip.dnsomatic.com",
|
||||
"www.geoplugin.net",
|
||||
@@ -120,7 +91,6 @@ network where host.os.type == "windows" and dns.question.name != null and proces
|
||||
"ip4.seeip.org",
|
||||
"*.geojs.io",
|
||||
"*portmap.io",
|
||||
"api.2ip.ua",
|
||||
"api.db-ip.com",
|
||||
"geolocation-db.com",
|
||||
"httpbin.org",
|
||||
@@ -128,6 +98,155 @@ network where host.os.type == "windows" and dns.question.name != null and proces
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating System Public IP Discovery via DNS Query
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Does the alert-local DNS event show request-only, successful resolution, or lookup failure for a public-IP service?
|
||||
- Why: request events show intent to resolve the service; result events plus `dns.resolved_ip` show resolver response, not a connection.
|
||||
- Focus: `dns.question.name`, `event.action`, `dns.resolved_ip`, `dns.Ext.status`, and `@timestamp`.
|
||||
- Implication: escalate faster when a suspicious process resolves a service that reports public egress IP; lower concern only when the lookup failed or stayed request-only and identity, lineage, and network checks all fit the same recognized connectivity test.
|
||||
|
||||
- Is the alerting binary a recognized tool or a suspicious LOLBin/script host in this context?
|
||||
- Focus: alert or recovered process identity: `process.name`, `process.executable`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
|
||||
- Implication: escalate when the lookup comes from a LOLBin, scripting runtime, unsigned binary, user-writable path, or signer mismatch; lower concern when a stable signed updater, endpoint-management, or managed connectivity-check component owns the exact binary. Identity alone does not close the alert.
|
||||
|
||||
- Does the launch chain explain why this process needed external-IP discovery?
|
||||
- Focus: recovered process start and parent context on `host.id` and `process.entity_id`: `process.command_line`, `process.parent.executable`, `process.parent.command_line`, `user.id`, and `process.Ext.session_info.logon_type`. $investigate_2
|
||||
- Implication: escalate when Office, a browser child, a script host, a service session, or an unexpected remote session launched the lookup; lower concern when parent, command line, user, and session all match one recognized troubleshooting, updater, endpoint-management, or managed connectivity-check workflow.
|
||||
|
||||
- Did the process connect to the resolved public-IP service or pivot to other external infrastructure?
|
||||
- Focus: same-process network events on `host.id` and `process.entity_id`, separating DNS results from connections and correlating `dns.resolved_ip` to `destination.ip`, `destination.port`, and `destination.as.organization.name`. $investigate_3
|
||||
- Hint: Missing network telemetry is unresolved, not benign. When present, treat `dns.question.name` as DNS evidence and `destination.ip` as connection evidence, including direct public-IP connections that bypass DNS.
|
||||
- Implication: escalate when the process reaches the resolved service, contacts unrelated public infrastructure, or later connects directly to public IPs without DNS; lower concern only when connection telemetry shows no related external connection or an environment-confirmed proxy path aligned with the same workflow.
|
||||
|
||||
- Did the same process launch follow-on commands that turn the lookup into staging, discovery, or C2 preparation?
|
||||
- Focus: child process starts where `process.parent.entity_id` matches `process.entity_id`: `process.name`, `process.command_line`, `process.executable`, and `process.code_signature.subject_name`. $investigate_4
|
||||
- Implication: escalate when shells, downloaders, installers, reconnaissance commands, or persistence tooling follow the lookup; lower concern when no child activity appears and earlier identity and lineage support one recognized connectivity check.
|
||||
|
||||
- If local evidence stays suspicious or unresolved, do related alerts show the same binary-and-domain tuple around this user or host?
|
||||
- Focus: related alert history for `user.id` and `host.id`: `dns.question.name`, `process.hash.sha256`, `process.code_signature.subject_name`, and recovered `process.parent.executable`. Review user and host alerts only after local DNS result, lineage, and follow-on network checks stay suspicious or unresolved.
|
||||
- $investigate_0
|
||||
- $investigate_1
|
||||
- Implication: broaden the case when the same hash, signer, parent, and public-IP service recur across other hosts for the same user or other users on the same host; keep response local when related alerts remain limited to one confirmed maintenance cohort.
|
||||
|
||||
- Based on DNS outcome, binary identity, launch chain, same-process network behavior, child processes, and scope, what disposition is supported?
|
||||
- Implication: escalate on unauthorized public-IP discovery plus suspicious lineage, external egress, child commands, or spread; close only when DNS outcome, binary identity, parent chain, user/session context, connection behavior, child activity, and scope bind one recognized workflow with no contradictions; preserve mixed or incomplete cases and escalate.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Administrative troubleshooting, software updater, endpoint-management, and managed connectivity-check workflows may query public-IP services to confirm egress or NAT behavior. Confirm that identity (`process.executable`, `process.hash.sha256`, `process.code_signature.subject_name`), lineage (`process.parent.executable`, `process.parent.command_line`), user/session context, DNS evidence (`dns.question.name`, `dns.resolved_ip`), and any connection evidence converge on the same exact workflow. Without organizational confirmation, close only when telemetry proves the exact component and workflow; otherwise treat the pattern as candidate exception evidence.
|
||||
- Before creating an exception, require a stable `process.hash.sha256` or `process.code_signature.subject_name`, `process.parent.executable`, the specific `dns.question.name`, and scope anchor (`host.id`, `host.name`, or `user.id`). Avoid exceptions on `dns.question.name` alone, `process.name` alone, or the full public-IP service list because benign tooling and malware use the same services.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, document the exact evidence that proved the workflow: binary identity, parent chain, user/session context, DNS result, connection behavior, and recurrence scope. Then reverse any temporary containment and build a narrow exception only for that confirmed workflow.
|
||||
- If suspicious but unconfirmed, preserve the alert, process start, DNS result, same-process connection events, child process starts, and related alert history before containment. Apply reversible containment such as temporary domain or DNS blocking, outbound restrictions for the affected process or host, or heightened monitoring on the affected `host.id` or `user.id`; escalate to host isolation only if follow-on child processes, suspicious external egress, or broader spread appears and host criticality allows it.
|
||||
- If confirmed malicious, isolate the host or restrict egress when binary identity, lineage, DNS, connection, or child-process evidence shows unauthorized internet discovery or pre-C2 activity. Block confirmed malicious `dns.question.name`, `dns.resolved_ip`, `destination.ip`, `process.hash.sha256`, and related domains, then scope other hosts and users for the same indicators before terminating processes or deleting artifacts.
|
||||
- Eradicate only the scripts, binaries, scheduled tasks, run keys, or configuration changes identified during the investigation after scoping related hosts and users. Remediate the launcher, user context, or deployment path that introduced the public-IP lookup.
|
||||
- Post-incident hardening: restrict unsigned or user-writable scripting and LOLBin execution where feasible, keep endpoint DNS and network telemetry enabled, and document any connectivity-check pattern or visibility gap for future triage.
|
||||
"""
|
||||
|
||||
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:
|
||||
|
||||
- [CrowdStrike](https://ela.st/crowdstrike-integration)
|
||||
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
|
||||
- [Sysmon Event ID 22 - DNS Query](https://ela.st/sysmon-event-22-setup)
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.entity_id",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"process.code_signature.trusted",
|
||||
"process.code_signature.subject_name",
|
||||
"dns.question.name",
|
||||
"dns.Ext.status",
|
||||
"dns.resolved_ip",
|
||||
"destination.ip",
|
||||
"event.action",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the DNS-querying process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network events for the DNS-querying process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Child processes spawned by the DNS-querying process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
creation_date = "2024/08/29"
|
||||
integration = ["endpoint", "windows", "system", "sentinel_one_cloud_funnel", "m365_defender", "crowdstrike"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/07"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies the Foxmail client spawning a child process with argument pointing to the Foxmail temp directory. This may
|
||||
indicate the successful exploitation of a Foxmail vulnerability for initial access and execution via a malicious email.
|
||||
Identifies the Foxmail client spawning a child process with arguments pointing to user-profile AppData paths or remote
|
||||
shares. This may indicate exploitation of a Foxmail vulnerability for initial access and execution via a malicious email.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = [
|
||||
@@ -25,41 +25,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Potential Foxmail Exploitation"
|
||||
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 Foxmail Exploitation
|
||||
|
||||
Foxmail, a popular email client, can be exploited by adversaries to gain initial access and execute malicious payloads. Attackers may leverage vulnerabilities to spawn child processes from Foxmail, directing them to temporary directories where malicious files reside. The detection rule identifies such suspicious activities by monitoring process creation events, specifically when Foxmail spawns processes with arguments pointing to its temp directory, indicating potential exploitation attempts.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Review the process creation event details to confirm that Foxmail.exe is the parent process and check the specific child process that was spawned.
|
||||
- Examine the arguments of the spawned process to verify if they point to a suspicious temporary directory, as indicated by the query pattern (e.g., paths under "?:\\Users\\*\\AppData\\*").
|
||||
- Investigate the contents of the identified temporary directory for any unusual or malicious files that may have been executed.
|
||||
- Check the email logs and Foxmail client activity to identify any recent emails that could have contained malicious attachments or links leading to the exploitation attempt.
|
||||
- Correlate the event with other security alerts or logs from data sources like Elastic Defend, Sysmon, or Microsoft Defender XDR to identify any related suspicious activities or patterns.
|
||||
- Assess the risk and impact on the affected system by determining if any unauthorized changes or additional malicious processes have been initiated following the initial alert.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Routine software updates or installations may cause Foxmail to spawn child processes in the temp directory. Users can create exceptions for known update processes to prevent false alerts.
|
||||
- Legitimate plugins or extensions for Foxmail might execute processes from the temp directory. Verify the legitimacy of these plugins and exclude them if they are trusted.
|
||||
- Automated scripts or backup software interacting with Foxmail could trigger the rule. Identify these scripts and add them to an exclusion list if they are verified as safe.
|
||||
- User-initiated actions such as importing or exporting data in Foxmail might result in temporary process creation. Monitor these activities and exclude them if they are part of regular operations.
|
||||
- Security software performing scans or checks on Foxmail's temp directory can be mistaken for exploitation attempts. Confirm these activities and whitelist the security software processes involved.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Isolate the affected system from the network to prevent further spread of the potential threat and to contain any ongoing malicious activity.
|
||||
- Terminate any suspicious processes spawned by Foxmail that are identified in the alert to stop the execution of potentially malicious payloads.
|
||||
- Conduct a thorough scan of the affected system using an updated antivirus or endpoint detection and response (EDR) tool to identify and remove any malicious files or remnants.
|
||||
- Review and analyze email logs and quarantine any suspicious emails that may have been the source of the exploit to prevent further exploitation attempts.
|
||||
- Apply any available security patches or updates to Foxmail and the operating system to mitigate known vulnerabilities and prevent future exploitation.
|
||||
- Monitor the network and systems for any signs of lateral movement or additional compromise, using indicators of compromise (IOCs) identified during the investigation.
|
||||
- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional actions are required based on the scope and impact of the threat."""
|
||||
references = ["https://mp.weixin.qq.com/s/F8hNyESBdKhwXkQPgtGpew"]
|
||||
risk_score = 73
|
||||
rule_id = "2c6a6acf-0dcb-404d-89fb-6b0327294cfa"
|
||||
@@ -87,6 +52,154 @@ process where host.os.type == "windows" and event.type == "start" and
|
||||
process.parent.name : "Foxmail.exe" and process.args : ("?:\\Users\\*\\AppData\\*", "\\\\*")
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential Foxmail Exploitation
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What exact Foxmail child execution did the alert capture?
|
||||
- Why: Foxmail exploit attempts execute code in the user's client context; the child process and path argument distinguish payload execution from routine file handling.
|
||||
- Focus: `process.parent.name`, `process.parent.executable`, child `process.executable`, `process.command_line`, and `process.args`.
|
||||
- Implication: escalate when Foxmail.exe launches a script host, LOLBin, interpreter, archive utility, installer, or payload from a user-writable or remote-share path; lower suspicion only when the child is a recognized signed Foxmail component with the expected path, argument pattern, and no contradictory process evidence.
|
||||
|
||||
- Does the Foxmail parent match the installed mail client and user launch context?
|
||||
- Focus: `process.parent.executable`, `process.parent.command_line`, `process.parent.code_signature.subject_name`, and `process.parent.code_signature.trusted`.
|
||||
- Implication: escalate when Foxmail runs from a user-writable or portable path, has an unexpected signer or trust state, or appears under an abnormal launch chain; lower suspicion when parent identity and user context match a recognized installed Foxmail workflow. Parent identity never clears the child behavior by itself.
|
||||
|
||||
- What does the child command line say it was trying to execute or open?
|
||||
- Why: the user-writable or remote path string in `process.args` is the rule-specific payload anchor; interpret it before relying on broader pivots.
|
||||
- Focus: `process.executable`, `process.command_line`, `process.args`, and `process.code_signature.subject_name`. $investigate_2
|
||||
- Implication: escalate when the child runs executable or scriptable content from a user-writable path, mounted archive, or remote share, especially through a LOLBin or interpreter; lower suspicion when signed child, arguments, and path pattern match a locally confirmed Foxmail file-handling action.
|
||||
|
||||
- Did the Foxmail child launch descendants that change impact or confirm execution?
|
||||
- Focus: process starts on the same `host.id` where `process.parent.entity_id` matches the child `process.entity_id`, or `process.parent.pid` matches `process.pid` in the alert window; review descendant `process.executable` and `process.command_line`. $investigate_3
|
||||
- Hint: prefer entity match; use PID only inside the alert window.
|
||||
- Implication: escalate when descendants include payload staging, scripting, installers, persistence tooling, or commands unrelated to Foxmail; lower suspicion when there are no descendants and the child command from the prior step already matches a recognized helper workflow.
|
||||
|
||||
- What delivery clue is embedded in the user-writable or remote path argument?
|
||||
- Focus: file name, extension, UNC host/share, and directory pattern visible in `process.args`, scoped to `host.name` and `user.id`.
|
||||
- Implication: escalate or broaden when the path suggests executable content, a deceptive attachment-like name, or a remote share that can execute content without local provenance; lower suspicion only as corroboration when the path shape fits a recognized Foxmail file-handling workflow supported by child identity and descendant evidence.
|
||||
|
||||
- Does related activity history show the same child/path pattern beyond this process?
|
||||
- Focus: related records for the same `user.id`; compare child `process.executable`, parent-child pair, and distinctive `process.args` fragments. $investigate_0
|
||||
- Hint: use same-asset related records to separate one user's repeat workflow from multiple users on one host. $investigate_1
|
||||
- Implication: broaden when the same child binary, remote share, or path fragment appears on unrelated users or hosts; keep response local when related records are absent and local process evidence already proves one recognized workflow.
|
||||
|
||||
- Based on the Foxmail parent, child command, argument path, descendants, and related activity, what disposition is supported?
|
||||
- Escalate for suspicious child intent, unexplained descendants, or the same pattern on multiple users or hosts; close only when process evidence and supported recovery prove one exact recognized Foxmail workflow on this host; preserve and escalate mixed, missing, or contradictory evidence, using outside confirmation only to corroborate details telemetry cannot prove.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Signed Foxmail child processes used for update or file handling and authorized internal tests are plausible benign candidates, but the label is not clearance. Confirm parent path/signer, child path/signer, `process.args`, `host.id`, and `user.id` all align with one workflow or exact test file/share, and verify no suspicious descendants; use prior alerts only to tune a durable exception, not to close the single alert by recurrence alone.
|
||||
- If test records are unavailable, use the process timeline, path shape, and user/host scope as fallback corroboration; do not close on owner confirmation alone when process evidence remains unexplained.
|
||||
- Before creating an exception, require stable anchors such as `process.parent.executable`, `process.executable`, `process.code_signature.subject_name`, the user-writable or remote path pattern in `process.args`, `host.id`, and `user.id`. Avoid exceptions on "Foxmail.exe" alone, temp-path strings alone, or `process.name` alone because exploit chains and benign components can share those surface features.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse any temporary containment and document the recognized Foxmail component, file-handling, or test workflow, including the expected parent-child pair, signer, path pattern, `host.id`, and `user.id`. Create a narrow exception only when those anchors are stable enough to avoid suppressing lookalike exploit chains.
|
||||
- If suspicious but unconfirmed, preserve the alert record, parent and child command lines, `process.entity_id`, `process.pid`, `process.args`, referenced user-writable or remote paths, descendant process identifiers, and case records that identify the delivery path before containment. Apply reversible containment such as temporary quarantine of the referenced artifact, temporary outbound restrictions for the affected host when remote retrieval is indicated, or heightened monitoring on the affected `host.id` and `user.id`; escalate to host isolation only if follow-on execution, staging, or wider compromise appears and the host role can tolerate it.
|
||||
- If confirmed malicious, isolate the host and terminate the Foxmail child or descendant payloads only after recording the relevant process identifiers, command lines, path strings, and delivery-path evidence; if direct endpoint response is unavailable, escalate with those preserved artifacts to the team that can act. Quarantine the referenced attachment or payload, block confirmed malicious indicators, and review other recipients, hosts, and users for the same attachment, remote path, or child-process pattern before deleting evidence or resetting accounts.
|
||||
- Eradicate only the payloads, persistence mechanisms, or configuration changes identified in the same chain after scoping affected recipients and hosts. Remediate the message source, attachment workflow, or remote share that led to the Foxmail launch.
|
||||
- Post-incident hardening: update Foxmail to a current vendor-fixed release, retain endpoint process telemetry and any mail or artifact telemetry used in this case, and document adjacent exploit-chain findings for the detection engineering team.
|
||||
"""
|
||||
|
||||
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:
|
||||
|
||||
- [CrowdStrike](https://ela.st/crowdstrike-integration)
|
||||
- [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)
|
||||
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.entity_id",
|
||||
"process.pid",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.args",
|
||||
"process.parent.entity_id",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Events for the Foxmail child process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Child processes launched by the Foxmail child"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
@@ -104,15 +217,14 @@ reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1189"
|
||||
name = "Drive-by Compromise"
|
||||
reference = "https://attack.mitre.org/techniques/T1189/"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1566"
|
||||
name = "Phishing"
|
||||
reference = "https://attack.mitre.org/techniques/T1566/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1566.001"
|
||||
name = "Spearphishing Attachment"
|
||||
reference = "https://attack.mitre.org/techniques/T1566/001/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0001"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2024/05/12"
|
||||
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/07"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -22,30 +22,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Unusual Execution via Microsoft Common Console File"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Unusual Execution via Microsoft Common Console File
|
||||
|
||||
- Investigate the source of the MSC file.
|
||||
- Investigate the process execution chain (all spawned child processes and their descendants).
|
||||
- Investigate the process and it's descendants network and file events.
|
||||
- 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.
|
||||
|
||||
### Response and remediation
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate the involved host 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.
|
||||
- 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.genians.co.kr/blog/threat_intelligence/facebook"]
|
||||
risk_score = 73
|
||||
rule_id = "e760c72b-bb1f-44f0-9f0d-37d51744ee75"
|
||||
@@ -97,6 +73,148 @@ process where host.os.type == "windows" and event.type == "start" and
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Unusual Execution via Microsoft Common Console File
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What ".msc" path and immediate child process triggered the alert?
|
||||
- Focus: `process.parent.executable`, `process.parent.args`, `process.parent.command_line`, `process.executable`, and `process.command_line`.
|
||||
- Implication: escalate when "mmc.exe" opens a user-writable, download, cloud-sync, archive-extraction, or document-like ".msc" and the child is a shell, script host, "mshta.exe", "schtasks.exe", or another LOLBin; lower suspicion only when the exact ".msc" path and child command fit a recognized administrative console workflow on this host.
|
||||
|
||||
- Does the child command line expose second-stage or persistence intent?
|
||||
- Focus: `process.command_line`, checking for "WScript.Shell", "schtasks /create", "OneDriveUpdate", "wscript.exe /b", "start /min", "mshta", ".hta", remote URLs, or script/batch names.
|
||||
- Hint: review same-child file and network events for staged scripts, task artifacts, or remote retrieval. Missing network telemetry is unresolved, not benign. $investigate_3
|
||||
- Implication: escalate when the command creates tasks, hides/minimizes execution, starts script hosts, or embeds remote retrieval; lower suspicion only when the arguments perform a narrow helper action expected from the same console.
|
||||
|
||||
- Does the child identity and session context fit expected administration?
|
||||
- Focus: `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.Ext.relative_file_creation_time`, and the `user.id` + `host.id` pair.
|
||||
- Implication: escalate when the child runs from a user-writable or recently created path, has a signer mismatch, or appears under an unexpected administrative user/session; identity confirmation alone never clears an unsafe command line.
|
||||
|
||||
- Do descendants continue the MSC-launched chain into scripting, tasks, or delayed execution?
|
||||
- Why: MSC lures can store task commands that create a scheduled task, run VBS, then launch HTA through "mshta.exe"; the first child may be only the handoff.
|
||||
- Focus: descendant starts on the same `host.id`, linked by `process.parent.entity_id` or `process.Ext.ancestry`, checking `process.name` and `process.command_line`. $investigate_2
|
||||
- Hint: if entity linkage is absent, match `process.parent.pid` to the alerting `process.pid` within a tight alert-time window and treat matches as weaker.
|
||||
- Hint: after a suspicious descendant, expand that descendant's file and network events from Timeline.
|
||||
- Implication: escalate when descendants show "cmd.exe", "wscript.exe", "cscript.exe", "mshta.exe", "powershell.exe", "pwsh.exe", "schtasks.exe", repeated shells, Microsoft-themed task names, or command-line URLs; lower suspicion when the tree ends at one expected helper with no delayed script or task process.
|
||||
|
||||
- If local evidence remains suspicious or unresolved, what related alerts change scope or containment?
|
||||
- Focus: related alerts for the same `user.id`, especially document delivery, script execution, task creation, or outbound staging. $investigate_0
|
||||
- Hint: review same-`host.id` alerts to separate one-host lure execution from repeated activity across assets. $investigate_1
|
||||
- Implication: broaden containment when the same user or host also shows initial-access, script-host, scheduled-task, or outbound-staging alerts; keep response local when those alerts are absent, but leave benign closure to the process-chain synthesis.
|
||||
|
||||
- Escalate for lure-driven ".msc" execution, script staging, scheduled-task creation, remote retrieval, or suspicious descendants; close only when alert-local evidence and process recovery bind one exact recognized console workflow with no contradictory descendants; preserve artifacts and escalate when evidence is mixed or visibility incomplete.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Custom administrative consoles, vendor MMC snap-ins, or IT troubleshooting bundles stored outside default Windows console paths can launch helpers, browsers, viewers, or support utilities. Confirm that `process.parent.args`, `process.parent.command_line`, `process.executable`, `process.command_line`, `process.code_signature.subject_name`, `user.id`, and `host.id` all align with one exact console package or affected cohort. If inventory, ticketing, or owner confirmation is unavailable, close only when process and descendant telemetry still prove that helper workflow with no unresolved script, task, hidden execution, or remote-retrieval behavior.
|
||||
- Before creating an exception, validate prior alerts from this rule for the same ".msc" path in `process.parent.args`, child `process.executable`, signer in `process.code_signature.subject_name`, stable `process.command_line`, and bounded `user.id` and `host.id` scope. Build the exception from that full workflow pattern; avoid exceptions on `process.parent.name` value "mmc.exe" or the child `process.executable` alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse any temporary containment and document the exact ".msc" path, child command pattern, signer, `user.id`, and `host.id`. Create an exception only after the same workflow pattern recurs consistently across prior alerts from this rule.
|
||||
- If suspicious but unconfirmed, preserve a case export for the alerting process instance (`host.id` plus `process.entity_id` or `process.pid` and alert time), the parent MSC path, child and descendant command lines, executable hash/signer, task names, script names, and URLs visible in command lines before making destructive changes. Apply reversible containment first, such as temporary URL/domain blocking, disabling a newly created scheduled task after preserving its command, or heightened monitoring on the affected `host.id` and `user.id`.
|
||||
- If confirmed malicious, isolate the host or contain the affected account only after preserving the process chain, scheduled-task names, script names, hashes, and command-line indicators. Terminate malicious child or descendant processes after preservation, block confirmed command-line URLs or domains, and hand off the preserved artifact set if endpoint response is unavailable.
|
||||
- Eradicate only the malicious ".msc", scripts, scheduled tasks, and staged payloads identified during the investigation, then remediate the delivery path that let the lure execute. Review related hosts and users for the same `process.parent.args` path or descendant `process.command_line` pattern before broad cleanup.
|
||||
- Post-incident hardening: restrict or warn on ".msc" launches from user-writable, download, archive-extraction, or cloud-sync paths, and retain process lineage and command-line telemetry needed to distinguish future admin consoles from MSC lures.
|
||||
"""
|
||||
|
||||
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.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.entity_id",
|
||||
"process.pid",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"process.hash.sha256",
|
||||
"process.Ext.session_info.logon_type",
|
||||
"process.Ext.relative_file_creation_time",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"process.parent.args",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Descendant processes from the MMC-launched child"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File and network events for the MMC-launched child"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2024/08/29"
|
||||
integration = ["endpoint", "windows"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/24"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -15,41 +15,6 @@ index = ["logs-endpoint.events.library-*", "logs-windows.sysmon_operational-*"]
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "WPS Office Exploitation via DLL Hijack"
|
||||
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 WPS Office Exploitation via DLL Hijack
|
||||
|
||||
DLL hijacking exploits the way applications load dynamic link libraries (DLLs), allowing adversaries to execute malicious code. In WPS Office, attackers may exploit vulnerabilities by loading a rogue DLL via the promecefpluginhost.exe process, leveraging the ksoqing protocol. The detection rule identifies suspicious DLL loads from temporary or network paths, signaling potential exploitation attempts.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Review the alert details to confirm the process name is promecefpluginhost.exe and check if the event category is either "library" or "process" with the action "Image loaded*".
|
||||
- Examine the DLL or file path involved in the alert to determine if it matches suspicious paths such as those in the user's Temp directory or network paths like \\\\Device\\\\Mup\\\\** or \\\\*.
|
||||
- Investigate the source of the DLL by checking the file's origin, creation date, and any associated network activity to identify potential malicious downloads or transfers.
|
||||
- Analyze the process tree to understand the parent and child processes of promecefpluginhost.exe, looking for any unusual or unexpected behavior that might indicate exploitation.
|
||||
- Check for any other alerts or logs related to the same host or user account to identify patterns or repeated attempts of exploitation.
|
||||
- Correlate the findings with known vulnerabilities CVE-2024-7262 and CVE-2024-7263 to assess if the observed activity aligns with known exploitation techniques.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate software updates or installations may temporarily load DLLs from network paths or temporary directories. Users can create exceptions for known update processes or trusted software installations to prevent false alerts.
|
||||
- Some enterprise environments use network-based storage solutions that may trigger alerts when legitimate DLLs are loaded from these paths. Administrators can whitelist specific network paths or devices that are known to host trusted libraries.
|
||||
- Custom scripts or automation tools that interact with WPS Office might inadvertently load DLLs from temporary directories. Identifying and excluding these scripts or tools from monitoring can reduce false positives.
|
||||
- Security software or system maintenance tools may perform scans or operations that mimic the behavior of DLL hijacking. Users should verify and exclude these tools if they are known to cause benign alerts.
|
||||
- In environments where WPS Office is heavily used, consider monitoring the frequency and context of alerts to distinguish between normal usage patterns and potential threats, adjusting the rule parameters accordingly.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Isolate the affected system from the network immediately to prevent further exploitation or lateral movement by the attacker.
|
||||
- Terminate the promecefpluginhost.exe process to stop any ongoing malicious activity and prevent further DLL hijacking attempts.
|
||||
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any malicious DLLs or other malware.
|
||||
- Review and clean up the temporary and network paths identified in the detection query, specifically focusing on the AppData\\Local\\Temp\\wps\\INetCache directory and any suspicious network shares.
|
||||
- Apply patches or updates for WPS Office to address the vulnerabilities CVE-2024-7262 and CVE-2024-7263, ensuring that the software is up to date and less susceptible to exploitation.
|
||||
- Monitor for any further suspicious activity related to the ksoqing protocol or similar DLL hijacking attempts, using enhanced logging and alerting mechanisms.
|
||||
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are compromised."""
|
||||
references = [
|
||||
"https://www.welivesecurity.com/en/eset-research/analysis-of-two-arbitrary-code-execution-vulnerabilities-affecting-wps-office/",
|
||||
"https://mp.weixin.qq.com/s/F8hNyESBdKhwXkQPgtGpew",
|
||||
@@ -85,6 +50,150 @@ any where host.os.type == "windows" and process.name : "promecefpluginhost.exe"
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating WPS Office Exploitation via DLL Hijack
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What WPS library-load path did the alert capture?
|
||||
- Why: WPS loading from cache, device, or UNC paths defines the likely abuse route before identity checks.
|
||||
- Focus: `process.name`, `process.executable`, `process.command_line`, `dll.path`, and `dll.name`.
|
||||
- Implication: escalate when "promecefpluginhost.exe" loads from "Temp\\wps\\INetCache", "\\Device\\Mup\\", or a UNC path outside the WPS install tree; lower suspicion only when normalized `dll.path` resolves to the same Kingsoft-controlled component path as the loader and no protocol-abuse arguments appear.
|
||||
|
||||
- Is the WPS loader the expected Kingsoft component?
|
||||
- Focus: `process.executable`, `process.pe.original_file_name`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
|
||||
- Implication: escalate when the loader is unsigned, renamed, outside the installed WPS Office directory, or signed by an unexpected publisher; lower suspicion when identity matches a stable Kingsoft WPS component, but continue because a trusted loader can still load an attacker DLL.
|
||||
|
||||
- Does the command line and parentage show "ksoqing" protocol abuse?
|
||||
- Focus: loader process events for `host.id` and `process.entity_id`, then `process.command_line`, `process.parent.executable`, and `process.parent.command_line`. $investigate_2
|
||||
- Implication: escalate when "wps.exe" or "et.exe" opens user content with arguments exposing "ksoqing", plugin-service paths, encoded paths, or remote paths; lower suspicion only when parentage and arguments match a recognized controlled-share launch without document-driven protocol handling.
|
||||
|
||||
- Does the loaded DLL identity fit a legitimate WPS dependency?
|
||||
- Focus: `dll.hash.sha256`, `dll.pe.original_file_name`, `dll.code_signature.subject_name`, `dll.code_signature.trusted`, and `dll.Ext.relative_file_creation_time`.
|
||||
- Hint: if endpoint file telemetry is available, use `host.id` and `dll.path` to identify the writer or rename event. Missing file telemetry is unresolved, not benign. $investigate_4
|
||||
- Implication: escalate when the DLL is unsigned, non-Kingsoft, recently created, recently renamed in `dll.Ext.relative_file_name_modify_time`, or loaded as an unexpected WPS dependency from a remote share; if recency metadata is absent, rely on path, hash, signer, and parentage.
|
||||
|
||||
- If local evidence is suspicious or incomplete, do related alerts show follow-on activity?
|
||||
- Focus: child process events from the WPS loader and related alerts for `user.id`, especially WPS document execution, additional library loads, downloader behavior, or child-process alerts from the same workstation.
|
||||
- $investigate_3
|
||||
- $investigate_0
|
||||
- Hint: if user context is missing or ambiguous, review same-host alerts for `host.id` across the last 48 hours. $investigate_1
|
||||
- Implication: broaden scope when the same user or host shows repeated WPS-triggered loads, the same `dll.hash.sha256`, the same suspicious path pattern, or follow-on execution; lower urgency when isolated, but do not close if local path or DLL identity remains unresolved.
|
||||
|
||||
- Escalate when load path, loader identity, protocol or parentage, DLL signer/hash/recency, or related-alert evidence supports attacker-controlled DLL loading from INetCache, a device path, or UNC path; close only when the same evidence binds to one authorized validation, sandbox, or controlled-share workflow with no contradictory artifacts; preserve artifacts and escalate if evidence is mixed or incomplete.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Authorized vulnerability validation or sandbox detonation can reproduce this load pattern. Confirm scope with outside records when available, and require telemetry alignment on `host.id`, `user.id`, `process.executable`, `process.command_line`, `dll.path`, `dll.hash.sha256`, and `dll.code_signature.subject_name`. If not a known test, default to suspicious.
|
||||
- Controlled software distribution or application virtualization can serve WPS components from a managed share. Confirm `dll.path` stays on that exact share, `dll.hash.sha256` and `dll.code_signature.subject_name` match the expected Kingsoft component, and parentage lacks document-driven protocol or plugin-path arguments. Without inventories, use recurrence only to validate the same stable share, hash, signer, `process.executable`, `host.id`, and `user.id` workflow before exceptioning.
|
||||
- Build exceptions only from the minimum confirmed workflow: stable `process.executable`, `process.code_signature.subject_name`, `dll.path`, `dll.hash.sha256`, `dll.code_signature.subject_name`, and bounded `host.id` or `user.id` scope. Avoid exceptions on `process.name` alone for "promecefpluginhost.exe", "Temp\\wps\\INetCache", or UNC prefixes.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, record the exact workflow evidence first: loader identity, `process.command_line`, DLL path/hash/signer, and bounded `host.id` or `user.id` scope. Then reverse temporary containment and create an exception only for that bounded workflow.
|
||||
- If suspicious but unconfirmed, preserve the alert, host/user scope, `process.entity_id`, parent lineage, `dll.path`, `dll.hash.sha256`, and DLL signer/recency evidence before containment. Use reversible actions first, such as restricting a non-business remote share named in `dll.path`, quarantining a recovered lure document, or temporarily restricting WPS on the affected host; isolate only when follow-on execution or repeated malicious loads justify the interruption.
|
||||
- If confirmed malicious, isolate the host through endpoint response after evidence preservation, then terminate the WPS loader chain if it is still active and block confirmed malicious `dll.hash.sha256` values and remote shares from `dll.path`. If endpoint response is unavailable, hand off the preserved process, DLL, host, and user identifiers to the team that can contain the system or share.
|
||||
- Eradicate only artifacts tied to the investigation: remove the malicious DLL, recovered lure document, and staged WPS abuse files after scope review for the same `dll.hash.sha256`, `dll.path`, WPS parentage, `host.id`, and `user.id`. Upgrade WPS Office to a vendor-supported release that remediates both CVE-2024-7262 and CVE-2024-7263.
|
||||
- Post-incident hardening: restrict WPS Office library loads from user-writable and UNC paths where feasible, retain process and library-load telemetry, and document any adjacent variant observed during triage, such as alternate WPS protocol arguments or related "promecefpluginhost.exe" load paths.
|
||||
"""
|
||||
|
||||
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:
|
||||
|
||||
- [Sysmon Event ID 7 - Image Loaded](https://ela.st/sysmon-event-7-setup)
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.entity_id",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"dll.path",
|
||||
"dll.hash.sha256",
|
||||
"dll.code_signature.subject_name",
|
||||
"dll.code_signature.trusted",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the WPS loader"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Child process events from the WPS loader"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File events for the loaded DLL path"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "file.path", queryType = "phrase", value = "{{dll.path}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2020/09/02"
|
||||
integration = ["endpoint"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/24"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -16,53 +16,6 @@ interval = "60m"
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Execution of File Written or Modified by Microsoft Office"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Execution of File Written or Modified by Microsoft Office
|
||||
|
||||
Microsoft Office, a widely used suite of productivity applications, is frequently targeted by attackers due to its popularity in corporate environments. Attackers exploit its extensive capabilities, like macro scripts in Word and Excel, to gain initial access to systems. They often use Office documents as delivery mechanisms for malware or phishing attempts, taking advantage of their trusted status in professional settings.
|
||||
|
||||
This rule searches for executable files written by MS Office applications executed in sequence. This is most likely the result of the execution of malicious documents or exploitation for initial access or privilege escalation. This rule can also detect suspicious processes masquerading as the MS Office applications.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- 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.
|
||||
- Investigate other alerts associated with the user/host during the past 48 hours.
|
||||
- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include, but are not limited to, the Downloads and Document folders and the folder configured at the email client.
|
||||
- Determine if the collected files are malicious:
|
||||
- Use a private sandboxed malware analysis system to perform analysis.
|
||||
- Observe and collect information about the following activities:
|
||||
- Attempts to contact external domains and addresses.
|
||||
- File and registry access, modification, and creation activities.
|
||||
- Service creation and launch activities.
|
||||
- Scheduled task creation.
|
||||
- Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.
|
||||
- Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- If the malicious file was delivered via phishing:
|
||||
- Block the email sender from sending future emails.
|
||||
- Block the malicious web pages.
|
||||
- Remove emails from the sender from mailboxes.
|
||||
- Consider improvements to the security awareness program.
|
||||
- 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).
|
||||
"""
|
||||
risk_score = 73
|
||||
rule_id = "0d8ad79f-9025-45d8-80c1-4f0cd3c5e8e5"
|
||||
severity = "high"
|
||||
@@ -80,14 +33,10 @@ type = "eql"
|
||||
query = '''
|
||||
sequence with maxspan=2h
|
||||
[file where host.os.type == "windows" and event.type != "deletion" and file.extension : "exe" and
|
||||
(process.name : "WINWORD.EXE" or
|
||||
process.name : "EXCEL.EXE" or
|
||||
process.name : "OUTLOOK.EXE" or
|
||||
process.name : "POWERPNT.EXE" or
|
||||
process.name : "eqnedt32.exe" or
|
||||
process.name : "fltldr.exe" or
|
||||
process.name : "MSPUB.EXE" or
|
||||
process.name : "MSACCESS.EXE")
|
||||
process.name : (
|
||||
"WINWORD.EXE", "EXCEL.EXE", "OUTLOOK.EXE", "POWERPNT.EXE",
|
||||
"eqnedt32.exe", "fltldr.exe", "MSPUB.EXE", "MSACCESS.EXE"
|
||||
)
|
||||
] by host.id, file.path
|
||||
[process where host.os.type == "windows" and event.type == "start" and
|
||||
not (process.name : "NewOutlookInstaller.exe" and process.code_signature.subject_name : "Microsoft Corporation" and process.code_signature.trusted == true) and
|
||||
@@ -95,6 +44,113 @@ sequence with maxspan=2h
|
||||
] by host.id, process.executable
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Execution of File Written or Modified by Microsoft Office
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Which source events matched the Office write-to-execute sequence?
|
||||
- Why: this sequence can merge fields from different file and process events, so source events are the evidence for writer and executed-process identity.
|
||||
- Focus: open Investigate in Timeline for the alert window on the same host; compare written `file.path` with executed `process.executable`, then record source `process.name`, `process.entity_id`, and stable `user.id`.
|
||||
- Implication: escalate when Office creates an executable that later starts from the same path; lower suspicion when the recovered sequence resolves to a recognized signed add-in or helper updater in a controlled product tree. Signed Microsoft NewOutlookInstaller.exe and Citrix ShareFileForOutlook helpers are excluded, so a generic updater label is not closure.
|
||||
|
||||
- Is the Office writer the expected Office component and parent context?
|
||||
- Focus: writer `process.executable`, signer/trust, `process.parent.executable`, and `process.parent.command_line`.
|
||||
- Implication: escalate when WINWORD.EXE, EXCEL.EXE, OUTLOOK.EXE, POWERPNT.EXE, MSPUB.EXE, MSACCESS.EXE, eqnedt32.exe, or fltldr.exe is renamed, untrusted, user-writable, or launched by an unusual parent; lower suspicion when writer path, signer, and parent chain match the user's recognized Office integration. Writer identity never clears the executed file by itself.
|
||||
|
||||
- Does the written executable look staged for payload delivery?
|
||||
- Focus: `file.path`, original path/extension, `file.Ext.header_bytes`, `file.Ext.windows.zone_identifier`, and same-host file activity on the written path. $investigate_1
|
||||
- Implication: escalate for Temp, Downloads, AppData, mail cache, startup, unrelated product paths, Internet Zone evidence, or executable content after rename; lower suspicion when the artifact stays in a recognized add-in or update tree and path history fits that workflow.
|
||||
|
||||
- Does the executed file's identity and command line fit the same workflow?
|
||||
- Focus: executed `process.executable`, `process.hash.sha256`, signer, `process.command_line`, and `process.Ext.relative_file_creation_time`.
|
||||
- Hint: use prior endpoint process starts or related alerts for `process.hash.sha256` only after identity and command line fit the suspected workflow. $investigate_2
|
||||
- Implication: escalate when the executable is newly created, unsigned, user-writable, mismatched to signer or path, or launched with script, LOLBin, unpacking, or self-extracting arguments; lower suspicion only when signer, hash history, path, age, and arguments all fit the same recognized helper workflow.
|
||||
|
||||
- What document, email, archive, or integration source caused Office to write the executable?
|
||||
- Focus: file events from writer `process.entity_id`; review `file.path`, `file.origin_url`, `file.origin_referrer_url`, and `file.Ext.windows.zone_identifier`.
|
||||
- Hint: if records are incomplete or the entity pivot returns none, use the same host, writer `process.pid`, and tight write-time window.
|
||||
- Implication: escalate when the write follows a downloaded document, email attachment, archive extraction, or web referrer outside the same recognized workflow; lower suspicion when provenance points to a recognized deployment package or Office integration source. Missing provenance is inconclusive, not benign.
|
||||
|
||||
- Did the executed file produce malicious follow-on process or file activity?
|
||||
- Focus: process and file events scoped to executed `process.entity_id`: child `process.parent.entity_id`, child `process.command_line`, and new `file.path` values.
|
||||
- Hint: if records are incomplete or the entity pivot returns none, use the same host, executed `process.pid`, and post-start window.
|
||||
- Implication: escalate when the payload launches script interpreters, LOLBins, unpackers, or additional binaries, or stages files outside the recognized product tree; lower urgency when follow-on activity stays limited to expected local install or update actions. Preserve Office-written DLLs, scripts, or shortcut launchers in the same scope as adjacent payload variants.
|
||||
|
||||
- If local findings remain suspicious or unresolved, do related alerts show the same delivery chain or spread?
|
||||
- Focus: related alerts for `host.id`, then pivot on recovered stable `user.id`; prioritize document delivery, script execution, persistence, and outbound connection alerts. $investigate_0
|
||||
- Implication: broaden scope when related alerts connect the same host or user to delivery, scripting, persistence, or beaconing; keep scope local when the sequence is isolated and local evidence supports one recognized workflow.
|
||||
|
||||
- Escalate when sequence, artifact, identity, delivery, behavior, or related-alert evidence supports suspicious Office write-to-execute activity; close only when all categories align with one recognized add-in, updater, or integration workflow and no contradictory artifacts remain; if evidence is mixed or incomplete, preserve artifacts and escalate.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Office add-in, repair, updater, document-management, e-signature, DLP, or collaboration integrations can write and launch helper executables. Confirm that writer identity, written path, executed hash or signer, parent context, provenance, command line, and follow-on activity all point to the same product or integration workflow. If records are unavailable, require telemetry-only recurrence of the same writer, path tree, signer/hash pattern, and `host.id` or `user.id` cohort across prior alerts.
|
||||
- Before creating an exception, validate that the same Office writer, path tree, executed signer or `process.hash.sha256`, provenance pattern, and `host.id`/`user.id` cohort recur across prior alerts from this rule. Build the exception from that minimum workflow pattern; avoid exceptions on Office process names, `process.name`, or `file.extension` alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse temporary containment and document the writer identity, written path tree, executed hash and signer, parent/delivery context, and recurrence evidence. Create an exception only for the same stable workflow pattern.
|
||||
- If suspicious but unconfirmed, preserve Timeline source events, copies of the written executable and source document/archive, process tree details, recovered entity IDs, command line, hash, path, and provenance URLs before containment. Apply reversible containment first: quarantine the lure or executable, block the confirmed hash/path temporarily where controls support it, or increase monitoring on the affected `host.id` and `user.id`. Isolate the host only if follow-on process/file evidence shows malicious staging or execution and the host can tolerate interruption.
|
||||
- If confirmed malicious, isolate the host and terminate the executed payload after preserving the source events, process tree, written executable, lure document or archive, hash, signer, and provenance evidence. Block the confirmed hash or path where controls support it, then remove the malicious executable, lure, archive, and staged files identified during the investigation.
|
||||
- Review related hosts and users for the same written path pattern, executed hash, signer, and provenance evidence before deleting artifacts. Then remediate the delivery path, such as the phishing message, archive, or malicious Office document, that led to the write-execute sequence.
|
||||
- Post-incident hardening: restrict Office-driven writes and launches of executable content in user-writable paths, retain endpoint file-provenance and process-start telemetry, and record confirmed adjacent variants, such as Office-written DLLs, scripts, or shortcut launchers, in the case history for future triage.
|
||||
"""
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"kibana.alert.reason",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File events for the written executable path"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "file.path", queryType = "phrase", value = "{{file.path}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-2h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the executed file hash"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "process.hash.sha256", queryType = "phrase", value = "{{process.hash.sha256}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
creation_date = "2025/08/21"
|
||||
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/07"
|
||||
|
||||
|
||||
updated_date = "2026/05/01"
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies suspicious execution patterns using NodeJS interpeter like process path and arguments.
|
||||
Identifies suspicious Node.js execution patterns, including user-writable runtimes, preload arguments, and inline
|
||||
eval, decode, or child-process usage.
|
||||
"""
|
||||
|
||||
from = "now-9m"
|
||||
@@ -26,7 +25,10 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Suspicious Execution with NodeJS"
|
||||
references = ["https://nodejs.org"]
|
||||
references = [
|
||||
"https://nodejs.org/api/child_process.html",
|
||||
"https://nodejs.org/api/globals.html#atobdata",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "55f711c1-6b4d-4787-930d-c9317a885adf"
|
||||
severity = "high"
|
||||
@@ -53,48 +55,167 @@ process where host.os.type == "windows" and event.type == "start" and
|
||||
(process.name : "node.exe" or ?process.pe.original_file_name == "node.exe" or ?process.code_signature.subject_name : "OpenJS Foundation") and
|
||||
|
||||
(
|
||||
(process.executable : ("?:\\Users\\*\\AppData\\*\\node.exe", "\\Device\\HarddiskVolume?\\\\Users\\*\\AppData\\*\\node.exe") and process.args : "*.js") or
|
||||
(process.executable : ("?:\\Users\\*\\AppData\\*\\node.exe", "\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\node.exe") and process.args : "*.js") or
|
||||
|
||||
(process.args : "-r" and process.parent.name : "powershell.exe") or
|
||||
|
||||
process.command_line : ("*eval(*", "*atob(*", "*require*child_process*")
|
||||
)
|
||||
'''
|
||||
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.
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Suspicious Execution with NodeJS
|
||||
|
||||
Windows scripts, often used for legitimate automation tasks, can be exploited by adversaries to execute malicious code. Attackers may download scripts via browsers or file utilities, then execute them using scripting tools like wscript or mshta. The detection rule identifies such threats by monitoring script creation from internet sources and subsequent execution, focusing on unusual parent-child process relationships and script attributes.
|
||||
#### Possible investigation steps
|
||||
|
||||
### Possible investigation steps
|
||||
- Which Node execution path did the alert capture?
|
||||
- Focus: `process.executable`, `process.command_line`, `process.parent.name`, and `process.pe.original_file_name`.
|
||||
- Implication: escalate faster when the match is a user-writable AppData "node.exe", PowerShell-launched preload, or inline decode/spawn pattern; lower suspicion when parent and command-line evidence show a recognized version-manager, IDE, package-manager, or test-runner pattern.
|
||||
|
||||
- Analyze the execution event of the scripting utility (node.exe) to identify the command-line arguments used, which may provide insight into the script's intended actions.
|
||||
- Review node.exe network, files and child process events for any suspicious activity.
|
||||
- Verify parent and grand parent processes to assess persence of persistence and the potential initial vector.
|
||||
- Check the user account associated with the script execution to determine if the activity is expected for that user or if it indicates a compromised account.
|
||||
- Look for any additional related alerts or logs on the host that might indicate further malicious activity or lateral movement following the script execution.
|
||||
- Do the runtime identity and launcher context fit recognized Node use?
|
||||
- Focus: `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.parent.command_line`, `user.id`, and `host.id`.
|
||||
- Implication: escalate when the runtime is unsigned, renamed, mismatched to "node.exe", staged from Temp/AppData outside a recognized toolchain, or launched by PowerShell, Office, a browser, an archive utility, or a download path without matching IDE/package/build context; lower suspicion only when runtime identity and parent chain fit the same recurring Node workflow for that user or host. Identity alone does not clear suspicious arguments.
|
||||
|
||||
- What do the arguments show about preload, script, or inline execution intent?
|
||||
- Why: "-r" / "--require" preloads a module at startup; "child_process" enables OS subprocess creation.
|
||||
- Focus: `process.command_line` and the script or preload path parsed from it.
|
||||
- Implication: escalate when Node preloads an unexpected module, decodes inline content with 'atob(' or 'eval(', or references "child_process"; lower suspicion when the target is a recognized preload such as a test harness, transpiler, or source-map helper inside the same project tree.
|
||||
|
||||
- If endpoint file telemetry is available, what provenance exists for the script or preload module?
|
||||
- Focus: recover file events with `host.id` + `process.entity_id`, or `host.id` + `process.pid` + a tight alert window as weaker fallback; inspect `file.path`, `file.origin_url`, `file.Ext.windows.zone_identifier`, and `file.Ext.original.path`. $investigate_2
|
||||
- Hint: missing file telemetry is unresolved, not benign; use parsed command-line paths and parent context as weaker evidence.
|
||||
- Implication: escalate when the script or module was downloaded, extracted, renamed, or staged into AppData/Temp shortly before execution; lower suspicion when it stays in a stable repository, package cache, or product install tree consistent with the parent workflow.
|
||||
|
||||
- If child-process or endpoint network telemetry is available, what did Node do next?
|
||||
- Focus: recover child and network events with `host.id` + `process.entity_id`, or `host.id` + `process.pid` + the post-start window as weaker fallback; inspect child `process.name` / `process.executable`, DNS `dns.question.name`, and connection `destination.ip` / `destination.port`.
|
||||
- $investigate_3
|
||||
- $investigate_4
|
||||
- Hint: separate DNS events from connection events before interpreting destinations; missing child or network telemetry is unresolved, not benign.
|
||||
- Implication: escalate when Node quickly launches shells, LOLBins, archivers, credential tooling, or reaches externally routable destinations unrelated to the workflow; lower suspicion when child activity and destinations stay bounded to recognized local development, build, package-registry, or deployment services.
|
||||
|
||||
- If local evidence stays suspicious or unresolved, do related alerts show broader scripting, download, persistence, or beaconing activity?
|
||||
- Focus: same-`user.id` related alerts or process events, especially PowerShell, archive, downloader, persistence, and outbound-connection activity.
|
||||
- Hint: if `user.id` is missing or ambiguous, review same-host alerts and process events for `host.id` in the last 48 hours.
|
||||
- $investigate_0
|
||||
- $investigate_1
|
||||
- Implication: expand scope when the host or user shows staged payload delivery, repeated Node misuse, persistence, or beaconing; keep scope local when behavior is isolated and local evidence supports one recognized workflow.
|
||||
|
||||
- Escalate when branch, runtime, argument, lineage, or recovered artifact/child/network evidence shows staged script, unrecognized preload, inline decode, or spawn abuse; close only when those categories tightly support one recognized workflow with no contradictions; preserve artifacts and escalate when evidence is mixed or incomplete.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate script automation tools may trigger this rule if they download and execute scripts from the internet. Users can create exceptions for known safe tools by excluding specific file paths or process names.
|
||||
- Software updates or installations that download scripts as part of their process might be flagged. To handle this, users can whitelist specific origin URLs or referrer URLs associated with trusted software vendors.
|
||||
- Internal scripts distributed via corporate intranet sites could be misidentified as threats. Users should consider excluding scripts with known internal origin URLs or specific user IDs associated with IT operations.
|
||||
- Browser extensions or plugins that automate tasks using scripts may cause false positives. Users can exclude these by identifying and excluding the specific browser process names or file extensions involved.
|
||||
- Frequent use of file utilities like winrar or 7zFM for legitimate script handling can be excluded by specifying trusted file paths or user IDs that regularly perform these actions.
|
||||
- Developer tooling, version managers, IDEs, package managers, and build/test runners can legitimately run "node.exe" from user-space paths or use "-r" preloads. Confirm one workflow: runtime path/hash/signer, parent, command line, and referenced script or preload path all align with the same toolchain. Without inventory or build records, telemetry-only closure requires exact workflow recurrence for the same `user.id` or `host.id` cohort plus no contradictory file, child-process, or network evidence; do not close on recurrence alone.
|
||||
- Treat partial matches as unresolved. An OpenJS signer, "node.exe" name, or familiar parent does not explain AppData execution, inline decode/eval, or child-process behavior by itself. Before creating an exception, validate recurrence of the same Node binary, argument pattern, parent context, and script or preload path; avoid exceptions on `process.name` or `process.code_signature.subject_name` alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Isolate the affected system from the network to prevent further execution of potentially malicious scripts and lateral movement.
|
||||
- Terminate any suspicious processes identified in the alert, such as wscript.exe or mshta.exe, to stop the execution of the downloaded script.
|
||||
- Quarantine the downloaded script file and any associated files to prevent further execution and facilitate forensic analysis.
|
||||
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any additional malicious files or remnants.
|
||||
- Review and analyze the origin URL and referrer URL of the downloaded script to identify potential malicious websites or compromised sources, and block these URLs at the network level.
|
||||
- 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 application whitelisting to restrict the execution of unauthorized scripts and scripting utilities, reducing the risk of similar threats in the future."""
|
||||
- If confirmed benign, reverse temporary containment and document the exact Node workflow: runtime path/hash/signer, parent launcher, command line, script or preload path, and `user.id` / `host.id` scope. Create an exception only when the same workflow recurs consistently across prior alerts from this rule.
|
||||
- If suspicious but unconfirmed, preserve the process start event, command line, binary hash/signature, script or preload artifact, child process chain, and any recovered DNS or connection events before containment. Apply reversible containment tied to the finding, such as temporary destination blocking, script quarantine, or heightened monitoring on the affected `host.id` and `user.id`. Escalate to host isolation only when follow-on execution, persistence, or outbound activity confirms broader compromise and host criticality allows interruption.
|
||||
- If confirmed malicious, preserve `process.entity_id` or `process.pid` with `host.id` and time, parent process context, `process.command_line`, `process.hash.sha256`, referenced script or preload paths, child-process lineage, and confirmed network indicators before terminating Node or isolating the host. If direct endpoint response is unavailable, hand off that artifact set to the team that can isolate the system or block destinations.
|
||||
- Scope related hosts and users for the same runtime hash, suspicious command-line pattern, script/preload paths, child-process lineage, and network indicators before deleting scripts, modules, or staged payloads. Then remove only the malicious artifacts identified during triage and remediate the delivery path or launcher that led to Node execution.
|
||||
- Post-incident hardening: restrict unrecognized "node.exe" execution from user-writable paths, retain process-start, file-provenance, and network telemetry, and document adjacent variants found during triage, such as renamed Node runtimes, packaged Electron launchers, alternate preload patterns, or `--require` abuse without PowerShell."""
|
||||
|
||||
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:
|
||||
|
||||
- [CrowdStrike](https://ela.st/crowdstrike-integration)
|
||||
- [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)
|
||||
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.entity_id",
|
||||
"process.pid",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.args",
|
||||
"process.working_directory",
|
||||
"process.pe.original_file_name",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"process.hash.sha256",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File events for the Node process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Child processes spawned by Node"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network events for the Node process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2026/02/16"
|
||||
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/07"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -21,38 +21,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Potential Notepad Markdown RCE Exploitation"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential Notepad Markdown RCE Exploitation
|
||||
|
||||
This rule detects a new child process launched by `notepad.exe` when Notepad was opened with a Markdown (`.md`) file.
|
||||
This behavior can indicate exploitation of a Notepad remote code execution vulnerability where crafted Markdown content
|
||||
triggers unintended process execution.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Validate the parent-child relationship and confirm `notepad.exe` is the direct parent of the suspicious process.
|
||||
- Review the full command line of both parent and child processes, including the Markdown file path in `process.parent.args`.
|
||||
- Identify the Markdown file source (email attachment, browser download, chat client, removable media, or network share).
|
||||
- Inspect process ancestry and descendants for additional payload execution, script interpreters, or LOLBIN activity.
|
||||
- Correlate with file, registry, and network events around the same timestamp to identify follow-on behavior.
|
||||
- Determine whether the child process and its execution path are expected in your environment.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate automation or editor extensions may occasionally spawn helper processes from Notepad workflows.
|
||||
- User-driven workflows that invoke external tools from Markdown previews can trigger this behavior.
|
||||
- If benign, tune by excluding known-safe child process names, hashes, signed binaries, and approved file paths.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Isolate affected endpoints until scope is understood.
|
||||
- Terminate suspicious child and descendant processes initiated from `notepad.exe`.
|
||||
- Quarantine and preserve the triggering Markdown file for forensic analysis.
|
||||
- Run endpoint malware scans and collect volatile artifacts (running processes, network connections, autoruns).
|
||||
- Patch Windows/Notepad to the latest security update level addressing the vulnerability.
|
||||
- Hunt for the same parent-child pattern across other hosts to identify additional impacted systems.
|
||||
"""
|
||||
references = ["https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-20841"]
|
||||
risk_score = 73
|
||||
rule_id = "7f3521dd-fb80-4548-a7eb-8db37b898dc2"
|
||||
@@ -78,6 +46,175 @@ process where host.os.type == "windows" and event.type == "start" and
|
||||
not process.executable : "C:\\Program Files\\WindowsApps\\Microsoft.WindowsNotepad_*\\Notepad\\Notepad.exe"
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential Notepad Markdown RCE Exploitation
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What exact Notepad-to-child path did the alert preserve?
|
||||
- Why: CVE-2026-20841 abuse centers on Markdown link handling that invokes unsafe protocol handlers, so the launched child and target are decisive.
|
||||
- Focus: `process.parent.executable`, `process.parent.command_line`, `process.parent.args`, child `process.executable`, and child `process.command_line`.
|
||||
- Implication: escalate when Notepad opened Markdown and launched a shell, script host, downloader, browser, archive handler, installer, or custom protocol handler with a URL, UNC path, file URI, app installer URI, or staged payload; lower suspicion only when child and target match a confirmed validation workflow.
|
||||
|
||||
- What does child binary identity add to command intent?
|
||||
- Focus: child `process.executable`, `process.hash.sha256`, `process.code_signature.subject_name`, `process.code_signature.trusted`, and `process.pe.original_file_name`.
|
||||
- Implication: escalate when the child is unsigned, user-writable, signer/name-mismatched, or unusual for Markdown link handling; reduce suspicion only when signer, path, hash history, and command target all fit the same confirmed validation workflow.
|
||||
|
||||
- Does parent launch context point to lure delivery or controlled use?
|
||||
- Focus: Markdown path from `process.parent.args`, `process.parent.command_line`, `user.id`, `host.id`, and `host.name`.
|
||||
- Implication: escalate when the path is in downloads, mail or chat caches, temp, removable media, network shares, or lure-like filenames; lower suspicion only when source path and child target match a confirmed validation case for the same user or host.
|
||||
|
||||
- Did the child start more exploit-chain processes?
|
||||
- Focus: process events on `host.id` where `process.parent.entity_id` links to `process.entity_id`, recording descendant `process.executable` and `process.command_line`. $investigate_4
|
||||
- Hint: prefer entity ID-linked descendants; treat PID-only matches as candidates tightly anchored to `@timestamp`. Inspect `process.Ext.ancestry` only when direct lineage is incomplete.
|
||||
- Implication: escalate for descendant shells, script interpreters, LOLBins, installers, payload runners, or browser-to-download chains; no descendants limits process scope but does not clear the Notepad launch.
|
||||
|
||||
- Did the child stage artifacts for later execution?
|
||||
- Focus: if file telemetry exists, review process-scoped `file.path`, `file.Ext.original.path`, and later `process.executable` reuse of a written path. $investigate_0
|
||||
- Hint: recover with `host.id` + `process.entity_id`; if unavailable, use `host.id` + `process.pid` + a tight alert window. Missing file telemetry is unresolved, not benign.
|
||||
- Implication: escalate when the child writes executables, scripts, shortcuts, archives, or renamed payloads to user-writable paths, or a written artifact later runs; clean available file telemetry means staging is not corroborated, not that the alert is benign.
|
||||
|
||||
- Did the child contact payload-delivery destinations?
|
||||
- Focus: if DNS or connection telemetry exists, review `dns.question.name`, `destination.ip`, and `destination.port`. $investigate_1
|
||||
- Hint: recover with `host.id` + `process.entity_id`; if unavailable, use `host.id` + `process.pid` + a tight alert window. Missing DNS or connection telemetry is unresolved, not benign.
|
||||
- Implication: escalate when the child resolves or connects to rare, external, newly introduced, or delivery-oriented destinations outside its role; clean available network telemetry removes one corroborator but cannot override suspicious alert-local execution.
|
||||
|
||||
- If local evidence is suspicious or unresolved, does the pattern change scope?
|
||||
- Focus: related alerts for the same `user.id` over 48 hours, comparing child `process.executable`, child `process.command_line`, and source-path patterns from `process.parent.args` when present. $investigate_2
|
||||
- Hint: if the user view is empty or ambiguous, compare related alerts for the same `host.id` over 48 hours before broadening. $investigate_3
|
||||
- Implication: broaden when related alerts show the same Notepad-child pattern, source-path family, or delivery indicator across unrelated users or hosts; use recurrence for scope only, not benign closure.
|
||||
|
||||
- Escalate when child intent, descendant lineage, artifact staging, or destinations point to payload delivery, even if one conditional telemetry family is absent; close only when source path, child identity, command target, and `user.id`/`host.id` context prove one benign workflow; preserve evidence and escalate when telemetry is missing or contradictory.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Authorized CVE validation, QA, or security lab activity can trigger this rule when controlled Markdown samples intentionally launch a stable helper. Confirm `process.parent.args`, child `process.executable`, child hash or signer, child `process.command_line`, and `user.id`/`host.id` cohort all match the same validation workflow; prior alerts support stability only after those anchors align.
|
||||
- Before creating an exception, validate stability for the same child identity, child command-target pattern, Markdown path family from `process.parent.args`, and `user.id` or `host.id` scope. Avoid exceptions on `process.parent.name`, `process.name`, or Notepad alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign:
|
||||
- Reverse temporary containment and record the Markdown path, child process identity, command target, and cohort evidence that confirmed the benign workflow. Build an exception only for the same stable `user.id` or `host.id` scope and child identity.
|
||||
- If suspicious but unconfirmed:
|
||||
- Preserve the triggering Markdown file, parent `process.parent.command_line`, child `process.entity_id`, child `process.command_line`, descendant process identifiers, written artifact paths, and DNS or IP indicators before cleanup.
|
||||
- Apply reversible containment tied to observed indicators, such as temporary restriction of the observed destination or heightened monitoring on the affected `host.id` and `user.id`.
|
||||
- Escalate to host isolation if the child continues spawning payloads, downloading content, or contacting suspicious destinations after preservation.
|
||||
- If confirmed malicious:
|
||||
- Isolate the host first, then stop the malicious child and descendant `process.entity_id` values after recording `process.entity_id`, `process.command_line`, the Markdown path from `process.parent.args`, and related artifact or destination indicators. If direct response is unavailable, hand off the preserved evidence set to the containment team.
|
||||
- Block confirmed malicious domains, IPs, URLs, hashes, and child process paths identified during the investigation.
|
||||
- Eradicate only the dropped files, startup artifacts, scheduled tasks, registry changes, and payload runners tied to the exploit chain, then quarantine the triggering Markdown file and remediate its delivery path.
|
||||
- Post-incident hardening:
|
||||
- Update the Windows Notepad App to a version that remediates CVE-2026-20841, and restrict unsafe protocol-handler launch exposure for Markdown viewers where enterprise controls support it.
|
||||
- Preserve or expand file and network telemetry if missing visibility prevented confirmation of Markdown source, payload staging, or destination activity.
|
||||
- Record the Markdown delivery path, child-process pattern, and adjacent protocol-handler or payload variants in the case notes.
|
||||
"""
|
||||
|
||||
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.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.entity_id",
|
||||
"process.pid",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.hash.sha256",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"process.code_signature.status",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"process.parent.args",
|
||||
"process.working_directory",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File events for the same child process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network events for the same child process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Child process events for the Notepad-spawned child"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
|
||||
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2024/05/08"
|
||||
integration = ["windows"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/02/09"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -12,90 +12,15 @@ example, public tool author names). Attackers often run public PowerShell toolin
|
||||
artifacts in comments or headers.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = ["winlogbeat-*", "logs-windows.powershell*"]
|
||||
index = ["logs-windows.powershell*", "winlogbeat-*"]
|
||||
language = "kuery"
|
||||
license = "Elastic License v2"
|
||||
name = "Potential PowerShell HackTool Script by Author"
|
||||
note = """## Triage and analysis
|
||||
|
||||
> **Disclaimer**:
|
||||
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
|
||||
|
||||
### Investigating Potential PowerShell HackTool Script by Author
|
||||
|
||||
This rule Detects PowerShell scripts that contains attribution strings commonly found in publicly available offensive PowerShell tooling. These artifacts are often present in headers or comment blocks but may also appear within embedded modules or minimally modified scripts. Use the script block content and metadata to reconstruct what ran, determine the likely source, and scope related activity across hosts and users.
|
||||
|
||||
#### Key alert fields to review
|
||||
|
||||
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
|
||||
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
|
||||
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
|
||||
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
|
||||
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
|
||||
- `powershell.file.script_block_length`: Script block length (size) context.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Capture basic context and triage priority:
|
||||
- Record `@timestamp`, `host.name`/`host.id`, and `user.name`/`user.domain`/`user.id`.
|
||||
- Use host and identity context (asset owner, role, and expected admin activity) to determine whether this execution is likely authorized for the alerted user and endpoint.
|
||||
|
||||
- Reconstruct the complete script block before making an assessment:
|
||||
- Review `powershell.file.script_block_text` and identify the specific author handle or attribution string and its surrounding lines.
|
||||
- If the content appears truncated or the event indicates multiple parts, use `powershell.file.script_block_id` together with `powershell.sequence` and `powershell.total` to assemble the full script in the correct order. Confirm all sequence parts are present.
|
||||
- Use `powershell.file.script_block_length` as additional context (for example, to distinguish short snippets from large modules) and preserve the reconstructed content for evidence and hunting.
|
||||
|
||||
- Determine the likely source of the script content:
|
||||
- If `file.path`/`file.name` (and `file.directory`) are present, treat this as file-backed execution and note whether the location and filename align with approved script storage or deployment paths for that host.
|
||||
- If `file.path` is a network share (UNC) or otherwise unusual for the host, treat it as higher risk until validated.
|
||||
- If file fields are absent, treat the script block as inline, interactive, or dynamically generated content. Prioritize review for scripts that fetch, decode, or build additional code at runtime.
|
||||
- If a file path is present, pivot on `file.path` and `file.name` to identify other executions or duplicates of the same script across users and hosts.
|
||||
|
||||
- Assess intent from the content and extract observables:
|
||||
- Determine whether the match is limited to comments/metadata or is accompanied by functional code.
|
||||
- Look for behaviors that commonly accompany offensive PowerShell tooling, such as broad host or domain discovery, credential access helpers, privilege manipulation, remote execution primitives, persistence logic, or payload delivery mechanisms.
|
||||
- Extract and record observables embedded in `powershell.file.script_block_text` (for example, domains, IPs, URLs, hostnames, usernames, file paths, or registry paths) and use them to pivot for additional activity.
|
||||
|
||||
- Scope and correlate related activity:
|
||||
- Search for additional script block events containing the same author handle within `powershell.file.script_block_text` across the environment. Start with the same `user.id` and `host.id`, then expand to other users and hosts.
|
||||
- On the same `host.name`, review other script block events from the same `user.name` in the minutes before and after the alert to identify setup actions (module imports, function definitions) and follow-on execution.
|
||||
- If other endpoint telemetry is available, correlate around `@timestamp` on the same host to identify:
|
||||
- The PowerShell host process and any parent process responsible for launching it.
|
||||
- Network connections, file writes, or registry changes consistent with the script content and extracted observables.
|
||||
- Authentication activity for `user.name` that could explain the session context (interactive use vs remote access).
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate administrative scripts may incorporate third-party modules that include author headers; these are typically file-backed and executed from expected locations or managed repositories.
|
||||
- False positives are more likely when the author string is isolated within comments and there is minimal additional script functionality; they are less likely when the script implements operational capabilities aligned with offensive tooling.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If activity is unauthorized or suspicious:
|
||||
- Preserve the full reconstructed script content (all parts) and retain supporting context: `powershell.file.script_block_id`, `host.id`, `host.name`, `user.id`, `user.name`, `user.domain`, and `@timestamp`.
|
||||
- Scope impact by searching for the same author handle and extracted observables across PowerShell script block logs to identify additional affected hosts and accounts.
|
||||
- If `file.path` is present, locate and quarantine the referenced script per your procedures and review the endpoint for other copies that share the same `file.name`.
|
||||
- Apply containment measures appropriate to the risk (for example, isolate the endpoint from the network) if the content indicates credential access, remote execution, or payload delivery.
|
||||
- Review the initiating account for compromise and take credential and access control actions consistent with your incident response process.
|
||||
|
||||
- If activity is authorized:
|
||||
- Document the activity (owner, timeframe, intended hosts) and validate alignment with change management or testing approvals.
|
||||
- Ensure the SOC has an up-to-date list of approved users and endpoints for testing. Consider environment-specific tuning to reduce recurring noise while preserving coverage elsewhere.
|
||||
|
||||
- Post-incident hardening:
|
||||
- Verify PowerShell logging coverage and retention are sufficient to reconstruct multi-part scripts during future investigations.
|
||||
- Use observed handles and extracted observables to perform retrospective searches for earlier executions and related activity patterns in historical script block logs.
|
||||
"""
|
||||
references = [
|
||||
"https://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0109_windows_powershell_script_block_log.md",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "2553a9af-52a4-4a05-bb03-85b2a479a0a0"
|
||||
setup = """## Setup
|
||||
|
||||
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
|
||||
Setup instructions: https://ela.st/powershell-logging-setup
|
||||
"""
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Domain: Endpoint",
|
||||
@@ -133,29 +58,84 @@ host.os.type:windows and event.category:process and
|
||||
"_nullbind" or "_tmenochet" or
|
||||
"jaredcatkinson" or "ChrisTruncer" or
|
||||
"monoxgas" or "TheRealWover" or
|
||||
"splinter_code"
|
||||
"splinter_code" or "samratashok" or
|
||||
"leechristensen" or "nikhil_mitt"
|
||||
) and
|
||||
not powershell.file.script_block_text : ("Get-UEFIDatabaseSigner" or "Posh-SSH")
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
[[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/"
|
||||
### Investigating Potential PowerShell HackTool Script by Author
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What did the alert-local author match show?
|
||||
- Focus: `powershell.file.script_block_text`, `powershell.file.script_block_length`, `file.path`, and `user.id` on `host.id`.
|
||||
- Implication: escalate when the handle appears beside executable functions, encoded strings, download, credential, discovery, remote-execution, or persistence logic; lower suspicion when it is only an inert header or comment in a recognized lab, test, or community-module path with harmless surrounding code.
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
- Can you reconstruct the complete script block before judging intent?
|
||||
- Focus: collect and order fragments on `host.id` with `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and `powershell.file.script_block_text`. $investigate_0
|
||||
- Implication: escalate when reconstruction reveals hidden stages, helper functions, obfuscation, decoding, or payload logic; keep unresolved if fragments are missing because they can hide decisive code.
|
||||
|
||||
- Was the script file-backed or fileless, and what does that say about delivery?
|
||||
- Focus: `file.path`, `file.directory`, and `file.name` when present; absent `file.path` suggests inline, generated, or interactive execution.
|
||||
- Implication: escalate when fileless execution, user-writable paths, shares, temp or staging folders, or suspicious names pair with hacktool code; lower suspicion when a stable repository, lab path, or community-module path matches benign content.
|
||||
|
||||
- Can you recover the PowerShell process and explain launch?
|
||||
- Focus: With endpoint process telemetry, recover the matching process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`. Capture `process.entity_id`, `process.command_line`, `process.parent.executable`, and `process.parent.command_line`. $investigate_1
|
||||
- Hint: confirm timestamps to reduce PID-reuse ambiguity; if no process start event appears, expand time before falling back to `host.id`, `user.id`, and alert time.
|
||||
- Implication: escalate when a document, browser, chat client, remote-management tool, scheduled task, service, or unexpected script host launched the code without matching lab, assessment, support, or deployment evidence; lower suspicion when lineage matches the exact workflow proven by script content.
|
||||
|
||||
- What capability or observables move this beyond attribution text?
|
||||
- Focus: reconstructed script for credential access, discovery, remote execution, payload delivery, persistence, AMSI or logging tampering, reflection, or decode-and-execute logic; extract domains, IPs, URLs, paths, accounts, registry targets, and reusable function or module names.
|
||||
- Implication: escalate when the body implements offensive capability or yields high-signal observables; lower suspicion only when it remains benign utility logic tied to a recognized workflow.
|
||||
|
||||
- Did script-extracted file or registry targets appear on the host?
|
||||
- Focus: With file or registry telemetry, search same-PID events around `@timestamp` for extracted `file.path`, `registry.path`, `registry.value`, or `registry.data.strings`. $investigate_4
|
||||
- Implication: escalate when extracted payload paths are created or executed, or registry targets indicate persistence or security changes; missing artifact or configuration telemetry is unresolved, not benign.
|
||||
|
||||
- Did extracted network or identity observables confirm active offensive use?
|
||||
- Focus: With network telemetry, search same-PID DNS and connection events for extracted domains in `dns.question.name` or `dns.resolved_ip` and IPs in `destination.ip`. $investigate_5 Review Windows 4624 or 4648 with `winlog.event_data.TargetUserName` and `winlog.event_data.SubjectUserName` for extracted accounts.
|
||||
- Implication: escalate when the host contacts extracted infrastructure, downloads content, or shows remote, credential, or lateral-use evidence. Missing network or authentication telemetry is unresolved, not benign.
|
||||
|
||||
- If the script content or launch chain remains suspicious or unresolved, does recurrence change scope?
|
||||
- Focus: related alerts for `user.id` in the last 48 hours, comparing author string, reconstructed script body, file source, launch pattern, and extracted observables. $investigate_2
|
||||
- Hint: if the user view is quiet or ambiguous, compare related alerts for `host.id` in the last 48 hours. $investigate_3
|
||||
- Implication: broaden when the same script body or extracted observables reach unrelated users or hosts; keep local when recurrence stays within the same lab, assessment, support, or deployment host/user cohort. Do not close on recurrence alone if script content or recovery remains unresolved.
|
||||
|
||||
- Escalate on reconstructed capability, unauthorized launch, follow-on evidence, or missing/conflicting required telemetry; close only when the author match, reconstructed script, source path, launch context, observables, and `user.id` or `host.id` scope bind one exact benign workflow, with outside confirmation when telemetry cannot verify it.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Authorized testing, red-team, malware-analysis, validation, community-module, or admin scripts can retain author strings. Confirm the reconstructed body, exact `user.id` and `host.id` scope, `file.path` or launch context, recognized test or lab records when telemetry cannot prove legitimacy, and no contradictory observables or follow-on activity.
|
||||
- Before creating an exception, validate recurrence of the same benign workflow with the same `powershell.file.script_block_text` fragment, `file.path` or launch source, and `user.id` or `host.id` scope. Avoid author-string-only exceptions because unrelated offensive scripts can reuse the same handle.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign:
|
||||
- Reverse temporary containment and document the reconstructed script, source path, launch context, `user.id`, and `host.id` evidence confirming the legitimate workflow. Build an exception only for that exact workflow and scope.
|
||||
- If suspicious but unconfirmed:
|
||||
- Preserve or export alert details, reconstructed script with fragment metadata, process PID, source path, extracted indicators, and recovered launch details before containment or cleanup.
|
||||
- Apply reversible containment tied to the evidence, such as temporary restrictions for extracted destinations or heightened monitoring on affected `host.id` and `user.id`.
|
||||
- Escalate to host isolation or stronger account action only if the script is still executing, staging payloads, reaching suspicious destinations, or showing credential or lateral-use evidence, and the host role tolerates isolation.
|
||||
- If confirmed malicious:
|
||||
- Preserve the reconstructed script, recovered process entity ID and launch details, extracted indicators, staged artifacts, and timeline before isolation, process termination, or cleanup.
|
||||
- Isolate the host when script capability, launch context, follow-on artifacts, or destination evidence confirms unauthorized activity and the host role tolerates isolation.
|
||||
- Block confirmed malicious destinations, URLs, file hashes, and script paths found during triage.
|
||||
- Eradicate only dropped files, registry changes, scheduled tasks, services, and follow-on payloads tied to this script, then remediate the path that delivered or launched it.
|
||||
- Review related hosts and users for the same author string, reconstructed script body, or extracted indicators before destructive cleanup so scoping is complete.
|
||||
- Post-incident hardening:
|
||||
- Verify PowerShell 4104 logging coverage and retention are sufficient to reconstruct multi-part scripts and preserve process recovery context.
|
||||
- Restrict authorized testing of public offensive PowerShell tooling to controlled hosts and identities.
|
||||
- Document matched author strings, extracted observables, and author-stripped or rebranded variants surfaced during triage for future analyst reference.
|
||||
"""
|
||||
|
||||
setup = """## Setup
|
||||
|
||||
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
|
||||
Setup instructions: https://ela.st/powershell-logging-setup
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
@@ -176,3 +156,105 @@ field_names = [
|
||||
"powershell.file.script_block_length"
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Script block fragments for the same script"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the PowerShell instance"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "File and registry events for the PowerShell PID"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "registry", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network and DNS events for the PowerShell PID"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
],
|
||||
[
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "dns", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
|
||||
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[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.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[metadata]
|
||||
creation_date = "2025/04/16"
|
||||
maturity = "production"
|
||||
updated_date = "2026/02/09"
|
||||
updated_date = "2026/05/01"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -14,78 +14,6 @@ from = "now-9m"
|
||||
language = "esql"
|
||||
license = "Elastic License v2"
|
||||
name = "Potential Malicious PowerShell Based on Alert Correlation"
|
||||
note = """## Triage and analysis
|
||||
|
||||
> **Disclaimer**:
|
||||
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
|
||||
|
||||
### Investigating Potential Malicious PowerShell Based on Alert Correlation
|
||||
|
||||
This alert groups multiple PowerShell-related detections that reference the same ScriptBlock identifier. When several independent detections fire on a single script block, it often indicates a single execution chain combining multiple suspicious behaviors. Treat the contributing alerts as the primary evidence and use this correlation to prioritize investigation and scoping.
|
||||
|
||||
Investigation goals:
|
||||
- Identify affected endpoints and users by pivoting to the contributing alerts.
|
||||
- Recover the complete script content associated with the ScriptBlock identifier and understand its intent.
|
||||
- Identify follow-on behavior (process, network, persistence) and scope the activity across the environment.
|
||||
|
||||
#### Key alert fields to review
|
||||
|
||||
- `Esql.script_block_id`: The ScriptBlock identifier used to correlate multiple alerts.
|
||||
- `Esql.kibana_alert_rule_name_count_distinct`: The number of distinct PowerShell-related rule names that contributed to the correlation.
|
||||
- `Esql.kibana_alert_rule_name_values`: The contributing rule names; use this list to quickly understand what detection logic was triggered.
|
||||
- `Esql._id_values`: The contributing alert document IDs; pivot to these source alerts for full context and supporting evidence.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Understand what drove the correlation:
|
||||
- Review `Esql.kibana_alert_rule_name_count_distinct` to gauge overall confidence and urgency.
|
||||
- Review `Esql.kibana_alert_rule_name_values` and group the contributing detections by behavior (for example, obfuscation/encoding, suspicious execution, network retrieval, or persistence-related activity). Use this grouping to decide what evidence is most important to validate first.
|
||||
|
||||
- Pivot to the contributing alerts and capture execution context:
|
||||
- Use `Esql._id_values` to open each contributing alert and collect the affected host and user context, along with the earliest and latest timestamps across the set.
|
||||
- Confirm the contributing alerts represent the same ScriptBlock ID and are not unrelated alerts that happen to share similar message content.
|
||||
- Identify whether the activity is limited to a single endpoint or appears on multiple endpoints. Multiple endpoints can indicate script reuse, distribution, or remote execution.
|
||||
|
||||
- Reconstruct the full script block content:
|
||||
- Using `Esql.script_block_id`, locate all available records (alerts and/or underlying telemetry referenced by the contributing alerts) tied to the same identifier.
|
||||
- If the script content is split across multiple fragments, reconstruct it in the correct order before assessing intent.
|
||||
- Identify any decoded/deobfuscated output that the script generates during execution and capture it as evidence for scoping.
|
||||
|
||||
- Assess intent and capability based on the recovered script:
|
||||
- Look for evidence of staged execution, such as multiple layers of decoding, dynamic code generation, or invocation of additional code.
|
||||
- Identify indicators that can be used for scoping (for example, external destinations, file locations, created services, or suspicious child process activity referenced by the contributing alerts).
|
||||
|
||||
- Correlate with adjacent activity during the same timeframe:
|
||||
- Process activity: check for unusual parent-child relationships involving PowerShell and unexpected child processes following the script block execution.
|
||||
- Network activity: review outbound connections and DNS activity that align with the execution window, especially first-time or rare destinations.
|
||||
- File and registry activity: look for payload staging, configuration changes, or persistence artifacts created near the execution window.
|
||||
- Authentication activity: review for suspicious logons or account changes that coincide with the script execution, especially if activity spans multiple endpoints.
|
||||
|
||||
- Scope and hunt for additional occurrences:
|
||||
- Search for other alerts containing the same `Esql.script_block_id` to determine if the script was reused or executed repeatedly.
|
||||
- Use indicators and behaviors observed in the contributing alerts to identify related activity in other alerts and telemetry sources, and establish first-seen/last-seen boundaries.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate administrative automation can produce multiple detections if it uses dynamic script generation, embedded encoded content, or downloads content at runtime. Validate whether the affected hosts, users, and timing align with an approved maintenance activity.
|
||||
- If the same ScriptBlock content repeatedly maps to a known benign workflow, document the expected behavior and tune upstream detections to better distinguish that workflow, rather than suppressing this correlation rule.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If the activity is confirmed or strongly suspected to be malicious:
|
||||
- Contain impacted endpoints to prevent additional execution and follow-on actions.
|
||||
- Restrict, reset, or rotate credentials for involved accounts as appropriate, especially for privileged or shared accounts.
|
||||
- Remove identified artifacts and persistence mechanisms (for example, suspicious services or dropped binaries) and remediate any affected systems.
|
||||
- Block or monitor indicators identified from the contributing alerts (external destinations, file locations, or other observable artifacts) to prevent reinfection and support hunting.
|
||||
|
||||
- Validation and recovery:
|
||||
- Use `Esql.script_block_id` and the contributing alert set in `Esql._id_values` to verify that the activity has ceased and to identify any additional impacted endpoints.
|
||||
- Continue monitoring for recurrence of the same ScriptBlock ID or the contributing behaviors to confirm remediation effectiveness.
|
||||
|
||||
- Post-incident:
|
||||
- Preserve the recovered script content and the full set of contributing alerts as evidence.
|
||||
- Identify and address the initial execution mechanism indicated by the contributing alerts and improve preventative controls and logging coverage to reduce recurrence.
|
||||
"""
|
||||
risk_score = 73
|
||||
rule_id = "f770ce79-05fd-4d74-9866-1c5d66c9b34b"
|
||||
severity = "high"
|
||||
@@ -111,19 +39,115 @@ from .alerts-security.* metadata _id
|
||||
| where Esql.script_block_id is not null
|
||||
|
||||
// keep relevant fields for further processing
|
||||
| keep kibana.alert.rule.name, Esql.script_block_id, _id
|
||||
| keep kibana.alert.rule.name, Esql.script_block_id, _id, user.id, process.pid, host.id
|
||||
|
||||
// count distinct alerts and filter for matches above the threshold
|
||||
| stats
|
||||
Esql.kibana_alert_rule_name_count_distinct = count_distinct(kibana.alert.rule.name),
|
||||
Esql.kibana_alert_rule_name_values = values(kibana.alert.rule.name),
|
||||
Esql._id_values = values(_id)
|
||||
Esql._id_values = values(_id),
|
||||
Esql.user_id_values = values(user.id),
|
||||
Esql.process_pid_values = values(process.pid),
|
||||
Esql.host_id_values = values(host.id)
|
||||
by Esql.script_block_id
|
||||
|
||||
// Apply detection threshold
|
||||
| where Esql.kibana_alert_rule_name_count_distinct >= 5
|
||||
| eval user.id = MV_MIN(Esql.user_id_values),
|
||||
process.pid = MV_MIN(Esql.process_pid_values),
|
||||
host.id = MV_MIN(Esql.host_id_values)
|
||||
| keep host.id, user.id, process.pid, Esql.*
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential Malicious PowerShell Based on Alert Correlation
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What does the ES|QL grouped alert preserve about the suspicious PowerShell mix?
|
||||
- Focus: treat `Esql.script_block_id`, `Esql.kibana_alert_rule_name_values`, `Esql._id_values`, preserved `host.id` / `user.id`, and `Esql.kibana_alert_rule_name_count_distinct` as search clues, not evidence.
|
||||
- Implication: escalate if rule names span obfuscation, download, execution, persistence, credential access, or defense evasion for one host/user; lower suspicion only when recovered source alerts/events show one recognized detection-validation script or controlled encoded-content automation pattern.
|
||||
|
||||
- Do the contributing alerts bind the summary to one script execution?
|
||||
- Focus: recover contributing alerts around grouped-alert time using preserved host/user, `Esql.kibana_alert_rule_name_values`, and script-block ID; use `Esql._id_values` only when alert search supports those IDs.
|
||||
- Hint: recover contributing alerts before interpreting grouped behavior; ES|QL grouped alerts lack member-event Timeline pivots and reliable source-event time, PID, or entity anchors.
|
||||
- Implication: treat as one execution chain only when source alerts and events align to one host, one user, one source-event window, and one script-block ID; keep unresolved if timestamps, script evidence, PID reuse risk, or entity scope conflict.
|
||||
|
||||
- Can you reconstruct and interpret the source PowerShell script block?
|
||||
- Focus: using recovered source-event host, process, and time, query PowerShell 4104 or source events; match `powershell.file.script_block_id`, order `powershell.sequence` / `powershell.total`, and read script-block text.
|
||||
- Implication: escalate when reconstructed text shows encoded/decoded stages, download cradles, reflection, hosted System.Management.Automation execution, credential access, persistence, or defense evasion; missing fragments or source PowerShell telemetry are unresolved, not benign.
|
||||
|
||||
- Which process and launch chain executed the script block?
|
||||
- Focus: use recovered time, `host.id`, and process identifiers to find the process start; collect `process.entity_id`, `process.command_line`, `process.parent.command_line`, and `process.Ext.authentication_id`.
|
||||
- Hint: if no process start appears, expand time first; if still missing, scope later file, registry, and network review to recovered source-event host/user/process/time.
|
||||
- Implication: escalate when the launcher is a document, browser, remote-management tool, scheduled task, unexpected script or .NET host, or command line with encoded, hidden, bypass, download, or dynamic evaluation; lower suspicion only when the same parent, command, user, and host bind to the exact recovered benign workflow.
|
||||
|
||||
- Did the process stage payloads, persistence, or security-impacting changes?
|
||||
- Focus: scope file and registry events to recovered `process.entity_id` or fallback source-event host/PID/time context; review `file.path`, `file.origin_url`, `registry.path`, `registry.value`, and `registry.data.strings`.
|
||||
- Implication: escalate when the script writes executable or scriptable content to user-writable or startup paths, leaves internet provenance, modifies persistence or security keys, or later executes staged content; lower suspicion only when artifacts stay inside the exact recovered benign workflow. Missing file or registry telemetry does not clear the alert.
|
||||
|
||||
- Did network or session evidence fit offensive PowerShell use?
|
||||
- Focus: scope DNS/connections to recovered `process.entity_id` or source-event host/PID/time context; read `dns.question.name`, `destination.ip`, and `destination.port`; when origin matters, bridge `process.Ext.authentication_id` to `winlog.event_data.TargetLogonId`.
|
||||
- Implication: escalate when the script reaches rare or public destinations, pulls content, contacts infrastructure unrelated to the recovered workflow, or runs from an unexpected remote session; missing network or Windows Security telemetry is unresolved, not benign.
|
||||
|
||||
- If local evidence is suspicious or unresolved, does the same pattern recur elsewhere enough to change scope?
|
||||
- Focus: related alerts for preserved `user.id` over 48 hours, looking for the same `Esql.kibana_alert_rule_name_values`, reconstructed script fragment, launch context, or extracted indicators. $investigate_0
|
||||
- Hint: if user-scoped alerts are quiet or ambiguous, compare related alerts for preserved `host.id` over 48 hours. $investigate_1
|
||||
- Implication: broaden response when the same script body, rule-name mix, or indicators appear on unrelated hosts or users; keep scope local when recurrence stays on the host under review, but do not close from recurrence alone.
|
||||
|
||||
- Weigh contributing-alert alignment, reconstructed script, launch chain, artifacts, destinations, and host/user scope; escalate for offensive tooling, unauthorized execution, staged payloads, persistence, or suspicious destinations; close only when source evidence binds to one exact benign workflow, using outside confirmation only for facts telemetry cannot prove; preserve artifacts and escalate on conflicts or missing telemetry.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Authorized red-team, lab, or detection-validation can trigger several PowerShell rules on one script. Confirm alert mix, reconstructed script, launch chain, `user.id`, and `host.id` match exact test scope; if records are unavailable, recurrence can support scoping but cannot close the alert.
|
||||
- Endpoint management or deployment automation can trigger multiple detections through encoded content, dynamic script generation, or controlled downloads. Confirm `powershell.file.script_block_text`, parent/child command lines, artifacts, and destinations align with one managed workflow. If script body, destinations, or follow-on artifacts diverge, do not close as benign.
|
||||
- Before an exception, validate stable benign anchors: `user.id`, `host.id`, parent/child command lines, script fragment, and destination or artifact pattern. Avoid exceptions on ES|QL summary fields or `Esql.script_block_id`; they are alert-local or execution-specific.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, document the alert mix, reconstructed script, launch chain, and recovered host/user context before reversing containment. Build exceptions from stable recovered workflow anchors, not ES|QL summary fields alone.
|
||||
- If suspicious but unconfirmed, preserve contributing alerts, `Esql._id_values`, `Esql.script_block_id`, rule-name values, reconstructed script text, recovered parent/child command lines, file/registry paths, and DNS/destination indicators before cleanup. Apply reversible containment first, such as temporary destination restrictions or heightened monitoring on recovered `host.id` and `user.id`; isolate or strengthen account action only if the script is still executing, staging payloads, or reaching suspicious destinations and host role allows.
|
||||
- If confirmed malicious, record entity IDs, command lines, and indicators, then isolate the host when lateral-movement or active-payload risk is present. Stop the PowerShell process or descendants only after preserving evidence; if direct response is unavailable, escalate with the evidence set. Block confirmed malicious destinations, URLs, hashes, and script paths; eradicate only tied files, registry changes, tasks, services, and payloads; remediate the launch path; and review related hosts/users before destructive cleanup.
|
||||
- Post-incident hardening: preserve or expand PowerShell 4104 logging, source-alert retention, endpoint process telemetry, and Windows Security logs when gaps limited recovery; where operations allow, restrict high-risk PowerShell through signed scripts, Constrained Language Mode, JEA, or WinRM controls. Document the rule-name mix, observables, and adjacent variants such as indirect System.Management.Automation execution.
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"host.id",
|
||||
"user.id",
|
||||
"process.pid",
|
||||
"Esql.script_block_id",
|
||||
"Esql._id_values",
|
||||
"Esql.kibana_alert_rule_name_values",
|
||||
"Esql.kibana_alert_rule_name_count_distinct",
|
||||
]
|
||||
|
||||
[transform]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the user"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Alerts associated with the host"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
|
||||
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-48h/h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
@@ -136,18 +160,7 @@ id = "T1059.001"
|
||||
name = "PowerShell"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/001/"
|
||||
|
||||
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"Esql.script_block_id",
|
||||
"Esql._id_values",
|
||||
"Esql.kibana_alert_rule_name_values",
|
||||
"Esql.kibana_alert_rule_name_count_distinct"
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user