Detection rules › Kusto

New user created and added to the built-in administrators group

Severity
low
Time window
1d
Group by
CreatedUserSid
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

Identifies when a user account was created and then added to the builtin Administrators group in the same day. This should be monitored closely and all additions reviewed.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

id: aa1eff90-29d4-49dc-a3ea-b65199f516db
name: New user created and added to the built-in administrators group
description: |
  'Identifies when a user account was created and then added to the builtin Administrators group in the same day.
  This should be monitored closely and all additions reviewed.'
severity: Low
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
     - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes: 
      - SecurityEvents 
  - connectorId: WindowsForwardedEvents
    dataTypes: 
      - WindowsEvent 
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Persistence
  - PrivilegeEscalation
relevantTechniques:
  - T1098
  - T1078
query: |
  (union isfuzzy=true
      (SecurityEvent
      | where EventID == 4720
      | where AccountType == "User"
      | project CreatedUserTime = TimeGenerated, CreatedUserEventID = EventID, CreatedUserActivity = Activity, Computer = toupper(Computer), 
      CreatedUser = tolower(TargetAccount), CreatedUserAccountName = TargetUserName, CreatedUserDomainName = TargetDomainName, CreatedUserSid = TargetSid, 
      AccountUsedToCreateUser = SubjectAccount, CreatedByAccountName = SubjectUserName, CreatedByDomainName = SubjectDomainName, SidofAccountUsedToCreateUser = SubjectUserSid
      ),
      (WindowsEvent
      | where EventID == 4720
      | extend SubjectUserSid = tostring(EventData.SubjectUserSid)
      | extend AccountType=case(EventData.SubjectUserName endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
      | where AccountType == "User"
      | extend SubjectAccount = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
      | extend SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName)
      | extend TargetAccount = strcat(EventData.TargetDomainName,"\\", EventData.TargetUserName)
      | extend TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName) 
      | extend Activity="4720 - A user account was created."
      | extend TargetSid = tostring(EventData.TargetSid)
      | project CreatedUserTime = TimeGenerated, CreatedUserEventID = EventID, CreatedUserActivity = Activity, Computer = toupper(Computer), 
      CreatedUser = tolower(TargetAccount), CreatedUserAccountName = TargetUserName, CreatedUserDomainName = TargetDomainName, CreatedUserSid = TargetSid, 
      AccountUsedToCreateUser = SubjectAccount, CreatedByAccountName = SubjectUserName, CreatedByDomainName = SubjectDomainName, SidofAccountUsedToCreateUser = SubjectUserSid
      )
    )
  | join kind=inner
  (
    (union isfuzzy=true
      (SecurityEvent 
      | where AccountType == "User"
      // 4732 - A member was added to a security-enabled local group
      | where EventID == 4732
      // TargetSid is the builin Admins group: S-1-5-32-544
      | where TargetSid == "S-1-5-32-544"
      | project GroupAddTime = TimeGenerated, GroupAddEventID = EventID, GroupAddActivity = Activity, Computer = toupper(Computer), GroupName = tolower(TargetAccount), 
      GroupSid = TargetSid, AccountThatAddedUser = SubjectAccount, SIDofAccountThatAddedUser = SubjectUserSid, AddedByAccountName = SubjectUserName, AddedByDomainName = SubjectDomainName,
      CreatedUserSid = MemberSid
      ),
      (  WindowsEvent 
      // 4732 - A member was added to a security-enabled local group
      | where EventID == 4732 and EventData has "S-1-5-32-544"
      //TargetSid is the builin Admins group: S-1-5-32-544
      | extend SubjectUserSid = tostring(EventData.SubjectUserSid)
      | extend AccountType=case(EventData.SubjectUserName endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
      | where AccountType == "User"
      | extend TargetSid = tostring(EventData.TargetSid)
      | where TargetSid == "S-1-5-32-544"
      | extend SubjectAccount = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
      | extend SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName)
      | extend TargetAccount = strcat(EventData.TargetDomainName,"\\", EventData.TargetUserName)
      | extend Activity="4732 - A member was added to a security-enabled local group."
      | extend MemberSid = tostring(EventData.MemberSid)
      | project GroupAddTime = TimeGenerated, GroupAddEventID = EventID, GroupAddActivity = Activity, Computer = toupper(Computer), GroupName = tolower(TargetAccount), 
      GroupSid = TargetSid, AccountThatAddedUser = SubjectAccount, SIDofAccountThatAddedUser = SubjectUserSid, AddedByAccountName = SubjectUserName, AddedByDomainName = SubjectDomainName,
      CreatedUserSid = MemberSid
      )
    )
  )
  on CreatedUserSid
  //Create User first, then the add to the group.
  | project Computer, CreatedUserTime, CreatedUserEventID, CreatedUserActivity, CreatedUser, CreatedUserSid, CreatedUserAccountName, CreatedUserDomainName,
  GroupAddTime, GroupAddEventID, GroupAddActivity, GroupName, GroupSid,
  AccountUsedToCreateUser, SidofAccountUsedToCreateUser, CreatedByAccountName, CreatedByDomainName, 
  AccountThatAddedUser, SIDofAccountThatAddedUser, AddedByAccountName, AddedByDomainName
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
  | project-away DomainIndex
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountUsedToCreateUser
      - identifier: Name
        columnName: CreatedByAccountName
      - identifier: NTDomain
        columnName: CreatedByDomainName
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountThatAddedUser
      - identifier: Name
        columnName: AddedByAccountName
      - identifier: NTDomain
        columnName: AddedByDomainName
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: CreatedUser
      - identifier: Name
        columnName: CreatedUserAccountName
      - identifier: NTDomain
        columnName: CreatedUserDomainName
  - entityType: Account
    fieldMappings:
      - identifier: Sid
        columnName: CreatedUserSid
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: NTDomain
        columnName: HostNameDomain
version: 1.2.1
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others", "Identity" ]

Stages and Predicates

Stage 1: union

union of 2 branches

Stage 2: source

SecurityEvent

Stage 3: where

| where EventID == 4720

Stage 4: where

| where AccountType == "User"

Stage 5: project

| project CreatedUserTime = TimeGenerated, CreatedUserEventID = EventID, CreatedUserActivity = Activity, Computer = toupper(Computer), 
    CreatedUser = tolower(TargetAccount), CreatedUserAccountName = TargetUserName, CreatedUserDomainName = TargetDomainName, CreatedUserSid = TargetSid, 
    AccountUsedToCreateUser = SubjectAccount, CreatedByAccountName = SubjectUserName, CreatedByDomainName = SubjectDomainName, SidofAccountUsedToCreateUser = SubjectUserSid

Stage 6: source

WindowsEvent

Stage 7: where

| where EventID == 4720

Stage 8: extend

| extend SubjectUserSid = tostring(EventData.SubjectUserSid)

Stage 9: extend

| extend AccountType=case(EventData.SubjectUserName endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
AccountType =
if(SubjectUserName endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"))"Machine"
elifisempty(SubjectUserSid)""
else"User"

Stage 10: where

| where AccountType == "User"

Stage 11: extend (6 consecutive steps)

| extend SubjectAccount = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend SubjectDomainName = tostring(EventData.SubjectDomainName), SubjectUserName = tostring(EventData.SubjectUserName)
| extend TargetAccount = strcat(EventData.TargetDomainName,"\\", EventData.TargetUserName)
| extend TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName)
| extend Activity="4720 - A user account was created."
| extend TargetSid = tostring(EventData.TargetSid)

Stage 12: project

| project CreatedUserTime = TimeGenerated, CreatedUserEventID = EventID, CreatedUserActivity = Activity, Computer = toupper(Computer), 
    CreatedUser = tolower(TargetAccount), CreatedUserAccountName = TargetUserName, CreatedUserDomainName = TargetDomainName, CreatedUserSid = TargetSid, 
    AccountUsedToCreateUser = SubjectAccount, CreatedByAccountName = SubjectUserName, CreatedByDomainName = SubjectDomainName, SidofAccountUsedToCreateUser = SubjectUserSid

Stage 13: join

join kind=inner (...) on CreatedUserSid

Stage 14: project

project AccountThatAddedUser, AccountUsedToCreateUser, AddedByAccountName, AddedByDomainName, Computer, CreatedByAccountName, CreatedByDomainName, CreatedUser, CreatedUserAccountName, CreatedUserActivity, CreatedUserDomainName, CreatedUserEventID, CreatedUserSid, CreatedUserTime, GroupAddActivity, GroupAddEventID, GroupAddTime, GroupName, GroupSid, SIDofAccountThatAddedUser, SidofAccountUsedToCreateUser

Stage 15: extend

extend DomainIndex, HostName

Stage 16: extend

extend HostNameDomain
HostNameDomain =
ifDomainIndex != -1substring(Computer, (DomainIndex + 1))
elseComputer

Stage 17: project-away

project-away DomainIndex

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
AccountTypeeq
  • User corpus 6 (kusto 6)
field:"AccountType" kind:eq value:"User"
EventDatamatch
  • S-1-5-32-544 transforms: term
field:"EventData" kind:match value:"S-1-5-32-544"
EventIDeq
  • 4720 corpus 5 (kusto 3, splunk 2)
  • 4732 corpus 4 (splunk 3, kusto 1)
field:"EventID" kind:eq
TargetSideq
  • S-1-5-32-544
field:"TargetSid" kind:eq value:"S-1-5-32-544"

Output fields

These fields are emitted when the rule matches.

FieldSource
AccountThatAddedUserproject
AccountUsedToCreateUserproject
AddedByAccountNameproject
AddedByDomainNameproject
Computerproject
CreatedByAccountNameproject
CreatedByDomainNameproject
CreatedUserproject
CreatedUserAccountNameproject
CreatedUserActivityproject
CreatedUserDomainNameproject
CreatedUserEventIDproject
CreatedUserSidproject
CreatedUserTimeproject
GroupAddActivityproject
GroupAddEventIDproject
GroupAddTimeproject
GroupNameproject
GroupSidproject
SIDofAccountThatAddedUserproject
SidofAccountUsedToCreateUserproject
HostNameextend
HostNameDomainextend