Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Failed logon attempts by valid accounts within 10 mins

Back
Id0777f138-e5d8-4eab-bec1-e11ddfbc2be2
RulenameFailed logon attempts by valid accounts within 10 mins
DescriptionIdentifies when failed logon attempts are 20 or higher during a 10 minute period (2 failed logons per minute minimum) from valid account.
SeverityLow
TacticsCredentialAccess
TechniquesT1110
Required data connectorsSecurityEvents
WindowsForwardedEvents
WindowsSecurityEvents
KindScheduled
Query frequency10m
Query period10m
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/gte_6_FailedLogons_10m.yaml
Version1.2.5
Arm template0777f138-e5d8-4eab-bec1-e11ddfbc2be2.json
Deploy To Azure
let threshold = 20;
let ReasontoSubStatus = datatable(SubStatus: string, Reason: string) [
    "0xc000005e", "There are currently no logon servers available to service the logon request.",
    "0xc0000064", "User logon with misspelled or bad user account",
    "0xc000006a", "User logon with misspelled or bad password",
    "0xc000006d", "Bad user name or password",
    "0xc000006e", "Unknown user name or bad password",
    "0xc000006f", "User logon outside authorized hours",
    "0xc0000070", "User logon from unauthorized workstation",
    "0xc0000071", "User logon with expired password",
    "0xc0000072", "User logon to account disabled by administrator",
    "0xc00000dc", "Indicates the Sam Server was in the wrong state to perform the desired operation",
    "0xc0000133", "Clocks between DC and other computer too far out of sync",
    "0xc000015b", "The user has not been granted the requested logon type (aka logon right) at this machine",
    "0xc000018c", "The logon request failed because the trust relationship between the primary domain and the trusted domain failed",
    "0xc0000192", "An attempt was made to logon, but the Netlogon service was not started",
    "0xc0000193", "User logon with expired account",
    "0xc0000224", "User is required to change password at next logon",
    "0xc0000225", "Evidently a bug in Windows and not a risk",
    "0xc0000234", "User logon with account locked",
    "0xc00002ee", "Failure Reason: An Error occurred during Logon",
    "0xc0000413", "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine"
];
(union isfuzzy=true
    (SecurityEvent
    | where EventID == 4625
    | where AccountType =~ "User"
    | where SubStatus !~ '0xc0000064' and Account !in ('\\', '-\\-')
    // SubStatus '0xc0000064' signifies 'Account name does not exist'
    | extend
        ResourceId = column_ifexists("_ResourceId", _ResourceId),
        SourceComputerId = column_ifexists("SourceComputerId", SourceComputerId),
        SubStatus = tolower(SubStatus)
    | lookup ReasontoSubStatus on SubStatus
    | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))
    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,
        Activity, Computer, Account, TargetAccount, TargetUserName, TargetDomainName,
        LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress
    | where FailedLogonCount >= threshold
    ),
    (
    (WindowsEvent
    | where EventID == 4625 and not(EventData has '0xc0000064')
    | extend TargetAccount = strcat(tostring(EventData.TargetDomainName), "\\", tostring(EventData.TargetUserName))
    | extend TargetUserSid = tostring(EventData.TargetUserSid)
    | extend AccountType=case(EventData.TargetUserName endswith "$" or TargetUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(TargetUserSid), "", "User")
    | where AccountType =~ "User"
    | extend SubStatus = tostring(EventData.SubStatus)
    | where SubStatus !~ '0xc0000064' and TargetAccount !in ('\\', '-\\-')
    // SubStatus '0xc0000064' signifies 'Account name does not exist'
    | extend
        ResourceId = column_ifexists("_ResourceId", _ResourceId),
        SourceComputerId = column_ifexists("SourceComputerId", ""),
        SubStatus = tolower(SubStatus)
    | lookup ReasontoSubStatus on SubStatus
    | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))
    | extend Activity="4625 - An account failed to log on."
    | extend TargetUserName = tostring(EventData.TargetUserName)
    | extend TargetDomainName = tostring(EventData.TargetDomainName)
    | extend LogonType = tostring(EventData.LogonType)
    | extend Status= tostring(EventData.Status)
    | extend LogonProcessName = tostring(EventData.LogonProcessName)
    | extend WorkstationName = tostring(EventData.WorkstationName)
    | extend IpAddress = tostring(EventData.IpAddress)
    | extend LogonTypeName=case(
      LogonType == 2, "2 - Interactive",
      LogonType == 3, "3 - Network",
      LogonType == 4, "4 - Batch",
      LogonType == 5, "5 - Service",
      LogonType == 7, "7 - Unlock",
      LogonType == 8, "8 - NetworkCleartext",
      LogonType == 9, "9 - NewCredentials",
      LogonType == 10, "10 - RemoteInteractive",
      LogonType == 11, "11 - CachedInteractive",
      tostring(LogonType)
    )
    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,
        Activity, Computer, TargetAccount, TargetUserName, TargetDomainName,
        LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress
    | where FailedLogonCount >= threshold
    )))
| summarize arg_max(TimeGenerated, *) by Computer, TargetAccount, TargetUserName, TargetDomainName
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
name: Failed logon attempts by valid accounts within 10 mins
id: 0777f138-e5d8-4eab-bec1-e11ddfbc2be2
triggerThreshold: 0
severity: Low
tactics:
- CredentialAccess
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/gte_6_FailedLogons_10m.yaml
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: TargetAccount
    identifier: FullName
  - columnName: TargetUserName
    identifier: Name
  - columnName: TargetDomainName
    identifier: NTDomain
- entityType: Host
  fieldMappings:
  - columnName: Computer
    identifier: FullName
  - columnName: HostName
    identifier: HostName
  - columnName: HostNameDomain
    identifier: NTDomain
- entityType: IP
  fieldMappings:
  - columnName: IpAddress
    identifier: Address
queryPeriod: 10m
queryFrequency: 10m
version: 1.2.5
triggerOperator: gt
description: |
    'Identifies when failed logon attempts are 20 or higher during a 10 minute period (2 failed logons per minute minimum) from valid account.'
metadata:
  support:
    tier: Community
  author:
    name: Microsoft Security Research
  source:
    kind: Community
  categories:
    domains:
    - Security - Others
    - Identity
query: |
  let threshold = 20;
  let ReasontoSubStatus = datatable(SubStatus: string, Reason: string) [
      "0xc000005e", "There are currently no logon servers available to service the logon request.",
      "0xc0000064", "User logon with misspelled or bad user account",
      "0xc000006a", "User logon with misspelled or bad password",
      "0xc000006d", "Bad user name or password",
      "0xc000006e", "Unknown user name or bad password",
      "0xc000006f", "User logon outside authorized hours",
      "0xc0000070", "User logon from unauthorized workstation",
      "0xc0000071", "User logon with expired password",
      "0xc0000072", "User logon to account disabled by administrator",
      "0xc00000dc", "Indicates the Sam Server was in the wrong state to perform the desired operation",
      "0xc0000133", "Clocks between DC and other computer too far out of sync",
      "0xc000015b", "The user has not been granted the requested logon type (aka logon right) at this machine",
      "0xc000018c", "The logon request failed because the trust relationship between the primary domain and the trusted domain failed",
      "0xc0000192", "An attempt was made to logon, but the Netlogon service was not started",
      "0xc0000193", "User logon with expired account",
      "0xc0000224", "User is required to change password at next logon",
      "0xc0000225", "Evidently a bug in Windows and not a risk",
      "0xc0000234", "User logon with account locked",
      "0xc00002ee", "Failure Reason: An Error occurred during Logon",
      "0xc0000413", "Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine"
  ];
  (union isfuzzy=true
      (SecurityEvent
      | where EventID == 4625
      | where AccountType =~ "User"
      | where SubStatus !~ '0xc0000064' and Account !in ('\\', '-\\-')
      // SubStatus '0xc0000064' signifies 'Account name does not exist'
      | extend
          ResourceId = column_ifexists("_ResourceId", _ResourceId),
          SourceComputerId = column_ifexists("SourceComputerId", SourceComputerId),
          SubStatus = tolower(SubStatus)
      | lookup ReasontoSubStatus on SubStatus
      | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))
      | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,
          Activity, Computer, Account, TargetAccount, TargetUserName, TargetDomainName,
          LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress
      | where FailedLogonCount >= threshold
      ),
      (
      (WindowsEvent
      | where EventID == 4625 and not(EventData has '0xc0000064')
      | extend TargetAccount = strcat(tostring(EventData.TargetDomainName), "\\", tostring(EventData.TargetUserName))
      | extend TargetUserSid = tostring(EventData.TargetUserSid)
      | extend AccountType=case(EventData.TargetUserName endswith "$" or TargetUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(TargetUserSid), "", "User")
      | where AccountType =~ "User"
      | extend SubStatus = tostring(EventData.SubStatus)
      | where SubStatus !~ '0xc0000064' and TargetAccount !in ('\\', '-\\-')
      // SubStatus '0xc0000064' signifies 'Account name does not exist'
      | extend
          ResourceId = column_ifexists("_ResourceId", _ResourceId),
          SourceComputerId = column_ifexists("SourceComputerId", ""),
          SubStatus = tolower(SubStatus)
      | lookup ReasontoSubStatus on SubStatus
      | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))
      | extend Activity="4625 - An account failed to log on."
      | extend TargetUserName = tostring(EventData.TargetUserName)
      | extend TargetDomainName = tostring(EventData.TargetDomainName)
      | extend LogonType = tostring(EventData.LogonType)
      | extend Status= tostring(EventData.Status)
      | extend LogonProcessName = tostring(EventData.LogonProcessName)
      | extend WorkstationName = tostring(EventData.WorkstationName)
      | extend IpAddress = tostring(EventData.IpAddress)
      | extend LogonTypeName=case(
        LogonType == 2, "2 - Interactive",
        LogonType == 3, "3 - Network",
        LogonType == 4, "4 - Batch",
        LogonType == 5, "5 - Service",
        LogonType == 7, "7 - Unlock",
        LogonType == 8, "8 - NetworkCleartext",
        LogonType == 9, "9 - NewCredentials",
        LogonType == 10, "10 - RemoteInteractive",
        LogonType == 11, "11 - CachedInteractive",
        tostring(LogonType)
      )
      | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,
          Activity, Computer, TargetAccount, TargetUserName, TargetDomainName,
          LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress
      | where FailedLogonCount >= threshold
      )))
  | summarize arg_max(TimeGenerated, *) by Computer, TargetAccount, TargetUserName, TargetDomainName
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)  
relevantTechniques:
- T1110
requiredDataConnectors:
- dataTypes:
  - SecurityEvent
  connectorId: SecurityEvents
- dataTypes:
  - SecurityEvent
  connectorId: WindowsSecurityEvents
- dataTypes:
  - WindowsEvent
  connectorId: WindowsForwardedEvents
kind: Scheduled
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/0777f138-e5d8-4eab-bec1-e11ddfbc2be2')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/0777f138-e5d8-4eab-bec1-e11ddfbc2be2')]",
      "properties": {
        "alertRuleTemplateName": "0777f138-e5d8-4eab-bec1-e11ddfbc2be2",
        "customDetails": null,
        "description": "'Identifies when failed logon attempts are 20 or higher during a 10 minute period (2 failed logons per minute minimum) from valid account.'\n",
        "displayName": "Failed logon attempts by valid accounts within 10 mins",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "TargetAccount",
                "identifier": "FullName"
              },
              {
                "columnName": "TargetUserName",
                "identifier": "Name"
              },
              {
                "columnName": "TargetDomainName",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "Computer",
                "identifier": "FullName"
              },
              {
                "columnName": "HostName",
                "identifier": "HostName"
              },
              {
                "columnName": "HostNameDomain",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IpAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/gte_6_FailedLogons_10m.yaml",
        "query": "let threshold = 20;\nlet ReasontoSubStatus = datatable(SubStatus: string, Reason: string) [\n    \"0xc000005e\", \"There are currently no logon servers available to service the logon request.\",\n    \"0xc0000064\", \"User logon with misspelled or bad user account\",\n    \"0xc000006a\", \"User logon with misspelled or bad password\",\n    \"0xc000006d\", \"Bad user name or password\",\n    \"0xc000006e\", \"Unknown user name or bad password\",\n    \"0xc000006f\", \"User logon outside authorized hours\",\n    \"0xc0000070\", \"User logon from unauthorized workstation\",\n    \"0xc0000071\", \"User logon with expired password\",\n    \"0xc0000072\", \"User logon to account disabled by administrator\",\n    \"0xc00000dc\", \"Indicates the Sam Server was in the wrong state to perform the desired operation\",\n    \"0xc0000133\", \"Clocks between DC and other computer too far out of sync\",\n    \"0xc000015b\", \"The user has not been granted the requested logon type (aka logon right) at this machine\",\n    \"0xc000018c\", \"The logon request failed because the trust relationship between the primary domain and the trusted domain failed\",\n    \"0xc0000192\", \"An attempt was made to logon, but the Netlogon service was not started\",\n    \"0xc0000193\", \"User logon with expired account\",\n    \"0xc0000224\", \"User is required to change password at next logon\",\n    \"0xc0000225\", \"Evidently a bug in Windows and not a risk\",\n    \"0xc0000234\", \"User logon with account locked\",\n    \"0xc00002ee\", \"Failure Reason: An Error occurred during Logon\",\n    \"0xc0000413\", \"Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine\"\n];\n(union isfuzzy=true\n    (SecurityEvent\n    | where EventID == 4625\n    | where AccountType =~ \"User\"\n    | where SubStatus !~ '0xc0000064' and Account !in ('\\\\', '-\\\\-')\n    // SubStatus '0xc0000064' signifies 'Account name does not exist'\n    | extend\n        ResourceId = column_ifexists(\"_ResourceId\", _ResourceId),\n        SourceComputerId = column_ifexists(\"SourceComputerId\", SourceComputerId),\n        SubStatus = tolower(SubStatus)\n    | lookup ReasontoSubStatus on SubStatus\n    | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))\n    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,\n        Activity, Computer, Account, TargetAccount, TargetUserName, TargetDomainName,\n        LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress\n    | where FailedLogonCount >= threshold\n    ),\n    (\n    (WindowsEvent\n    | where EventID == 4625 and not(EventData has '0xc0000064')\n    | extend TargetAccount = strcat(tostring(EventData.TargetDomainName), \"\\\\\", tostring(EventData.TargetUserName))\n    | extend TargetUserSid = tostring(EventData.TargetUserSid)\n    | extend AccountType=case(EventData.TargetUserName endswith \"$\" or TargetUserSid in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\"), \"Machine\", isempty(TargetUserSid), \"\", \"User\")\n    | where AccountType =~ \"User\"\n    | extend SubStatus = tostring(EventData.SubStatus)\n    | where SubStatus !~ '0xc0000064' and TargetAccount !in ('\\\\', '-\\\\-')\n    // SubStatus '0xc0000064' signifies 'Account name does not exist'\n    | extend\n        ResourceId = column_ifexists(\"_ResourceId\", _ResourceId),\n        SourceComputerId = column_ifexists(\"SourceComputerId\", \"\"),\n        SubStatus = tolower(SubStatus)\n    | lookup ReasontoSubStatus on SubStatus\n    | extend coalesce(Reason, strcat('Unknown reason substatus: ', SubStatus))\n    | extend Activity=\"4625 - An account failed to log on.\"\n    | extend TargetUserName = tostring(EventData.TargetUserName)\n    | extend TargetDomainName = tostring(EventData.TargetDomainName)\n    | extend LogonType = tostring(EventData.LogonType)\n    | extend Status= tostring(EventData.Status)\n    | extend LogonProcessName = tostring(EventData.LogonProcessName)\n    | extend WorkstationName = tostring(EventData.WorkstationName)\n    | extend IpAddress = tostring(EventData.IpAddress)\n    | extend LogonTypeName=case(\n      LogonType == 2, \"2 - Interactive\",\n      LogonType == 3, \"3 - Network\",\n      LogonType == 4, \"4 - Batch\",\n      LogonType == 5, \"5 - Service\",\n      LogonType == 7, \"7 - Unlock\",\n      LogonType == 8, \"8 - NetworkCleartext\",\n      LogonType == 9, \"9 - NewCredentials\",\n      LogonType == 10, \"10 - RemoteInteractive\",\n      LogonType == 11, \"11 - CachedInteractive\",\n      tostring(LogonType)\n    )\n    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), FailedLogonCount = count() by bin(TimeGenerated,10m), EventID,\n        Activity, Computer, TargetAccount, TargetUserName, TargetDomainName,\n        LogonType, LogonTypeName, LogonProcessName, Status, SubStatus, Reason, ResourceId, SourceComputerId, WorkstationName, IpAddress\n    | where FailedLogonCount >= threshold\n    )))\n| summarize arg_max(TimeGenerated, *) by Computer, TargetAccount, TargetUserName, TargetDomainName\n| extend HostName = tostring(split(Computer, \".\")[0]), DomainIndex = toint(indexof(Computer, '.'))\n| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)\n",
        "queryFrequency": "PT10M",
        "queryPeriod": "PT10M",
        "severity": "Low",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CredentialAccess"
        ],
        "techniques": [
          "T1110"
        ],
        "templateVersion": "1.2.5",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}