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

AD account with Dont Expire Password

Back
Id6c360107-f3ee-4b91-9f43-f4cfd90441cf
RulenameAD account with Don’t Expire Password
DescriptionIdentifies whenever a user account has the setting “Password Never Expires” in the user account properties selected.

This is indicated in Security event 4738 in the EventData item labeled UserAccountControl with an included value of %%2089.

%%2089 resolves to “Don’t Expire Password - Enabled”.
SeverityLow
TacticsPersistence
TechniquesT1098
Required data connectorsSecurityEvents
WindowsForwardedEvents
WindowsSecurityEvents
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/password_never_expires.yaml
Version1.2.2
Arm template6c360107-f3ee-4b91-9f43-f4cfd90441cf.json
Deploy To Azure
union isfuzzy=true
(
 SecurityEvent
 | where EventID == 4738
 // 2089 value indicates the Don't Expire Password value has been set
 | where UserAccountControl has "%%2089"
 | extend Value_2089 = iff(UserAccountControl has "%%2089","'Don't Expire Password' - Enabled", "Not Changed")
 // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.
 | extend Value_2050 = iff(UserAccountControl has "%%2050","'Password Not Required' - Disabled", "Not Changed")
 // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.
 | extend Value_2082 = iff(UserAccountControl has "%%2082","'Password Not Required' - Enabled", "Not Changed")
 | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName, TargetDomainName, TargetSid, 
 AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid
 ),
 (
 WindowsEvent
 | where EventID == 4738 and EventData has '2089'
 // 2089 value indicates the Don't Expire Password value has been set
 | extend UserAccountControl = tostring(EventData.UserAccountControl)
 | where UserAccountControl has "%%2089"
 | extend Value_2089 = iff(UserAccountControl has "%%2089","'Don't Expire Password' - Enabled", "Not Changed")
 // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.
 | extend Value_2050 = iff(UserAccountControl has "%%2050","'Password Not Required' - Disabled", "Not Changed")
 // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.
 | extend Value_2082 = iff(UserAccountControl has "%%2082","'Password Not Required' - Enabled", "Not Changed")
 | extend Activity="4738 - A user account was changed."
 | extend TargetAccount = strcat(EventData.TargetDomainName,"\\", EventData.TargetUserName)
 | extend TargetSid = tostring(EventData.TargetSid)
 | extend SubjectAccount = strcat(EventData.SubjectDomainName,"\\", EventData.SubjectUserName)
 | extend SubjectUserSid = tostring(EventData.SubjectUserSid)
 | extend AccountType=case(SubjectAccount endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
 | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName), TargetSid, 
 AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName), SubjectUserSid = tostring(EventData.SubjectUserSid)
 )
 | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
 | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
 | project-away DomainIndex
queryFrequency: 1d
description: |
  'Identifies whenever a user account has the setting "Password Never Expires" in the user account properties selected.
  This is indicated in Security event 4738 in the EventData item labeled UserAccountControl with an included value of %%2089.
  %%2089 resolves to "Don't Expire Password - Enabled".'  
severity: Low
version: 1.2.2
relevantTechniques:
- T1098
name: AD account with Don't Expire Password
triggerThreshold: 0
kind: Scheduled
query: |
  union isfuzzy=true
  (
   SecurityEvent
   | where EventID == 4738
   // 2089 value indicates the Don't Expire Password value has been set
   | where UserAccountControl has "%%2089"
   | extend Value_2089 = iff(UserAccountControl has "%%2089","'Don't Expire Password' - Enabled", "Not Changed")
   // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.
   | extend Value_2050 = iff(UserAccountControl has "%%2050","'Password Not Required' - Disabled", "Not Changed")
   // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.
   | extend Value_2082 = iff(UserAccountControl has "%%2082","'Password Not Required' - Enabled", "Not Changed")
   | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName, TargetDomainName, TargetSid, 
   AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid
   ),
   (
   WindowsEvent
   | where EventID == 4738 and EventData has '2089'
   // 2089 value indicates the Don't Expire Password value has been set
   | extend UserAccountControl = tostring(EventData.UserAccountControl)
   | where UserAccountControl has "%%2089"
   | extend Value_2089 = iff(UserAccountControl has "%%2089","'Don't Expire Password' - Enabled", "Not Changed")
   // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.
   | extend Value_2050 = iff(UserAccountControl has "%%2050","'Password Not Required' - Disabled", "Not Changed")
   // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.
   | extend Value_2082 = iff(UserAccountControl has "%%2082","'Password Not Required' - Enabled", "Not Changed")
   | extend Activity="4738 - A user account was changed."
   | extend TargetAccount = strcat(EventData.TargetDomainName,"\\", EventData.TargetUserName)
   | extend TargetSid = tostring(EventData.TargetSid)
   | extend SubjectAccount = strcat(EventData.SubjectDomainName,"\\", EventData.SubjectUserName)
   | extend SubjectUserSid = tostring(EventData.SubjectUserSid)
   | extend AccountType=case(SubjectAccount endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
   | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName), TargetSid, 
   AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName), SubjectUserSid = tostring(EventData.SubjectUserSid)
   )
   | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
   | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
   | project-away DomainIndex  
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/password_never_expires.yaml
requiredDataConnectors:
- connectorId: SecurityEvents
  dataTypes:
  - SecurityEvent
- connectorId: WindowsSecurityEvents
  dataTypes:
  - SecurityEvent
- connectorId: WindowsForwardedEvents
  dataTypes:
  - WindowsEvent
metadata:
  source:
    kind: Community
  author:
    name: Microsoft Security Research
  support:
    tier: Community
  categories:
    domains:
    - Security - Others
    - Identity
tactics:
- Persistence
id: 6c360107-f3ee-4b91-9f43-f4cfd90441cf
queryPeriod: 1d
entityMappings:
- fieldMappings:
  - columnName: TargetAccount
    identifier: FullName
  - columnName: TargetUserName
    identifier: Name
  - columnName: TargetDomainName
    identifier: NTDomain
  entityType: Account
- fieldMappings:
  - columnName: TargetSid
    identifier: Sid
  entityType: Account
- fieldMappings:
  - columnName: SubjectAccount
    identifier: FullName
  - columnName: SubjectUserName
    identifier: Name
  - columnName: SubjectDomainName
    identifier: NTDomain
  entityType: Account
- fieldMappings:
  - columnName: SubjectUserSid
    identifier: Sid
  entityType: Account
- fieldMappings:
  - columnName: Computer
    identifier: FullName
  - columnName: HostName
    identifier: HostName
  - columnName: HostNameDomain
    identifier: DnsDomain
  entityType: Host
{
  "$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/6c360107-f3ee-4b91-9f43-f4cfd90441cf')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/6c360107-f3ee-4b91-9f43-f4cfd90441cf')]",
      "properties": {
        "alertRuleTemplateName": "6c360107-f3ee-4b91-9f43-f4cfd90441cf",
        "customDetails": null,
        "description": "'Identifies whenever a user account has the setting \"Password Never Expires\" in the user account properties selected.\nThis is indicated in Security event 4738 in the EventData item labeled UserAccountControl with an included value of %%2089.\n%%2089 resolves to \"Don't Expire Password - Enabled\".'\n",
        "displayName": "AD account with Don't Expire Password",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "TargetAccount",
                "identifier": "FullName"
              },
              {
                "columnName": "TargetUserName",
                "identifier": "Name"
              },
              {
                "columnName": "TargetDomainName",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "TargetSid",
                "identifier": "Sid"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "SubjectAccount",
                "identifier": "FullName"
              },
              {
                "columnName": "SubjectUserName",
                "identifier": "Name"
              },
              {
                "columnName": "SubjectDomainName",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "SubjectUserSid",
                "identifier": "Sid"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "Computer",
                "identifier": "FullName"
              },
              {
                "columnName": "HostName",
                "identifier": "HostName"
              },
              {
                "columnName": "HostNameDomain",
                "identifier": "DnsDomain"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SecurityEvent/password_never_expires.yaml",
        "query": "union isfuzzy=true\n(\n SecurityEvent\n | where EventID == 4738\n // 2089 value indicates the Don't Expire Password value has been set\n | where UserAccountControl has \"%%2089\"\n | extend Value_2089 = iff(UserAccountControl has \"%%2089\",\"'Don't Expire Password' - Enabled\", \"Not Changed\")\n // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.\n | extend Value_2050 = iff(UserAccountControl has \"%%2050\",\"'Password Not Required' - Disabled\", \"Not Changed\")\n // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.\n | extend Value_2082 = iff(UserAccountControl has \"%%2082\",\"'Password Not Required' - Enabled\", \"Not Changed\")\n | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName, TargetDomainName, TargetSid, \n AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid\n ),\n (\n WindowsEvent\n | where EventID == 4738 and EventData has '2089'\n // 2089 value indicates the Don't Expire Password value has been set\n | extend UserAccountControl = tostring(EventData.UserAccountControl)\n | where UserAccountControl has \"%%2089\"\n | extend Value_2089 = iff(UserAccountControl has \"%%2089\",\"'Don't Expire Password' - Enabled\", \"Not Changed\")\n // 2050 indicates that the Password Not Required value is NOT set, this often shows up at the same time as a 2089 and is the recommended value.  This value may not be in the event.\n | extend Value_2050 = iff(UserAccountControl has \"%%2050\",\"'Password Not Required' - Disabled\", \"Not Changed\")\n // If value %%2082 is present in the 4738 event, this indicates the account has been configured to logon WITHOUT a password. Generally you should only see this value when an account is created and only in Event 4720: Account Creation Event.\n | extend Value_2082 = iff(UserAccountControl has \"%%2082\",\"'Password Not Required' - Enabled\", \"Not Changed\")\n | extend Activity=\"4738 - A user account was changed.\"\n | extend TargetAccount = strcat(EventData.TargetDomainName,\"\\\\\", EventData.TargetUserName)\n | extend TargetSid = tostring(EventData.TargetSid)\n | extend SubjectAccount = strcat(EventData.SubjectDomainName,\"\\\\\", EventData.SubjectUserName)\n | extend SubjectUserSid = tostring(EventData.SubjectUserSid)\n | extend AccountType=case(SubjectAccount endswith \"$\" or SubjectUserSid in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\"), \"Machine\", isempty(SubjectUserSid), \"\", \"User\")\n | project StartTime = TimeGenerated, EventID, Activity, Computer, TargetAccount, TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName), TargetSid, \n AccountType, UserAccountControl, Value_2089, Value_2050, Value_2082, SubjectAccount, SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName), SubjectUserSid = tostring(EventData.SubjectUserSid)\n )\n | extend HostName = tostring(split(Computer, \".\")[0]), DomainIndex = toint(indexof(Computer, '.'))\n | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)\n | project-away DomainIndex\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Low",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence"
        ],
        "techniques": [
          "T1098"
        ],
        "templateVersion": "1.2.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}