Detection rules › Kusto
CYFIRMA - Compromised Employees Detection Rule
This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.
"Identifies and alerts on internal employee accounts that have been compromised, based on CYFIRMA's threat intelligence. This rule captures the latest exposure of user credentials, IP addresses, hostnames, operating systems, and pass hashes observed in the threat feed. It supports rapid detection and investigation of phishing, stealer malware, and insider compromise scenarios."
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | T1078 Valid Accounts |
| Persistence | T1078 Valid Accounts, T1098 Account Manipulation |
| Credential Access | T1003 OS Credential Dumping, T1552 Unsecured Credentials |
Rule body kusto
id: 72d3fb86-d1eb-44d6-9352-170c6bb45bb7
name: CYFIRMA - Compromised Employees Detection Rule
description: |
"Identifies and alerts on internal employee accounts that have been compromised, based on CYFIRMA's threat intelligence.
This rule captures the latest exposure of user credentials, IP addresses, hostnames, operating systems, and pass hashes observed in the threat feed.
It supports rapid detection and investigation of phishing, stealer malware, and insider compromise scenarios."
version: 1.0.1
kind: Scheduled
severity: High
requiredDataConnectors:
- connectorId: CyfirmaCompromisedAccountsDataConnector
dataTypes:
- CyfirmaCompromisedAccounts_CL
queryFrequency: 5m
queryPeriod: 5m
suppressionDuration: 6h
suppressionEnabled: true
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
- CredentialAccess
- InitialAccess
- Persistence
relevantTechniques:
- T1003
- T1552
- T1078
- T1098
query: |
// Compromised Employees - Latest per UID
let timeFrame = 5m;
CyfirmaCompromisedAccounts_CL
| where TimeGenerated between (ago(timeFrame) .. now())
and Category has "Compromised Employees"
| extend
ProviderName = 'CYFIRMA',
ProductName = 'DeCYFIR/DeTCT'
| summarize arg_max(TimeGenerated,
url,
ip,
email,
user_name,
computer_name,
operating_system,
breach_date,
first_seen,
last_seen,
impact,
recommendations,
description,
source,
pass_hash,
ProductName,
ProviderName
) by uid
| sort by TimeGenerated desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: user_name
- identifier: UPNSuffix
columnName: email
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: computer_name
- identifier: OSVersion
columnName: operating_system
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ip
- entityType: URL
fieldMappings:
- identifier: Url
columnName: url
customDetails:
UID: uid
TimeGenerated: TimeGenerated
BreachDate: breach_date
FirstSeen: first_seen
LastSeen: last_seen
Impact: impact
Recommendations: recommendations
Source: source
Description: description
PassHash: pass_hash
alertDetailsOverride:
alertDisplayNameFormat: "Employee Compromised - {{user_name}} - {{email}}"
alertDescriptionFormat: "{{description}}"
alertDynamicProperties:
- alertProperty: ProductName
value: ProductName
- alertProperty: ProviderName
value: ProviderName
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
eventGroupingSettings:
aggregationKind: AlertPerResult
Stages and Predicates
Parameters
let timeFrame = 5m;
Stage 1: source
CyfirmaCompromisedAccounts_CL
Stage 2: where
| where TimeGenerated between (ago(timeFrame) .. now())
and Category has "Compromised Employees"
Stage 3: extend
| extend
ProviderName = 'CYFIRMA',
ProductName = 'DeCYFIR/DeTCT'
Stage 4: summarize
| summarize arg_max(TimeGenerated,
url,
ip,
email,
user_name,
computer_name,
operating_system,
breach_date,
first_seen,
last_seen,
impact,
recommendations,
description,
source,
pass_hash,
ProductName,
ProviderName
) by uid
Stage 5: sort
| sort by TimeGenerated desc
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
Category | match |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
uid | summarize |