id: a35f2c18-1b97-458f-ad26-e033af18eb99
name: User account added to built in domain local or global group
description: |
  'Identifies when a user account has been added to a privileged built in domain local group or global group such as the Enterprise Admins, Cert Publishers or DnsAdmins. Be sure to verify this is an expected addition.'
severity: Low
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsForwardedEvents
    dataTypes:
      - WindowsEvent
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Persistence
  - PrivilegeEscalation
relevantTechniques:
  - T1098
  - T1078
query: |
  // For AD SID mappings - https://docs.microsoft.com/windows/security/identity-protection/access-control/active-directory-security-groups
  let WellKnownLocalSID = "S-1-5-32-5[0-9][0-9]$";
  let WellKnownGroupSID = "S-1-5-21-[0-9]*-[0-9]*-[0-9]*-5[0-9][0-9]$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1102$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1103$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-498$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1000$";
  union isfuzzy=true
  (
  SecurityEvent
  // 4728 - A member was added to a security-enabled global group
  // 4732 - A member was added to a security-enabled local group
  // 4756 - A member was added to a security-enabled universal group
  | where EventID in (4728, 4732, 4756)
  | where AccountType == "User"
  | where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
  // Exclude Remote Desktop Users group: S-1-5-32-555
  | where TargetSid !in ("S-1-5-32-555")
  | extend SimpleMemberName = iff(MemberName == "-", MemberName, substring(MemberName, 3, indexof_regex(MemberName, @",OU|,CN") - 3))
  | project TimeGenerated, EventID, Activity, Computer, SimpleMemberName, MemberName, MemberSid, TargetAccount, TargetUserName, TargetDomainName, TargetSid, UserPrincipalName, 
  SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid
  ),
  (
  WindowsEvent
  // 4728 - A member was added to a security-enabled global group
  // 4732 - A member was added to a security-enabled local group
  // 4756 - A member was added to a security-enabled universal group
  | where EventID in (4728, 4732, 4756) and not(EventData has "S-1-5-32-555")
  | extend SubjectUserSid = tostring(EventData.SubjectUserSid)
  | extend Account =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
  | extend AccountType=case(Account endswith "$" or SubjectUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(SubjectUserSid), "", "User")
  | extend MemberName = tostring(EventData.MemberName)
  | where AccountType == "User"
  | extend TargetSid = tostring(EventData.TargetSid)
  | where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
  // Exclude Remote Desktop Users group: S-1-5-32-555
  | where TargetSid !in ("S-1-5-32-555")
  | extend SimpleMemberName = iff(MemberName == "-", MemberName, substring(MemberName, 3, indexof_regex(MemberName, @",OU|,CN") - 3))
  | extend MemberSid = tostring(EventData.MemberSid)
  | extend TargetUserName = tostring(EventData.TargetUserName), TargetDomainName = tostring(EventData.TargetDomainName), 
  TargetAccount = strcat(tostring(EventData.TargetDomainName),"\\", tostring(EventData.TargetUserName))
  | extend UserPrincipalName = tostring(EventData.UserPrincipalName)
  | extend SubjectUserName = tostring(EventData.SubjectUserName), SubjectDomainName = tostring(EventData.SubjectDomainName), 
  SubjectAccount = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
  | project TimeGenerated, EventID, Computer, SimpleMemberName, MemberName, MemberSid, TargetAccount, TargetUserName, TargetDomainName, TargetSid, UserPrincipalName, 
  SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid
  )
  | extend GroupAddedMemberTo = TargetAccount, AddedByAccount = SubjectAccount, AddedByAccountName = SubjectUserName, AddedByAccountDomainName = SubjectDomainName, 
  AddedByAccountSid = SubjectUserSid, AddedMemberName = SimpleMemberName, AddedMemberSid = MemberSid
  | 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: SubjectAccount
      - identifier: Name
        columnName: SubjectUserName
      - identifier: NTDomain
        columnName: SubjectDomainName
  - entityType: Account
    fieldMappings:
      - identifier: Sid
        columnName: SubjectUserSid
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AddedMemberName
      - identifier: Sid
        columnName: AddedMemberSid
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: NTDomain
        columnName: HostNameDomain
version: 1.3.8
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others", "Identity" ]