26 Fibratus detection rules, 34 LimaCharlie D&R rules, plus community detections I run in production. Organized by MITRE ATT&CK tactic.
A chokepoint is a prerequisite the attacker cannot avoid. Tools rotate and infrastructure rotates, but the prerequisite stays, so a detection built on it survives the rotation. These are the entries I've contributed to Tyler Bohlmann's framework, read from the repo's main branch so the page only shows work that merged upstream.
Capability that context does not already settle → relevant AWS API request → AWS service returns an authorization outcome
Identity-aware enumeration benefits from resolving whether the credential belongs to an IAM user or assumed role, because that changes which policy and trust APIs are relevant. sts:GetCallerIdentity is a common permissionless sequence anchor, but this stage is optional: generic permission probing can proceed without first resolving the identity.
Why it can't be bypassedThis stage can be bypassed. Identity-aware policy or trust enumeration needs the principal type, while a generic brute-force routine can probe blindly. Skipping orientation may increase the number of calls and denials, but it does not prevent permission testing.
Any capability the operator has not already established from context or a readable policy MUST be tested by calling the relevant AWS API and reading the outcome. Grants are per-service and per-action and the constraining layers are frequently invisible from the principal side, so there is no offline inference for the untested part of the set. How far that testing spreads is situational: context or a correct first guess may reduce it to a few calls, while an operator starting blind samples across namespaces because the grant could sit in any of several hundred services. This tier scores breadth as a heuristic for that undirected case.
Why it can't be bypassedA capability the operator cannot establish from context has to be attempted, and the AWS service returns an authorization outcome. CloudTrail observes that request only when the service and operation are supported, the relevant event category is selected, and the integration records denied requests. What the operator influences is how much testing is needed, so breadth indicates undirected enumeration rather than being an unavoidable step: an operator starting blind cannot narrow the search without testing.
Any capability the operator goes on to use MUST first have been established, and where context did not establish it that means a successful API call. A success in a namespace that has just denied the same actor is the clearest evidence enumeration located the exploitable path, so this tier scores that transition as follow-on confirmation. It remains a heuristic: an operator can stop after the denials, or succeed first with no prior denial.
Why it can't be bypassedEnumeration can finish with only denials, but any capability the operator actually uses still requires a successful AWS API request and service outcome. CloudTrail visibility for that action depends on service and operation support, event-category selection, and whether the integration records the relevant result. The denied-then-allowed ordering is not required to complete permission enumeration; it is scored here as the highest-fidelity confirmation available when it occurs, and an operator who already knew where the grant was skips it.
title: AWS Identity Orientation and Authorization Failure Baseline
id: 3c1f7a92-6b04-4d55-9e88-2a0c5f31b7de
status: experimental
description: >
Baselining rule for visibility. Surfaces sts:GetCallerIdentity and CloudTrail
authorization failures so the Hunt and Analyst thresholds can be derived from local data.
Deploy it to characterise the environment, then tune the higher tiers from what it shows.
Answer three questions before deploying the higher tiers:
1. Which principals call GetCallerIdentity routinely, and from which source IPs?
2. Which principals carry chronic authorization failures, and on which
(eventSource, eventName) pairs? That list becomes the Hunt tier allowlist.
3. What is the normal distinct-namespace denial spread per principal? Most legitimate
principals sit at 0-1. Re-derive the Hunt threshold from this, do not assume 5.
Choosing the principal key: baseline on the identity that issued the session. A temporary
ASIA* access key rotates per session, and an assumed-role ARN embeds a RoleSessionName that
repeats only when the caller reuses it, so neither is a dependable long-term baseline
identity. All three tiers key on COALESCE(useridentity.sessioncontext.sessionissuer.arn,
useridentity.arn, useridentity.principalid, useridentity.accesskeyid) — the session issuer
ARN (the role) for AssumedRole sessions, the caller ARN or principal ID otherwise, with
accessKeyId as a last fallback. Keep the expression identical across tiers so baselines,
aggregations, and joins agree on what a principal is.
Only authorization and authentication failures count as denials — AccessDenied,
AccessDeniedException, UnauthorizedOperation, Client.UnauthorizedOperation,
AuthorizationError, AuthFailure. Throttling, validation, and missing-resource errors are
also written to errorCode and say nothing about the caller's permissions, so counting every
non-empty errorCode as probing inflates the denial ratio with application noise. Total event
counts stay as the denominator. AWS documents errorCode and errorMessage as optional record
fields, and some services report authorization failures inside responseElements rather
than the top-level errorcode column this query reads. CloudTrail visibility also depends on
support for the service and operation, the selected event category, and whether that
integration records denied requests. Confirm those conditions before relying on the count.
Avoid building detection on userAgent. AWS SDKs and tools commonly expose application-ID or
custom user-agent metadata, so tool-name matches such as "Pacu" or "Boto3" are not durable.
Baseline query (Athena). It needs a CloudTrail trail delivering management events to S3 and
an Athena table over that data. Management events are selected by default when a trail is
created, but the S3 delivery and the Athena table are not created automatically; console
event history is automatic and covers 90 days, but is not queryable this way.
WITH ct AS (
SELECT COALESCE(useridentity.sessioncontext.sessionissuer.arn,
useridentity.arn,
useridentity.principalid,
useridentity.accesskeyid) AS principal,
eventsource,
eventname,
sourceipaddress,
useridentity.accesskeyid AS access_key,
COALESCE(errorcode, '') IN (
'AccessDenied', 'AccessDeniedException', 'UnauthorizedOperation',
'Client.UnauthorizedOperation', 'AuthorizationError', 'AuthFailure'
) AS auth_denied
FROM cloudtrail_logs
WHERE from_iso8601_timestamp(eventtime) > now() - INTERVAL '30' DAY
)
SELECT principal,
count(*) AS total_events,
count_if(auth_denied) AS auth_denials,
count(DISTINCT CASE WHEN auth_denied THEN eventsource END) AS denied_namespaces,
array_agg(DISTINCT concat(eventsource, ':', eventname))
FILTER (WHERE auth_denied) AS denied_pairs,
count_if(eventname = 'GetCallerIdentity') AS orientation_calls,
count(DISTINCT sourceipaddress) AS src_ips,
count(DISTINCT access_key) AS session_keys
FROM ct
GROUP BY 1
ORDER BY total_events DESC
This tier keeps service and chronic-denial principals in the results, since identifying them
is the point, and nothing here needs data-event logging.
references:
- https://unit42.paloaltonetworks.com/large-scale-cloud-extortion-operation/
- https://attack.mitre.org/techniques/T1580/
- https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-unsupported-aws-services.html
- https://docs.aws.amazon.com/athena/latest/ug/cloudtrail-logs.html
author: '@NovaSky0x1'
date: 2026-08-09
tags:
- attack.discovery
- attack.t1580
- attack.t1526
- detection.maturity.research
logsource:
product: aws
service: cloudtrail
detection:
selection_orientation:
eventSource: 'sts.amazonaws.com'
eventName: 'GetCallerIdentity'
selection_denied:
errorCode:
- 'AccessDenied'
- 'AccessDeniedException'
- 'UnauthorizedOperation'
- 'Client.UnauthorizedOperation'
- 'AuthorizationError'
- 'AuthFailure'
condition: selection_orientation or selection_denied
falsepositives:
- Expected at this tier. GetCallerIdentity is routine SDK, CI/CD, and Terraform behaviour
- AWS Config rules and drift detection generating chronic denials on a fixed API set
- Backup and inventory agents probing services they are not permitted to read
- Developers running exploratory CLI commands against accounts they legitimately hold
level: informational
title: AWS Credential Permission Probing — Denial Breadth Across Service Namespaces
id: 8d4b21e6-70af-4c19-b3a6-9f5c2e6188a4
status: experimental
description: >
Detects one principal generating authorization failures across five or more distinct
service namespaces in a rolling window, with an authorization-failure ratio of at least
0.5 against all events by that principal in the window. That is the shape of an operator
mapping a credential whose scope they do not know.
Breadth is a heuristic rather than an invariant: an operator with useful context, a readable
identity policy, or a correct first guess can settle capability in a handful of calls, so
this tier targets the generic, undirected case. Within it the distinct-namespace count
discriminates better than raw denial volume, since a principal denied 200 times on one API
is almost always misconfigured while one denied five times across five namespaces is mapping
its own permissions.
Choosing the principal key: aggregate on the identity that issued the session, using
COALESCE(useridentity.sessioncontext.sessionissuer.arn, useridentity.arn,
useridentity.principalid, useridentity.accesskeyid) as the Research and Analyst tiers do, so
Research-tier allowlists apply unchanged. A temporary ASIA* key rotates per session and an
assumed-role ARN repeats only when its RoleSessionName is reused, so grouping on either can
split one operator's probing into single-event groups that never reach the threshold of 5.
Populate filter_chronic_principals with session issuer ARNs for the same reason.
Only authorization and authentication failures count toward the namespace breadth and the
ratio numerator — AccessDenied, AccessDeniedException, UnauthorizedOperation,
Client.UnauthorizedOperation, AuthorizationError, AuthFailure. Throttling, validation, and
missing-resource errors also populate errorCode and carry no permission information, so
counting every non-empty errorCode inflates both measures with application noise. The
denominator stays every event by the principal in the window, successful or not. Services
that report authorization failures inside responseElements rather than the top-level
errorcode column are a blind spot. CloudTrail visibility also depends on support for the
service and operation, the selected event category, and whether that integration records
denied requests.
Distinct-namespace counts and ratios cannot be expressed in Sigma, so the detection block
below is a partial stub firing on any single authorization failure; deploy the query for
production. It needs a CloudTrail trail delivering management events to S3 and an Athena
table over that data — management events are selected by default when a trail is created,
but the S3 delivery and the table are not. No data-event logging is needed at this tier.
Athena:
WITH ct AS (
SELECT COALESCE(useridentity.sessioncontext.sessionissuer.arn,
useridentity.arn,
useridentity.principalid,
useridentity.accesskeyid) AS principal,
eventsource,
COALESCE(errorcode, '') IN (
'AccessDenied', 'AccessDeniedException', 'UnauthorizedOperation',
'Client.UnauthorizedOperation', 'AuthorizationError', 'AuthFailure'
) AS auth_denied
FROM cloudtrail_logs
WHERE from_iso8601_timestamp(eventtime) > now() - INTERVAL '15' MINUTE
AND useridentity.type <> 'AWSService' -- matches filter_service_principals below
)
SELECT principal,
count(*) AS total_events,
count_if(auth_denied) AS auth_denials,
count(DISTINCT CASE WHEN auth_denied THEN eventsource END) AS denied_namespaces
FROM ct
GROUP BY 1
HAVING count(DISTINCT CASE WHEN auth_denied THEN eventsource END) >= 5
AND count_if(auth_denied) * 1.0 / count(*) >= 0.5
Before production: re-derive both thresholds from the Research tier, build the chronic-denial
allowlist, and add those principal exclusions to the Athena WHERE clause by hand, since
filter_chronic_principals below constrains only the Sigma stub. Config rules, drift
detection, and backup agents are the dominant false positives and they are stable and
enumerable.
Pacing defeats a 15-minute window; widening it to 24 hours catches slower operators at
query cost. The Analyst tier's novelty scoring helps against a low call rate inside its own
window, but that window is one day, so multi-day pacing evades it too.
references:
- https://unit42.paloaltonetworks.com/large-scale-cloud-extortion-operation/
- https://sysdig.com/blog/scarleteel-2-0/
- https://github.com/andresriancho/enumerate-iam
- https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-unsupported-aws-services.html
- https://docs.aws.amazon.com/athena/latest/ug/cloudtrail-logs.html
author: '@NovaSky0x1'
date: 2026-08-09
tags:
- attack.discovery
- attack.t1580
- attack.t1526
- detection.maturity.hunt
logsource:
product: aws
service: cloudtrail
detection:
# Distinct-namespace and ratio aggregation cannot be expressed in Sigma.
# Use the Athena query above for production. This stub is a partial signal only.
selection:
errorCode:
- 'AccessDenied'
- 'AccessDeniedException'
- 'UnauthorizedOperation'
- 'Client.UnauthorizedOperation'
- 'AuthorizationError'
- 'AuthFailure'
filter_chronic_principals:
# PENDING: populate from the Research-tier baseline before production, and mirror the
# same exclusions into the Athena CTE. Use session issuer ARNs (the role), not session
# ARNs or ASIA* keys.
# userIdentity.sessionContext.sessionIssuer.arn|contains:
# - 'role/aws-config-role'
# - 'role/backup-inventory-agent'
userIdentity.arn: '' # placeholder — remove and populate before production
filter_service_principals:
userIdentity.type: 'AWSService'
condition: selection and not filter_chronic_principals and not filter_service_principals
falsepositives:
- AWS Config rules and drift detection probing resources they cannot read — chronic, stable, allowlistable
- Backup and inventory agents sweeping services outside their grant
- Terraform or CloudFormation against a partially-provisioned role, especially on first apply
- Newly deployed service accounts before policies are finalised — expect a burst, then silence
- CSPM and security scanners operating with intentionally reduced permissions
level: medium
title: AWS Capability Confirmation — Novel Denial Breadth Followed by Success in a Denied Namespace
id: b6e09f34-25cd-4a71-8c02-71d4a3e5f9b8
status: experimental
description: >
Fires when a principal is denied on (eventSource, eventName) pairs it has never been observed
calling in 30 days, across three or more namespaces, and then succeeds in a namespace that
just denied it — the clearest available evidence that an operator located an exploitable path.
Both signals are heuristics rather than invariants. Permission enumeration does not require
cross-namespace breadth when context or a readable policy narrows the search, and it does not
require a denied-then-allowed transition, since an operator can stop after the denials or
succeed on the first call attempted. What holds is that any capability not already known from
context or a readable policy has to be tested through the relevant AWS API, and the AWS
service returns an authorization outcome. CloudTrail sees the request only when the service
and operation are supported, the relevant event category is selected, and that integration
records denied requests.
The baseline holds every (principal, eventSource, eventName) tuple observed in the preceding
30 days, successful or failed. Restricting it to successes would make a routinely denied
tuple — a Config rule probing a resource it can never read — look novel every day.
Two keys, deliberately. The 30-day baseline uses a stable principal (session issuer ARN
first, then caller ARN, principal ID, access key) so a role's history survives session
turnover, while the denial-to-success correlation additionally joins on an actor key (access
key first, since a temporary credential's ASIA* key is unique to one session, then caller ARN
or principal ID, then the stable principal) so a denial in one session under a shared role
cannot join a different session's success. Neither an ASIA* key nor an assumed-role ARN is a
dependable long-term baseline identity: the key rotates per session, and the ARN embeds a
RoleSessionName that repeats only when the caller reuses it.
A novel denial means an authorization or authentication failure — AccessDenied,
AccessDeniedException, UnauthorizedOperation, Client.UnauthorizedOperation,
AuthorizationError, AuthFailure. Throttling, validation, and missing-resource errors carry no
permission information and do not count toward the three-namespace breadth. Success is the
absence of any error code, and errorcode is NULL on success in the AWS sample CloudTrail
table, so it must be tested with IS NULL rather than = ''. Services reporting authorization
failures inside responseElements rather than the top-level errorcode column are a blind spot
for the novel-denial half and can also be misread as successes by that test, so normalize
them into errorcode first.
Fidelity rises sharply when the successful call is itself sensitive — CreateAccessKey,
AttachUserPolicy, UpdateAssumeRolePolicy, GetSecretValue, or CreateSnapshot, all management
events. s3:GetObject against a bucket this principal has never read is a strong signal too,
but it is an object-level data event, present only where a data-event selector covers that
bucket, so treat it as optional coverage and otherwise leave it out of the selection below.
Baseline comparison and cross-event correlation cannot be expressed in Sigma, so the stub
below covers only the sensitive-success half; deploy the query for production. It needs a
CloudTrail trail delivering management events to S3 and an Athena table over that data —
management events are selected by default when a trail is created; the S3 delivery and the
table are not. Athena:
WITH ct AS ( -- both keys and the denial test applied once
SELECT COALESCE(useridentity.sessioncontext.sessionissuer.arn,
useridentity.arn,
useridentity.principalid,
useridentity.accesskeyid) AS principal,
COALESCE(useridentity.accesskeyid,
useridentity.arn,
useridentity.principalid,
useridentity.sessioncontext.sessionissuer.arn) AS actor_key,
useridentity.arn AS identity_arn, eventsource, eventname,
sourceipaddress, errorcode,
from_iso8601_timestamp(eventtime) AS ts,
COALESCE(errorcode, '') IN (
'AccessDenied', 'AccessDeniedException', 'UnauthorizedOperation',
'Client.UnauthorizedOperation', 'AuthorizationError', 'AuthFailure'
) AS auth_denied
FROM cloudtrail_logs
WHERE from_iso8601_timestamp(eventtime) > now() - INTERVAL '31' DAY
AND useridentity.type <> 'AWSService' -- matches filter_service_principals below
),
baseline AS ( -- every tuple seen for this principal, successful or denied
SELECT DISTINCT principal, eventsource, eventname, 1 AS seen
FROM ct
WHERE ts BETWEEN now() - INTERVAL '31' DAY AND now() - INTERVAL '1' DAY
),
novel_denials AS ( -- auth failures on never-before-seen tuples
SELECT c.principal, c.actor_key, c.eventsource, min(c.ts) AS first_denial
FROM ct c
LEFT JOIN baseline b
ON b.principal = c.principal AND b.eventsource = c.eventsource
AND b.eventname = c.eventname
WHERE c.ts > now() - INTERVAL '1' DAY AND c.auth_denied AND b.seen IS NULL
GROUP BY 1, 2, 3
),
probing AS ( -- actors novel-denied in >= 3 namespaces
SELECT principal, actor_key FROM novel_denials
GROUP BY 1, 2
HAVING count(DISTINCT eventsource) >= 3
)
SELECT s.ts, s.identity_arn, s.principal, s.actor_key, s.eventsource, s.eventname,
s.sourceipaddress, d.first_denial
FROM ct s
JOIN novel_denials d -- same actor, same namespace that denied it
ON d.principal = s.principal AND d.actor_key = s.actor_key
AND d.eventsource = s.eventsource
JOIN probing p
ON p.principal = s.principal AND p.actor_key = s.actor_key
WHERE s.ts > now() - INTERVAL '1' DAY
AND s.ts > d.first_denial -- success after the denial
AND (s.errorcode IS NULL OR s.errorcode = '')
ORDER BY s.ts
Requires a stable 30-day CloudTrail history; expect elevated false positives in younger
environments or right after a large deployment change. Novelty helps against a low call rate
inside the observation window, but that window is one day here, so multi-day pacing evades it
unless the window is widened at query cost. Apply the environment's chronic and
legitimate-principal allowlist inside the Athena CTE before production, since
filter_legit_software below constrains only the Sigma stub. Avoid keying on userAgent.
references:
- https://unit42.paloaltonetworks.com/large-scale-cloud-extortion-operation/
- https://sysdig.com/blog/scarleteel-2-0/
- https://github.com/RhinoSecurityLabs/pacu
- https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-unsupported-aws-services.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html
- https://docs.aws.amazon.com/athena/latest/ug/cloudtrail-logs.html
author: '@NovaSky0x1'
date: 2026-08-09
tags:
- attack.discovery
- attack.t1580
- attack.t1526
- detection.maturity.analyst
logsource:
product: aws
service: cloudtrail
detection:
# Baseline anti-join and denied-to-allowed correlation cannot be expressed in Sigma.
# Use the Athena query above for production. This stub covers the sensitive-success
# half only and must be correlated with the novel-denial condition to reach the
# stated fidelity. Every eventName below is a management event; adding data-event
# names such as GetObject requires an S3 object-level data-event selector.
selection_sensitive_success:
eventName:
- 'CreateAccessKey'
- 'AttachUserPolicy'
- 'AttachRolePolicy'
- 'PutUserPolicy'
- 'UpdateAssumeRolePolicy'
- 'CreateLoginProfile'
- 'UpdateLoginProfile'
- 'GetSecretValue'
- 'CreateSnapshot'
- 'ModifySnapshotAttribute'
filter_failed:
errorCode|exists: true
filter_service_principals:
userIdentity.type: 'AWSService'
filter_legit_software:
# PENDING: populate with the approved administrative and automation principals that
# legitimately call these APIs — IaC deployment roles, break-glass roles, IAM
# provisioning pipelines, backup services taking snapshots — and mirror the same
# exclusions into the Athena CTE. Key on the session issuer ARN (the role), not on
# session ARNs or ASIA* access keys.
# userIdentity.sessionContext.sessionIssuer.arn|contains:
# - 'role/terraform-deploy'
# - 'role/iam-provisioning-pipeline'
userIdentity.arn: '' # placeholder — remove and populate before production
condition: selection_sensitive_success and not filter_failed and not filter_service_principals and not filter_legit_software
falsepositives:
- Break-glass or IR administrators exploring an unfamiliar account under legitimate authority
- Newly onboarded engineers whose principal has no 30-day baseline yet
- Migration and refactoring work legitimately calling APIs a principal has never called
- Penetration tests and red-team engagements — check the engagement window before escalating
- Environments with less than 30 days of CloudTrail history
level: high
A process must open a kernel-mediated handle to lsass.exe and read its virtual memory to extract credential material
Any process must request a handle to lsass.exe with memory-read access rights from the Windows kernel.
Why it can't be bypassedWindows enforces process isolation at the kernel level: NtOpenProcess must be called to obtain a handle, and the kernel's ObRegisterCallbacks fires for every handle request regardless of whether the caller used standard APIs or direct syscalls.
The process must read lsass.exe virtual memory to extract credential material using NtReadVirtualMemory or MiniDumpWriteDump.
Why it can't be bypassedCredential material (NTLM hashes, Kerberos tickets, plaintext passwords cached by WDigest/SSP) resides in lsass.exe process memory. There is no file or registry location that contains the same live credential state.
The attacker must parse LSASS memory structures or dump file contents to extract usable credentials, producing observable artifacts (either an in-memory read with a suspicious CallTrace, a dump file on disk, or a DLL injected into lsass via SSP).
Why it can't be bypassedCredential structures in lsass memory use Microsoft's internal SSP format. The attacker must either parse them in-process (generating the ProcessAccess event) or write a dump file for offline parsing (generating a FileCreate event). SSP injection (loading a malicious DLL into lsass) generates an ImageLoaded event for a DLL outside System32.
title: LSASS Memory Access by Non-System Process (Research Baseline)
id: c08fffe8-ab3c-4e16-abd8-61e648faf95b
status: experimental
description: >
Detects any non-core-OS process opening a handle to lsass.exe with memory-read
access rights. This research-level rule establishes a baseline of all LSASS
access in the environment (AV/EDR products, WerFault, Task Manager, monitoring
tools, and actual attacks) all appear. Run this for one week to build an
environment-specific allowlist of legitimate LSASS accessors before tuning to
Hunt level. The chokepoint is invariant: every credential dumping tool (Mimikatz,
nanodump, comsvcs.dll, ProcDump, HandleKatz, direct syscall loaders) must obtain
a kernel handle to lsass.exe. Sysmon Event ID 10 captures this regardless of the
API path used.
references:
- https://attack.mitre.org/techniques/T1003/001/
- https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://github.com/fortra/nanodump
author: "@NovaSky0x1"
date: 2026/03/30
tags:
- attack.credential_access
- attack.t1003.001
- attack.t1003
- detection.maturity.research
logsource:
category: process_access
product: windows
detection:
selection:
TargetImage|endswith: '\lsass.exe'
GrantedAccess|contains:
- '0x1FFFFF' # PROCESS_ALL_ACCESS
- '0x1010' # PROCESS_VM_READ | PROCESS_QUERY_LIMITED_INFORMATION (Mimikatz classic)
- '0x1410' # PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION
- '0x0810' # PROCESS_VM_READ | PROCESS_QUERY_INFORMATION (nanodump)
- '0x1038' # PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION
- '0x1438' # PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION
- '0x0040' # PROCESS_DUP_HANDLE (handle duplication, HandleKatz, nanodump duphandle mode)
- '0x0010' # PROCESS_VM_READ alone
filter_os_core:
SourceImage|startswith:
- 'C:\Windows\System32\csrss.exe'
- 'C:\Windows\System32\lsass.exe'
- 'C:\Windows\System32\services.exe'
- 'C:\Windows\System32\svchost.exe'
- 'C:\Windows\System32\wininit.exe'
- 'C:\Windows\System32\lsaiso.exe'
- 'C:\Windows\System32\smss.exe'
- 'C:\Windows\System32\winlogon.exe'
condition: selection and not filter_os_core
falsepositives:
- Antivirus and EDR agents performing routine LSASS inspection (MsMpEng.exe, SentinelAgent.exe, CSFalconService.exe, CylanceSvc.exe)
- WerFault.exe collecting crash diagnostics for lsass.exe
- Task Manager (taskmgr.exe) when an administrator manually creates a process dump
- Performance and diagnostic tools (procexp64.exe, procmon64.exe, perfmon.exe)
- WMI provider host (wmiprvse.exe) during certain management queries
- Windows Defender Advanced Threat Protection sensor (MsSense.exe)
level: informational
title: LSASS Access with Suspicious CallTrace or Non-Standard Source Path
id: 3d932b09-9d74-428d-bb0f-9368b28c6bb9
status: experimental
description: >
Hunt-level detection for LSASS credential dumping. Adds behavioral context to the
research baseline to separate attack tooling from legitimate security products.
CallTrace analysis reveals the mechanism used to read LSASS memory: dbgcore.dll
and dbghelp.dll indicate MiniDumpWriteDump (ProcDump, comsvcs.dll, custom dump
tools), while UNKNOWN indicates direct syscalls or ntdll unhooking. Legitimate
AV/EDR products produce clean API call stacks without these indicators. Source
path filtering captures tools staged in user-writable directories; attack tools
land in Temp, Downloads, AppData while legitimate security products run from
Program Files. This rule excludes known AV/EDR paths and WerFault to reduce the
research baseline to actionable hunt leads.
references:
- https://attack.mitre.org/techniques/T1003/001/
- https://github.com/fortra/nanodump
- https://github.com/codewhitesec/HandleKatz
- https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://www.microsoft.com/en-us/security/blog/2022/10/05/detecting-and-preventing-lsass-credential-dumping-attacks/
author: "@NovaSky0x1"
date: 2026/03/30
tags:
- attack.credential_access
- attack.t1003.001
- attack.t1003
- detection.maturity.hunt
logsource:
category: process_access
product: windows
detection:
selection_lsass_access:
TargetImage|endswith: '\lsass.exe'
GrantedAccess|contains:
- '0x1FFFFF'
- '0x1010'
- '0x1410'
- '0x0810'
- '0x1038'
- '0x1438'
- '0x0040'
selection_suspicious_calltrace:
CallTrace|contains:
- 'dbgcore.dll'
- 'dbghelp.dll'
- 'UNKNOWN'
selection_suspicious_source_path:
SourceImage|contains:
- '\Temp\'
- '\tmp\'
- '\Downloads\'
- '\AppData\'
- '\Users\Public\'
- '\ProgramData\'
- '\Desktop\'
- '\Recycle'
filter_os_core:
SourceImage|startswith:
- 'C:\Windows\System32\csrss.exe'
- 'C:\Windows\System32\lsass.exe'
- 'C:\Windows\System32\services.exe'
- 'C:\Windows\System32\svchost.exe'
- 'C:\Windows\System32\wininit.exe'
- 'C:\Windows\System32\lsaiso.exe'
- 'C:\Windows\System32\smss.exe'
- 'C:\Windows\System32\winlogon.exe'
filter_security_products:
SourceImage|contains:
- '\Program Files\Windows Defender\'
- '\Program Files\Microsoft Security Client\'
- '\Program Files\CrowdStrike\'
- '\Program Files\SentinelOne\'
- '\Program Files\Cylance\'
- '\Program Files\Carbon Black\'
- '\Program Files\Sophos\'
- '\Program Files\ESET\'
- '\Program Files\Kaspersky\'
- '\Program Files\Trend Micro\'
- '\Program Files (x86)\Trend Micro\'
- '\Program Files\Bitdefender\'
- '\Program Files\Malwarebytes\'
- '\Program Files\Palo Alto Networks\'
filter_werfault:
SourceImage|endswith: '\WerFault.exe'
condition: >
selection_lsass_access
and (selection_suspicious_calltrace or selection_suspicious_source_path)
and not (filter_os_core or filter_security_products or filter_werfault)
falsepositives:
- IT administrators running portable diagnostic tools from non-standard paths that inspect LSASS
- Custom monitoring agents installed outside Program Files that query process information
- Authorized penetration testing tools during sanctioned engagements
- Third-party security products not in the exclusion list (requires environment-specific tuning)
level: medium
title: 'LSASS Credential Dump: Non-Standard Process with Dump Mechanism and Suspicious Access Rights'
id: 2abc46f9-9c70-47cf-932e-fe803e06f5c7
status: experimental
description: >
High-fidelity detection for LSASS credential dumping. Detects a non-standard process
(outside System32 and Program Files) opening a handle to lsass.exe with credential-dump
access rights where the CallTrace reveals MiniDumpWriteDump usage (dbgcore.dll,
dbghelp.dll) or direct syscall evasion (UNKNOWN). This triple-AND (suspicious access
mask, dump mechanism fingerprint, and non-standard source path) eliminates virtually
all legitimate LSASS access. AV/EDR products run from Program Files with clean
CallTraces; attack tools run from temp paths with dbgcore.dll or UNKNOWN stacks.
A secondary selection covers handle duplication (GrantedAccess 0x0040) from non-standard
paths, the HandleKatz and nanodump evasion technique that uses NtDuplicateObject to
clone an existing LSASS handle instead of requesting a direct read handle. This
GrantedAccess value targeting lsass.exe from outside System32/Program Files has no
legitimate use case. Supplementary detections for comsvcs.dll MiniDump LOLBin
(process_creation), SSP injection (image_load), and dump file artifacts (file_event)
should be implemented as companion rules at the SIEM level for coverage across event
types. If this rule fires, assume credential compromise and begin host isolation.
references:
- https://attack.mitre.org/techniques/T1003/001/
- https://github.com/fortra/nanodump
- https://github.com/codewhitesec/HandleKatz
- https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://www.microsoft.com/en-us/security/blog/2022/10/05/detecting-and-preventing-lsass-credential-dumping-attacks/
- https://unit42.paloaltonetworks.com/mimikatz-overview/
author: "@NovaSky0x1"
date: 2026/03/30
tags:
- attack.credential_access
- attack.t1003.001
- attack.t1003
- detection.maturity.analyst
logsource:
category: process_access
product: windows
detection:
selection_lsass_target:
TargetImage|endswith: '\lsass.exe'
GrantedAccess|contains:
- '0x1FFFFF'
- '0x1010'
- '0x1410'
- '0x0810'
- '0x1038'
- '0x1438'
selection_dump_mechanism:
CallTrace|contains:
- 'dbgcore.dll'
- 'dbghelp.dll'
- 'UNKNOWN'
selection_nonstandard_source:
SourceImage|not|startswith:
- 'C:\Windows\System32\'
- 'C:\Windows\SysWOW64\'
- 'C:\Program Files\'
- 'C:\Program Files (x86)\'
selection_handle_duplication:
TargetImage|endswith: '\lsass.exe'
GrantedAccess: '0x0040'
SourceImage|not|startswith:
- 'C:\Windows\System32\'
- 'C:\Windows\SysWOW64\'
- 'C:\Program Files\'
- 'C:\Program Files (x86)\'
filter_os_core:
SourceImage|startswith:
- 'C:\Windows\System32\csrss.exe'
- 'C:\Windows\System32\lsass.exe'
- 'C:\Windows\System32\services.exe'
- 'C:\Windows\System32\svchost.exe'
- 'C:\Windows\System32\wininit.exe'
- 'C:\Windows\System32\lsaiso.exe'
- 'C:\Windows\System32\smss.exe'
- 'C:\Windows\System32\winlogon.exe'
condition: >
(selection_lsass_target and selection_dump_mechanism and selection_nonstandard_source and not filter_os_core)
or selection_handle_duplication
falsepositives:
- Portable diagnostic tools run by administrators from non-standard paths that access LSASS (should be blocked by policy in hardened environments)
- Authorized red team or penetration testing tools during sanctioned engagements
level: high
Read from iimp0ster/detection-chokepoints on main, newest first, showing 2 of 17 published chokepoints. Last synced 2026-09-08 10:25 UTC.
APT campaigns, exploit detection, and reconnaissance patterns.
- action: report
metadata:
author: Josh Strickland
description: >-
Detects potential ClickFix attack where explorer.exe spawns PowerShell
variants, scripting engines, or LOLBins with suspicious command arguments
via Run dialog (Win+R). Covers multiple PowerShell versions, common
Living off the Land binaries abused in ClickFix campaigns.
falsepositives:
- Legitimate administrative PowerShell scripts launched via Run dialog
- IT management tools using encoded commands
- Software deployment using msiexec or bitsadmin
- Web developers testing scripts with mshta or rundll32
- System administrators using certutil for certificate management
level: high
references:
- https://blog.sekoia.io/clickfix-tactic-the-phantom-meet/
- https://detect.fyi/hunting-clickfix-initial-access-techniques-8c1b38d5ef9b
- https://lolbas-project.github.io/
tags:
- attack.initial_access
- attack.t1204.002
- attack.execution
- attack.t1059.001
- attack.t1059.003
- attack.t1059.005
- attack.t1059.007
- attack.defense_evasion
- attack.t1218
name: Potential ClickFix Chain
event: NEW_PROCESS
op: and
rules:
- op: is windows
- case sensitive: false
op: ends with
path: event/PARENT/FILE_PATH
value: explorer.exe
- op: or
rules:
- { op: ends with, path: event/FILE_PATH, value: powershell.exe }
- { op: ends with, path: event/FILE_PATH, value: pwsh.exe }
- { op: ends with, path: event/FILE_PATH, value: cmd.exe }
- { op: ends with, path: event/FILE_PATH, value: wscript.exe }
- { op: ends with, path: event/FILE_PATH, value: cscript.exe }
- { op: ends with, path: event/FILE_PATH, value: mshta.exe }
- { op: ends with, path: event/FILE_PATH, value: certutil.exe }
- { op: ends with, path: event/FILE_PATH, value: bitsadmin.exe }
- { op: ends with, path: event/FILE_PATH, value: rundll32.exe }
- { op: ends with, path: event/FILE_PATH, value: regsvr32.exe }
- { op: ends with, path: event/FILE_PATH, value: msiexec.exe }
- { op: ends with, path: event/FILE_PATH, value: regasm.exe }
- { op: ends with, path: event/FILE_PATH, value: msbuild.exe }
- { op: ends with, path: event/FILE_PATH, value: wmic.exe }
- not: true
op: or
rules:
- { op: starts with, path: event/COMMAND_LINE, value: '"C:\Program Files\' }
- { op: starts with, path: event/COMMAND_LINE, value: '"C:\Program Files (x86)\' }
- { op: starts with, path: event/COMMAND_LINE, value: 'C:\Program Files\' }
- { op: starts with, path: event/COMMAND_LINE, value: 'C:\Program Files (x86)\' }
- op: or
rules:
- op: matches
path: event/COMMAND_LINE
re: >-
.*\s-e(nc|nco|ncod|ncode|ncoded|ncodedC|ncodedCo|ncodedCom|
ncodedComm|ncodedComma|ncodedComman|ncodedCommand)
\s+[A-Za-z0-9+/=]{50,}.*
- { op: matches, path: event/COMMAND_LINE,
re: '.*(downloadstring|downloadfile).*\|.*(iex|invoke-expression).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*(invoke-webrequest|iwr|wget|curl).*\|.*(iex|invoke-expression).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*net\.webclient.*\.(downloadstring|downloadfile).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*(-w hidden|-windowstyle hidden).*(http|downloadstring).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*bypass.*(http|downloadstring|downloadfile|iex).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*certutil.*-urlcache.*(http|ftp).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*certutil.*-decode.*\.(exe|dll|bat|ps1|vbs).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*bitsadmin.*/transfer.*(http|ftp).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*mshta.*(http|javascript:|vbscript:).*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*rundll32.*javascript:.*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*rundll32.*,.*http.*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*regsvr32.*/s\s+/u\s+/i:http.*scrobj\.dll.*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*wmic.*process call create.*http.*' }
- { op: matches, path: event/COMMAND_LINE,
re: '.*(\\temp\\|\\downloads\\|\\appdata\\local\\temp\\).*\.(exe|bat|cmd|ps1|vbs).*' }
name: Potential ClickFix infection chain
id: ffe1fc54-2893-4760-ab50-51a83bd71d13
version: 2.0.1
description: |
Identifies the execution of the process via the Run command dialog box,
Windows Console shortcut, or Explorer address bar followed by spawning
of the potential infostealer process. This could be indicative of the
ClickFix deceptive tactic used by attackers to lure victims into
executing malicious commands under the guise of meeting pages or CAPTCHAs.
labels:
tactic.id: TA0001
tactic.name: Initial Access
technique.id: T1566
technique.name: Phishing
references:
- https://blog.sekoia.io/clickfix-tactic-the-phantom-meet/
- https://blog.sekoia.io/clickfix-tactic-revenge-of-detection/
- https://detect.fyi/hunting-clickfix-initial-access-techniques-8c1b38d5ef9b
condition: >
sequence
maxspan 2m
|spawn_process and
ps.parent.name ~= 'explorer.exe' and length(ps.args) >= 2 and
ps.name iin ('cmd.exe', 'powershell.exe', 'pwsh.exe', 'wget.exe',
'curl.exe', 'msiexec.exe', 'mshta.exe', 'wscript.exe',
'cscript.exe', 'msbuild.exe') and
(thread.callstack.summary imatches
('ntdll.dll|KernelBase.dll|kernel32.dll|windows.storage.dll|shell32.dll|user32.dll|shell32.dll|explorer.exe|SHCore.dll|*',
'ntdll.dll|KernelBase.dll|kernel32.dll|windows.storage.dll|shell32.dll|windows.storage.dll|shell32.dll|user32.dll|shell32.dll|explorer.exe|SHCore.dll|*',
'ntdll.dll|KernelBase.dll|kernel32.dll|windows.storage.dll|shell32.dll|windows.storage.dll|SHCore.dll|*')
or
(thread.callstack.summary imatches '*shell32.dll|explorer.exe|*'
and thread.callstack.symbols imatches '*shell32.dll!GetFileNameFromBrowse*'))
| by ps.uuid
|spawn_process and ps.exe not imatches
('?:\Program Files\*.exe',
'?:\Program Files (x86)\*.exe')
| by ps.parent.uuid
action:
- name: kill
output: >
Potential infostealer process %2.ps.exe delivered via ClickFix infection chain
severity: high
min-engine-version: 3.0.0
name: Palo Alto GlobalProtect command injection via CVE-2024-3400
id: c9f1e4d3-5a7b-6c9e-1d4f-8b2c3e5f6789
version: 1.0.0
description: |
Detects active exploitation of CVE-2024-3400, a critical command injection
vulnerability in Palo Alto Networks GlobalProtect Gateway (CVSS 10.0).
Attackers can execute arbitrary commands with root privileges without
authentication.
condition: >
spawn_process
and
ps.name imatches '*PanGPS.exe'
and
ps.child.name iin ('cmd.exe', 'powershell.exe', 'pwsh.exe', 'whoami.exe')
and
not (
ps.child.cmdline icontains 'flushdns'
or
ps.child.cmdline imatches
'*reg export*Settings\\*\\windows\\TEMP\\uninstall.reg*'
)
severity: critical
min-engine-version: 2.4.0
name: SocGholish fake browser update with scheduled task persistence
id: b7e5f3a2-4d6f-5e8a-0b3c-7f9d8e1a2345
version: 1.0.0
description: |
Identifies the SocGholish (FakeUpdates) malware campaign that uses
compromised websites to serve fake browser update notifications.
Victims download malicious JavaScript files which establish persistence
through Windows scheduled tasks and deploy secondary payloads.
condition: >
sequence
maxspan 5m
|create_file and file.extension = '.js'
and file.path imatches '*\\Downloads\\*.js'| by ps.sid
|spawn_process and ps.child.name ~= 'schtasks.exe'
and ps.child.cmdline imatches '*/create*'| by ps.sid
severity: critical
min-engine-version: 2.4.0
- action: report
metadata:
author: Joshua Strickland
description: >-
Detected login attempt using a suspicious user agent commonly associated
with automation tools, credential stuffing, or security scanning
false_positives:
- Legitimate automation scripts
- Security scanning tools used by IT
- DevOps automation
mitre_attack:
- T1078 - Valid Accounts
- T1110 - Brute Force
references:
- https://attack.mitre.org/techniques/T1078/
severity: medium
name: M365 - Suspicious User Agent on Login
suppression:
is_global: true
keys:
- '{{ .event.UserId }}'
- m365-suspicious-ua
max_count: 5
period: 1h
events:
- UserLoggedIn
- UserLoginFailed
op: or
rules:
- { op: contains, path: event/ExtendedProperties/?/Value, value: axios }
- { op: contains, path: event/ExtendedProperties/?/Value, value: TruffleHog }
- { op: contains, path: event/ExtendedProperties/?/Value, value: python-requests }
- { op: contains, path: event/ExtendedProperties/?/Value, value: python-urllib }
- { op: matches, path: event/ExtendedProperties/?/Value, re: "^curl/.*" }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Go-http-client }
- { op: contains, path: event/ExtendedProperties/?/Value, value: PostmanRuntime }
- { op: contains, path: event/ExtendedProperties/?/Value, value: HTTPie }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Scrapy }
- { op: matches, path: event/ExtendedProperties/?/Value, re: "^Wget/.*" }
- { op: contains, path: event/ExtendedProperties/?/Value, value: WindowsPowerShell }
- { op: contains, path: event/ExtendedProperties/?/Value, value: node-fetch }
- { op: matches, path: event/ExtendedProperties/?/Value, re: "^Java/\d+.*" }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Apache-HttpClient }
- { op: contains, path: event/ExtendedProperties/?/Value, value: okhttp }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Nuclei }
- { op: is, path: event/ExtendedProperties/?/Value, value: "" }
- { op: contains, path: event/ExtendedProperties/?/Value, value: BOT }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Burp }
- { op: contains, path: event/ExtendedProperties/?/Value, value: Nikto }
- { op: contains, path: event/ExtendedProperties/?/Value, value: sqlmap }
- { op: contains, path: event/ExtendedProperties/?/Value, value: AADInternals }
- { op: contains, path: event/ExtendedProperties/?/Value, value: ROADtools }
Hack tools, suspicious process patterns, and malicious code execution.
name: CrackMapExec Execution Patterns
id: b162fa0f-8dbc-4b99-b483-77f9e659d44e
version: 1.0.0
description: |
Detects command patterns specific to CrackMapExec (CME) post-exploitation
framework. CME automates network reconnaissance, credential harvesting,
and lateral movement.
condition: >
spawn_process
and
(
ps.child.cmdline icontains 'cmd.exe /Q /c * 1> \\\\*\\*\\* 2>&1'
or ps.child.cmdline icontains 'cmd.exe /C * > \\\\*\\*\\* 2>&1'
or ps.child.cmdline icontains 'cmd.exe /C * > *\\Temp\\* 2>&1'
or ps.child.cmdline icontains 'powershell.exe -exec bypass -noni -nop -w 1 -C "'
or ps.child.cmdline icontains 'powershell.exe -noni -nop -w 1 -enc '
)
severity: high
min-engine-version: 2.0.0
name: HackTool - Empire PowerShell Launch Parameters
id: 79f4ede3-402e-41c8-bc3e-ebbf5f162581
version: 1.0.0
description: |
Detects suspicious PowerShell command line parameters commonly used by
Empire framework for launching encoded payloads. Empire typically uses
specific combinations of flags to bypass security controls, hide windows,
and execute base64-encoded commands.
condition: >
spawn_process
and
(ps.child.name ~= 'powershell.exe' or ps.child.name ~= 'pwsh.exe')
and
ps.child.cmdline icontains
(
' -NoP -sta -NonI -W Hidden -Enc ',
' -noP -sta -w 1 -enc ',
' -NoP -NonI -W Hidden -enc ',
' -enc SQB',
' -nop -exec bypass -EncodedCommand '
)
severity: high
min-engine-version: 2.0.0
name: PowerShell Script Execution in Public Folder
id: 52c9da6b-49bf-4dca-bc82-60998f6aaf94
version: 1.0.0
description: |
Detects execution of PowerShell scripts located in the
"C:\Users\Public" folder.
condition: |
spawn_process
and
((ps.child.exe iendswith '\\powershell.exe'
or ps.child.exe iendswith '\\pwsh.exe')
and (ps.child.cmdline icontains '-f C:\\Users\\Public'
or ps.child.cmdline icontains '-fi C:\\Users\\Public'
or ps.child.cmdline icontains '-fil C:\\Users\\Public'
or ps.child.cmdline icontains '-file C:\\Users\\Public'
or ps.child.cmdline icontains '-f %Public%'))
severity: high
min-engine-version: 2.0.0
name: Critical Suspicious Executable Pattern (Unsigned)
id: 01a35edb-78c2-5a09-9d7c-2f18e145517c
version: 2.0.0
description: |
Detects unsigned executables exhibiting suspicious behavioral patterns
including rapid sequential file system operations and PAGEFILE memory
mapping. This pattern indicates potential ransomware preparing for mass
file encryption.
condition: >
sequence
maxspan 50ms
by ps.uuid
|( kevt.name = 'LoadImage' and image.is_exec = true
and image.signature.type = 'NONE'
and image.signature.level = 'UNCHECKED'
and not ps.exe imatches ('?:\\Windows\\system32\\*',
'?:\\Program Files*')
and not ps.name in ('svchost.exe', 'services.exe',
'lsass.exe', 'csrss.exe') )|
|( kevt.name = 'CreateFile' and kevt.arg[type] = 'Directory'
and kevt.arg[share_mask] = 'READ|WRITE'
and file.path imatches ('?:\\Users\\*\\Documents\\*',
'?:\\Users\\*\\Desktop\\*') )|
|( kevt.name = 'MapViewFile' and file.view.type = 'PAGEFILE'
and file.view.protection = 'READONLY' )|
severity: critical
min-engine-version: 2.0.0
- action: report
metadata:
author: Josh Strickland
cve: CVE-2025-55182
description: >-
Detects cmd.exe spawned by Node.js with Next.js/React context using the
/d /s /c flag pattern typical of child_process.execSync(), containing
suspicious reconnaissance or post-exploitation commands. This is a strong
indicator of CVE-2025-55182 (React2Shell) exploitation.
false_positives:
- Legitimate build scripts or development tools using cmd.exe
- Custom deployment scripts that execute system commands
- Note: The combination of Next.js parent + suspicious command is very rare
mitre_attack:
- T1059.003 - Windows Command Shell
- T1190 - Exploit Public-Facing Application
references:
- https://react2shell.com/
- https://nodejs.org/api/child_process.html#child_processexecsynccommand-options
- https://github.com/msanft/CVE-2025-55182
severity: critical
name: React2Shell - Node.js execSync Suspicious Command
event: NEW_PROCESS
op: and
rules:
- op: ends with
path: event/FILE_PATH
value: \cmd.exe
- op: contains
path: event/COMMAND_LINE
value: /d /s /c
- op: ends with
path: event/PARENT/FILE_PATH
value: \node.exe
- op: or
rules:
- { op: contains, path: event/PARENT/COMMAND_LINE, value: node_modules\next }
- { op: contains, path: event/PARENT/COMMAND_LINE, value: next\dist\server }
- { op: contains, path: event/PARENT/COMMAND_LINE, value: start-server.js }
- { op: contains, path: event/PARENT/COMMAND_LINE, value: next dev }
- { op: contains, path: event/PARENT/COMMAND_LINE, value: next start }
- { op: contains, path: event/PARENT/COMMAND_LINE, value: react-scripts }
- op: or
rules:
- { op: contains, path: event/COMMAND_LINE, value: whoami }
- { op: contains, path: event/COMMAND_LINE, value: powershell }
- { op: contains, path: event/COMMAND_LINE, value: curl }
- { op: contains, path: event/COMMAND_LINE, value: certutil }
- { op: contains, path: event/COMMAND_LINE, value: bitsadmin }
- { op: contains, path: event/COMMAND_LINE, value: mshta }
- { op: contains, path: event/COMMAND_LINE, value: wscript }
- { op: contains, path: event/COMMAND_LINE, value: systeminfo }
- { op: contains, path: event/COMMAND_LINE, value: net user }
- { op: contains, path: event/COMMAND_LINE, value: net localgroup }
- { op: contains, path: event/COMMAND_LINE, value: netsh }
- { op: contains, path: event/COMMAND_LINE, value: sc.exe }
- { op: contains, path: event/COMMAND_LINE, value: reg add }
- { op: contains, path: event/COMMAND_LINE, value: wmic }
- { op: contains, path: event/COMMAND_LINE, value: base64 }
- { op: contains, path: event/COMMAND_LINE, value: "-enc" }
- { op: contains, path: event/COMMAND_LINE, value: downloadstring }
- { op: contains, path: event/COMMAND_LINE, value: invoke-expression }
- { op: contains, path: event/COMMAND_LINE, value: "&&" }
- { op: contains, path: event/COMMAND_LINE, value: " | " }
- { op: matches, path: event/COMMAND_LINE,
re: ".*\\.(ps1|bat|vbs|js|exe).*" }
Scheduled tasks, hidden accounts, and maintaining access.
name: Sysmon registry detection of a local hidden user account
id: dfa902c0-c21a-4ae6-b29c-77442034f16c
version: 1.0.0
description: |
Detects the creation of hidden local user accounts through registry
modification. Attackers create accounts ending with $ to hide them
from standard user enumeration tools.
condition: >
modify_registry
and
ps.exe iendswith '\\lsass.exe'
and
registry.path icontains
'\\SAM\\SAM\\Domains\\Account\\Users\\Names\\'
and
registry.path iendswith '$'
severity: high
min-engine-version: 2.0.0
name: HackTool - Default PowerSploit/Empire Scheduled Task Creation
id: 56c217c3-2de2-479b-990f-5c109ba8458f
version: 1.0.0
description: |
Detects creation of a scheduled task via PowerSploit or Empire default
configuration. Task typically named "Updater" executes PowerShell with
non-interactive flags.
condition: >
spawn_process
and
(ps.name ~= 'powershell.exe' or ps.name ~= 'pwsh.exe')
and
(ps.child.name ~= 'schtasks.exe')
and
(ps.child.cmdline icontains '/Create')
and
(ps.child.cmdline icontains 'powershell.exe -NonI')
and
(ps.child.cmdline icontains '/TN Updater /TR')
and
((ps.child.cmdline icontains '/SC ONLOGON')
or (ps.child.cmdline icontains '/SC DAILY /ST')
or (ps.child.cmdline icontains '/SC ONIDLE')
or (ps.child.cmdline icontains '/SC HOURLY'))
severity: high
min-engine-version: 2.0.0
- action: report
metadata:
author: Joshua Strickland
description: >-
A dynamic group membership rule was modified. Dynamic groups in Entra ID
automatically assign membership based on user or device attributes
matching a defined rule. Attackers with sufficient privileges modify these
rules to automatically grant themselves or compromised accounts membership
in privileged groups. This is a stealthy privilege escalation technique
because the membership appears legitimate (rule-based) rather than
manually assigned.
false_positives:
- Legitimate organizational restructuring requiring rule updates
- Corrections to misconfigured membership rules
- Security team adjustments to group automation
- HR-driven changes to department or role-based rules
investigation_steps:
- Identify which group had its membership rule modified
- Check if the group has privileged roles or sensitive resource access
- Review the old membership rule versus the new membership rule
- Determine what user attributes the new rule matches on
- Verify the user account that modified the rule
- Check if the rule change resulted in new members being added
mitre_attack:
- T1098.003 - Account Manipulation: Additional Cloud Roles
- T1484 - Domain Policy Modification
- T1069.003 - Permission Groups Discovery: Cloud Groups
references:
- https://attack.mitre.org/techniques/T1098/003/
- https://attack.mitre.org/techniques/T1484/
- https://posts.specterops.io/azure-privilege-escalation-via-service-principal-abuse-210ae2be2a5
severity: high
name: M365 - Dynamic Group Membership Rule Modified
suppression:
is_global: true
keys:
- '{{ .event.ObjectId }}'
- m365-dynamic-rule
max_count: 3
period: 24h
event: Update group
op: or
rules:
- op: is
path: event/ModifiedProperties/?/Name
value: MembershipRule
- op: is
path: event/ModifiedProperties/?/Name
value: MembershipRuleProcessingStat
Defender tampering, masquerading, and security tool bypass.
name: Renamed NetSupport RAT Execution
id: 3e6a1c5d-e7d6-4840-a835-942b71ff76a6
version: 1.0.0
description: |
Detects execution of renamed NetSupport Manager client. Attackers
frequently deploy renamed versions to establish remote control while
evading filename-based detections.
condition: >
load_module
and
pe.product icontains 'NetSupport'
and
not image.name = 'client32.exe'
severity: high
min-engine-version: 2.0.0
name: Suspicious Hosts File Access
id: f7b2c9d3-99e7-41d5-bb4a-6ea1a5f7f9e2
version: 1.0.0
description: |
Detects attempts to modify the Windows hosts file for DNS hijacking
or security tool blocking. Malware commonly edits hosts files to
redirect security update servers to localhost or redirect banking
sites to phishing servers.
condition: >
open_file
and
file.path imatches
'?:\\Windows\\System32\\drivers\\etc\\hosts'
and
( ps.name iin ('notepad.exe', 'wordpad.exe', 'powershell.exe',
'pwsh.exe', 'sublime_text.exe', 'code.exe', 'vim.exe')
or ps.parent.name iin ('powershell.exe', 'pwsh.exe', 'cmd.exe') )
and
not ps.exe imatches (
'?:\\Windows\\servicing\\TrustedInstaller.exe',
'?:\\Windows\\System32\\svchost.exe',
'?:\\Program Files\\Windows Defender\\*')
severity: high
min-engine-version: 2.0.0
name: Windows Defender Disabling Attempt
id: 8c2f5b7a-d93e-47f5-9b1a-3f6e8e2c91fc
version: 1.3.0
description: |
Detects direct registry modifications to disable Windows Defender
real-time protection. Setting DisableRealtimeMonitoring to 1
immediately disables antivirus scanning.
condition: >
kevt.name = 'RegSetValue'
and
ps.name = 'MsMpEng.exe'
and
registry.path = 'HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection\\DisableRealtimeMonitoring'
and
registry.value = 1
severity: critical
min-engine-version: 2.0.0
name: Windows Defender Exclusion Modification
id: a1234567-89ab-cdef-0123-456789abcdef
version: 1.0.0
description: |
Detects modifications to Windows Defender exclusion lists via registry
or PowerShell. Attackers add malware paths, extensions, or process
names to exclusions to operate undetected.
condition: >
( kevt.name in ('RegSetValue', 'RegDeleteValue')
and ( registry.path icontains
'Windows Defender\\Exclusions\\Paths\\'
or registry.path icontains
'Windows Defender\\Exclusions\\Extensions\\'
or registry.path icontains
'Windows Defender\\Exclusions\\Processes\\' )
and ps.name = 'MsMpEng.exe' )
or
( kevt.name = 'CreateProcess'
and ps.name in ('MpCmdRun.exe')
and kevt.arg[cmdline] contains 'MpPreference'
and kevt.arg[cmdline] contains '-Exclusion' )
severity: high
min-engine-version: 2.0.0
Credential dumping and harvesting tools.
name: Remote Credential Dumping via CrackMapExec/Impacket
id: 0c0bf53b-9875-48ce-a389-0d309f51fdcf
version: 1.0.0
description: |
Detects temporary file patterns created by CrackMapExec and
Impacket-secretsdump during remote credential harvesting. These tools
dump SAM/SECURITY/SYSTEM registry hives to 8-character random .tmp
files in System32.
Normal: Never - legitimate Windows operations don't create random
8-char .tmp files in System32
Likely malicious: svchost.exe creating [8chars].tmp in System32
condition: >
create_file
and
ps.exe iendswith '\\svchost.exe'
and
file.path matches '?:\\Windows\\System32\\????????.tmp'
severity: high
min-engine-version: 2.0.0
- action: report
metadata:
author: Joshua Strickland
description: >-
A user authentication was completed using a session token where MFA was
"previously satisfied" or "satisfied by claim in token" rather than an
interactive MFA challenge. This is a strong indicator of
Adversary-in-the-Middle (AiTM) phishing and session token replay attacks.
Sophisticated phishing toolkits (Evilginx, Modlishka, Muraena) proxy the
real authentication flow, allowing the victim to complete legitimate
authentication including MFA, while the attacker intercepts and steals the
resulting session cookies. The attacker then replays these stolen tokens
to gain unauthorized access that bypasses MFA.
false_positives:
- Legitimate SSO scenarios where tokens are exchanged between apps
- OAuth token exchanges in federated environments
- Mobile app authentication flows that cache tokens
- Azure AD Seamless SSO in hybrid environments
- Browser session resumption after legitimate authentication
investigation_steps:
- Identify the user account that authenticated with token replay
- Review the source IP address and geolocation of this login
- Check for recent logins from the same user from different IPs
- Look for preceding authentic authentication from normal location
- Review user agent string for anomalies or headless browsers
- Check if the IP is associated with VPN, proxy, or hosting providers
- Examine actions taken immediately after this authentication
- Look for data exfiltration, inbox rules, or privilege escalation
- Check for mailbox forwarding rules or OAuth app consents after login
mitre_attack:
- T1539 - Steal Web Session Cookie
- T1185 - Browser Session Hijacking
- T1566.002 - Phishing: Spearphishing Link
- T1550.004 - Use Alternate Authentication Material: Web Session Cookie
references:
- https://attack.mitre.org/techniques/T1539/
- https://attack.mitre.org/techniques/T1550/004/
- https://www.microsoft.com/security/blog/2022/07/12/from-cookie-theft-to-bec/
- https://github.com/kgretzky/evilginx2
severity: critical
name: M365 - AiTM Session Token Replay
suppression:
is_global: true
keys:
- '{{ .event.UserId }}'
- m365-aitm-token
max_count: 2
period: 1h
event: UserLoggedIn
op: or
rules:
- { op: contains, path: event/AuthenticationDetails/?/authenticationMethod,
value: claim }
- { op: contains, path: event/AuthenticationDetails/?/authenticationMethod,
value: previously satisfied }
- { op: contains, path: event/MfaDetail/?/authMethod,
value: claim }
- { op: contains, path: event/MfaDetail/?/authMethod,
value: previously satisfied }
- { op: contains, path: event/ExtendedProperties/?/Value,
value: Previously satisfied }
- { op: contains, path: event/ExtendedProperties/?/Value,
value: claim in the token }
RATs, C2 comms, reverse shells, and tunneling.
- action: report
metadata:
author: Josh Strickland
description: >-
Detects NetSupport RAT activity including both execution and file drops.
NetSupport Manager is legitimate remote access software frequently
weaponized by threat actors. This rule identifies NetSupport client
executables and associated configuration files when they are dropped on
disk or executed from suspicious locations. Covers common naming
variations and obfuscation techniques used in malicious campaigns.
falsepositives:
- Legitimate NetSupport Manager installations used by IT support teams
- Authorized remote support sessions initiated by help desk
- MSPs using NetSupport for client management
- Educational institutions using NetSupport School
level: high
references:
- https://www.cisa.gov/news-events/cybersecurity-advisories/aa20-259a
- https://attack.mitre.org/software/S0122/
- https://www.huntress.com/blog/netsupport-manager-rat-installed-via-fake-update-notices
- https://redcanary.com/threat-detection-report/threats/netsupport-manager/
tags:
- attack.command_and_control
- attack.t1219
- attack.defense_evasion
- attack.t1036.005
- attack.persistence
- attack.t1547.001
- attack.t1105
name: NetSupport RAT Activity
events:
- NEW_PROCESS
- NEW_DOCUMENT
- FILE_CREATE
op: or
rules:
# === Process Execution ===
- op: and
rules:
- { op: is, path: routing/event_type, value: NEW_PROCESS }
- op: or
rules:
# Known NetSupport binary names
- op: matches
path: event/FILE_PATH
re: >-
.*\\(client32|uclient32|nclient32|rclient|sclient|
tclient|xclient|pclient|gclient|vnclient|nsclient)\.exe$
# NetSupport binaries in suspicious locations
- op: and
rules:
- op: or
rules:
- { op: contains, path: event/FILE_PATH, value: client32 }
- { op: contains, path: event/FILE_PATH, value: uclient }
- { op: contains, path: event/FILE_PATH, value: nsclient }
- op: or
rules:
- { op: contains, path: event/FILE_PATH, value: "\\Temp\\" }
- { op: contains, path: event/FILE_PATH, value: "\\AppData\\Roaming\\" }
- { op: contains, path: event/FILE_PATH, value: "\\AppData\\Local\\Temp\\" }
- { op: contains, path: event/FILE_PATH, value: "\\ProgramData\\" }
- { op: contains, path: event/FILE_PATH, value: "\\Users\\Public\\" }
- { op: contains, path: event/FILE_PATH, value: "\\Windows\\Temp\\" }
- { op: contains, path: event/FILE_PATH, value: "\\Downloads\\" }
# Command line indicators outside Program Files
- op: and
rules:
- op: or
rules:
- { op: contains, path: event/COMMAND_LINE, value: NetSupport }
- { op: contains, path: event/COMMAND_LINE, value: NSM_ }
- { op: contains, path: event/COMMAND_LINE, value: client32 }
- not: true
op: contains
path: event/FILE_PATH
value: "\\Program Files\\"
# === File Drops (NEW_DOCUMENT + FILE_CREATE) ===
- op: and
rules:
- op: or
rules:
- { op: is, path: routing/event_type, value: NEW_DOCUMENT }
- { op: is, path: routing/event_type, value: FILE_CREATE }
- op: or
rules:
# NetSupport executables dropped to disk
- op: matches
path: event/FILE_PATH
re: >-
.*\\(client32|uclient32|nclient32|nsclient|pciclient)\.exe$
# Config files (ini, lic, cfg)
- op: matches
path: event/FILE_PATH
re: >-
.*\\(client32\.ini|nsm\.ini|nsm\.lic|NSM.*\.cfg|
NetSupport.*\.ini)$
name: NetSupport RAT Detection
id: 8a7b9c2d-4f3e-5a6b-9d1c-2e8f7b3a4156
version: 1.0.0
description: |
Detects execution of NetSupport Manager components commonly abused as
a Remote Access Trojan. Unauthorized installations are frequently used
by attackers for remote control.
Normal: NetSupport in Program Files with proper licensing, IT-managed
Likely malicious: client32.exe in AppData/Temp/ProgramData
condition: >
spawn_process
and
ps.child.name iin ('client32.exe', 'uclient32.exe')
severity: high
min-engine-version: 2.0.0
name: Suspicious DNS Query Detection
id: a5e6d8f2-74b1-4c3e-bb4a-9c2d58e3f0d2
version: 1.4.0
description: |
Detects suspicious DNS queries indicating C2 communications, data
exfiltration via DNS tunneling, or DGA activity. Monitors for known
malicious TLDs, file-sharing services commonly abused by infostealers,
and dynamic DNS providers used for C2 infrastructure.
condition: >
query_dns
and dns.name in (
'ngrok.io', 'pastebin.com', 'discordapp.com', '.onion',
'.top', '.xyz', '.tk', 'limewire.com', '.bit', '.ir',
'.ru', '.dyn', '.no-ip', '.duckdns', 'file.io',
'anonfiles.com', 'bayfiles.com', 'wetransfer.com',
'sendspace.com', 'filedropper.com', 'mega.nz',
'transfer.sh', 'pixeldrain.com', 'gofile.io',
'zippyshare.com'
)
and dns.name not contains 'microsoft.com'
and dns.name not contains 'windows.com'
min-engine-version: 2.0.0
name: VPN and Proxy Detection
id: f9b1d2e3-82c1-4d7a-91ea-3f4cbb64a1f2
version: 1.2.0
description: |
Detects VPN and proxy usage through process execution patterns, network
connections, and DNS queries to known VPN/proxy providers. Covers
OpenVPN, WireGuard, NordVPN, ExpressVPN, ProtonVPN, Surfshark, SSH
tunneling (-D/-L/-R), stunnel, and more.
condition: >
( spawn_process
and ps.child.name iin (
'openvpn.exe', 'openvpn-gui.exe', 'wireguard.exe',
'nordvpn.exe', 'NordVPN.exe', 'expressvpn.exe',
'protonvpn.exe', 'surfshark.exe', 'mullvad-vpn.exe',
'proxifier.exe', 'softether-vpnclient.exe', 'stunnel.exe'
)
)
or
( spawn_process
and ps.child.name iin ('ssh.exe', 'plink.exe')
and ps.child.cmdline imatches ('*-D *', '*-L *', '*-R *') )
or
( query_dns
and dns.name iin (
'nordvpn.com', 'expressvpn.com', 'protonvpn.com',
'surfshark.com', 'mullvad.net', 'privateinternetaccess.com',
'cyberghostvpn.com', 'windscribe.com', 'tunnelbear.com',
'hotspotshield.com', 'ipvanish.com', 'purevpn.com',
'hide.me', 'torguard.net', 'strongvpn.com',
'astrill.com', 'zenmate.com', 'ivpn.net',
'perfectprivacy.com', 'cactusvpn.com'
)
)
severity: high
min-engine-version: 2.0.0
name: Reverse Shell Detection
id: e74b8d1a-6a9d-4f8a-b1ef-2e24c9b3e9fc
version: 4.1.0
description: |
Detects reverse shell techniques across multiple vectors including
traditional shells (bash -i, cmd), scripting languages (python/perl/
ruby -c/-e), network utilities (nc -e, socat), and modern techniques
(ConPtyShell, encoded PowerShell).
condition: >
spawn_process
and
ps.child.name iin (
'cmd.exe', 'powershell.exe', 'pwsh.exe', 'bash.exe',
'python.exe', 'python3.exe', 'perl.exe', 'ruby.exe',
'lua.exe', 'php.exe', 'nc.exe', 'ncat.exe', 'netcat.exe',
'socat.exe', 'openssl.exe', 'java.exe', 'javaw.exe',
'telnet.exe', 'node.exe', 'mshta.exe', 'wscript.exe',
'cscript.exe'
)
and
ps.child.cmdline icontains (
'nc ', 'ncat ', '-e /bin/sh', '-e /bin/bash',
'-e cmd.exe', 'bash -i', '/dev/tcp/', 'socket(',
'SOCK_STREAM', 'AF_INET', 'DownloadString(',
'New-Object Net.Sockets.TCPClient',
'System.Net.Sockets.TcpClient', 'ConPtyShell',
'pty.spawn', 'IEX(', 'Invoke-Expression',
'IO.StreamReader', 'IO.StreamWriter',
'Net.WebClient', '-e cmd', '-e powershell',
'exec 5<>/dev/tcp', 'socat exec:'
)
and
not ps.parent.name iin (
'Action1_Agent.exe', 'Velociraptor.exe',
'svchost.exe', 'taskhostw.exe'
)
and
not ps.parent.exe imatches (
'?:\\Program Files\\*',
'?:\\Program Files (x86)\\*'
)
severity: critical
min-engine-version: 2.0.0
8 kernel-level ransomware detections using ETW File I/O sequence analysis with tight timing windows (2ms to 50ms). These catch ransomware during initialization and active encryption by fingerprinting the exact file operation sequences different families use.
name: Ransomware Process Detected (6)
id: 01a45edb-78c2-4a39-9d7c-2f19e384517d
version: 1.0.0
description: |
Detects Gamma ransomware through its distinctive PyInstaller unpacking
behavior, creating multiple Windows API and runtime DLLs in temporary
_MEI directories. Early-stage detection catches Gamma before encryption
begins.
condition: >
create_file
and
file.path imatches
'C:\\Users\\*\\AppData\\Local\\Temp\\_MEI*\\*'
and
(
file.name contains ('api-ms-win-core-')
or file.name contains ('api-ms-win-crt-')
or file.name iin (
'ucrtbase.dll', 'VCRUNTIME140.dll', 'libssl-1_1.dll',
'libcrypto-1_1.dll', 'python37.dll', 'tk86t.dll',
'tcl86t.dll'
)
)
severity: critical
min-engine-version: 2.0.0
name: Generic Ransomware Initialization Pattern
id: 95a1d8c3-7e4b-42f5-b9d1-8c5e4f6a2b3d
version: 5.0.0
description: |
Identifies ransomware initialization through a precise 27ms behavioral
fingerprint. Matches multiple families (including Hive) as they resolve
critical Windows APIs, map system DLLs, and prepare for file operations.
condition: >
sequence
maxspan 27ms
by ps.uuid
|( kevt.name = 'MapViewFile'
and file.view.type = 'PAGEFILE'
and file.view.size = 16384
and not ps.name in ('svchost.exe', 'services.exe',
'lsass.exe', 'explorer.exe') )|
|( kevt.name = 'CreateFile'
and kevt.arg[create_options] icontains 'DIRECTORY_FILE'
and file.path imatches 'C:\\Windows' )|
|( kevt.name = 'MapViewFile'
and file.view.type = 'IMAGE'
and file.path imatches '*\\wow64.dll' )|
|( kevt.name = 'EnumDirectory'
and kevt.arg[directory] imatches 'C:\\Windows\\System32' )|
|( kevt.name = 'MapViewFile'
and file.view.type = 'IMAGE'
and file.path imatches (
'*\\kernel32.dll', '*\\KernelBase.dll') )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware or Malware Process Detected (Generic 2)
id: 8e7d9c2a-5f1b-4c3d-b8e1-6a8f37d49b5c
version: 1.0.2
description: |
Detects Vipasana ransomware's unique initialization sequence combining
memory allocation with rapid directory discovery. 45ms pattern provides
early detection before file damage.
condition: >
sequence
maxspan 45ms
by ps.uuid
|( kevt.name = 'MapViewFile'
and file.view.type = 'PAGEFILE'
and file.view.size = 16384 )|
|( kevt.name = 'CreateFile'
and file.path imatches 'C:\\Windows'
and kevt.arg[type] = 'Directory' )|
|( kevt.name = 'MapViewFile'
and file.view.type = 'IMAGE'
and file.path imatches
'C:\\Windows\\System32\\wow64*.dll' )|
|( kevt.name = 'CreateFile'
and file.path imatches 'C:\\Users\\*\\Desktop\\'
and kevt.arg[type] = 'Directory' )|
|( kevt.name = 'MapViewFile'
and file.view.type = 'IMAGE'
and file.path imatches
'C:\\Windows\\SysWOW64\\*.dll' )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware In Progress - File I/O variant
id: 9f7aab92-0002-4fcd-85ea-59692f44712f
version: 1.1.0
description: |
Detects classic ransomware file operation sequence: enumerate directory,
delete shadow copies or backups, create new encrypted files, read
original content, and write encrypted data. 2ms sequential pattern
captures the moment ransomware begins actively encrypting.
condition: >
sequence
maxspan 2ms
by ps.uuid
|( (image.signature.type = 'NONE' or pe.is_trusted = false)
and (kevt.name = 'EnumDirectory'
or kevt.name = 'DeleteFile')
and file.path imatches (
'?:\\Users\\*\\Desktop\\*',
'?:\\Users\\*\\Documents\\*',
'?:\\Users\\*\\Downloads\\*',
'?:\\Users\\*\\Pictures\\*')
and not ps.exe imatches '?:\\Program Files*' )|
|( kevt.name = 'CreateFile'
and file.operation in ('CREATE', 'OPEN')
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'ReadFile'
and file.path imatches '?:\\Users\\*' )|
|( (kevt.name = 'ReadFile' or kevt.name = 'WriteFile')
and file.path imatches '?:\\Users\\*' )|
|( (kevt.name = 'WriteFile' or kevt.name = 'CreateFile')
and file.path imatches '?:\\Users\\*' )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware In Progress - File-to-File with Delete
id: bd306ce2-03e8-46f8-9bf4-841c33b60056
version: 1.0.0
description: |
Detects file-by-file encryption pattern where ransomware reads original
files, creates encrypted copies with new extensions, then deletes
originals. 17ms window captures the complete encrypt-and-delete cycle.
condition: >
sequence
maxspan 17ms
by ps.uuid
|( (image.signature.type = 'NONE' or pe.is_trusted = false)
and kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches (
'?:\\Users\\*\\Desktop\\*',
'?:\\Users\\*\\Documents\\*',
'?:\\Users\\*\\Downloads\\*',
'?:\\Users\\*\\Pictures\\*')
and not ps.exe imatches '?:\\Program Files*' )|
|( kevt.name = 'ReadFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'WriteFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'DeleteFile'
and file.path imatches '?:\\Users\\*' )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware In Progress - File-to-File with Rename and Delete
id: cb3ec28b-0914-4f24-b84c-74185feecfba
version: 1.0.0
description: |
Detects ransomware using temporary file encryption before renaming to
final encrypted form and deleting originals. Used by families like
LockBit. 16ms pattern catches the multi-step process.
condition: >
sequence
maxspan 16ms
by ps.uuid
|( (image.signature.type = 'NONE' or pe.is_trusted = false)
and kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches (
'?:\\Users\\*\\Desktop\\*',
'?:\\Users\\*\\Documents\\*',
'?:\\Users\\*\\Downloads\\*',
'?:\\Users\\*\\Pictures\\*')
and not ps.exe imatches '?:\\Program Files*' )|
|( kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'WriteFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'RenameFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'DeleteFile'
and file.path imatches '?:\\Users\\*' )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware In Progress - Memory-to-File Post-Overwrite
id: 1e1350b5-4562-4515-b3bd-fcd7db52dd13
version: 1.0.0
description: |
Detects Cerber-style encryption where files are opened, read into memory
for encryption, written back encrypted, then subjected to additional
operations. Tracked by file object for accurate correlation across the
15ms window.
condition: >
sequence
maxspan 15ms
by file.object
|( kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches '?:\\Users\\*'
and not file.path imatches '?:\\Users\\*\\AppData\\*'
and not ps.name in ('OneDrive.exe', 'Dropbox.exe',
'explorer.exe', 'SearchProtocolHost.exe') )|
|( kevt.name = 'ReadFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'WriteFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'WriteFile'
and file.io.size > 0
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'RenameFile'
or kevt.name = 'FileDelete'
or kevt.name = 'FileCreate' )|
severity: critical
min-engine-version: 2.0.0
name: Ransomware In Progress - Memory-to-File Pre-Overwrite
id: a72a98a9-d230-41e7-af68-c3e5105f3a2e
version: 1.0.2
description: |
Detects immediate file corruption pattern where ransomware opens files,
renames them to backup copies, then overwrites originals with encrypted
content. Rapid 2ms sequence prevents file recovery. Common in wiper
malware and destructive ransomware variants.
condition: >
sequence
maxspan 2ms
by ps.uuid
|( (image.signature.type = 'NONE' or pe.is_trusted = false)
and kevt.name = 'CreateFile'
and file.operation = 'OPEN'
and file.path imatches (
'?:\\Users\\*\\Desktop\\*',
'?:\\Users\\*\\Documents\\*',
'?:\\Users\\*\\Downloads\\*',
'?:\\Users\\*\\Pictures\\*')
and not ps.exe imatches '?:\\Program Files*' )|
|( kevt.name = 'RenameFile'
and file.path imatches '?:\\Users\\*' )|
|( kevt.name = 'WriteFile'
and file.io.size > 0
and file.path imatches '?:\\Users\\*' )|
severity: critical
min-engine-version: 2.0.0
All detections are open source on GitHub. Use them, adapt them, make them better.
Go to GitHub