Account Manipulation
Adversaries may manipulate accounts to maintain and/or elevate access to victim systems. Account manipulation may consist of any action that preserves or modifies adversary access to a compromised account, such as modifying credentials or permission groups. These actions could also include account activity designed to subvert security policies, such as performing iterative password updates to bypass password duration policies and preserve the life of compromised credentials. In order to create or manipulate accounts, the adversary must already have sufficient permissions on systems or the domain. Account manipulation may also lead to privilege escalation where modifications grant access to additional roles, permissions, or higher-privileged Valid Accounts.
// T1098 — Account Manipulation: Detects suspicious account property changes, privilege assignments, and group membership modifications
let SensitiveGroups = dynamic(["Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators", "Account Operators", "Backup Operators", "Print Operators", "Server Operators", "Group Policy Creator Owners", "Remote Management Users", "ESX Admins"]);
let LookbackWindow = 1d;
union
(
// 4738 - User account changed (password reset, UserAccountControl changes, etc.)
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4738
| extend TargetAccount = TargetUserName, ChangedBy = SubjectUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = "UserAccountModified"
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
),
(
// 4670 - Account permissions changed
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4670
| extend TargetAccount = TargetUserName, ChangedBy = SubjectUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = "PermissionsChanged"
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
),
(
// 4732 - Member added to security-enabled local group
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4732
| extend TargetAccount = MemberName, ChangedBy = SubjectUserName
| extend GroupName = TargetUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = strcat("AddedToGroup:", GroupName)
| where GroupName in~ (SensitiveGroups)
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
),
(
// 4728 - Member added to security-enabled global group
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4728
| extend TargetAccount = MemberName, ChangedBy = SubjectUserName
| extend GroupName = TargetUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = strcat("AddedToGlobalGroup:", GroupName)
| where GroupName in~ (SensitiveGroups)
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
),
(
// 4756 - Member added to security-enabled universal group
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4756
| extend TargetAccount = MemberName, ChangedBy = SubjectUserName
| extend GroupName = TargetUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = strcat("AddedToUniversalGroup:", GroupName)
| where GroupName in~ (SensitiveGroups)
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
),
(
// 4648 - Logon using explicit credentials after account change (potential Skeleton Key)
SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID == 4648
| extend TargetAccount = TargetUserName, ChangedBy = SubjectUserName
| extend AccountDomain = TargetDomainName
| extend ChangeType = "ExplicitCredentialLogon"
| where SubjectUserName != TargetUserName
| project TimeGenerated, EventID, TargetAccount, ChangedBy, AccountDomain, ChangeType, Computer, _SubscriptionId
)
| summarize EventCount=count(), EventTypes=make_set(ChangeType), AffectedAccounts=make_set(TargetAccount), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by ChangedBy, Computer
| where EventCount >= 1
| extend RiskScore = case(
EventCount >= 10, "High",
EventCount >= 3, "Medium",
"Low"
)
| sort by EventCount desc Data Sources
Required Tables
False Positives
- IT administrators performing legitimate account provisioning or group membership changes during onboarding or role transitions
- Automated identity management systems (SailPoint, Saviynt, AD Connect) performing scheduled sync operations that generate bulk account modification events
- Help desk staff performing password resets or account unlock operations which generate 4738 events
- Group Policy or SCCM deployments that modify local group membership across endpoints as part of standard configuration management
- Scheduled account maintenance scripts that iterate through stale accounts and modify their properties
References (10)
- https://attack.mitre.org/techniques/T1098/
- https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4738
- https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4670
- https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4732
- https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738
- https://blog.stealthbits.com/manipulating-user-passwords-with-mimikatz-SetNTLM-ChangeNTLM
- https://github.com/gentilkiwi/mimikatz/issues/92
- https://www.fireeye.com/blog/threat-research/2021/06/darkside-affiliate-supply-chain-software-compromise.html
- https://www.volexity.com/blog/2021/03/01/the-mass-exploitation-of-on-premises-exchange-servers/
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1098/T1098.md
Unlock Pro Content
Get the full detection package for T1098 including response playbook, investigation guide, and atomic red team tests.