Back
Ide00f72ab-fea1-4a31-9ecc-eea6397cd38d
RulenamePassword Spraying
DescriptionThis query detects a password spraying attack, where a single machine has performed a large number of failed login attempts, with a large number of different accounts.

For each account, the attacker uses just a few attempts to prevent account lockout. This query uses the DeviceLogonEvents per machine to detect a password spraying attacks.

The machine against which the password spraying is performed (can be DC, a server or even an endpoint) needs to be enrolled in Microsoft Defender for Endpoint.
SeverityMedium
TacticsCredentialAccess
TechniquesT1110.003
Required data connectorsMicrosoftThreatProtection
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic%20Rules/PasswordSprayingWithMDE.yaml
Version1.0.1
Arm templatee00f72ab-fea1-4a31-9ecc-eea6397cd38d.json
Deploy To Azure
let thresholdForUniqueFailedAccounts = 20;
let upperBoundOfFailedLogonsPerAccount = 10;
let ratioSuccessFailedLogons = 0.5;
let timeframe = 1d;
DeviceLogonEvents
| where Timestamp >= ago(timeframe)
| where LogonType != "Unlock" and ActionType in ("LogonSuccess", "LogonFailed")
| where not(isempty( RemoteIP) and isempty( RemoteDeviceName))
| extend LocalLogon=parse_json(AdditionalFields)
| where RemoteIPType != "Loopback"
| summarize SuccessLogonCount = countif(ActionType == "LogonSuccess"), FailedLogonCount = countif(ActionType == "LogonFailed"),
    UniqueAccountFailedLogons=dcountif(AccountName, ActionType == "LogonFailed"), FirstFailed=minif(Timestamp, ActionType == "LogonFailed"),
    LastFailed=maxif(Timestamp, ActionType == "LogonFailed"), LastTimestamp=arg_max(Timestamp, tostring(ReportId)) by RemoteIP, DeviceName // RemoteIP is the source of the logon attempt.
| project-rename IPAddress=RemoteIP
| where UniqueAccountFailedLogons > thresholdForUniqueFailedAccounts and SuccessLogonCount*ratioSuccessFailedLogons < FailedLogonCount and UniqueAccountFailedLogons*upperBoundOfFailedLogonsPerAccount > FailedLogonCount 
severity: Medium
tactics:
- CredentialAccess
queryFrequency: 1d
id: e00f72ab-fea1-4a31-9ecc-eea6397cd38d
query: |
  let thresholdForUniqueFailedAccounts = 20;
  let upperBoundOfFailedLogonsPerAccount = 10;
  let ratioSuccessFailedLogons = 0.5;
  let timeframe = 1d;
  DeviceLogonEvents
  | where Timestamp >= ago(timeframe)
  | where LogonType != "Unlock" and ActionType in ("LogonSuccess", "LogonFailed")
  | where not(isempty( RemoteIP) and isempty( RemoteDeviceName))
  | extend LocalLogon=parse_json(AdditionalFields)
  | where RemoteIPType != "Loopback"
  | summarize SuccessLogonCount = countif(ActionType == "LogonSuccess"), FailedLogonCount = countif(ActionType == "LogonFailed"),
      UniqueAccountFailedLogons=dcountif(AccountName, ActionType == "LogonFailed"), FirstFailed=minif(Timestamp, ActionType == "LogonFailed"),
      LastFailed=maxif(Timestamp, ActionType == "LogonFailed"), LastTimestamp=arg_max(Timestamp, tostring(ReportId)) by RemoteIP, DeviceName // RemoteIP is the source of the logon attempt.
  | project-rename IPAddress=RemoteIP
  | where UniqueAccountFailedLogons > thresholdForUniqueFailedAccounts and SuccessLogonCount*ratioSuccessFailedLogons < FailedLogonCount and UniqueAccountFailedLogons*upperBoundOfFailedLogonsPerAccount > FailedLogonCount 
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: DeviceName
  entityType: Host
- fieldMappings:
  - identifier: Address
    columnName: IPAddress
  entityType: IP
kind: Scheduled
triggerOperator: gt
name: Password Spraying
version: 1.0.1
status: Available
requiredDataConnectors:
- dataTypes:
  - DeviceLogonEvents
  connectorId: MicrosoftThreatProtection
description: |
  This query detects a password spraying attack, where a single machine has performed a large number of failed login attempts, with a large number of different accounts. 
  For each account, the attacker uses just a few attempts to prevent account lockout. This query uses the DeviceLogonEvents per machine to detect a password spraying attacks. 
  The machine against which the password spraying is performed (can be DC, a server or even an endpoint) needs to be enrolled in Microsoft Defender for Endpoint.
relevantTechniques:
- T1110.003
queryPeriod: 1d
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic%20Rules/PasswordSprayingWithMDE.yaml
triggerThreshold: 0
{
  "$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/e00f72ab-fea1-4a31-9ecc-eea6397cd38d')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e00f72ab-fea1-4a31-9ecc-eea6397cd38d')]",
      "properties": {
        "alertRuleTemplateName": "e00f72ab-fea1-4a31-9ecc-eea6397cd38d",
        "customDetails": null,
        "description": "This query detects a password spraying attack, where a single machine has performed a large number of failed login attempts, with a large number of different accounts. \nFor each account, the attacker uses just a few attempts to prevent account lockout. This query uses the DeviceLogonEvents per machine to detect a password spraying attacks. \nThe machine against which the password spraying is performed (can be DC, a server or even an endpoint) needs to be enrolled in Microsoft Defender for Endpoint.\n",
        "displayName": "Password Spraying",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "DeviceName",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic%20Rules/PasswordSprayingWithMDE.yaml",
        "query": "let thresholdForUniqueFailedAccounts = 20;\nlet upperBoundOfFailedLogonsPerAccount = 10;\nlet ratioSuccessFailedLogons = 0.5;\nlet timeframe = 1d;\nDeviceLogonEvents\n| where Timestamp >= ago(timeframe)\n| where LogonType != \"Unlock\" and ActionType in (\"LogonSuccess\", \"LogonFailed\")\n| where not(isempty( RemoteIP) and isempty( RemoteDeviceName))\n| extend LocalLogon=parse_json(AdditionalFields)\n| where RemoteIPType != \"Loopback\"\n| summarize SuccessLogonCount = countif(ActionType == \"LogonSuccess\"), FailedLogonCount = countif(ActionType == \"LogonFailed\"),\n    UniqueAccountFailedLogons=dcountif(AccountName, ActionType == \"LogonFailed\"), FirstFailed=minif(Timestamp, ActionType == \"LogonFailed\"),\n    LastFailed=maxif(Timestamp, ActionType == \"LogonFailed\"), LastTimestamp=arg_max(Timestamp, tostring(ReportId)) by RemoteIP, DeviceName // RemoteIP is the source of the logon attempt.\n| project-rename IPAddress=RemoteIP\n| where UniqueAccountFailedLogons > thresholdForUniqueFailedAccounts and SuccessLogonCount*ratioSuccessFailedLogons < FailedLogonCount and UniqueAccountFailedLogons*upperBoundOfFailedLogonsPerAccount > FailedLogonCount \n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [
          "T1110.003"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess"
        ],
        "techniques": [
          "T1110"
        ],
        "templateVersion": "1.0.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}