From 61ee9caf8a47d1557fa504df0150965ec36e60aa Mon Sep 17 00:00:00 2001 From: Jonhnathan <26856693+w0rk3r@users.noreply.github.com> Date: Fri, 1 May 2026 17:02:56 -0300 Subject: [PATCH] [Rule Tuning] Windows High-Severity Rules Revamp - 5 (#6004) --- ..._access_mod_wdigest_security_provider.toml | 217 ++++++++++--- ...edential_access_posh_invoke_ninjacopy.toml | 262 +++++++++------- ...edential_access_posh_kerb_ticket_dump.toml | 271 ++++++++++------ .../credential_access_posh_minidump.toml | 293 ++++++++++-------- .../credential_access_posh_relay_tools.toml | 258 +++++++++------ ...credential_access_posh_request_ticket.toml | 279 ++++++++++------- ...ial_access_regback_sam_security_hives.toml | 198 +++++++++--- ...cess_relay_ntlm_auth_via_http_spoolss.toml | 198 +++++++++--- ...dential_access_remote_sam_secretsdump.toml | 200 +++++++++--- ...edelegationprivilege_assigned_to_user.toml | 243 +++++++++++---- 10 files changed, 1635 insertions(+), 784 deletions(-) diff --git a/rules/windows/credential_access_mod_wdigest_security_provider.toml b/rules/windows/credential_access_mod_wdigest_security_provider.toml index 01b035e3c..e091a428f 100644 --- a/rules/windows/credential_access_mod_wdigest_security_provider.toml +++ b/rules/windows/credential_access_mod_wdigest_security_provider.toml @@ -2,15 +2,15 @@ creation_date = "2021/01/19" integration = ["endpoint", "windows", "m365_defender"] maturity = "production" -updated_date = "2026/04/07" +updated_date = "2026/04/29" [rule] author = ["Elastic"] description = """ Identifies attempts to modify the WDigest security provider in the registry to force the user's password to be stored in -clear text in memory. This behavior can be indicative of an adversary attempting to weaken the security configuration of -an endpoint. Once the UseLogonCredential value is modified, the adversary may attempt to dump clear text passwords from -memory. +clear text in memory. Windows 8.1+ and Server 2012 R2+ disable WDigest plaintext credential caching by default, but +setting UseLogonCredential to 1 re-enables it, causing LSASS to retain cleartext passwords for subsequent interactive +logons. Adversaries abuse this to prepare for credential dumping from LSASS memory. """ from = "now-9m" index = [ @@ -23,53 +23,10 @@ index = [ language = "eql" license = "Elastic License v2" name = "Modification of WDigest Security Provider" -note = """## Triage and analysis - -### Investigating Modification of WDigest Security Provider - -In Windows XP, Microsoft added support for a protocol known as WDigest. The WDigest protocol allows clients to send cleartext credentials to Hypertext Transfer Protocol (HTTP) and Simple Authentication Security Layer (SASL) applications based on RFC 2617 and 2831. Windows versions up to 8 and 2012 store logon credentials in memory in plaintext by default, which is no longer the case with newer Windows versions. - -Still, attackers can force WDigest to store the passwords insecurely on the memory by modifying the `HKLM\\SYSTEM\\*ControlSet*\\Control\\SecurityProviders\\WDigest\\UseLogonCredential` registry key. This activity is commonly related to the execution of credential dumping tools. - -#### Possible investigation steps - -- It is unlikely that the monitored registry key was modified legitimately in newer versions of Windows. Analysts should treat any activity triggered from this rule with high priority as it typically represents an active adversary. -- Investigate the script 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. -- Determine if credential dumping tools were run on the host, and retrieve and analyze suspicious executables: - - 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. -- Use process name, command line, and file hash to search for occurrences on other hosts. -- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification. - -### False positive analysis - -- This modification should not happen legitimately. Any potential benign true positive (B-TP) should be mapped and monitored by the security team, as these modifications expose the entire domain to credential compromises and consequently unauthorized access. - -### Related rules - -- Mimikatz Powershell Module Activity - ac96ceb8-4399-4191-af1d-4feeac1f1f46 - -### Response and remediation - -- Initiate the incident response process based on the outcome of the triage. -- Isolate the involved hosts to prevent further post-compromise behavior. -- 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. -- Reimage the host operating system and restore 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://www.csoonline.com/article/3438824/how-to-detect-and-halt-credential-theft-via-windows-wdigest.html", + "https://www.csoonline.com/article/567747/how-to-detect-and-halt-credential-theft-via-windows-wdigest.html", "https://www.praetorian.com/blog/mitigating-mimikatz-wdigest-cleartext-credential-theft?edition=2019", - "https://frsecure.com/compromised-credentials-response-playbook", + "https://frsecure.com/compromised-credentials-response-playbook/", "https://www.elastic.co/security-labs/detect-credential-access", ] risk_score = 73 @@ -97,6 +54,168 @@ registry where host.os.type == "windows" and event.type in ("creation", "change" not (process.executable : "?:\\Windows\\System32\\svchost.exe" and user.id : "S-1-5-18") ''' +note = """## Triage and analysis + +### Investigating Modification of WDigest Security Provider +#### Possible investigation steps + +- Is the write to the active ControlSet, and does host context explain enablement? + - Focus: `registry.path`, `registry.data.strings`, and `host.id`. + - Implication: escalate when the active ControlSet is enabled, leaving cleartext credentials in LSASS for later logons; lower suspicion only for a recognized lab or legacy compatibility host with the exact expected pattern. + +- Which process made the change, and does its identity fit? + - Focus: `process.executable`, `process.command_line`, `process.code_signature.subject_name`, and `process.parent.command_line`. $investigate_0 + - Hint: pivot on `host.id` plus `process.entity_id`; if absent, bound to alert time and host. + - Implication: escalate when the writer is unsigned, user-writable, renamed, script-launched, or has an unrelated parent; lower suspicion only when identity, parent, and registry outcome match one recognized validation activity. Trusted signer alone is not clearance. + +- Does user and session context explain the change? + - Focus: `user.id`, `user.domain`, `process.Ext.session_info.logon_type`, and `process.Ext.token.integrity_level_name`. + - Implication: escalate when a normal user, unexpected admin, service account, remote session, or elevated token performs the write outside a recognized test path. + +- Did the same process leave WDigest enabled or change adjacent security registry state? + - Focus: registry events from the same `process.entity_id`: `registry.path`, `registry.value`, and `registry.data.strings`. $investigate_1 + - Hint: check for WDigest reversal and LSA or SecurityProviders changes before widening to the host. + - Implication: escalate when WDigest stays enabled or the writer weakens LSA or security-provider settings; scope narrower when the write is isolated, promptly reversed, and no contradictory registry evidence remains. + +- Does process activity after the write show credential-dumping preparation or execution? + - Focus: child process events from `process.entity_id`: `process.executable` and `process.command_line`. $investigate_2 + - Implication: escalate when children show Mimikatz/sekurlsa, ProcDump or comsvcs.dll LSASS dumping, CrackMapExec, PowerShell remote execution, archives, or cleanup; absent follow-on evidence narrows extraction proof but does not clear enablement. + +- Did any accounts authenticate while WDigest was enabled? + - Focus: logon events after `@timestamp`: `event.code` 4624, `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, `winlog.logon.type`, and `source.ip`. $investigate_3 + - Hint: expand until WDigest is disabled or the host is contained; for domain NTLM, search domain-controller 4776 records for the alert host as source workstation. + - Implication: escalate credential exposure when successful WDigest or privileged logons occur after enablement. Missing authentication telemetry is unresolved, not benign. + +- If local evidence is suspicious or unresolved, do related alerts change scope? + - Focus: alerts for `user.id`, especially credential access, privilege escalation, or lateral movement. $investigate_4 + - Hint: compare host alerts for precursor access, LSASS-oriented follow-on, staging, or cleanup. $investigate_5 + - Implication: broaden when the same user or host shows adjacent post-compromise behavior; keep local when related alerts are quiet and local evidence fits one recognized workflow. + +- Escalate when writer identity, session context, registry changes, unreverted WDigest exposure, follow-on activity, or related alerts indicate unauthorized credential-protection weakening; close only when those categories align with one confirmed activity and no contradictions remain; preserve and escalate when evidence is mixed or incomplete. + +### False positive analysis + +- Authorized security validation or legacy compatibility testing may enable WDigest. Confirm `process.executable`, `process.command_line`, `process.parent.command_line`, `user.id`, `host.id`, `registry.data.strings`, prompt reversion, and no contradictory registry or LSASS-oriented follow-on. If telemetry cannot prove the activity, leave unresolved. +- Build exceptions from the minimum confirmed workflow: `process.executable` or signer, `process.parent.command_line`, `user.id`, `host.id`, `registry.path`, and expected `registry.data.strings`. Avoid exceptions on `registry.path`, `process.name`, signer, or `host.id` alone. + +### Response and remediation + +- If confirmed benign, reverse any temporary containment, document the aligned workflow evidence, and create an exception only when the confirmed evidence pattern is expected to repeat and can be scoped narrowly. +- If suspicious but unconfirmed, preserve the alert, process tree, command lines, relevant registry events, related-alert results, and current WDigest state before containment. Apply reversible containment first, such as heightened monitoring or EDR network restrictions, and use host isolation only when follow-on dumping, unreverted exposure on a sensitive host, or broader compromise evidence justifies the operational impact. +- If confirmed malicious, preserve the writer `process.entity_id`, process tree, command lines, registry evidence, and current WDigest state; then isolate the host when the evidence supports it, restore WDigest to the disabled state, and eradicate only the scripts, binaries, registry changes, and persistence found during the investigation. +- After containment, review other registry changes by the same process and scope accounts that may have authenticated while WDigest was enabled through available authentication records; when those records are unavailable, treat credential exposure as unresolved and prioritize privileged, service, and lateral-movement-capable accounts for credential hygiene. +- Post-incident hardening: restrict who can modify WDigest and related LSA policy, validate baseline configuration through endpoint or policy management, retain registry and process telemetry for this host class, and document the confirmed workflow or malicious pattern for future analysts. +""" + +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) +- [Sysmon Registry Events](https://ela.st/sysmon-event-reg-setup) +""" + +[rule.investigation_fields] +field_names = [ + "@timestamp", + "host.id", + "user.id", + "process.code_signature.subject_name", + "process.code_signature.trusted", + "process.executable", + "process.command_line", + "process.entity_id", + "process.parent.executable", + "process.parent.command_line", + "process.Ext.session_info.logon_type", + "process.Ext.token.integrity_level_name", + "registry.path", + "registry.value", + "registry.data.strings", +] + +[transform] + +[[transform.investigate]] +label = "Process events by WDigest writer" +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 = "Registry events by WDigest writer" +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 = "registry", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" + +[[transform.investigate]] +label = "Child process events by WDigest writer" +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 = "Logon events on the WDigest host" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ] +] +relativeFrom = "now-24h" +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" [[rule.threat]] framework = "MITRE ATT&CK" diff --git a/rules/windows/credential_access_posh_invoke_ninjacopy.toml b/rules/windows/credential_access_posh_invoke_ninjacopy.toml index 0713a1dcf..8e9c8d317 100644 --- a/rules/windows/credential_access_posh_invoke_ninjacopy.toml +++ b/rules/windows/credential_access_posh_invoke_ninjacopy.toml @@ -2,7 +2,7 @@ creation_date = "2023/01/23" integration = ["windows"] maturity = "production" -updated_date = "2026/03/24" +updated_date = "2026/04/26" [rule] author = ["Elastic"] @@ -12,99 +12,10 @@ file access. Attackers use NinjaCopy to read locked system files such as NTDS.di dumping. """ from = "now-9m" -index = ["winlogbeat-*", "logs-windows.powershell*"] +index = ["logs-windows.powershell*", "winlogbeat-*"] language = "kuery" license = "Elastic License v2" name = "PowerShell Invoke-NinjaCopy script" -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 PowerShell Invoke-NinjaCopy script - -This rule identifies PowerShell script block content referencing `Invoke-NinjaCopy` or related `Stealth*` helper functions. These functions are commonly used to perform direct volume file reads that can bypass normal file locking and access controls, enabling copies of sensitive credential stores (for example, `NTDS.dit` or registry hives like `SAM`, `SYSTEM`, and `SECURITY`). The presence of these strings can represent tool staging (definition/import) or active execution, so focus on determining intent, targeted artifacts, output locations, and surrounding activity. - -#### 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 - -- Triage the alert context: - - Identify the affected `host.name` / `host.id` and the account (`user.name`, `user.domain`, `user.id`). - - Determine whether the host is expected to store credential material (for example, a directory services server) and whether the user is expected to perform privileged maintenance on it. - - Use the alert time (`@timestamp`) to define an initial correlation window and expand as needed. - -- Analyze `powershell.file.script_block_text` to understand what was staged or executed: - - Determine whether the content is primarily function definitions/module code (tool load) or includes direct invocation of `Invoke-NinjaCopy` and `Stealth*` functions. - - Extract any referenced source artifacts (for example, `NTDS.dit` or registry hives) and any destination/output file names, directories, or remote paths. - - Look for indicators of direct volume access, such as device/volume path handling, low-level file handle usage, delegates, or logic intended to bypass normal file locking. - - Identify follow-on logic that would support collection and handling (copy loops, chunking, archiving, encoding, renaming, or cleanup). - -- Use script block metadata to reconstruct full content when logged in multiple parts: - - Pivot on `powershell.file.script_block_id` for the same `host.id`. - - Order fragments by `powershell.sequence` and confirm the final part count matches `powershell.total`. - - If parts are missing, treat the content as incomplete and continue scoping for additional fragments. - - Preserve the reconstructed content and the original fragment events for case evidence. - -- Determine script provenance when file context is present: - - Review `file.path` / `file.name` (and `file.directory` if populated) to identify where the script was executed from. - - Treat execution from user-writable or temporary locations as higher risk, and scope for other executions originating from the same path or directory on the host. - - If file context is not present, consider interactive execution or remote delivery and expand scoping to other script blocks from the same `host.id` and `user.id` around the alert time. - -- Scope for related PowerShell activity on the endpoint: - - Review additional Script Block Logging events for the same `host.id` and `user.id` around the alert time to identify staging, retries, and post-collection actions. - - Use `powershell.file.script_block_length` to prioritize larger blocks that may contain full tooling, embedded functions, or post-processing logic. - - Prioritize script blocks that reference the same artifact names or output locations observed in the matched content. - -- Assess prevalence across the environment: - - Search for the same keywords within `powershell.file.script_block_text` (for example, `Invoke-NinjaCopy` and `StealthOpenFile`) across other hosts to identify broader deployment. - - If `file.path` or `file.name` is present, use it to identify reuse of the same script file across multiple hosts or users. - -- Correlate with adjacent telemetry (if available) using `host.name`, `host.id`, `user.id`, and the alert time: - - Process activity to identify the PowerShell host process and the parent/source that initiated it, and whether execution aligns with expected administrative workflows. - - File activity to confirm whether copies of targeted artifacts were created, where they were written, and whether they were later archived or moved. - - Network activity to identify outbound transfers or remote access shortly after script execution. - - Authentication activity to identify suspicious logons, privilege use, or lateral movement following potential credential material collection. - -- Determine impact: - - If the script indicates attempted access to directory services database files or registry hives, treat this as potential credential exposure until corroborating telemetry shows otherwise and respond accordingly. - -### False positive analysis - -- Approved security testing, adversary emulation, or controlled red team activity that includes NinjaCopy-derived code. -- Authorized incident response, forensic acquisition, or recovery workflows that require copying locked system files. -- Administrative tooling that embeds similar helper functions for troubleshooting or backup operations (uncommon); validate ownership, expected hosts, and change control. - -### Response and remediation - -- If the activity is not expected or cannot be attributed to an approved task: - - Isolate the affected host to prevent additional collection, staging, or lateral movement. - - Take immediate steps to prevent further use of the implicated account (`user.id`) until legitimacy is confirmed. - -- Preserve and collect evidence: - - Save the full `powershell.file.script_block_text` and reconstruct missing fragments using `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total` where applicable. - - Record `@timestamp`, `host.name`, `host.id`, `user.name`, `user.domain`, `user.id`, and any available `file.path` / `file.name` context. - - Identify any destination/output locations referenced in the script content and preserve related artifacts (copied files, archives, temporary staging). - -- Assess credential exposure and potential follow-on activity: - - Use available endpoint telemetry to determine whether credential stores were successfully copied or staged. - - If credential stores may have been accessed or copied, follow your credential containment process and prioritize rotation of impacted and privileged credentials. - -- Eradicate and scope: - - Remove unauthorized scripts and supporting artifacts identified from `file.path` / `file.name` and from any output locations referenced in the script. - - Hunt for additional NinjaCopy-related script blocks across endpoints and for subsequent suspicious authentication activity associated with the same user and host context. - -- Recover and harden: - - Restore affected systems as needed and validate that no persistence remains. - - Reduce recurrence by tightening administrative scripting governance for PowerShell (least privilege, controlled script deployment locations, and application control where feasible) and by restricting access to systems that store credential material. -""" references = [ "https://github.com/BC-SECURITY/Empire/blob/main/empire/server/data/module_source/collection/Invoke-NinjaCopy.ps1", ] @@ -130,15 +41,158 @@ event.category:process and host.os.type:windows and "StealthCloseFileDelegate" or "StealthOpenFile" or "StealthCloseFile" or - "StealthReadFile" or "Invoke-NinjaCopy" - ) - and not user.id : "S-1-5-18" - and not powershell.file.script_block_text : ( + ) and + not powershell.file.script_block_text : ( "sentinelbreakpoints" and "Set-PSBreakpoint" and "PowerSploitIndicators" ) ''' +note = """## Triage and analysis + +### Investigating PowerShell Invoke-NinjaCopy script + +#### Possible investigation steps + +- Does the alert-preserved script content show active NinjaCopy direct-volume access rather than inert reference text? + - Focus: `powershell.file.script_block_text`, `powershell.file.script_block_length`, and file-backed `file.path` or `file.name`. + - Implication: escalate sooner when the fragment shows `Invoke-NinjaCopy`, `StealthOpenFile`, `StealthReadFile`, credential-store targets, output destinations, or cleanup logic; lower concern only for inert example or recognized validation content that later recovery does not contradict. + +- Does full script reconstruction reveal target, destination, or cleanup behavior that the matching fragment did not show? + - Why: Script Block Logging can split one script across events; later fragments often contain output paths, loops, or cleanup logic that change urgency. + - Focus: reconstruct on `host.id` + `powershell.file.script_block_id`, ordering by `powershell.sequence` / `powershell.total`; read `powershell.file.script_block_text` for "-Path", "-ComputerName", "-LocalDestination", or "-RemoteDestination". $investigate_2 + - Hint: if `powershell.sequence` is missing or never reaches `powershell.total`, record the gap before treating the script as understood. + - Implication: escalate when reconstruction adds remote targets, credential stores (`NTDS.dit`, `SAM`, `SYSTEM`, `SECURITY`), temp/share destinations, large copy buffers, archive paths, encoding, or delete-after-copy logic; lower concern when the full script is confirmed lab, forensic, or validation content with no hostile follow-on behavior. + +- Does the script provenance and reconstructed target fit a recognized workflow? + - Focus: `file.path`, `file.name`, `user.id`, `host.id`, and reconstructed "-Path", "-ComputerName", "-LocalDestination", or "-RemoteDestination". + - Hint: if `file.path` is absent, treat content as inline, generated, interactive, or remote; do not close on path absence alone. + - Implication: escalate when source is temp, downloads, or user-writable shares, or parameters name remote servers, `NTDS.dit`, registry hives, or staging destinations; lower concern when source, targets, and destinations match one recognized forensic, IR, lab, or validation workflow. + +- Do surrounding script blocks from the same user and host show staging, retries, or variant logic? + - Focus: manually search the same execution window for `user.id`, `host.id`, `powershell.file.script_block_text`, and adjacent `powershell.file.script_block_id` values. + - Hint: renamed wrappers may omit `Invoke-NinjaCopy`; still check `Stealth*` helpers and reconstructed target or destination values. + - Implication: escalate when adjacent fragments show retries, renamed helpers, alternative raw-volume logic, output-file reuse, or follow-on compression and cleanup. + +- Can process telemetry recover the PowerShell process and explain how it was launched? + - Focus: match the PowerShell PID on `host.id`, `process.pid`, and `@timestamp`; record `process.entity_id`, then interpret `process.command_line`, `process.parent.command_line`, and `process.Ext.token.integrity_level_name`. $investigate_3 + - Hint: recover the matching process via `host.id + process.pid` before using `process.*` or `process.parent.*`. If no process start event appears, expand the window because PowerShell can predate the script block; if still absent, bound file review to `host.id`, `user.id`, `process.pid`, and alert time. + - Implication: escalate when recovery shows encoded commands, remote-admin launchers, Office/browser ancestry, or unexpected high-integrity execution; unresolved process recovery does not make direct-volume script content benign. + +- Do file events confirm copied credential stores or staging artifacts? + - Focus: endpoint file events scoped to `host.id`, `process.pid`, and alert time; review `file.path`, `file.directory`, and `file.name`. $investigate_4 + - Implication: escalate when file activity confirms copied hives, `NTDS.dit`, archives, or renamed staging files; missing file telemetry is unresolved, not benign. + +- If the local script, launch, or artifact answers remain suspicious or unresolved, is this script block isolated, or part of broader suspicious activity for the same user or host? + - Focus: related `user.id` alerts for repeated credential access, execution, or post-compromise behavior. $investigate_0 + - Hint: compare `host.id` alerts for credential access, persistence, or staging. $investigate_1 + - Implication: broaden scope when either view shows adjacent credential-access or post-compromise behavior; keep it local only when both are quiet and the local evidence fits one recognized workflow. + +- Escalate when script content, reconstruction, target parameters, launch context, or artifacts show unauthorized direct-volume access or credential-store targeting; close only when source path, targets, destinations, launch context, and artifacts align with one recognized forensic, IR, lab, or validation workflow; preserve and escalate if mixed or incomplete. + +### False positive analysis + +- Recognized red-team, security-validation, forensic-acquisition, or IR workflows can legitimately include NinjaCopy-derived code. Confirm only when `powershell.file.script_block_text`, reconstructed targets/destinations, `file.path`, `user.id`, `host.id`, and recovered launch context align with the same workflow. If records are unavailable, prior recurrence can support but not replace local telemetry proof; first occurrences stay candidate exceptions. +- Build exceptions from `user.id`, `host.id`, stable `file.path`, recovered parent-launch pattern when available, and the `powershell.file.script_block_text` pattern. Avoid exceptions on "Invoke-NinjaCopy", `user.name`, or host alone. + +### Response and remediation + +- If confirmed benign, reverse containment and document the recognized workflow: `user.id`, `host.id`, `file.path`, `powershell.file.script_block_id`, recovered launch context, and reconstructed target or destination values. Create an exception only if the same pattern recurs across prior alerts. +- If suspicious but unconfirmed, preserve reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `process.pid`, recovered launch context, target or destination values, and `file.path` before cleanup. Apply reversible containment first; escalate to host isolation only if copied credential artifacts, staging, or broader post-compromise activity appears. +- If confirmed malicious, preserve the reconstructed script, launch context, targets, destinations, copied stores, and related alerts first. Then use reversible endpoint response to isolate the host when needed; if unavailable, escalate with the preserved artifact set to the team that can act. Record all evidence before terminating processes or deleting files. +- If "NTDS.dit", "SAM", "SYSTEM", or "SECURITY" targeting is confirmed with copied artifacts, follow the organization's credential-exposure playbook and prioritize privileged-account hygiene. +- Before eradicating, review related hosts for the same script pattern, `file.path` destinations, and recovered parent-launch pattern. Then remove unauthorized scripts, copied stores, archives, and persistence mechanisms and remediate the delivery path. +- Post-incident hardening: restrict direct-volume-copy tooling to controlled acquisition hosts, retain PowerShell Script Block Logging and endpoint file/process telemetry, and document the recognized workflow pattern for future analysts. +""" + +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 = [ + "@timestamp", + "user.name", + "user.id", + "user.domain", + "powershell.file.script_block_text", + "powershell.file.script_block_id", + "powershell.sequence", + "powershell.total", + "file.path", + "file.directory", + "file.name", + "process.pid", + "host.name", + "host.id", + "powershell.file.script_block_length" +] + +[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 = "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 = "File events for the PowerShell process" +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 = "file", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" [[rule.threat]] framework = "MITRE ATT&CK" @@ -203,21 +257,3 @@ reference = "https://attack.mitre.org/techniques/T1006/" id = "TA0005" name = "Defense Evasion" reference = "https://attack.mitre.org/tactics/TA0005/" -[rule.investigation_fields] -field_names = [ - "@timestamp", - "user.name", - "user.id", - "user.domain", - "powershell.file.script_block_text", - "powershell.file.script_block_id", - "powershell.sequence", - "powershell.total", - "file.path", - "file.directory", - "file.name", - "process.pid", - "host.name", - "host.id", - "powershell.file.script_block_length" -] diff --git a/rules/windows/credential_access_posh_kerb_ticket_dump.toml b/rules/windows/credential_access_posh_kerb_ticket_dump.toml index 2050fa06d..92a8fdcab 100644 --- a/rules/windows/credential_access_posh_kerb_ticket_dump.toml +++ b/rules/windows/credential_access_posh_kerb_ticket_dump.toml @@ -2,100 +2,23 @@ creation_date = "2023/07/26" integration = ["windows"] maturity = "production" -updated_date = "2026/03/24" +updated_date = "2026/04/27" [rule] author = ["Elastic"] description = """ -Detects PowerShell script block content that references LSA Kerberos ticket retrieval APIs and Kerb* message types. -Attackers dump Kerberos tickets from memory to reuse credentials and move laterally. +Detects PowerShell script block content that references LSA Kerberos authentication-package access patterns, including +explicit Kerberos ticket message types or dynamic Kerberos package lookup. These patterns are consistent with tooling +that enumerates, retrieves, or exports Kerberos tickets from memory for credential reuse or lateral movement. """ from = "now-9m" -index = ["winlogbeat-*", "logs-windows.powershell*"] +index = ["logs-windows.powershell*", "winlogbeat-*"] language = "kuery" license = "Elastic License v2" name = "PowerShell Kerberos Ticket Dump" -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 PowerShell Kerberos Ticket Dump - -This alert identifies PowerShell script block content referencing the LSA Kerberos authentication package API `LsaCallAuthenticationPackage` along with Kerberos ticket cache query and ticket retrieval message types. This pattern is consistent with tooling that enumerates, extracts, or manipulates Kerberos tickets from memory, which can enable credential reuse and lateral movement. - -#### 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 - -- Reconstruct and preserve the full script content: - - Use `powershell.file.script_block_id` to gather all related fragments and order them by `powershell.sequence` up to `powershell.total`. - - Preserve the reconstructed content from `powershell.file.script_block_text` for case notes and to support environment-wide scoping. - - Use `powershell.file.script_block_length` to understand whether the content is a full implementation, a loader/stager, or a small inline snippet that may be part of a larger sequence of script blocks. - -- Identify the specific Kerberos capability referenced: - - Review `powershell.file.script_block_text` and note which message types are present. Use this to prioritize severity and intent: - - Cache enumeration indicators: `KerbQueryTicketCacheMessage`, `KerbQueryTicketCacheExMessage`, `KerbQueryTicketCacheEx2Message` - - Ticket retrieval/export indicators: `KerbRetrieveTicketMessage`, `KerbRetrieveEncodedTicketMessage` - - Ticket-related decryption indicators: `KerbDecryptDataMessage` - - Determine whether the script only defines interop types/functions or includes invocation logic that executes ticket operations and processes results. - - Look for signs that output is being prepared for reuse or transfer (e.g., structured serialization, encoding, or explicit output handling). If `file.path` is populated, assess whether the script is associated with a specific on-disk source. - -- Validate execution context and plausibility: - - Review `@timestamp`, `host.name`/`host.id`, and `user.name`/`user.domain`/`user.id` to confirm where and under which identity the activity occurred. - - Assess whether the user and host context align with expected administrative or troubleshooting activity in your environment. Unexpected use by standard users, or on endpoints where administrative scripting is uncommon, should be treated as higher risk. - - If `file.path`/`file.name` (and `file.directory`, if present) indicate an on-disk origin, evaluate whether the location is consistent with approved scripts. Treat user-writable and temporary locations as higher risk, especially when combined with ticket retrieval/decryption indicators. - -- Scope for additional PowerShell activity on the same host and user: - - Pivot on `host.id` and `user.id` to review other script block activity near `@timestamp` to identify precursors (staging, discovery) and follow-on actions (additional credential access attempts, lateral movement preparation). - - Check for repeated execution patterns: multiple script blocks with similar content, repeated `powershell.file.script_block_id` occurrences, or the same `file.name` appearing multiple times in a short window. - -- Assess prevalence across the environment: - - Search for the same or highly similar `powershell.file.script_block_text` content (or distinctive substrings) across hosts to determine whether this is isolated or widespread. - - If `file.name` is present, look for the same script name used across multiple hosts. Consistent, predictable use may indicate managed tooling; sporadic or single-host use may indicate targeted activity. - -- Correlate with adjacent telemetry (when available): - - Process telemetry: identify the PowerShell execution instance that produced the script block and determine the initiating process to establish whether execution was interactive, scheduled, or launched by another application. - - File telemetry: review for newly created or modified artifacts near `@timestamp` that could store extracted ticket material or related output. - - Network and authentication telemetry: review subsequent outbound activity and authentication attempts associated with the same host and/or user to identify potential ticket reuse and rapid lateral movement following the script execution. - -### False positive analysis - -- Some legitimate Kerberos troubleshooting and diagnostics workflows can reference LSA Kerberos APIs to query ticket cache state. Validate whether the script source (`file.path`/`file.name`), execution context (`user.id`, `host.id`), and timing align with an approved operational process. -- Administrative automation or security tooling may include Kerberos interop code for visibility or health checks. Benign usage is typically repeatable (consistent script content, consistent script origin, predictable execution patterns) and tied to known administrative accounts. -- Prioritize deeper investigation when the activity is one-off, appears only on a single host, is executed by unexpected users, or includes retrieval/decryption indicators rather than simple cache query logic. - -### Response and remediation - -- If the activity is unexpected or cannot be validated as authorized: - - Isolate the affected host to reduce the risk of credential theft and lateral movement. - - Preserve evidence for scoping: retain the reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, host identifiers, user identifiers, and any on-disk script context (`file.path`, `file.name`). - - Treat as a potential credential access incident and initiate environment-wide scoping for similar script content and related activity from the same user and host. - -- If Kerberos ticket theft or export is confirmed: - - Remove the script source (as identified by `file.path`/`file.name`) and any related artifacts identified during triage. - - Reset or rotate credentials for impacted accounts and review privileged access paths associated with the affected host and user. - - Investigate for lateral movement following `@timestamp`, identify affected systems, and remediate access pathways used. - -- Post-incident hardening: - - Ensure PowerShell script block logging coverage and retention support reconstruction and historical scoping. - - Review administrative scripting controls and monitoring for unauthorized use of authentication-package APIs in PowerShell, and align execution permissions with least-privilege practices. -""" references = ["https://github.com/MzHmO/PowershellKerberos/blob/main/dumper.ps1"] risk_score = 73 rule_id = "fddff193-48a3-484d-8d35-90bb3d323a56" -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", @@ -118,11 +41,175 @@ event.category:process and host.os.type:windows and "KerbQueryTicketCacheExMessage" or "KerbQueryTicketCacheEx2Message" or "KerbRetrieveTicketMessage" or - "KerbDecryptDataMessage" + "KerbDecryptDataMessage" or + ("LsaLookupAuthenticationPackage" and "kerberos" and "KERB_RETRIEVE_TKT_REQUEST") ) ) ''' +note = """## Triage and analysis + +### Investigating PowerShell Kerberos Ticket Dump + +#### Possible investigation steps + +- What does the reconstructed script block attempt to do with Kerberos tickets? + - Why: PowerShell Script Block Logging can split one script across events; interpretation before reconstruction can miss export, helper, or cleanup logic. + - Focus: recover fragments on the same `host.id` with `powershell.file.script_block_id`, order by `powershell.sequence` of `powershell.total`, then read reconstructed `powershell.file.script_block_text`. $investigate_2 + - Implication: escalate when the full script retrieves, decrypts, serializes, or outputs tickets through explicit Kerberos message types, dynamic Kerberos package lookup, "LsaCallAuthenticationPackage", "ExtractTicket", or "Ticketb64"; lower concern only when reconstruction stays query-only, fits a recognized diagnostic or declared test, and shows no export or follow-on logic. + +- Does the reconstructed script try to gain SYSTEM or enumerate other logon sessions? + - Focus: reconstructed `powershell.file.script_block_text`, checking for "Invoke-AsSystem", token duplication or impersonation calls, LSA registration/connect calls, "LsaEnumerateLogonSessions", and "GetLogonSessionData". + - Implication: escalate when the script attempts SYSTEM impersonation, LSA registration, or multi-session enumeration because ticket access may extend beyond the alerting user; current-session cache queries remain suspicious but carry less scope impact when no retrieval/export evidence appears. + +- Can endpoint process telemetry explain how this PowerShell instance was launched? + - Focus: recover the matching process via `host.id` and `process.pid` before interpreting lineage; review `process.entity_id`, `process.command_line`, `process.parent.command_line`, `process.Ext.token.integrity_level_name`, and `process.Ext.authentication_id`. $investigate_3 + - Hint: If no process start event is found, expand the window because PowerShell can predate the script block; if still absent, keep launch, process-scoped file review, and auth-bridge context unresolved. + - Implication: escalate when the recovered launch shows encoded commands, remote-admin launchers, Office or browser parents, unexpected elevation, or SYSTEM-adjacent execution; missing endpoint process telemetry leaves launch chain, process-scoped file review, and auth-bridge context unresolved, not benign. + +- Do the script source or output artifacts show ticket material was staged or exported? + - Focus: source `file.path` and `file.name`, plus file activity for `host.id`, `process.pid`, and recovered `process.entity_id` when available. Look for ".kirbi", ticket text output, archives, temp/user-writable paths, or cleanup. $investigate_4 + - Implication: escalate when file evidence confirms exported tickets, archives, staging, or cleanup; if source path is absent or file telemetry is missing but reconstruction emits "Ticketb64" or ticket objects, treat the case as unresolved high concern rather than benign. + +- Do authentication events explain the PowerShell session or show follow-on credential use? + - Focus: same-host/user Windows Security events for `event.code` 4624, 4625, or 4648; review `source.ip`, `winlog.event_data.AuthenticationPackageName`, and `winlog.logon.type` where present. $investigate_5 + - Hint: After process recovery, search backward from the recovered process `@timestamp`, bridge `process.Ext.authentication_id` to `winlog.event_data.TargetLogonId`, and search 4648 on `winlog.event_data.SubjectLogonId` for explicit-credential targets. + - Implication: escalate when session origin, authentication package, logon type, explicit-credential target, or later remote or privileged logons conflict with the expected diagnostic or test workflow. Missing authentication telemetry is unresolved, not benign. + +- If local evidence remains suspicious or incomplete, do related alerts widen user or host scope? + - Focus: related alerts for `user.id` showing credential access, execution, or lateral movement. $investigate_0 + - Hint: compare `host.id` alerts only after local script, launch, artifact, and authentication review. $investigate_1 + - Implication: broaden containment and hunting when either view shows connected credential access, delivery, persistence, or lateral movement; quiet related alerts keep scope local only when the local evidence also supports a recognized workflow. + +- Escalate when script, SYSTEM or multi-session behavior, launch, artifacts, authentication, or related alerts show unauthorized ticket retrieval or follow-on credential use; close only when reconstruction and recovery bind one exact benign diagnostic, red-team, or lab workflow and outside confirmation covers gaps; preserve and escalate when evidence is mixed, incomplete, or dependent telemetry is missing. + +### False positive analysis + +- Kerberos diagnostics, identity troubleshooting, red-team, or lab validation can trigger this rule when reconstruction is query-oriented or scoped to an authorized test. Confirm no unexplained SYSTEM impersonation, multi-session enumeration, "Ticketb64" output, export paths, or cleanup; `user.id`, `host.id`, and any `file.path` or `file.name` align with the declared workflow; launch and authentication recovery do not contradict it. Record first-time verified-benign activity, but wait for stable recurrence before exceptioning. +- Ticket retrieval, decryption, or base64 ticket output is an operational anti-pattern outside confirmed testing. Do not close on a Kerberos troubleshooting claim when reconstruction or follow-on evidence shows export, reuse, or unexplained privilege/session expansion. +- Build exceptions from the minimum confirmed pattern: `user.id`, `host.id`, stable `file.path` or `file.name`, declared test or diagnostic scope, and recovered launch context when available. Avoid exceptions on Kerberos API strings, `user.name`, `host.name`, or `host.id` alone. + +### Response and remediation + +- If confirmed benign, reverse any temporary containment and document the exact workflow evidence: reconstructed `powershell.file.script_block_text`, fragment identifiers, `user.id`, `host.id`, source `file.path` or `file.name`, recovered launch context when available, and bounded authentication evidence. Create an exception only after the same pattern recurs without contradictory export or reuse evidence. +- If suspicious but unconfirmed, preserve the reconstructed script, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, SYSTEM or multi-session indicators, source and output artifacts, recovered launch details when available, and authentication evidence such as `winlog.event_data.TargetLogonId` and `source.ip`. Apply reversible containment first, such as heightened monitoring or temporary account/session restrictions, and isolate the host only if ticket export, reuse, or privileged session creation appears. +- If confirmed malicious, preserve the artifact set before destructive actions, then isolate the host with endpoint response or escalate to the team that can contain it. Contain affected accounts after recording evidence for the identities and sessions involved. +- If ticket retrieval or reuse is confirmed, purge tickets on affected hosts, reset impacted credentials, and prioritize privileged, service, and delegation-capable accounts. Consider domain-wide Kerberos actions only with identity-team approval and evidence of broader TGT or KRBTGT exposure. +- Eradicate only the unauthorized scripts, exported tickets, archives, persistence mechanisms, and delivery artifacts identified during the investigation, then remediate the entry path. +- After containment, hunt for the same reconstructed script fragments, "Ticketb64" output patterns, related file artifacts, and post-alert authentication patterns across other hosts. +""" + +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 = [ + "@timestamp", + "user.name", + "user.id", + "user.domain", + "powershell.file.script_block_text", + "powershell.file.script_block_id", + "powershell.sequence", + "powershell.total", + "file.path", + "file.directory", + "file.name", + "process.pid", + "host.name", + "host.id", + "powershell.file.script_block_length" +] + +[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 = "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 = "File events for the PowerShell process" +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 = "file", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" + +[[transform.investigate]] +label = "Windows Security authentication events for the user" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" [[rule.threat]] framework = "MITRE ATT&CK" @@ -169,21 +256,3 @@ reference = "https://attack.mitre.org/techniques/T1106/" id = "TA0002" name = "Execution" reference = "https://attack.mitre.org/tactics/TA0002/" -[rule.investigation_fields] -field_names = [ - "@timestamp", - "user.name", - "user.id", - "user.domain", - "powershell.file.script_block_text", - "powershell.file.script_block_id", - "powershell.sequence", - "powershell.total", - "file.path", - "file.directory", - "file.name", - "process.pid", - "host.name", - "host.id", - "powershell.file.script_block_length" -] diff --git a/rules/windows/credential_access_posh_minidump.toml b/rules/windows/credential_access_posh_minidump.toml index f417da3fd..6954ed4ad 100644 --- a/rules/windows/credential_access_posh_minidump.toml +++ b/rules/windows/credential_access_posh_minidump.toml @@ -2,103 +2,23 @@ creation_date = "2021/10/05" integration = ["windows"] maturity = "production" -updated_date = "2026/01/26" +updated_date = "2026/04/27" [rule] author = ["Elastic"] description = """ Detects PowerShell scripts referencing MiniDumpWriteDump or full-memory minidump types, which can capture -process memory. Attackers often use this technique to dump credential-bearing processes like LSASS for credential theft. +process memory. Attackers use this technique to dump credential-bearing processes like LSASS for credential theft and +lateral movement. """ -false_positives = ["PowerShell scripts that use this capability for troubleshooting."] +false_positives = [ + "Bounded troubleshooting, IR, lab-validation, or red-team activity where the reconstructed target/output, launch context, and artifact/authentication evidence align.", +] from = "now-9m" -index = ["winlogbeat-*", "logs-windows.powershell*"] +index = ["logs-windows.powershell*", "winlogbeat-*"] language = "kuery" license = "Elastic License v2" name = "PowerShell MiniDump Script" -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 PowerShell MiniDump Script - -This alert identifies PowerShell script block content that references MiniDumpWriteDump or a full-memory minidump type. This capability can be used to capture process memory and, if aimed at credential-bearing processes (for example, LSASS), may enable credential theft. The goal of the investigation is to determine intent, identify the target process and any dump artifacts, validate execution context, and scope related activity. - -#### 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 - -- Validate alert context and exposure: - - Review `host.name` and `host.id` to understand where the activity occurred and whether the host is expected to run administrative PowerShell workflows. - - Review `user.name`, `user.domain`, and `user.id` to determine whether the account is expected to perform troubleshooting or diagnostic actions that could include memory dumps. - -- Analyze the script block for intent and capability: - - Review `powershell.file.script_block_text` to identify how the script invokes memory dumping functionality: - - Look for direct references to `MiniDumpWriteDump` or full-memory minidump flags, including simple obfuscation (for example, reversed strings such as `pmuDetirWpmuDiniM`). - - Identify how the function is loaded or called (for example, dynamic invocation patterns, embedded code, or calls into Windows components referenced in the script content). - - Identify target selection logic (process name, PID, handle acquisition, or enumeration) and whether the intended target appears sensitive (for example, LSASS). - - Identify any dump artifact handling in the script content, such as output path/filename patterns, compression or encoding steps, cleanup (delete/move), or staging behavior. - - Use `powershell.file.script_block_length` as a quick signal for unusually large or complex content that may indicate embedded code, obfuscation, or multi-stage logic. - -- Reconstruct complete script content when split across events: - - If the script appears incomplete or segmented, pivot using `powershell.file.script_block_id` and order fragments by `powershell.sequence` up to `powershell.total`. - - Re-review the reconstructed content to ensure the suspected dump logic is not part of a larger workflow (for example, download, execution, artifact handling, or cleanup steps). - -- Determine execution source and assess legitimacy: - - If `file.path`, `file.directory`, or `file.name` are present, treat them as the source script context and determine whether the script location and naming align with approved administrative tooling in your environment. - - If file-origin fields are absent, treat the activity as potentially interactive or dynamically generated and prioritize understanding how the content was introduced (for example, ad-hoc execution, copied code, or a scripted task). - -- Scope and correlate related PowerShell activity: - - On the same `host.id` and `user.id`, review adjacent PowerShell script block activity around the alert time to identify: - - Additional dumping attempts (different minidump types or alternate invocation patterns). - - Follow-on handling of dump output (archiving, encoding, or transfer logic referenced in script text). - - Attempts to reduce visibility or rapidly clean up artifacts (explicit deletion or overwrite logic referenced in script text). - -- Look for evidence of a dump artifact and potential data movement (as available in your environment): - - Investigate whether a memory dump file was created shortly after the alert on the same host, and whether it was renamed, moved, archived, or deleted soon after creation. - - Review any available network telemetry for the host around the alert time for unusual outbound activity that could indicate transfer of a dump artifact (for example, large uploads or new external destinations). - -- Assess potential impact: - - If the script content indicates a credential-bearing process was targeted, treat local credentials on the host as potentially exposed and increase priority for containment and credential hygiene actions. - - Use the key strings and patterns identified in `powershell.file.script_block_text` to search for additional occurrences across hosts and users to identify broader exposure. - -### False positive analysis - -- Legitimate diagnostic workflows may use process dumps for troubleshooting, crash analysis, or vendor support. These cases often have clear ownership, approved scripts, and controlled storage locations for dump artifacts. -- Internal security or IT teams may collect memory dumps for authorized incident response or forensic collection. Validate whether the activity aligns with a documented procedure and an expected operator and host scope. -- Suspicion should increase when the script targets credential-bearing processes, uses basic obfuscation, writes artifacts to unusual or user-writable locations, rapidly stages or removes artifacts, or appears on hosts/users that do not typically perform diagnostic dumping. - -### Response and remediation - -- If the activity is suspicious or unauthorized: - - Contain the host to reduce the risk of credential theft and lateral movement. - - Preserve evidence: - - Retain the full `powershell.file.script_block_text` content (including any reconstructed fragments via `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`). - - Preserve any identified on-disk source script referenced by `file.path` / `file.name`, and collect any dump artifacts discovered during scoping. - - Record the associated `host.id` / `host.name` and `user.id` / `user.name` / `user.domain` for incident tracking and scoping. - - Determine credential exposure and take appropriate action: - - Prioritize credential resets/rotation for accounts that may have been exposed if a credential-bearing process was targeted. - - Review for signs of credential misuse originating from the affected host or account following the alert. - - Hunt for related activity: - - Search for additional occurrences of the same dumping strings and function patterns across the environment. - - Identify other hosts where the same user executed similar script content. - -- If the activity is authorized but unexpected: - - Document the owner, business justification, and expected operating scope (hosts, users, and timeframe). - - Ensure dump artifacts are stored securely, access is restricted, and retention is minimized to reduce credential exposure risk. - -- Preventive and hardening actions: - - Restrict who can perform diagnostic dumping and where dumps can be written. - - Maintain and monitor PowerShell script block logging coverage and retention to support script reconstruction and scoping during investigations. -""" references = [ "https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Out-Minidump.ps1", "https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Get-ProcessMiniDump.ps1", @@ -106,11 +26,6 @@ references = [ ] risk_score = 73 rule_id = "577ec21e-56fe-4065-91d8-45eb8224fe77" -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", @@ -124,45 +39,61 @@ timestamp_override = "event.ingested" type = "query" query = ''' -event.category:process and host.os.type:windows and powershell.file.script_block_text:(MiniDumpWriteDump or MiniDumpWithFullMemory or pmuDetirWpmuDiniM) and not user.id : "S-1-5-18" +event.category:process and host.os.type:windows and +powershell.file.script_block_text:(MiniDumpWriteDump or MiniDumpWithFullMemory or pmuDetirWpmuDiniM) ''' +note = """## Triage and analysis -[[rule.threat]] -framework = "MITRE ATT&CK" -[[rule.threat.technique]] -id = "T1003" -name = "OS Credential Dumping" -reference = "https://attack.mitre.org/techniques/T1003/" -[[rule.threat.technique.subtechnique]] -id = "T1003.001" -name = "LSASS Memory" -reference = "https://attack.mitre.org/techniques/T1003/001/" +### Investigating PowerShell MiniDump Script +#### Possible investigation steps +- What does the reconstructed script block prove about minidump intent? + - Focus: Reconstruct `powershell.file.script_block_text` with `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and `host.id`; determine whether code only defines dump capability, selects a target, or invokes a full-memory dump with an output path. + - Hint: recover fragments, order by `powershell.sequence`, then interpret the full text. $investigate_2 + - Implication: escalate when reconstruction shows LSASS or another credential-bearing target, all-process dumping, full-memory flags, explicit PID/output path, archive/base64 handling, or cleanup; lower concern only for confirmed examples or comments with no target, output, or execution path. +- If endpoint process telemetry is available, how was the PowerShell instance launched? + - Focus: Recover the matching process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`; review recovered `process.command_line`, `process.parent.executable`, `process.parent.command_line`, and `process.Ext.token.integrity_level_name`. $investigate_3 + - Hint: record `process.entity_id` for file scoping and `process.Ext.authentication_id` for authentication bridging. If no process start event appears after time expansion, keep later pivots bounded to `host.id`, `user.id`, `process.pid`, and alert time. + - Implication: escalate when launch came from a browser, document, chat client, remote tool, scheduled task, user-writable script path, or unexplained elevated context; lower concern when the launch chain matches the same recognized troubleshooting, IR, lab-validation, or red-team workflow as the script content. -[rule.threat.tactic] -id = "TA0006" -name = "Credential Access" -reference = "https://attack.mitre.org/tactics/TA0006/" -[[rule.threat]] -framework = "MITRE ATT&CK" -[[rule.threat.technique]] -id = "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/" +- Did the script or recovered process leave dump output or staging evidence? + - Focus: reconstructed `powershell.file.script_block_text` for operator-controlled dump paths, default "_.dmp" names, full-dump flags, archive/base64 staging, or delete-after-write logic. + - Hint: scope file events to `host.id`, `process.pid`, and the alert window with `file.path` and `file.name`. $investigate_4 + - Implication: confirm dumping when a ".dmp", renamed dump, archive, or cleanup path matches the script or recovered process. Missing endpoint file telemetry is unresolved, not benign. +- If a process session is recovered, does authentication evidence show credential use after dumping? + - Focus: Use same-host/user Windows Security events for `event.code` 4624, 4625, or 4648; review `source.ip` and `winlog.event_data.AuthenticationPackageName` where present. $investigate_5 + - Hint: Bridge `process.Ext.authentication_id` to same-host `winlog.event_data.TargetLogonId`; search backward from process `@timestamp` because session-creating 4624 can predate the script. Search `event.code` 4648 separately on `winlog.event_data.SubjectLogonId` for explicit-credential use. + - Implication: escalate when new remote logons, unexpected NTLM or Kerberos activity, explicit-credential use, or privileged session creation follows the dump window. Missing authentication telemetry is unresolved, not benign. +- If local evidence remains suspicious or unresolved, does related activity widen the user or host scope? + - Focus: related alerts for `user.id` covering credential access, LSASS access, dump-file creation, or lateral movement. $investigate_0 + - Hint: compare `host.id` related alerts for the same behavior families, including non-PowerShell LSASS access or dump-file creation that confirms adjacent credential-dumping variants. $investigate_1 + - Implication: broaden containment or scoping when related alerts show adjacent credential-dumping or post-compromise behavior by the same user or host; keep local when related alerts are quiet and local evidence resolves to one recognized workflow. Recurrence alone does not close unresolved telemetry. -[rule.threat.tactic] -id = "TA0002" -name = "Execution" -reference = "https://attack.mitre.org/tactics/TA0002/" +- Escalate when script intent, launch, artifacts, authentication follow-on, or related-alert scope points to unauthorized memory dumping; close only when all evidence fits one bounded troubleshooting, IR, lab-validation, or red-team activity; preserve and escalate when evidence is mixed or incomplete. +### False positive analysis + +- Recognized troubleshooting, IR, lab-validation, or red-team activity can use minidump code. Confirm that reconstructed `powershell.file.script_block_text`, target or PID, output path, `user.id`, `host.id`, alert source path, recovered launch chain if available, and dump/authentication evidence align with the same bounded activity. If workflow records are unavailable, recurrence must show the same target/output, user/host cohort, and launch pattern without contradictory dump or authentication activity. LSASS targeting, cleanup, archive/base64 handling, post-alert authentication outside that activity, or unresolved script/process/auth evidence prevents benign closure. +- Build exceptions from the minimum confirmed pattern: `user.id`, `host.id`, alert source path, reconstructed target/output pattern, and recovered launcher identity if available. Avoid exceptions on minidump strings, `user.name`, or host alone. + +### Response and remediation + +- If confirmed benign, reverse temporary containment and document the exact workflow evidence: reconstructed script content, target process, output path, source path, `user.id`, `host.id`, and recovered launch context if available. Create an exception only after the same pattern is proven stable across prior alerts. +- If suspicious but unconfirmed, preserve the alert, reconstructed script fragments, recovered process details, dump paths, dump or archive artifacts, and linked `winlog.event_data.TargetLogonId`, `winlog.event_data.SubjectLogonId`, or `source.ip` evidence before containment. Apply reversible containment tied to the findings, such as restricting the affected account, collecting the dump artifact, or isolating the host when active dumping or credential use may continue. +- If confirmed malicious, preserve the evidence set before terminating processes or deleting files, then contain the host or account according to host criticality and credential-use evidence. Rotate or reset exposed credentials when LSASS, another credential-bearing process, confirmed dump artifacts, or post-dump authentication are present. +- Eradicate only the unauthorized scripts, dump files, archives, and persistence or delivery artifacts identified during the investigation. Review related `user.id` and `host.id` alerts for the same script fragments or dump paths before declaring scope closed. +- Document any missing process, file, or Windows Security telemetry that limited the investigation so responders know which conclusions were evidence-backed and which remained unresolved. +""" + +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 = [ @@ -182,3 +113,123 @@ field_names = [ "host.id", "powershell.file.script_block_length" ] + +[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 = "All PowerShell 4104 fragments for this script on this host" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4104", 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 = "File events for the PowerShell process" +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 = "file", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" + +[[transform.investigate]] +label = "Windows Security authentication events for the user" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1003" +name = "OS Credential Dumping" +reference = "https://attack.mitre.org/techniques/T1003/" +[[rule.threat.technique.subtechnique]] +id = "T1003.001" +name = "LSASS Memory" +reference = "https://attack.mitre.org/techniques/T1003/001/" + +[rule.threat.tactic] +id = "TA0006" +name = "Credential Access" +reference = "https://attack.mitre.org/tactics/TA0006/" + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "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/" diff --git a/rules/windows/credential_access_posh_relay_tools.toml b/rules/windows/credential_access_posh_relay_tools.toml index 22fae39b3..9468f80fd 100644 --- a/rules/windows/credential_access_posh_relay_tools.toml +++ b/rules/windows/credential_access_posh_relay_tools.toml @@ -2,7 +2,7 @@ creation_date = "2024/03/27" integration = ["windows"] maturity = "production" -updated_date = "2026/03/24" +updated_date = "2026/04/27" [rule] author = ["Elastic"] @@ -11,78 +11,10 @@ Detects PowerShell scripts associated with NTLM relay or pass-the-hash tooling a artifacts. Attackers use relay and PtH techniques to authenticate without passwords and pivot to other systems. """ from = "now-9m" -index = ["winlogbeat-*", "logs-windows.powershell*"] +index = ["logs-windows.powershell*", "winlogbeat-*"] language = "kuery" license = "Elastic License v2" name = "Potential PowerShell Pass-the-Hash/Relay Script" -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 PowerShell Pass-the-Hash/Relay Script - -This alert indicates PowerShell script block content consistent with low-level NTLM and SMB/SMB2 negotiation handling. These artifacts are commonly embedded in credential relay and pass-the-hash tooling and can be associated with credential access and lateral movement activity. - -#### 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 - -- Review `powershell.file.script_block_text` to understand capability and intent: - - Identify whether the script is building, parsing, or transmitting NTLMSSP messages and SMB/SMB2 negotiation data (often represented as hex strings or byte arrays). - - Determine whether the logic aligns more closely with: - - A capture/relay workflow (for example, listener-style components, authentication forwarding, or multiple inbound and outbound endpoints), or - - A pass-the-hash style workflow (for example, authentication material variables combined with remote access or remote execution logic). - - Note any tool identifiers, function names, or comments that resemble known PowerShell relay/PtH frameworks (for example, Inveigh, Invoke-TheHash, Invoke-SMBExec, Invoke-WMIExec, or Invoke-Tater). - - Extract any referenced remote targets or infrastructure (hostnames, IP addresses, UNC paths, share names, or URLs) and record them for scoping and downstream validation. - -- Reconstruct the complete script when the content is split across multiple events: - - Pivot on `powershell.file.script_block_id` and order fragments by `powershell.sequence`; use `powershell.total` to confirm the script is complete. - - Review other script blocks for the same host and user around the alert time to capture configuration values, embedded payloads, or follow-on actions not present in the matching fragment. - -- Establish execution context and expectedness: - - Validate the execution context using `host.name`, `host.id`, `user.name`, `user.domain`, and `user.id`. - - Prioritize investigation when the executing account is privileged, rarely uses PowerShell on the host, or when the host is a server or administrative jump system. - - Use `powershell.file.script_block_length` to help gauge whether this resembles embedded tooling (larger or highly structured blocks) versus incidental string handling. - -- Identify script origin (when file context is available): - - If `file.path`, `file.directory`, or `file.name` are present, determine whether the script originated from disk and whether the location and naming align with approved scripts and expected operators. - - Treat scripts sourced from user-writable or temporary locations as higher risk, especially when combined with protocol-crafting logic. - -- Correlate with adjacent telemetry to understand how PowerShell was launched and what occurred afterward (if available in your environment): - - Review process activity near `@timestamp` on the same host to identify the PowerShell host process and its parent process, and whether execution appears interactive, scheduled, or remotely initiated. - - Review network and authentication activity from the same host and user near the alert time for evidence of SMB or other NTLM-based authentication attempts to multiple targets, repeated failures, or unusual destination systems. - - Look for short-following activity consistent with lateral movement (for example, remote management actions, remote execution behaviors, or additional suspicious PowerShell script blocks). - -- Expand the scope and hunt for related activity: - - Search for additional occurrences of distinctive strings or byte patterns from `powershell.file.script_block_text` across other hosts to identify reuse of the same tooling or broader compromise. - - Review other alerts tied to the same `user.id` and `host.id` within a broader window to identify credential access precursors, staging behavior, or persistence attempts. - -### False positive analysis - -- False positives can occur during authorized security testing, incident response, or troubleshooting where scripts intentionally craft or parse NTLM/SMB protocol messages. -- Validate whether the activity is expected by confirming the script owner (when `file.path` is present), the approved operator, and whether the host and account match the intended scope for such work. -- Benign administrative automation rarely embeds raw NTLMSSP/SMB negotiation byte sequences; prioritize additional review when the script content implements low-level protocol logic or includes relay-style workflows. - -### Response and remediation - -- If malicious or unauthorized activity is suspected: - - Contain the affected host to reduce the risk of credential interception and lateral movement. - - Preserve evidence, including the full reconstructed script content, relevant PowerShell log events, and any on-disk script files referenced by `file.path`. - - Identify potentially impacted accounts using `user.name`, `user.domain`, and `user.id`; take credential containment actions per policy (for example, password resets, revocation of exposed credentials, and review of privileged access). - - Investigate potential lateral movement by reviewing activity on any systems referenced in the script content and by hunting for the same script patterns across other hosts. - -- If the activity is confirmed benign: - - Document the business justification and expected host/account scope, and ensure appropriate approvals are in place. - - Apply targeted tuning using stable attributes such as known script paths, approved execution accounts, or consistent script content patterns. -""" references = [ "https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-WMIExec.ps1", "https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-SMBExec.ps1", @@ -92,11 +24,6 @@ references = [ ] risk_score = 73 rule_id = "951779c2-82ad-4a6c-82b8-296c1f691449" -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", @@ -122,6 +49,169 @@ event.category:process and host.os.type:windows and not file.directory : "C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\Downloads" ''' +note = """## Triage and analysis + +### Investigating Potential PowerShell Pass-the-Hash/Relay Script + +#### Possible investigation steps + +- Does the visible script content implement relay-listener behavior, pass-the-hash execution, target validation, or more than one? + - Focus: `powershell.file.script_block_text` and any file-backed `file.path`. + - Implication: escalate when the fragment builds NTLMSSP/SMB messages, starts HTTP/SMB/proxy listeners, forwards authentication, references WMI/SMB/WinRM helpers, or pairs byte arrays with target selection; lower suspicion only for parser or lab text with no targeting, listener, credential, or execution logic. + +- Does full script reconstruction reveal target lists, credential material, service names, or listener settings the matching fragment did not show? + - Why: script block logging often splits relay mode, target configuration, and execution helpers into separate fragments. + - Focus: `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and reconstructed `powershell.file.script_block_text` on `host.id`; reassemble by `powershell.sequence` and treat missing fragments as unresolved. $investigate_0 + - Implication: escalate on remote targets, password hashes, "TargetList", "SMBRelayTarget", "wpad.dat", "WPAD", listener ports, service names, execution helpers, or fan-out logic; lower suspicion only for research or validation code with no credential material, targets, listener, or execution path. + +- Which recovered PowerShell process explains launch context and downstream pivots? + - Focus: If endpoint process telemetry exists, recover the matching process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`; if absent, keep launch context unresolved. Record `process.command_line`, `process.parent.executable`, `process.Ext.session_info.logon_type`, `process.Ext.authentication_id`, and `process.entity_id`. $investigate_1 + - Implication: escalate when the recovered launch shows encoded commands, remote-administration launchers, Office or browser parents, elevated context, or service/network logon sessions that do not fit the user; do not infer legitimacy from `process.pid` alone. + +- Do authentication events show local operator context or relay/PtH follow-on? + - Focus: same-`host.id`/`user.id` Windows Security events for `event.code` 4624, 4625, or 4648; review `source.ip`, `winlog.event_data.AuthenticationPackageName`, and `winlog.logon.type`. $investigate_2 + - Hint: bridge recovered `process.Ext.authentication_id` to `winlog.event_data.TargetLogonId` only for the local session; prove relay/PtH with same-host inbound NTLM without `user.id`, target-host 4624/4625, or DC-side 4776 for reconstructed targets or sources. + - Implication: escalate when local, target-host, or DC authentication shows unexpected type 3 NTLM, repeated failures, privileged sessions, or explicit-credential use tied to reconstructed targets; missing authentication telemetry is unresolved, not benign. + +- Do network events show outbound relay or hash-validation activity to targets named in the script? + - Why: relay code often resolves targets, then reaches SMB, RPC, WinRM, or HTTP destinations; listener-only capture may not. + - Focus: If endpoint network telemetry exists, scope same-host events to `host.id`, `process.pid`, and the alert window, or use reconstructed targets when process identity is unavailable; separate DNS (`dns.question.name`, `dns.resolved_ip`) from connections (`destination.ip`, `destination.port`). $investigate_3 + - Implication: escalate when the host fans out to named targets or reaches SMB, RPC, WinRM, or relay ports (80, 443, 445) outside the declared test scope; listener scripts stay suspicious with little outbound traffic when reconstruction shows "SMBRelayTarget", "wpad.dat", or similar relay-ready settings. Missing network telemetry is unresolved, not benign. + +- If local evidence remains suspicious or incomplete, do related alerts widen the user or host scope? + - Focus: related alerts for `user.id`; if quiet, compare `host.id` for adjacent relay, pass-the-hash, remote-service, persistence, or post-compromise alerts. + - $investigate_4 + - $investigate_5 + - Implication: broaden when local evidence stays suspicious or unresolved and related alerts show connected relay, listener-only capture, hash-validation fan-out, or lateral-movement behavior; keep local when surrounding alerts are absent or confined to the same declared test scope. + +- Weigh script intent, reconstruction, launch context, authentication follow-on, network contact, and related-alert scope: escalate when they align on unauthorized relay or pass-the-hash activity; close only when reconstructed content, launch, source, and available auth or network evidence support one controlled workflow with no contradictions; preserve and escalate if evidence is mixed or incomplete. + +### False positive analysis + +- Controlled testing, incident-response, or protocol-research workflows can trigger this rule when reconstructed `powershell.file.script_block_text` names only recognized targets or stays limited to parser/validation routines, recovered launch context matches the operator workflow, and authentication or network telemetry shows no live relay, listener, or execution outside scope. If engagement or change records exist, require alignment; otherwise, confirm recurring `user.id`, `host.id`, source pattern, recovered launch pattern, and target or port pattern across prior alerts from this rule. Do not close if hashes, listener ports, or follow-on authentication diverge. +- Before creating an exception, validate recurring `user.id`, `host.id`, recovered launch pattern, source pattern, and target set across prior alerts. Build the exception from that minimum workflow. Avoid exceptions on byte sequences alone, `user.name` alone, or host alone. + +### Response and remediation + +- If confirmed benign, reverse any temporary containment and document the script content, recovered launch chain, source path pattern, target set, and session origin or logon-type pattern that proved the lab, response, or troubleshooting workflow. Create an exception only if the same workflow recurs across prior alerts from this rule. +- If suspicious but unconfirmed, preserve the reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, fragment ordering metadata, recovered process and parent details, named targets, listener ports, service names, UNC paths, and related authentication or network evidence before destructive actions. +- Apply reversible containment first, such as host isolation if tolerable or temporary controls on exposed accounts and named targets. Avoid terminating processes or deleting artifacts until possible credential misuse and lateral movement scope is clearer. +- If confirmed malicious, isolate the endpoint when possible; otherwise escalate with the recorded `host.id`, recovered process identifiers, source IP values, named targets, and authentication evidence. Rotate or invalidate impacted credentials, review named systems for successful SMB/WMI/WinRM/service activity, restrict exposed NTLM pathways where supported, then remove only the scripts, services, scheduled tasks, persistence, or staging artifacts found during the investigation. +- Retain PowerShell Script Block Logging plus supporting endpoint, authentication, and network telemetry. Document adjacent variants such as listener-only capture, hash-validation fan-out, or non-PowerShell relay/pass-the-hash alerts for detection follow-up. +""" + +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 = [ + "@timestamp", + "user.name", + "user.id", + "user.domain", + "powershell.file.script_block_text", + "powershell.file.script_block_id", + "powershell.sequence", + "powershell.total", + "file.path", + "file.directory", + "file.name", + "process.pid", + "host.name", + "host.id", + "powershell.file.script_block_length" +] + +[transform] + +[[transform.investigate]] +label = "All PowerShell 4104 fragments for this script on this host" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4104", 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 = "Windows Security authentication events for the user" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "Network events for the PowerShell process" +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 = "network", 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" [[rule.threat]] framework = "MITRE ATT&CK" @@ -176,21 +266,3 @@ reference = "https://attack.mitre.org/techniques/T1550/002/" id = "TA0008" name = "Lateral Movement" reference = "https://attack.mitre.org/tactics/TA0008/" -[rule.investigation_fields] -field_names = [ - "@timestamp", - "user.name", - "user.id", - "user.domain", - "powershell.file.script_block_text", - "powershell.file.script_block_id", - "powershell.sequence", - "powershell.total", - "file.path", - "file.directory", - "file.name", - "process.pid", - "host.name", - "host.id", - "powershell.file.script_block_length" -] diff --git a/rules/windows/credential_access_posh_request_ticket.toml b/rules/windows/credential_access_posh_request_ticket.toml index 3c2c84359..25d542910 100644 --- a/rules/windows/credential_access_posh_request_ticket.toml +++ b/rules/windows/credential_access_posh_request_ticket.toml @@ -2,101 +2,25 @@ creation_date = "2022/01/24" integration = ["windows"] maturity = "production" -updated_date = "2026/01/26" +updated_date = "2026/04/27" [rule] author = ["Elastic"] description = """ -Detects PowerShell scripts that requests Kerberos service tickets via KerberosRequestorSecurityToken. -Attackers request service tickets to perform Kerberoasting against service accounts. +Detects PowerShell script content that references KerberosRequestorSecurityToken, which can request Kerberos service +tickets. Attackers request service tickets to perform Kerberoasting for offline password cracking of service accounts. """ from = "now-9m" -index = ["winlogbeat-*", "logs-windows.powershell*"] +index = ["logs-windows.powershell*", "winlogbeat-*"] language = "kuery" license = "Elastic License v2" name = "PowerShell Kerberos Ticket Request" -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 PowerShell Kerberos Ticket Request - -This alert indicates that PowerShell script block content referenced `KerberosRequestorSecurityToken`, a .NET type that can be used to request Kerberos service tickets. In adversary tradecraft, repeated or targeted service ticket requests can support Kerberoasting by obtaining ticket material for offline password cracking of service accounts. - -#### 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 - -- Analyze `powershell.file.script_block_text` to determine whether the reference reflects active ticket requesting or incidental text: - - Identify instantiation patterns (for example, creating a new `KerberosRequestorSecurityToken` object) versus references in comments, strings, or documentation. - - Identify any service identifiers in the script (for example, SPN-like strings in the form `SERVICE/HOST`) to understand which services are being targeted. - - Look for signs of bulk activity (loops, arrays/lists of targets, or repeated ticket requests) that would be atypical for troubleshooting and more consistent with Kerberoasting. - - Look for evidence of ticket material handling or staging (formatting large blobs, encoding/decoding, writing output to disk, or preparing data for transfer) in the same or nearby script blocks. - -- Reconstruct complete script content when split across multiple events: - - If `powershell.total` indicates multiple fragments, pivot on `powershell.file.script_block_id` and order by `powershell.sequence` to rebuild the full script block before drawing conclusions. - - Note whether the detected fragment is a helper function, an imported module snippet, or part of a larger multi-stage script. - -- Use script size and origin to guide triage: - - Review `powershell.file.script_block_length` to understand whether the script block is a small snippet or a larger embedded tool/module. - - Review `file.path`, `file.directory`, and `file.name` (when present) to determine whether the script originated from a controlled location. If these fields are absent, treat the activity as potentially interactive or fileless and prioritize reconstructing the full script content. - -- Validate execution context and expectedness: - - Review `user.name`, `user.domain`, and `user.id` to determine whether the account is expected to perform Kerberos troubleshooting or authentication testing from PowerShell. - - Review `host.name` and `host.id` to determine whether the host is an expected administrative endpoint (for example, a management workstation) or an atypical system for this activity. - - Check for repeated alerts for the same `user.id` or `host.id` over a short period, which can indicate automation or systematic targeting. - -- Assess potential scope and impact: - - Identify whether the same script content (or the same file name/path, when available) appears across multiple hosts or users, which can indicate a distributed execution campaign. - - If the script content indicates specific target services, identify the corresponding service accounts in your identity inventory and prioritize high-privilege or broadly scoped services for review. - -- Correlate with adjacent telemetry around `@timestamp` (if available in your environment): - - Review authentication auditing on domain controllers for Kerberos service ticket requests near the alert time and attribute requests to the initiating account and source host to confirm whether ticket requests occurred and whether there was a burst across multiple services. - - Review endpoint process telemetry for the same host and time window to identify how PowerShell was initiated and whether the parent activity aligns with an expected administrative workflow. - - Review other PowerShell script block events for the same `user.id` and `host.id` before and after the alert for follow-on behaviors such as discovery, credential access, persistence, or data staging. - -- Scope the behavior across the environment: - - Search for additional occurrences of `KerberosRequestorSecurityToken` in `powershell.file.script_block_text` to identify other potentially affected hosts, users, or time periods. - - Compare the observed script content and file origin (when available) with known-good scripts to determine whether the behavior is novel or consistent with approved operational activity. - -### False positive analysis - -- Legitimate Kerberos troubleshooting, authentication validation, or service connectivity testing can request service tickets from PowerShell, especially in environments with custom identity tooling. -- Some administrative automation may request service tickets for a small, fixed set of internal services as part of health checks or integration testing. -- Benign activity is more likely when the script source is known and controlled, the executing account and host are expected for identity administration, and the behavior is limited in scope (few services, short duration, no evidence of ticket material staging). - -### Response and remediation - -- If the activity is confirmed or strongly suspected malicious: - - Follow incident response procedures to contain the affected host(s) and prevent additional credential access and lateral movement. - - Identify the services and accounts potentially targeted based on the script content and Kerberos auditing, then prioritize credential rotation for impacted service accounts and review their privilege and group memberships. - - Hunt for additional evidence of ticket collection and cracking workflows by reviewing related PowerShell script blocks on the same host/user and by reviewing Kerberos service ticket request patterns over the same time period. - - Assess whether the initiating user account is compromised and take appropriate actions (credential reset, session invalidation, and access review) based on your organization's response process. - -- If the activity is confirmed benign: - - Document the script owner, purpose, and expected execution context (expected `user.name`, `host.name`, and script location) to speed up future triage. - - Where possible, move scripts to controlled locations and limit execution to authorized administrative accounts and hosts. - - Continue monitoring for deviations, such as execution by new accounts, execution from unusual hosts, or expansion to a larger set of targeted services. -""" references = [ - "https://cobalt.io/blog/kerberoast-attack-techniques", + "https://www.cobalt.io/blog/kerberoast-attack-techniques", "https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1", ] risk_score = 73 rule_id = "eb610e70-f9e6-4949-82b9-f1c5bcd37c39" -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", @@ -111,56 +35,70 @@ type = "query" query = ''' event.category:process and host.os.type:windows and - powershell.file.script_block_text : ( - KerberosRequestorSecurityToken - ) and not user.id : ("S-1-5-18" or "S-1-5-20") and + powershell.file.script_block_text : "KerberosRequestorSecurityToken" and not powershell.file.script_block_text : ( ("sentinelbreakpoints" and ("Set-PSBreakpoint" or "Set-HookFunctionTabs")) or ("function global" and "\\windows\\sentinel\\4") ) ''' +note = """## Triage and analysis -[[rule.threat]] -framework = "MITRE ATT&CK" -[[rule.threat.technique]] -id = "T1003" -name = "OS Credential Dumping" -reference = "https://attack.mitre.org/techniques/T1003/" +### Investigating PowerShell Kerberos Ticket Request -[[rule.threat.technique]] -id = "T1558" -name = "Steal or Forge Kerberos Tickets" -reference = "https://attack.mitre.org/techniques/T1558/" -[[rule.threat.technique.subtechnique]] -id = "T1558.003" -name = "Kerberoasting" -reference = "https://attack.mitre.org/techniques/T1558/003/" +#### Possible investigation steps +- What does the reconstructed script actually do with KerberosRequestorSecurityToken? + - Focus: Reconstruct full 4104 content on `host.id` with `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`; interpret `powershell.file.script_block_text`. + - Hint: pull fragments with matching `host.id` and `powershell.file.script_block_id`, order by `powershell.sequence`, and note gaps before judging intent. $investigate_2 + - Implication: escalate when the script requests SPN TGS tickets, loops across "Get-DomainUser -SPN" results, or emits John/Hashcat, "TicketByteHexStream", "$krb5tgs$", or ".kirbi" material; lower suspicion only when reconstruction proves incidental text, comments, or a bounded fixed-SPN test with no output logic. +- Do the user, host, and script source fit a bounded recognized Kerberos test? + - Focus: `user.id`, `user.name`, `user.domain`, `host.id`, and `file.path`. + - Hint: absent `file.path` means the script block may be interactive, pasted, or generated in memory, so require stronger corroboration before closure. + - Implication: escalate when a standard user, shared workstation, production server, user-writable `file.path`, or absent `file.path` pairs with broad SPN targeting; lower suspicion only for a recognized identity test or Kerberos diagnostic on the expected host and user with a fixed SPN set. -[rule.threat.tactic] -id = "TA0006" -name = "Credential Access" -reference = "https://attack.mitre.org/tactics/TA0006/" -[[rule.threat]] -framework = "MITRE ATT&CK" -[[rule.threat.technique]] -id = "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/" +- If endpoint process telemetry is available for this host, how did the PowerShell session start? + - Focus: `process.command_line`, `process.parent.executable`, `process.parent.command_line`, and `process.Ext.session_info.logon_type`. + - Hint: recover the process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`; if absent after a wider lookup, keep launch context unresolved and scope later pivots with `host.id`, `user.id`, and alert time. $investigate_3 + - Implication: escalate when launch context shows encoded commands, pasted or remote delivery, Office or browser parents, unexpected service or network logon, or alternate-credential use; lower suspicion when command line and parent chain match the exact recognized test workflow. +- Did the activity create ticket, hash, or target-list artifacts? + - Focus: If endpoint file telemetry exists, scope writes to `host.id`, `user.id`, and the alert window; use the recovered process only after process recovery succeeds, and review `file.path` and `file.Ext.header_bytes`. $investigate_4 + - Implication: escalate when writes show SPN lists, ".kirbi" tickets, "$krb5tgs$" or John/Hashcat text, "TicketByteHexStream", base64 blobs, archives, or temp/share/user-writable staging; no file output does not clear direct hash output or memory-only ticket export, and missing file telemetry is unresolved, not benign. +- Do domain-controller ticket events confirm active Kerberoasting behavior? + - Focus: DC-side Windows Security `event.code` 4769 near alert time, starting with `winlog.event_data.TargetUserName` = alert `user.name` for domain requesters; review `winlog.event_data.TargetDomainName`, `source.ip`, `winlog.event_data.ServiceName`, `winlog.event_data.TicketEncryptionType`, and target SPN volume. $investigate_5 + - Hint: if the alert user is local, SYSTEM, or the transform is quiet, retry DC 4769 with UPN/domain variants from `user.name` + `user.domain`, then pivot by source host/address and candidate requester from reconstruction or launch context. + - Implication: escalate when 4769 events show broad SPN enumeration, RC4 or weak encryption, service-account-heavy targeting, or client addresses inconsistent with the expected workflow. Missing authentication telemetry is unresolved, not benign. -[rule.threat.tactic] -id = "TA0002" -name = "Execution" -reference = "https://attack.mitre.org/tactics/TA0002/" +- Is this ticket-request activity isolated or part of broader suspicious behavior? + - Focus: same-scope events or alerts for `user.id` in the last 48 hours for credential access, execution, discovery, or lateral movement. $investigate_0 + - Hint: use the host pivot separately when user scope is noisy or service-account-heavy. $investigate_1 + - Implication: broaden response when either pivot shows adjacent credential access, execution, discovery, or lateral movement; keep the case local only when related alerts stay quiet or match the same bounded recognized workflow. +- Escalate active service-ticket collection without a recognized owner or with suspicious scope, output, launch, artifact, DC 4769, or same-scope evidence; close only when alert-local evidence and supported recovery bind one exact bounded workflow and outside confirmation resolves gaps; preserve evidence and escalate when findings are mixed or incomplete. + +### False positive analysis + +- Recognized Kerberos diagnostics, identity validation, or red-team tests can trigger this rule when reconstructed `powershell.file.script_block_text` stays limited to a fixed SPN set, creates no ticket or hash output, and the script source fits. If process telemetry was recovered via `host.id + process.pid`, require `process.command_line` and `process.parent.executable` to match. Require test-record alignment when present; otherwise close only when current telemetry proves the same fixed-SPN, no-output, user-host, source, and launch-chain pattern. +- Build exceptions from the minimum confirmed workflow: `user.id`, `host.id`, exact source pattern, recovered launch chain, and fixed SPN set. If prior alerts exist, verify they do not add expanded targets, crackable output, or a different launch path; for a first verified case, prefer a narrow candidate or time-bounded exception over broad suppression. Avoid exceptions on "KerberosRequestorSecurityToken" alone, `user.name` alone, or host alone. + +### Response and remediation + +- If confirmed benign, reverse any temporary containment and record the evidence that proved the recognized diagnostics, lab, or identity-test workflow: stable user-host pairing, fixed SPN scope, script source, recovered launch chain when available, and no contradictory artifact or same-scope evidence. Create only a narrow exception from that confirmed evidence; use prior alerts to tighten scope when they exist, not as the primary proof. +- If suspicious but unconfirmed, preserve the reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, `process.pid`, any recovered process details, named SPNs, output paths, and available identity records before containment. Apply reversible containment first, such as temporary host isolation or account restriction matched to host criticality, and avoid destructive cleanup until service-account exposure is scoped. +- If confirmed malicious, contain the host and affected account when script intent, recovered launch context, named SPNs, output artifacts, or same-scope events support unauthorized ticket collection. Record the recovered PowerShell command line, parent chain, named SPNs, output locations, and available identity evidence before terminating processes, deleting files, or purging sessions. +- If targeted or bulk service-ticket requests are confirmed, prioritize the named service accounts for password rotation, privilege review, and downstream logon analysis, then review affected services for anomalous authentication or access tied to the same period. +- Eradicate only the unauthorized scripts, SPN lists, ticket or hash output, scheduled tasks, and persistence mechanisms uncovered during the investigation, then remediate the delivery path or administrative-control gap that allowed the script to run. +- After containment, hunt for the same reconstructed script fragments, SPN patterns, and ticket-request evidence across other hosts, and retain PowerShell Script Block Logging plus supporting endpoint or identity telemetry where gaps limited the investigation. +""" + +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 = [ @@ -180,3 +118,112 @@ field_names = [ "host.id", "powershell.file.script_block_length" ] + +[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 = "All PowerShell 4104 fragments for this script on this host" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4104", 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 = "File events for the PowerShell process" +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 = "file", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" + +[[transform.investigate]] +label = "Kerberos service ticket events for the alert user name" +description = "" +providers = [ + [ + { excluded = false, field = "winlog.event_data.TargetUserName", queryType = "phrase", value = "{{user.name}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4769", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1558" +name = "Steal or Forge Kerberos Tickets" +reference = "https://attack.mitre.org/techniques/T1558/" +[[rule.threat.technique.subtechnique]] +id = "T1558.003" +name = "Kerberoasting" +reference = "https://attack.mitre.org/techniques/T1558/003/" + +[rule.threat.tactic] +id = "TA0006" +name = "Credential Access" +reference = "https://attack.mitre.org/tactics/TA0006/" + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "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/" diff --git a/rules/windows/credential_access_regback_sam_security_hives.toml b/rules/windows/credential_access_regback_sam_security_hives.toml index 711ea0363..df893b63c 100644 --- a/rules/windows/credential_access_regback_sam_security_hives.toml +++ b/rules/windows/credential_access_regback_sam_security_hives.toml @@ -2,53 +2,19 @@ creation_date = "2024/07/01" integration = ["endpoint"] maturity = "production" -updated_date = "2026/03/24" +updated_date = "2026/04/27" [rule] author = ["Elastic"] -description = "Identifies attempts to access sensitive registry hives which contain credentials from the registry backup folder." +description = "Identifies attempts to access registry backup hives that can contain or enable access to credential material." from = "now-9m" index = ["logs-endpoint.events.file-*"] language = "eql" license = "Elastic License v2" name = "Sensitive Registry Hive Access via RegBack" -note = """## Triage and analysis - -### Investigating Sensitive Registry Hive Access via RegBack - -Collecting registry hives is a common way to access credential information as some hives store credential material. - -For example, the SAM hive stores locally cached credentials (SAM Secrets), and the SECURITY hive stores domain cached credentials (LSA secrets). - -Dumping these hives in combination with the SYSTEM hive enables the attacker to decrypt these secrets. - -#### Possible investigation steps - -- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures. -- Identify the user account that performed the action and whether it should perform this kind of action. -- Contact the account owner and confirm whether they are aware of this activity. -- Investigate other alerts associated with the user/host during the past 48 hours. -- Investigate if the credential material was exfiltrated or processed locally by other tools. -- Investigate potentially compromised accounts. Analysts can do this by searching for login events (e.g., 4624) to the target host. - -### False positive analysis - -- Administrators can export registry hives for backup purposes. Check whether the user is legitamitely performing this kind of activity. - -### Related rules - -- Registry Hive File Creation via SMB - a4c7473a-5cb4-4bc1-9d06-e4a75adbc494 - -### Response and remediation - -- Initiate the incident response process based on the outcome of the triage. -- Isolate the involved hosts to prevent further post-compromise behavior. -- 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. -- Reimage the host operating system and restore 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/T1003/002/", +] risk_score = 73 rule_id = "63e381a6-0ffe-4afb-9a26-72a59ad16d7b" severity = "high" @@ -64,18 +30,162 @@ timestamp_override = "event.ingested" type = "eql" query = ''' -file where host.os.type == "windows" and - event.action == "open" and event.outcome == "success" and process.executable != null and +file where host.os.type == "windows" and + event.action == "open" and event.outcome == "success" and process.executable != null and file.path : ("?:\\Windows\\System32\\config\\RegBack\\SAM", "?:\\Windows\\System32\\config\\RegBack\\SECURITY", - "?:\\Windows\\System32\\config\\RegBack\\SYSTEM") and + "?:\\Windows\\System32\\config\\RegBack\\SYSTEM") and not ( user.id == "S-1-5-18" and process.executable : ( - "?:\\Windows\\system32\\taskhostw.exe", "?:\\Windows\\system32\\taskhost.exe" - )) + "?:\\Windows\\system32\\taskhostw.exe", + "?:\\Windows\\system32\\taskhost.exe", + "?:\\Program Files\\Sophos\\Endpoint Defense\\SophosScanCoordinator.exe", + "?:\\Program Files\\Sophos\\Endpoint Defense\\SSPService.exe", + "?:\\Program Files\\Windows Defender Advanced Threat Protection\\MsSense.exe", + "?:\\Program Files\\Trend Micro\\AMSP\\coreServiceShell.exe", + "?:\\Program Files\\Symantec\\Symantec Endpoint Protection\\*\\Bin64\\ccSvcHst.exe", + "?:\\Program Files\\Bitdefender\\Endpoint Security\\EPSecurityService.exe", + "?:\\Program Files\\N-able Technologies\\AVDefender\\EPSecurityService.exe", + "?:\\Program Files\\Cylance\\Optics\\CyOptics.exe", + "?:\\Program Files\\Common Files\\McAfee\\AVSolution\\mcshield.exe", + "?:\\Program Files (x86)\\Padvish AV\\APCcSvc.exe" + ) + ) ''' +note = """## Triage and analysis + +### Investigating Sensitive Registry Hive Access via RegBack + +#### Possible investigation steps + +- Which RegBack hives did the process open, and is the set usable for credential access? + - Why: "SAM" or "SECURITY" becomes credential material when paired with "SYSTEM"; `file.size` helps assess populated hives but does not replace hive-set review. + - Focus: alert `file.path` and `file.size`, then same-process opens for other RegBack hives. $investigate_2 + - Implication: escalate when one process accesses "SAM" plus "SYSTEM" or all three hives, especially with populated sizes; do not close on empty/missing size alone, and keep isolated single-hive access unresolved until identity and staging are checked. + +- Does the accessing process fit a recognized recovery, backup, or forensic chain? + - Focus: `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, and `process.parent.executable`. + - Hint: use `process.entity_id` to tie `process.command_line` and `process.parent.command_line` to the opener; if renamed, check `process.pe.original_file_name`. Trusted signer or Microsoft path does not clear credential-hive access. + - Implication: escalate when the binary is unsigned, user-writable, renamed, or launched by shell, script, Office, or remote-admin lineage outside recovery/evidence collection; lower suspicion when signer, path, parent, and command lines converge on one recognized workflow. + +- Did the same process stage, rename, archive, or hide hive files? + - Focus: same-process file events by `host.id` and `process.entity_id`, especially `file.path` and `file.size`. + - Hint: look for temp, user-profile, admin-share, removable, archive, or deceptive names omitting "SAM", "SECURITY", or "SYSTEM". + - Implication: escalate when hives are copied, renamed, compressed, or staged outside a recognized evidence or backup repository; lower suspicion when copies stay inside the bounded recovery/forensic case path. + +- Does the user and session identity fit protected RegBack access? + - Focus: `user.id`, `process.Ext.authentication_id`, `process.command_line`, and `process.parent.executable`. + - Hint: when present, use `process.Ext.session_info.logon_type` only as support; otherwise anchor on `process.Ext.authentication_id`, parent, and command line. + - Implication: escalate on rare user, unexplained session identifier, or remote-admin lineage without matching process and file-path evidence for recovery or forensics; lower suspicion when account, session, parent, and command line match the bounded workflow. + +- Do command lines or child processes show hive parsing, cleanup, or transfer? + - Why: RegBack reads may pair with "reg save", shadow-copy, or raw-copy variants for offline secret extraction. + - Focus: `process.command_line`, child process events where `process.parent.entity_id` matches `process.entity_id`, and copied-hive `file.path` values. $investigate_3 + - Hint: check for "reg.exe save", shadow-copy utilities, raw-copy tools, archive tools, credential dumpers, cleanup commands, removable paths, or UNC paths. + - Implication: escalate when the lineage parses hives, creates archives, deletes staged hives, writes UNC/removable paths, or uses reg-save/shadow-copy/raw-copy variants; absence of these follow-on artifacts does not clear populated multi-hive access. + +- If local evidence is suspicious or incomplete, do related alerts expand scope? + - Focus: related alerts for `user.id` covering credential access, privilege escalation, staging, transfer, persistence, or lateral movement. $investigate_0 + - Hint: use `host.id` when user scope is quiet or the actor is "S-1-5-18" or another service context. $investigate_1 + - Implication: broaden containment and credential-impact review when related alerts show adjacent post-compromise behavior; keep the case local when related alerts are quiet and all local evidence fits one recognized workflow. + +- Escalate on populated multi-hive access with suspicious identity, staging, transfer, privilege, or related-alert context; close only when telemetry aligns with one recognized backup, recovery, or forensic workflow and no contradictory evidence remains; preserve hives, process records, and copied artifacts when evidence is mixed, incomplete, or needs outside confirmation. + +### False positive analysis + +- Endpoint security products (AV/EDR) routinely open RegBack hives during full-disk scans. Confirm when `process.executable` is a trusted-signed binary from a `Program Files` AV/EDR install path, `user.id` is `S-1-5-18`, and the same `process.entity_id` shows no staging, copy, archive, or multi-hive credential-set access. +- Recognized backup, recovery, or forensic workflows can legitimately access RegBack hives only when `process.executable`, `process.code_signature.subject_name`, `process.parent.executable`, `process.command_line`, copied `file.path`, `user.id`, `process.Ext.authentication_id`, and `host.id` identify the same bounded maintenance or evidence-collection scope. Leave unresolved if staging, child-process, or related-alert evidence contradicts the workflow or legitimacy rests only on owner/context. +- Before creating an exception, require recurring `process.executable`, `process.command_line`, `file.path`, `user.id`, and `host.id` across prior alerts; avoid exceptions on the RegBack path, hive name, or host alone. + +### Response and remediation + +- If confirmed benign, release any temporary containment and document the confirmed workflow anchors: tool identity, parent and command line, bounded RegBack `file.path` set, copied path pattern, `user.id`, and `host.id`. Create an exception only if those anchors recur consistently across prior alerts from this rule. +- If suspicious but unconfirmed, export the alert, process timeline, same-process file activity, and any copied, archived, UNC, or removable-media hive paths before containment. Preserve hive copies when present. Apply reversible containment first, such as restricting the process, copied path, share access, or involved `user.id`; escalate to host isolation only when populated multi-hive access is paired with staging, transfer paths, or related post-compromise alerts and the asset can tolerate it. +- If confirmed malicious, record and preserve the responsible process instance, process timeline, and hive artifact paths before containment. Then use Elastic Defend response actions to isolate the host and kill or suspend the process. If direct endpoint response is unavailable, escalate with those artifacts to the team that can isolate the host or disable the involved account. Block confirmed malicious tools, paths, shares, and copied artifacts tied to the RegBack access before cleanup. +- If the same process accessed populated "SAM", "SECURITY", and "SYSTEM" files, treat the case as higher-confidence credential exposure and begin local-account and cached-credential hygiene appropriate to the host role. On shared admin systems or servers with privileged local accounts, escalate identity-impact handling according to the credential-compromise runbook. +- Before eradication, scope the same process identity, RegBack path set, copy destinations, `user.id`, and `host.id` across related alerts so evidence is preserved before cleanup. Then remove unauthorized tools, copied hives, archives, remote-share artifacts, and persistence mechanisms uncovered during the investigation, and remediate the access vector or privilege path that allowed RegBack access. +- Post-incident hardening: restrict RegBack access to recognized backup, recovery, and forensic tooling; retain endpoint process and file telemetry needed for this workflow; and document any "reg save", shadow-copy, or raw-copy variants surfaced during triage for future case comparison. +""" + +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", + "user.name", + "user.id", + "process.executable", + "process.entity_id", + "process.command_line", + "process.parent.executable", + "process.pe.original_file_name", + "process.code_signature.subject_name", + "process.code_signature.trusted", + "process.Ext.authentication_id", + "file.path", + "file.size", +] + +[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 activity for the same 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 process events for the accessing 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" diff --git a/rules/windows/credential_access_relay_ntlm_auth_via_http_spoolss.toml b/rules/windows/credential_access_relay_ntlm_auth_via_http_spoolss.toml index a0fe23faf..52fb81270 100644 --- a/rules/windows/credential_access_relay_ntlm_auth_via_http_spoolss.toml +++ b/rules/windows/credential_access_relay_ntlm_auth_via_http_spoolss.toml @@ -2,13 +2,13 @@ creation_date = "2022/04/30" integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"] maturity = "production" -updated_date = "2026/04/07" +updated_date = "2026/04/27" [rule] author = ["Elastic"] description = """ -Identifies attempt to coerce a local NTLM authentication via HTTP using the Windows Printer Spooler service as a target. -An adversary may use this primitive in combination with other techniques to elevate privileges on a compromised system. +Identifies attempts to coerce local NTLM authentication over HTTP through WebDAV named-pipe paths such as +Print Spooler or SRVSVC. Adversaries can combine this primitive with relay tooling to elevate privileges. """ from = "now-9m" index = [ @@ -25,41 +25,6 @@ index = [ language = "eql" license = "Elastic License v2" name = "Potential Local NTLM Relay via HTTP" -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 Local NTLM Relay via HTTP - -NTLM, a suite of Microsoft security protocols, is often targeted by adversaries for credential theft. Attackers may exploit the Windows Printer Spooler service to coerce NTLM authentication over HTTP, potentially elevating privileges. The detection rule identifies suspicious rundll32.exe executions invoking WebDAV client DLLs with specific arguments, signaling attempts to access named pipes via HTTP, indicative of NTLM relay attacks. - -### Possible investigation steps - -- Review the process execution details for rundll32.exe, focusing on the specific arguments related to davclnt.dll and DavSetCookie, to confirm the presence of suspicious WebDAV client activity. -- Investigate the network connections initiated by the rundll32.exe process to identify any HTTP requests targeting named pipes, such as those containing "/print/pipe/", "/pipe/spoolss", or "/pipe/srvsvc". -- Check the system's event logs for any related authentication attempts or failures around the time of the alert to identify potential NTLM relay activity. -- Analyze the history of the Windows Printer Spooler service on the affected host to determine if it has been recently manipulated or exploited. -- Correlate the alert with other security events or alerts from data sources like Microsoft Defender XDR or Sysmon to identify any related suspicious activities or patterns. -- Assess the user account associated with the NTLM authentication attempt to determine if it has been compromised or is being used in an unauthorized manner. - -### False positive analysis - -- Legitimate administrative tasks using rundll32.exe with WebDAV client DLLs may trigger the rule. Review the context of the execution, such as the user account and the timing, to determine if it aligns with expected administrative activities. -- Automated software deployment or update processes might use similar rundll32.exe calls. Verify if the process is part of a scheduled or known deployment task and consider excluding these specific processes from the rule. -- Some third-party applications may use WebDAV for legitimate purposes, which could mimic the behavior detected by the rule. Identify these applications and create exceptions for their known processes to prevent false alerts. -- System maintenance scripts or tools that interact with network resources via HTTP might inadvertently match the rule's criteria. Ensure these scripts are documented and exclude them if they are verified as non-threatening. -- Regularly review and update the exclusion list to accommodate changes in legitimate software behavior, ensuring that only verified false positives are excluded to maintain the rule's effectiveness. - -### Response and remediation - -- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement. -- Terminate any suspicious rundll32.exe processes identified in the alert to stop ongoing malicious activity. -- Conduct a thorough review of the affected system's event logs and network traffic to identify any additional indicators of compromise or related malicious activity. -- Reset credentials for any accounts that may have been exposed or compromised during the attack to prevent unauthorized access. -- Apply the latest security patches and updates to the Windows Printer Spooler service and related components to mitigate known vulnerabilities. -- Implement network segmentation to limit the exposure of critical services and reduce the risk of similar attacks in the future. -- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to ensure comprehensive remediation efforts are undertaken.""" references = [ "https://github.com/med0x2e/NTLMRelay2Self", "https://github.com/topotam/PetitPotam", @@ -97,6 +62,163 @@ process where host.os.type == "windows" and event.type == "start" and process.args : ("http*/print/pipe/*", "http*/pipe/spoolss", "http*/pipe/srvsvc") ''' +note = """## Triage and analysis + +### Investigating Potential Local NTLM Relay via HTTP + +#### Possible investigation steps + +- Does the alert-local command line confirm WebDAV-to-named-pipe relay behavior? + - Focus: `process.command_line` and `process.executable`; confirm rundll32.exe loads davclnt.dll,DavSetCookie and targets HTTP pipe paths: /print/pipe/, /pipe/spoolss, or /pipe/srvsvc. + - Implication: escalate when one command combines DavSetCookie with HTTP named-pipe paths, matching NTLMRelay2Self and printerbug-style coercion; close only when exact `process.command_line`, `user.id`, and `host.id` tie to authorized relay testing or explicit WebDAV/print diagnostics intentionally exercising this path. + +- Is the binary identity and launch chain consistent with the relay context? + - Focus: `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`, `process.parent.executable`, and `process.parent.command_line`. + - Implication: escalate when rundll32.exe is renamed, outside a Windows system path, launched by a script, document, remote-management, or user-writable parent, or signer-mismatched; lower suspicion only when identity and parent chain match the authorized test or diagnostic workflow. Identity alone does not clear relay behavior. + +- Did the process contact the HTTP listener implied by the relay path? + - Focus: if endpoint network telemetry exists, recover process network events with `host.id` plus `process.entity_id`; fallback to `host.id` plus `process.pid` in a tight window. Read DNS via `dns.question.name`; connections via `destination.ip` and `destination.port`. $investigate_2 + - Hint: compare destinations to the HTTP host in `process.command_line`; loopback, same-host aliases, private listeners, or unexpected external HTTP infrastructure are decisive. + - Implication: escalate when traffic reaches the listener named by the relay command or an unexplained HTTP endpoint. Missing endpoint network or DNS telemetry is unresolved, not benign. + +- Did authentication events explain the local rundll32 session or relay follow-on? + - Why: the process alert proves relay intent; Windows Security events can explain the operator session, while relay proof may surface as inbound NTLM on this host, target-host authentication, or DC-side validation. + - Focus: for local session context, bridge `process.Ext.authentication_id` to same-host `winlog.event_data.TargetLogonId`; on 4624, read `winlog.event_data.AuthenticationPackageName` and `source.ip`. $investigate_3 + - Hint: for relay proof, search same-host inbound NTLM without `user.id`, target-host 4624/4625, and DC-side 4776 using the listener, reconstructed targets, or source addresses from command/network evidence. Search 4648 on `winlog.event_data.SubjectLogonId` only for explicit credentials from the local session. + - Implication: escalate when the local session origin is unexplained, same-host inbound NTLM appears around the alert, or target/DC authentication shows coerced machine or service-account use tied to the listener or targets. Missing authentication telemetry is unresolved, not benign. + +- Is there follow-on execution, tooling, or repeated coercion around the process? + - Focus: child processes where `process.parent.entity_id` matches `process.entity_id`, reading `process.Ext.token.integrity_level_name`; if endpoint file telemetry exists, recover files with `host.id` plus `process.entity_id`, or `host.id` plus `process.pid` in a tight window, then read `file.path`. $investigate_4 + - Hint: look for command lines or artifacts naming PetitPotam, printerbug, NTLMRelay2Self, ntlmrelayx, shadow credentials, RBCD, or WebClient/Print Spooler preparation. + - Implication: escalate when the window shows dropped tools, secondary scripts, repeated rundll32.exe relay attempts, privileged child processes, or WebClient/Print Spooler preparation. Missing endpoint file telemetry limits corroboration, not the alert-local finding. + +- If local evidence is suspicious or unresolved, do related alerts change scope? + - Focus: related alerts for `user.id` covering credential access, relay testing, privilege escalation, or lateral movement. $investigate_0 + - Hint: compare related alerts for `host.id` for spooler abuse, WebClient activity, remote execution, NTLM relay, or coercion patterns. $investigate_1 + - Implication: broaden when either pivot shows repeated relay/coercion or credential-access activity outside the authorized test or diagnostic; keep local when both stay confined to that activity. + +- Escalate when relay-path arguments plus binary lineage, listener contact, NTLM/auth evidence, follow-on tooling, or related alerts indicate unauthorized relay; close only when alert-local evidence and supported recovery fit one authorized workflow; preserve and escalate if evidence is mixed or incomplete. + +### False positive analysis + +- Authorized red-team, purple-team, relay-lab validation, or explicit WebDAV/print diagnostics can trigger this rule. Confirm that `process.command_line`, `process.parent.executable`, `user.id`, `host.id`, destination evidence if available, and authentication evidence all align with that activity. Routine WebDAV or print troubleshooting is insufficient unless it explains the DavSetCookie-to-HTTP-pipe pattern. +- Without workflow records, require a telemetry-only match across prior alerts from this rule: same `process.parent.executable`, exact `process.command_line` pattern, `user.id`, `host.id`, and supported destination or authentication pattern. Build exceptions only from that full workflow; avoid exceptions on rundll32.exe, davclnt.dll, or the pipe path alone. + +### Response and remediation + +- If confirmed benign, release temporary containment and document the workflow anchors: `process.executable`, `process.parent.executable`, exact `process.command_line`, `user.id`, `host.id`, and the recovered destination or authentication evidence. Create an exception only when the same full workflow recurs across prior alerts from this rule. +- If suspicious but unconfirmed, preserve the alert details, `process.entity_id` or `process.pid`, `process.command_line`, `process.parent.command_line`, process tree, recovered network or DNS records, Windows Security records, and file artifacts before containment. Apply reversible containment first, such as temporary HTTP/WebDAV restrictions or heightened monitoring on the host; isolate only if repeated relay attempts, corroborating NTLM activity, follow-on execution, or exposure on a domain controller, print server, or jump host raises the risk and the asset can tolerate isolation. +- If confirmed malicious, preserve the command line, process tree, listener details, authentication records, and dropped artifacts first. Then isolate the host through endpoint response when the evidence establishes unauthorized relay, and kill or suspend the responsible process if it is still active. Block confirmed malicious listeners, path fragments, hashes, or follow-on tools before cleanup. +- If investigation shows successful relay or privileged machine/service-account use, review and rotate affected credentials or secrets according to privilege tier, and coordinate disruptive identity or infrastructure changes before acting on domain controllers, print servers, or jump hosts. +- Before eradication, scope the same command fragment, listener, `user.id`, `host.id`, authentication indicators, and adjacent tooling across other hosts and sessions so evidence is not destroyed before spread is understood. Then remove the relay tooling and harden the exposed path, including unnecessary WebClient or Print Spooler exposure, NTLM relay mitigations, and service-specific controls identified during the investigation. +- Post-incident hardening: retain process, endpoint network, endpoint file, and Windows Security telemetry needed for this correlation, and document adjacent PetitPotam, printerbug, NTLMRelay2Self, or alternate coercion evidence 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) +- [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", + "host.name", + "user.id", + "user.name", + "process.entity_id", + "process.pid", + "process.executable", + "process.command_line", + "process.pe.original_file_name", + "process.parent.executable", + "process.parent.command_line", + "process.code_signature.subject_name", + "process.code_signature.trusted", + "process.Ext.authentication_id", +] + +[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 = "Network events for the relay 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 = "Windows Security events for the local process session" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "Child process events for the relay 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" diff --git a/rules/windows/credential_access_remote_sam_secretsdump.toml b/rules/windows/credential_access_remote_sam_secretsdump.toml index f3fde2b08..7436c9089 100644 --- a/rules/windows/credential_access_remote_sam_secretsdump.toml +++ b/rules/windows/credential_access_remote_sam_secretsdump.toml @@ -2,7 +2,7 @@ creation_date = "2022/03/01" integration = ["endpoint"] maturity = "production" -updated_date = "2024/05/21" +updated_date = "2026/04/27" [rule] author = ["Elastic"] @@ -15,57 +15,12 @@ index = ["logs-endpoint.events.file-*"] language = "eql" license = "Elastic License v2" name = "Potential Remote Credential Access via Registry" -note = """## Triage and analysis - -### Investigating Potential Remote Credential Access via Registry - -Dumping registry hives is a common way to access credential information. Some hives store credential material, such as the SAM hive, which stores locally cached credentials (SAM secrets), and the SECURITY hive, which stores domain cached credentials (LSA secrets). Dumping these hives in combination with the SYSTEM hive enables the attacker to decrypt these secrets. - -Attackers can use tools like secretsdump.py or CrackMapExec to dump the registry hives remotely, and use dumped credentials to access other systems in the domain. - -#### Possible investigation steps - -- Identify the specifics of the involved assets, such as their role, criticality, and associated users. -- Identify the user account that performed the action and whether it should perform this kind of action. -- Determine the privileges of the compromised accounts. -- Investigate other alerts associated with the user/source host during the past 48 hours. -- Investigate potentially compromised accounts. Analysts can do this by searching for login events (e.g., 4624) to the target host. - -### False positive analysis - -- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently malicious must be monitored by the security team. - -### Related rules - -- Credential Acquisition via Registry Hive Dumping - a7e7bfa3-088e-4f13-b29e-3986e0e756b8 - -### Response and remediation - -- Initiate the incident response process based on the outcome of the triage. -- Isolate the involved hosts to prevent further post-compromise behavior. -- 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 if other hosts were compromised. -- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components. -- Reimage the host operating system or restore the compromised files to clean versions. -- Ensure that the machine has the latest security updates and is not running unsupported Windows versions. -- 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/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py", + "https://github.com/fortra/impacket/blob/master/examples/secretsdump.py", "https://www.elastic.co/security-labs/detect-credential-access", ] risk_score = 73 rule_id = "850d901a-2a3c-46c6-8b22-55398a01aad8" -setup = """## Setup - -This rule uses Elastic Endpoint file creation and system integration events for correlation. Both data should be collected from the host for this detection to work. - -If enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, -events will not define `event.ingested` and default fallback for EQL rules was not added until version 8.2. -Hence for this rule to work effectively, users will need to add a custom ingest pipeline to populate -`event.ingested` to @timestamp. -For more details on adding a custom ingest pipeline refer - https://www.elastic.co/guide/en/fleet/current/data-streams-pipeline-tutorial.html -""" severity = "high" tags = [ "Domain: Endpoint", @@ -86,6 +41,153 @@ file where host.os.type == "windows" and file.path : ("?:\\Windows\\system32\\*.tmp", "?:\\WINDOWS\\Temp\\*.tmp") ''' +note = """## Triage and analysis + +### Investigating Potential Remote Credential Access via Registry + +#### Possible investigation steps + +- Does the alert-local file prove a registry hive save? + - Focus: `event.action`, `file.path`, `file.size`, `file.Ext.header_bytes`, and `process.name`. + - Implication: escalate when svchost.exe writes a hive-sized Windows temp file with REGF header bytes; lower concern only when content or location contradicts hive export or matches a recognized hive-export workflow on this host. + +- Does the svchost instance fit RemoteRegistry-backed collection? + - Focus: `process.executable`, `process.command_line`, `process.parent.executable`, `process.Ext.session_info.logon_type`, and `process.Ext.session_info.authentication_package`. + - Hint: if parent or session fields are absent, recover the endpoint process event with `host.id` and `process.entity_id`. + - Implication: escalate when svchost is outside the Windows system path, lacks service-control lineage, uses an unusual service group, or runs under an unexpected remote/network session; lower concern when service context and session fields align with one recognized collection workflow. + +- Did the same process create companion hive artifacts? + - Why: secretsdump-style collection often saves SAM, SECURITY, and SYSTEM hives to target temp storage before parsing or retrieval. + - Focus: file events on `host.id` scoped to `process.entity_id`: `file.path`, `file.name`, `file.size`, `file.Ext.header_bytes`, and `file.Ext.original.path`. $investigate_0 + - Implication: escalate when the same process creates multiple hive-sized REGF temp files, renamed copies, or cleanup artifacts; a single hive artifact narrows scope but does not clear the alert by itself. + +- Does the account and logon session fit recognized collection on this host? + - Focus: `user.id`, `user.name`, `user.domain`, `process.Ext.authentication_id`, and `process.Ext.token.elevation_level`. + - Hint: if Windows Security telemetry exists, bridge `process.Ext.authentication_id` to same-host logon events and read source host/IP, logon type, and authentication package. Missing authentication telemetry is unresolved, not benign. $investigate_2 + - Implication: escalate when account, SID/domain, logon session, or elevation is not the identity used for recognized collection on this host; lower concern only when the same account and session context match that exact workflow. + +- Did the same session leave local staging, cleanup, or follow-on credential-access activity? + - Focus: endpoint process events on `host.id` scoped to `process.Ext.authentication_id`, then file events for matching `process.entity_id`: `process.command_line`, `process.parent.command_line`, `file.path`, and `file.Ext.original.path`. $investigate_1 + - Hint: if the alert lacks `process.Ext.authentication_id`, recover it from the endpoint process event before same-session review. + - Implication: escalate when the same session starts service-control, scripting, copy, compression, cleanup, or additional credential-access activity around the hive write; a single visible hive file remains unresolved because missing follow-on endpoint evidence is not benign. + +- If local evidence remains suspicious or incomplete, do related alerts widen scope? + - Focus: related `user.id` alerts for credential dumping, remote-service abuse, hive saves, or archive staging. $investigate_3 + - Hint: if account ownership is shared or ambiguous, compare `host.id` alerts for remote execution, service abuse, or alternate collection paths. $investigate_4 + - Implication: broaden when the same user or host shows credential dumping, remote-service abuse, archive staging, or repeated hive-save alerts; keep local when related activity stays confined to one recognized collection case. + +- Escalate on a valid hive save plus unexplained service context, account/session, companion artifacts, cleanup, or related-alert evidence; close only when endpoint evidence and any needed outside confirmation bind one exact recognized workflow on this host; preserve and escalate when evidence is mixed or incomplete. + +### False positive analysis + +- Incident-response, forensic acquisition, recovery, or credential-audit jobs can legitimately trigger only when they explicitly export registry hives. Confirm one exact workflow across svchost service context, `process.command_line`, `user.id`, `host.id`, session fields, hive-sized temp `file.path` values, and companion SAM, SECURITY, or SYSTEM artifacts. If telemetry cannot prove legitimacy, require case or owner confirmation; do not close if account, service context, artifact set, or host scope expands beyond that workflow. +- Before exceptioning, validate stable `process.command_line`, `process.executable`, parent context, `user.id`, `host.id`, hive temp-path pattern, and `file.Ext.header_bytes` across prior alerts. Avoid exceptions on svchost.exe, temp paths, or REGF header bytes alone. + +### Response and remediation + +- If confirmed benign, release temporary containment and document the recognized service context, `process.command_line`, account, session context, `host.id`, hive `file.path` values, and companion artifacts that matched the collection workflow. Create an exception only after the same evidence pattern is stable across prior alerts from this rule. +- If suspicious but unconfirmed, preserve a case export covering the alert file, same-process companion hives, same-session process and file activity, process tree, related-alert records, hive paths, sizes, and header bytes before containment. Record the re-query anchors `host.id`, `user.id`, `process.entity_id`, and `process.Ext.authentication_id` with the preserved case export. Apply reversible containment first, such as temporary RemoteRegistry restrictions, share restrictions, or heightened monitoring for the affected account and host; weigh server criticality before isolation. +- If confirmed malicious, first preserve the case export and record `process.entity_id`, `process.command_line`, parent context, companion hive paths, same-session activity, and affected `host.id`. Then isolate the host when artifact, service-context, session, or related-alert evidence establishes unauthorized hive collection. Kill or suspend the responsible process and disable or reset the involved account only after evidence capture and only when the `user.id` evidence supports compromise or unauthorized use. +- Treat companion SAM, SECURITY, and SYSTEM artifacts as exposure of local account material, cached secrets, machine secrets, and LSA secrets for the affected asset. Start credential hygiene appropriate to the host role and any accounts or services touched by the same session. +- After scoping, eradicate only artifacts and changes identified during triage: unauthorized hive copies, staging archives, dump tooling, cleanup scripts, and remote-service changes that enabled the access. Restore legitimate RemoteRegistry or backup configuration if it was altered, and remediate the entry path that allowed the hive save. +- Post-incident hardening: restrict RemoteRegistry-backed hive collection to controlled workflows, minimize accounts allowed to perform remote collection, and retain endpoint process and file telemetry needed to distinguish secretsdump-style, VSS-based, or WMI-based variants in future 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.id", + "user.name", + "user.id", + "process.executable", + "process.command_line", + "process.entity_id", + "process.parent.executable", + "process.Ext.authentication_id", + "process.Ext.session_info.logon_type", + "process.Ext.session_info.authentication_package", + "process.Ext.token.elevation_level", + "file.path", + "file.size", + "file.Ext.header_bytes", +] + +[transform] + +[[transform.investigate]] +label = "File activity for the same 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 = "Process events for the same session" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "process.Ext.authentication_id", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" }, + { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" } + ] +] +relativeFrom = "now-1h" +relativeTo = "now" + +[[transform.investigate]] +label = "Windows Security events for the local process session" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +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" [[rule.threat]] framework = "MITRE ATT&CK" @@ -98,8 +200,6 @@ id = "T1003.002" name = "Security Account Manager" reference = "https://attack.mitre.org/techniques/T1003/002/" - - [rule.threat.tactic] id = "TA0006" name = "Credential Access" @@ -111,9 +211,7 @@ id = "T1021" name = "Remote Services" reference = "https://attack.mitre.org/techniques/T1021/" - [rule.threat.tactic] id = "TA0008" name = "Lateral Movement" reference = "https://attack.mitre.org/tactics/TA0008/" - diff --git a/rules/windows/credential_access_seenabledelegationprivilege_assigned_to_user.toml b/rules/windows/credential_access_seenabledelegationprivilege_assigned_to_user.toml index 6746281b9..fe34873a9 100644 --- a/rules/windows/credential_access_seenabledelegationprivilege_assigned_to_user.toml +++ b/rules/windows/credential_access_seenabledelegationprivilege_assigned_to_user.toml @@ -2,78 +2,29 @@ creation_date = "2022/01/27" integration = ["system", "windows"] maturity = "production" -updated_date = "2025/11/14" +updated_date = "2026/04/27" [rule] author = ["Elastic"] description = """ -Identifies the assignment of the SeEnableDelegationPrivilege sensitive "user right" to a user. The -SeEnableDelegationPrivilege "user right" enables computer and user accounts to be trusted for delegation. Attackers can -abuse this right to compromise Active Directory accounts and elevate their privileges. +Identifies the assignment of the SeEnableDelegationPrivilege sensitive "user right" to a security principal. This +right enables computer and user accounts to be trusted for delegation. Attackers can abuse it to compromise Active +Directory accounts and elevate their privileges. """ from = "now-9m" index = ["winlogbeat-*", "logs-system.security*", "logs-windows.forwarded*"] language = "kuery" license = "Elastic License v2" -name = "Sensitive Privilege SeEnableDelegationPrivilege assigned to a User" -note = """## Triage and analysis - -### Investigating Sensitive Privilege SeEnableDelegationPrivilege assigned to a User - -Kerberos delegation is an Active Directory feature that allows user and computer accounts to impersonate other accounts, act on their behalf, and use their privileges. Delegation (constrained and unconstrained) can be configured for user and computer objects. - -Enabling unconstrained delegation for a computer causes the computer to store the ticket-granting ticket (TGT) in memory at any time an account connects to the computer, so it can be used by the computer for impersonation when needed. Risk is heightened if an attacker compromises computers with unconstrained delegation enabled, as they could extract TGTs from memory and then replay them to move laterally on the domain. If the attacker coerces a privileged user to connect to the server, or if the user does so routinely, the account will be compromised and the attacker will be able to pass-the-ticket to privileged assets. - -SeEnableDelegationPrivilege is a user right that is controlled within the Local Security Policy of a domain controller and is managed through Group Policy. This setting is named **Enable computer and user accounts to be trusted for delegation**. - -It is critical to control the assignment of this privilege. A user with this privilege and write access to a computer can control delegation settings, perform the attacks described above, and harvest TGTs from any user that connects to the system. - -#### Possible investigation steps - -- Investigate how the privilege was assigned to the user and who assigned it. -- Investigate other potentially malicious activity that was performed by the user that assigned the privileges using the `user.id` and `winlog.activity_id` fields as a filter during the past 48 hours. -- Investigate other alerts associated with the users/host during the past 48 hours. - -### False positive analysis - -- The SeEnableDelegationPrivilege privilege should not be assigned to users. If this rule is triggered in your environment legitimately, the security team should notify the administrators about the risks of using it. - -### Related rules - -- KRBTGT Delegation Backdoor - e052c845-48d0-4f46-8a13-7d0aba05df82 - -### Response and remediation - -- Initiate the incident response process based on the outcome of the triage. -- Remove the privilege from the account. -- Review the privileges of the administrator account that performed the action. -- 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). -""" +name = "Sensitive Privilege SeEnableDelegationPrivilege assigned to a Principal" references = [ "https://blog.harmj0y.net/activedirectory/the-most-dangerous-user-right-you-probably-have-never-heard-of/", - "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/builtin/security/win_alert_active_directory_user_control.yml", + "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/builtin/security/win_security_alert_active_directory_user_control.yml", "https://twitter.com/_nwodtuhs/status/1454049485080907776", "https://www.thehacker.recipes/ad/movement/kerberos/delegations", "https://github.com/atc-project/atomic-threat-coverage/blob/master/Atomic_Threat_Coverage/Logging_Policies/LP_0105_windows_audit_authorization_policy_change.md", ] risk_score = 73 rule_id = "f494c678-3c33-43aa-b169-bb3d5198c41d" -setup = """## Setup - -The 'Audit Authorization Policy Change' logging policy must be configured for (Success, Failure). -Steps to implement the logging policy with Advanced Audit Configuration: - -``` -Computer Configuration > -Windows Settings > -Security Settings > -Advanced Audit Policy Configuration > -Audit Policies > -Policy Change > -Audit Authorization Policy Change (Success,Failure) -``` -""" severity = "high" tags = [ "Domain: Endpoint", @@ -93,6 +44,185 @@ query = ''' event.code:4704 and host.os.type:"windows" and winlog.event_data.PrivilegeList:"SeEnableDelegationPrivilege" ''' +note = """## Triage and analysis + +### Investigating Sensitive Privilege SeEnableDelegationPrivilege assigned to a Principal + +#### Possible investigation steps + +- Which principal received SeEnableDelegationPrivilege, and is it narrow enough for delegation administration? + - Focus: the "4704" grant's `winlog.event_data.PrivilegeList`, `winlog.event_data.TargetSid`, and `winlog.computer_name`; resolve `winlog.event_data.TargetSid` when the account name is absent. + - Implication: escalate when the target is a human user, broad admin cohort, stale account, or identity not dedicated to delegation administration; lower concern only for a narrow delegation-admin or service-management principal with controlled source, rollback, and no follow-on abuse. + +- Did a direct actor assign the right, or is the event local policy application? + - Why: "4704" often shows "SYSTEM" or the machine account applying policy, which is not the same as identifying the upstream policy editor. + - Focus: `winlog.event_data.SubjectUserSid`, `winlog.event_data.SubjectUserName`, `winlog.event_data.SubjectLogonId`, and `winlog.computer_name` to separate a human or service actor from "S-1-5-18" or a machine account. + - Implication: escalate when a user-backed or unexpected service account directly assigned the right; when the subject is "SYSTEM" or the machine account, treat it as policy application and keep the upstream policy source unresolved until evidence outside "4704" explains it. + +- If the grant came from a user-backed session, does the linked logon fit the admin tier? + - Focus: authentication events on `host.id` where `winlog.event_data.TargetLogonId` matches `winlog.event_data.SubjectLogonId`; read `source.ip`, `winlog.logon.type`, and `winlog.event_data.AuthenticationPackageName`. $investigate_0 + - Hint: search `winlog.event_data.SubjectLogonId` separately for "4648" explicit-credential context. Missing authentication telemetry is unresolved, not benign; skip this bridge for SYSTEM or machine-account policy application. + - Implication: escalate for an unusual admin source, remote-interactive or NewCredentials logon, unexpected NTLM, or explicit-credential use; lower concern when Kerberos and the source host fit the controlled delegation-admin workflow. + +- Did authorization-policy activity stay bounded and roll back? + - Focus: surrounding grant/removal events on `winlog.computer_name` for the same `winlog.event_data.SubjectUserSid` and `winlog.event_data.SubjectLogonId`, including other `winlog.event_data.PrivilegeList` or `winlog.event_data.TargetSid` values. $investigate_1 + - Hint: check paired removals for the same `winlog.event_data.TargetSid`, `winlog.event_data.PrivilegeList`, and `winlog.computer_name`. $investigate_2 + - Implication: escalate when the same context grants other rights, removes guardrails, touches multiple principals, repeats the grant, or lacks rollback; lower urgency when activity stays bounded to one controlled grant-plus-rollback cycle for the same target. + +- Did the actor or newly empowered account modify delegation attributes after the grant? + - Why: this right is most dangerous when followed by delegation changes on user or computer objects. + - Focus: later "5136" events where `winlog.event_data.SubjectUserSid` matches the assigning or granted principal; review `winlog.event_data.ObjectDN`, `winlog.event_data.AttributeLDAPDisplayName`, and `winlog.event_data.AttributeValue` for "userAccountControl" trusted-for-delegation flags or "msDS-AllowedToDelegateTo" updates. $investigate_3 + - Hint: if "5136" coverage is unavailable, preserve `winlog.event_data.TargetSid`, `winlog.event_data.SubjectUserSid`, and `winlog.computer_name` for AD follow-up instead of treating absent evidence as benign. + - Implication: escalate when either principal soon changes delegation flags or constrained-delegation targets because these values can enable Kerberos S4U abuse against named services; absence of follow-on changes lowers urgency only when target, source, and rollback also align. + +- If local evidence remains suspicious or unresolved, do detection alerts for either SID widen scope? + - Focus: recent alert-window results for the assigning account SID, `winlog.event_data.SubjectUserSid`. $investigate_4 + - Hint: compare the same recent window with alerts for the granted account SID, `winlog.event_data.TargetSid`. $investigate_5 + - Implication: escalate scope when either account has privilege, directory, ticket, or lateral-movement alerts; keep the case local when histories are quiet and local evidence supports a controlled workflow. + +- Escalate for unexpected target/source, abnormal session, absent rollback, follow-on delegation changes, or related alerts; close only when target, source, session, rollback, delegation attributes, and scope bind one controlled workflow; preserve and escalate mixed or incomplete evidence. + +### False positive analysis + +- Controlled delegation administration can legitimately trigger this rule when a dedicated delegation-admin or service-management principal is temporarily granted this right. Confirm only when `winlog.event_data.TargetSid`, `winlog.event_data.SubjectUserSid` or SYSTEM/machine policy path, `winlog.computer_name`, direct-session `source.ip`, `winlog.logon.type`, `winlog.event_data.AuthenticationPackageName`, rollback, and bounded `winlog.event_data.AttributeLDAPDisplayName` or `winlog.event_data.ObjectDN` changes all fit the same change; use change records or AD owner confirmation when telemetry cannot prove intent, and do not close if any dimension diverges. +- Before creating an exception, validate recurrence for the same source, `winlog.event_data.TargetSid`, `winlog.computer_name`, direct-session source when applicable, and bounded delegation-attribute pattern. Build the exception from that minimum workflow, never from "SeEnableDelegationPrivilege" or the rule name alone. + +### Response and remediation + +- If confirmed benign, reverse temporary containment and document the controlled workflow evidence: target SID, assigning or policy-application source, emitting system, linked authentication context, rollback, and bounded delegation-attribute changes. Keep any exception narrow and require the same workflow to recur before suppressing future alerts. +- If suspicious but unconfirmed, preserve the alert document, exported authorization-policy grant/removal records, linked "4624"/"4648" authentication records, SID-resolution notes, and any related "5136" delegation-change records before containment. Apply reversible containment such as heightened monitoring on both identities or temporary delegation-administration restrictions. Escalate to stronger containment only if follow-on directory changes, repeated grants, or related alerts show broader abuse. +- If confirmed malicious, preserve the same Windows Security records and SID-resolution evidence before destructive actions. Disable or restrict the granting or granted principal, contain the originating admin workstation when identified from `source.ip`, and hand off to Active Directory or incident response if direct response is unavailable. +- After containment, remove SeEnableDelegationPrivilege from the granted principal, verify paired removal evidence, revert unauthorized delegation-related attribute changes, and review recent authorization-policy events from the same actor for additional rollback. If delegation abuse is confirmed, prioritize credential hygiene for affected identities. +- Post-incident hardening: restrict delegation-administration rights to dedicated accounts, keep Windows Security auditing for authorization-policy and directory-service changes enabled on domain controllers, and document the final workflow or abuse pattern for future triage. +""" + +setup = """## Setup + +Audit Authorization Policy Change must be enabled to generate the events used by this rule. +Setup instructions: https://ela.st/audit-authorization-policy-change +""" + +[rule.investigation_fields] +field_names = [ + "@timestamp", + "event.code", + "host.name", + "host.id", + "winlog.computer_name", + "winlog.event_data.SubjectUserName", + "winlog.event_data.SubjectUserSid", + "winlog.event_data.SubjectDomainName", + "winlog.event_data.SubjectLogonId", + "winlog.event_data.TargetSid", + "winlog.event_data.PrivilegeList", + "winlog.activity_id", +] + +[transform] + +[[transform.investigate]] +label = "Logon events for the assigning session" +description = "" +providers = [ + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" } + ], + [ + { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "User-right changes by the same source session" +description = "" +providers = [ + [ + { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4704", valueType = "string" } + ], + [ + { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4705", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "User-right removals for the granted principal" +description = "" +providers = [ + [ + { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.TargetSid", queryType = "phrase", value = "{{winlog.event_data.TargetSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.PrivilegeList", queryType = "phrase", value = "{{winlog.event_data.PrivilegeList}}", valueType = "string" }, + { excluded = false, field = "event.code", queryType = "phrase", value = "4705", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "Delegation attribute changes by involved principals" +description = "" +providers = [ + [ + { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.AttributeLDAPDisplayName", queryType = "phrase", value = "userAccountControl", valueType = "string" } + ], + [ + { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.AttributeLDAPDisplayName", queryType = "phrase", value = "msDS-AllowedToDelegateTo", valueType = "string" } + ], + [ + { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.TargetSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.AttributeLDAPDisplayName", queryType = "phrase", value = "userAccountControl", valueType = "string" } + ], + [ + { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.TargetSid}}", valueType = "string" }, + { excluded = false, field = "winlog.event_data.AttributeLDAPDisplayName", queryType = "phrase", value = "msDS-AllowedToDelegateTo", valueType = "string" } + ] +] +relativeFrom = "now-24h" +relativeTo = "now" + +[[transform.investigate]] +label = "Alerts associated with the assigning account" +description = "" +providers = [ + [ + { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" }, + { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" } + ] +] +relativeFrom = "now-48h/h" +relativeTo = "now" + +[[transform.investigate]] +label = "Alerts associated with the granted principal" +description = "" +providers = [ + [ + { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" }, + { excluded = false, field = "winlog.event_data.TargetSid", queryType = "phrase", value = "{{winlog.event_data.TargetSid}}", valueType = "string" } + ] +] +relativeFrom = "now-48h/h" +relativeTo = "now" [[rule.threat]] framework = "MITRE ATT&CK" @@ -101,7 +231,6 @@ id = "T1558" name = "Steal or Forge Kerberos Tickets" reference = "https://attack.mitre.org/techniques/T1558/" - [rule.threat.tactic] id = "TA0006" name = "Credential Access" @@ -113,9 +242,7 @@ id = "T1098" name = "Account Manipulation" reference = "https://attack.mitre.org/techniques/T1098/" - [rule.threat.tactic] id = "TA0003" name = "Persistence" reference = "https://attack.mitre.org/tactics/TA0003/" -