Detection rules › Kusto

CYFIRMA - Public Accounts Leaks 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.

Status
available
Severity
high
Time window
5m
Group by
uid
Source
github.com/Azure/Azure-Sentinel

"Detects exposed public-facing account credentials as identified in CYFIRMA's threat intelligence feeds. This rule monitors for credentials leaked through third-party breaches, dark web sources, or public repositories that could impact the organization's users or systems. It captures key details such as email, username, IP address, and associated devices. These accounts may not be directly managed by the enterprise but still pose a risk of lateral access, shadow IT, or third-party exposure."

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1078 Valid Accounts
Credential AccessT1552 Unsecured Credentials
DiscoveryT1087 Account Discovery

Rule body kusto

id: 57602938-e95a-4fc3-9352-8d473ed256e1
name: CYFIRMA - Public Accounts Leaks Detection Rule
description: |
  "Detects exposed public-facing account credentials as identified in CYFIRMA's threat intelligence feeds.
  This rule monitors for credentials leaked through third-party breaches, dark web sources, or public repositories that could impact the organization's users or systems.
  It captures key details such as email, username, IP address, and associated devices. These accounts may not be directly managed by the enterprise but still pose a risk of lateral access, shadow IT, or third-party exposure."
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
  - Discovery
relevantTechniques:
  - T1078
  - T1087
  - T1552
query: |
  // Public Accounts Leaks - Latest per UID
  let timeFrame = 5m;
  CyfirmaCompromisedAccounts_CL
  | where TimeGenerated between (ago(timeFrame) .. now())
      and Category has "Public Accounts Leaks"
  | extend 
      ProviderName = 'CYFIRMA',
      ProductName = 'DeCYFIR/DeTCT'
  | summarize arg_max(TimeGenerated, 
      email,
      user_name,
      password,
      url,
      ip,
      computer_name,
      operating_system,
      breach_date,
      first_seen,
      last_seen,
      impact,
      recommendations,
      description,
      source,
      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
alertDetailsOverride:
  alertDisplayNameFormat: "Public Leak - {{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 "Public Accounts Leaks"

Stage 3: extend

| extend 
    ProviderName = 'CYFIRMA',
    ProductName = 'DeCYFIR/DeTCT'

Stage 4: summarize

| summarize arg_max(TimeGenerated, 
    email,
    user_name,
    password,
    url,
    ip,
    computer_name,
    operating_system,
    breach_date,
    first_seen,
    last_seen,
    impact,
    recommendations,
    description,
    source,
    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.

FieldKindValues
Categorymatch
  • Public Accounts Leaks transforms: term

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.

FieldSource
uidsummarize