Back
Ida25eba0e-ff42-4c97-a379-d76bdb2aa1e3
RulenameSpyCloud plaintext credential exposure detected
Description#DONT_CORR#

‘Identifies user accounts exposed with a plaintext password in a third-party data breach.

Unremediated exposures of this kind can lead directly to account takeover.
SeverityHigh
TacticsCredentialAccess
TechniquesT1555
Required data connectorsSpyCloudEnterpriseProtectionCCF
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SpyCloud%20Enterprise%20Protection%20CCF/Analytic%20Rules/AR_Breached_Users_20.yaml
Version1.0.0
Arm templatea25eba0e-ff42-4c97-a379-d76bdb2aa1e3.json
Deploy To Azure
// Human-readable constant for the severity threshold used below
let severityThreshold = 20;
SpyCloudBreachWatchlistV2_CL
| where Severity == severityThreshold
// Severity alone determines this detection. mv-expand emits no rows for an empty
// array, which would silently drop exposures carrying no IP data, so substitute a
// single empty placeholder before expanding.
| extend IPList = iff(isnull(IPAddresses) or array_length(IPAddresses) == 0, dynamic([""]), IPAddresses)
| mv-expand IPAddress = IPList to typeof(string)
| extend AccountName = Username, AccountEmail = Email,
    AccountUpn = iff(isnotempty(Email), Email, Username)
| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,
    TargetDomain, PasswordPlaintext, AccountName, AccountUpn, IPAddress
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SpyCloud%20Enterprise%20Protection%20CCF/Analytic%20Rules/AR_Breached_Users_20.yaml
triggerThreshold: 0
query: |
  // Human-readable constant for the severity threshold used below
  let severityThreshold = 20;
  SpyCloudBreachWatchlistV2_CL
  | where Severity == severityThreshold
  // Severity alone determines this detection. mv-expand emits no rows for an empty
  // array, which would silently drop exposures carrying no IP data, so substitute a
  // single empty placeholder before expanding.
  | extend IPList = iff(isnull(IPAddresses) or array_length(IPAddresses) == 0, dynamic([""]), IPAddresses)
  | mv-expand IPAddress = IPList to typeof(string)
  | extend AccountName = Username, AccountEmail = Email,
      AccountUpn = iff(isnotempty(Email), Email, Username)
  | project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,
      TargetDomain, PasswordPlaintext, AccountName, AccountUpn, IPAddress
kind: Scheduled
relevantTechniques:
- T1555
version: 1.0.0
tactics:
- CredentialAccess
id: a25eba0e-ff42-4c97-a379-d76bdb2aa1e3
queryPeriod: 1h
queryFrequency: 1h
severity: High
name: SpyCloud plaintext credential exposure detected
customDetails:
  DocumentID: DocumentId
  SpyCloudPublishDate: SpyCloudPublishDate
requiredDataConnectors:
- connectorId: SpyCloudEnterpriseProtectionCCF
  dataTypes:
  - SpyCloudBreachWatchlistV2_CL
description: |
  #DONT_CORR#
  'Identifies user accounts exposed with a plaintext password in a third-party data breach.
  Unremediated exposures of this kind can lead directly to account takeover.'
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: AccountUpn
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IPAddress
- entityType: Mailbox
  fieldMappings:
  - identifier: MailboxPrimaryAddress
    columnName: AccountEmail
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/a25eba0e-ff42-4c97-a379-d76bdb2aa1e3')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/a25eba0e-ff42-4c97-a379-d76bdb2aa1e3')]",
      "properties": {
        "alertRuleTemplateName": "a25eba0e-ff42-4c97-a379-d76bdb2aa1e3",
        "customDetails": {
          "DocumentID": "DocumentId",
          "SpyCloudPublishDate": "SpyCloudPublishDate"
        },
        "description": "#DONT_CORR#\n'Identifies user accounts exposed with a plaintext password in a third-party data breach.\nUnremediated exposures of this kind can lead directly to account takeover.'\n",
        "displayName": "SpyCloud plaintext credential exposure detected",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountUpn",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Mailbox",
            "fieldMappings": [
              {
                "columnName": "AccountEmail",
                "identifier": "MailboxPrimaryAddress"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "SingleAlert"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SpyCloud%20Enterprise%20Protection%20CCF/Analytic%20Rules/AR_Breached_Users_20.yaml",
        "query": "// Human-readable constant for the severity threshold used below\nlet severityThreshold = 20;\nSpyCloudBreachWatchlistV2_CL\n| where Severity == severityThreshold\n// Severity alone determines this detection. mv-expand emits no rows for an empty\n// array, which would silently drop exposures carrying no IP data, so substitute a\n// single empty placeholder before expanding.\n| extend IPList = iff(isnull(IPAddresses) or array_length(IPAddresses) == 0, dynamic([\"\"]), IPAddresses)\n| mv-expand IPAddress = IPList to typeof(string)\n| extend AccountName = Username, AccountEmail = Email,\n    AccountUpn = iff(isnotempty(Email), Email, Username)\n| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,\n    TargetDomain, PasswordPlaintext, AccountName, AccountUpn, IPAddress\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "High",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess"
        ],
        "techniques": [
          "T1555"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}