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.[1] 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. However, account manipulation may also lead to privilege escalation where modifications grant access to additional roles, permissions, or higher-privileged Valid Accounts.
73rd pctamong all ATT&CK techniques for number of groups
5 groups have been recorded using this technique. Newest first; each entry carries MITRE’s procedure text and a link to the group’s full record. Click a name to filter the rules below.
Has leveraged access to administrative control systems to achieve disruptive effects, consistent with administrative account abuse or privilege escalation within existing access.12
3 software entries are documented implementing this technique. MITRE files each as a tool or as malware; newest first, then by how many groups carry them.
The Mimikatz credential dumper has been extended to include Skeleton Key domain controller authentication bypass functionality. The LSADUMP::ChangeNTLM and LSADUMP::SetNTLM modules can also manipulate the password hash of an account without knowing the clear text value.12
created 2017-05-31TOOLcarried by 51 groups
All 3 software entries for this technique
Offense vs defense T1098
Compare defenses against adversary use. Eight counts, ranking this technique against the entire ATT&CK Enterprise matrix. Attack sits left, defense right.
Range
Technique Campaign use over its cumulative rule count.
MITRE names one behaviour worth catching for this technique and breaks it into 6 analytics, one per platform. Each carries the log sources it needs and the fields you tune per environment.
Account Manipulation Behavior Chain Detection
Enterprise
6 platforms
AN0265 · Windows
Account attribute changes (e.g., password set, group membership, servicePrincipalName, logon hours) correlated with unusual process lineage or timing, indicating privilege escalation or persistence via valid accounts.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
Field
What you tune
TimeWindow
Time between suspicious process and account change (e.g., 5m).
HighPrivilegeGroupList
Customize group list (e.g., Domain Admins, Enterprise Admins) to monitor.
SubjectTargetMismatch
Flag if account modifier != modified user (potential hijack).
AN0266 · Linux
Use of native tools or scripting (e.g., usermod, passwd, groupmod) to escalate permissions or persist access on existing users, correlated with login or process events.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
Field
What you tune
SudoPath
Common sudo or privilege escalation paths (e.g., /usr/bin/passwd).
ModifiedShellList
Detect if user shell is changed to unusual one (e.g., /bin/sh -> /bin/bash).
AN0267 · macOS
Modifications to user accounts via dscl, pwpolicy, or System Preferences CLI (sysadminctl) that alter user groups, enable root, or bypass MDM restrictions.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
Field
What you tune
SharingSensitivityLabel
Threshold for labeling sensitive document access escalation.
CrossOrgChanges
Track changes made across organizational boundaries (e.g., guest users).
1 analytic
Certain commands are frequently used by malicious actors and infrequently used by normal users. By looking for execution of these commands in short periods of time, we can not only see when a malicious user was on the system but also get an idea of what they were doing.
TypeTTPCoverageLowSubmitted2013
D3FEND techniques
The defensive countermeasure this analytic implements, in MITRE’s D3FEND ontology.
Pseudocode is the canonical logic; the rest are CAR’s translations into vendor query languages.
processes = search Process:Create
reg_processes = filter processes where (exe == "arp.exe" or exe == "at.exe" or exe == "attrib.exe"
or exe == "cscript.exe" or exe == "dsquery.exe" or exe == "hostname.exe"
or exe == "ipconfig.exe" or exe == "mimikatz.exe" or exe == "nbstat.exe"
or exe == "net.exe" or exe == "netsh.exe" or exe == "nslookup.exe"
or exe == "ping.exe" or exe == "quser.exe" or exe == "qwinsta.exe"
or exe == "reg.exe" or exe == "runas.exe" or exe == "sc.exe"
or exe == "schtasks.exe" or exe == "ssh.exe" or exe == "systeminfo.exe"
or exe == "taskkill.exe" or exe == "telnet.exe" or exe == "tracert.exe"
or exe == "wscript.exe" or exe == "xcopy.exe")
reg_grouped = group reg by hostname, ppid where(max time between two events is 30 minutes)
output reg_grouped
Sigma version of the above pseudocode, with some modifications.
DNIF version of the above pseudocode.
_fetch * from event where $LogName=WINDOWS-SYSMON AND $EventID=1 AND $App=regex(arp\.exe|at\.exe|attrib\.exe|cscript\.exe|dsquery\.exe|hostname\.exe|ipconfig\.exe|mimikatz.exe|nbstat\.exe|net\.exe|netsh\.exe|nslookup\.exe|ping\.exe|quser\.exe|qwinsta\.exe|reg\.exe|runas\.exe|sc\.exe|schtasks\.exe|ssh\.exe|systeminfo\.exe|taskkill\.exe|telnet\.exe|tracert\.exe|wscript\.exe|xcopy\.exe)i group count_unique $App limit 100
>>_agg count
>>_checkif int_compare Count > 1 include
Configure access controls and firewalls to limit access to critical systems and domain controllers. Most cloud environments support separate virtual private cloud (VPC) instances that enable further segmentation of cloud systems.
Protect domain controllers by ensuring proper security configuration for critical servers to limit access by potentially unnecessary protocols and services, such as SMB file sharing.
Create a random atr-nnnnnnnn account and add it to a domain group (by default, Domain Admins).
The quickest way to run it is against a domain controller, using -Session of Invoke-AtomicTest. Alternatively,
you need to install PS Module ActiveDirectory (in prereqs) and run the script with appropriare AD privileges to
create the user and alter the group. Automatic installation of the dependency requires an elevated session,
and is unlikely to work with Powershell Core (untested).
If you consider running this test against a production Active Directory, the good practise is to create a dedicated
service account whose delegation is given onto a dedicated OU for user creation and deletion, as well as delegated
as group manager of the target group.
Example: Invoke-AtomicTest -Session $session 'T1098' -TestNames "Domain Account and Group Manipulate" -InputArgs @{"group" = "DNSAdmins" }
Inputs
Name
Description
Type
Default Value
group
Name of the group to alter
string
Domain Admins
create_args
Additional string appended to New-ADUser call
string
account_prefix
Prefix string of the random username (by default, atr-). Because the cleanup deletes such account based on
a match `(&(samaccountname=#{account_prefix}-*)(givenName=Test))`, if you are to change it, be careful.
Adversaries create AWS group, add users to specific to that group to elevate their privileges to gain more accesss
Inputs
Name
Description
Type
Default Value
username
Name of the AWS group to create
string
atomicredteam
Attack Commandsrun with sh
aws iam create-group --group-name #{username}
aws iam add-user-to-group --user-name #{username} --group-name #{username}
Cleanup Commands
aws iam remove-user-from-group --user-name #{username} --group-name #{username}
aws iam delete-group --group-name #{username}
Dependencies
Description
Check if the user exists, we can only add a user to a group if the user exists.
Check Prereq Commands
aws iam list-users | grep #{username}
Get Prereq Commands
echo Please run atomic test T1136.003, before running this atomic test
GUID8822c3b0-d9f9-4daf-a043-49f110a31122
04
Azure AD - adding user to Azure AD role
azure-ad
powershell
—
1
Yes
The adversaries want to add user to some Azure AD role. Threat actor
may be interested primarily in highly privileged roles, e.g. Global Administrator, Application Administrator,
Privileged Authentication Administrator (this role can reset Global Administrator password!).
By default, the role Global Reader is assigned to the user principal in this test.
The account you use to run the PowerShell command should have Privileged Role Administrator or Global Administrator role in your Azure AD.
Detection hint - check Activity "Add member to role" in Azure AD Audit Logs. In targer you will also see User as a type.
Inputs
Name
Description
Type
Default Value
password
Azure AD password
string
p4sswd
username
Azure AD username
string
jonh@contoso.com
role_name
Name of the targeted Azure AD role
string
Global Reader
user_principal_name
Display Name, or User Principal Name, of the targeted user principal
Azure AD - adding service principal to Azure AD role
azure-ad
powershell
—
1
Yes
The adversaries want to add service principal to some Azure AD role. Threat actor
may be interested primarily in highly privileged roles, e.g. Global Administrator, Application Administrator,
Privileged Authentication Administrator (this role can reset Global Administrator password!).
By default, the role Global Reader is assigned to service principal in this test.
The account you use to run the PowerShell command should have Privileged Role Administrator or Global Administrator role in your Azure AD.
Detection hint - check Activity "Add member to role" in Azure AD Audit Logs. In targer you will also see Service Principal as a type.
Inputs
Name
Description
Type
Default Value
password
Azure AD password
string
p4sswd
username
Azure AD username
string
jonh@contoso.com
role_name
Name of the targeted Azure AD role
string
Global Reader
service_principal_name
Name of the service principal
string
SuperSP
Attack Commandsrun with powershell
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential
$sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '#{service_principal_name}'"
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$role = Get-AzureADDirectoryRole -Filter "DisplayName eq '#{role_name}'"
if ($role -eq $null) { Write-Warning "Role not found"; exit }
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $sp.ObjectId
Write-Host "Service Principal $($sp.DisplayName) was added to $($role.DisplayName)"
Cleanup Commands
Import-Module -Name AzureAD -ErrorAction Ignore
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential -ErrorAction Ignore
$sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '#{service_principal_name}'"
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$role = Get-AzureADDirectoryRole -Filter "DisplayName eq '#{role_name}'"
if ($role -eq $null) { Write-Warning "Role not found"; exit }
Remove-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -MemberId $sp.ObjectId
Write-Host "Service Principal $($sp.DisplayName) was removed from $($role.DisplayName) role"
The adversaries want to add user to some Azure role, also called Azure resource role. Threat actor
may be interested primarily in highly privileged roles, e.g. Owner, Contributor.
By default, the role Reader is assigned to user in this test.
New-AzRoleAssignment cmdlet could be also use to assign user/service principal to resource, resource group and management group.
The account you use to run the PowerShell command must have Microsoft.Authorization/roleAssignments/write
(e.g. such as User Access Administrator or Owner) and the Azure Active Directory Graph Directory.Read.All
and Microsoft Graph Directory.Read.All permissions.
Detection hint - check Operation Name "Create role assignment" in subscriptions Activity Logs.
Inputs
Name
Description
Type
Default Value
password
Azure AD password
string
p4sswd
username
Azure AD username
string
jonh@contoso.com
role_name
Name of the targeted Azure role
string
Reader
subscription
Name of the targeted subscription
string
Azure subscription 1
user_principal_name
Display Name, or User Principal Name, of the targeted user principal
Azure - adding service principal to Azure role in subscription
iaas:azure
powershell
—
1
Yes
The adversaries want to add service principal to some Azure role, also called Azure resource role. Threat actor
may be interested primarily in highly privileged roles, e.g. Owner, Contributor.
By default, the role Reader is assigned to service principal in this test.
New-AzRoleAssignment cmdlet could be also use to assign user/service principal to resource, resource group and management group.
The account you use to run the PowerShell command must have Microsoft.Authorization/roleAssignments/write
(e.g. such as User Access Administrator or Owner) and the Azure Active Directory Graph Directory.Read.All
and Microsoft Graph Directory.Read.All permissions.
Detection hint - check Operation Name "Create role assignment" in subscriptions Activity Logs.
Inputs
Name
Description
Type
Default Value
password
Azure AD password
string
p4sswd
username
Azure AD username
string
jonh@contoso.com
role_name
Name of the targeted Azure role
string
Reader
subscription
Name of the targeted subscription
string
Azure subscription 1
service_principal_name
Name of the service principal
string
SuperSP
Attack Commandsrun with powershell
Import-Module -Name Az.Resources
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzAccount -Credential $Credential
$sp = Get-AzADServicePrincipal | where-object {$_.DisplayName -eq "#{service_principal_name}"}
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$subscription = Get-AzSubscription | where-object {$_.Name -eq "#{subscription}"}
if ($subscription -eq $null) { Write-Warning "Subscription not found"; exit }
$role = Get-AzRoleDefinition | where-object {$_.Name -eq "#{role_name}"}
if ($role -eq $null) { Write-Warning "Role not found"; exit }
New-AzRoleAssignment -ObjectId $sp.id -RoleDefinitionId $role.id -Scope /subscriptions/$subscription
Write-Host "Service Principal $($sp.DisplayName) was added to $($role.Name) role in subscriptions $($subscriptions.Name)"
Cleanup Commands
Import-Module -Name AzureAD -ErrorAction Ignore
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzAccount -Credential $Credential -ErrorAction Ignore
$sp = Get-AzADServicePrincipal | where-object {$_.DisplayName -eq "#{service_principal_name}"}
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
$subscription = Get-AzSubscription | where-object {$_.Name -eq "#{subscription}"}
if ($subscription -eq $null) { Write-Warning "Subscription not found"; exit }
$role = Get-AzRoleDefinition | where-object {$_.Name -eq "#{role_name}"}
if ($role -eq $null) { Write-Warning "Role not found"; exit }
Remove-AzRoleAssignment -ObjectId $sp.id -RoleDefinitionId $role.id -Scope /subscriptions/$subscription
Write-Host "Service Principal $($sp.DisplayName) was removed from $($role.Name) role in subscriptions $($subscriptions.Name)"
The adversaries want to add permission to newly created application. Application could be then used for persistence or for further operation in the attacked infrastructure. Permissions like AppRoleAssignment.ReadWrite.All or RoleManagement.ReadWrite.Directory in particular can be a valuable target for a threat actor.
This technique will create a new app, with the provided name, and give it the provided permission. But if you prefer to add credentials to an existing app, replace in the code: "Get-AzureADApplication" instead of "New-AzureADServicePrincipal".
The DirectoryRecommendations.Read.All permissions has been selected as the default.
The account you use to run the PowerShell command should have Global Administrator/Application Administrator/Cloud Application Administrator role in your Azure AD.
Detection hint - check Operation Name "Add app role assignment to service principal" in subscriptions Activity Logs.
You can also take a look at the materials:
https://learnsentinel.blog/2022/01/04/azuread-privesc-sentinel/
https://github.com/reprise99/Sentinel-Queries
https://docs.google.com/presentation/d/1AWx1w0Xcq8ENvOmSjAJswEgEio-il09QWZlGg9PbHqE/edit#slide=id.g10460eb209c_0_2766
https://gist.github.com/andyrobbins/7c3dd62e6ed8678c97df9565ff3523fb
Inputs
Name
Description
Type
Default Value
password
Azure AD password
string
p4sswd
username
Azure AD username
string
jonh@contoso.com
application_name
Name of the targeted application that will be created
string
test_app
application_permission
Permission from Microsoft Graph Resource API that will be added to application
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default value is 7 characters)
string
Uplow-1
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUIDfc5f9414-bd67-4f5f-a08e-e5381e29cbd1
11
Domain Password Policy Check: No Number in Password
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default is long and has upper and lower case and special character but no number)
string
UpperLowerLong-special
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUID68190529-069b-4ffc-a942-919704158065
12
Domain Password Policy Check: No Special Character in Password
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default is long and has upper and lower case and number but no special character)
string
UpperLowerLong333noSpecialChar
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUID7d984ef2-2db2-4cec-b090-e637e1698f61
13
Domain Password Policy Check: No Uppercase Character in Password
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default is long and has and lower case and special character and number but no uppercase)
string
lower-long-special-333
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUIDb299c120-44a7-4d68-b8e2-8ba5a28511ec
14
Domain Password Policy Check: No Lowercase Character in Password
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default is long and has and upper case and special character and number but no lowercase)
string
UPPER-LONG-SPECIAL-333
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUID945da11e-977e-4dab-85d2-f394d03c5887
15
Domain Password Policy Check: Only Two Character Classes
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default has only upper and lower case characters)
string
onlyUPandLowChars
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUID784d1349-5a26-4d20-af5e-d6af53bae460
16
Domain Password Policy Check: Common Password Use
windows
powershell
—
1
—
Attempt to change the password of the current domain user in order to check password policy. Ideally, you would only run this atomic test to verify that your password policy is blocking the use of the new password.
If the password is succesfully changed to the new password, the credential file will be updated to reflect the new password. You can then run the atomic manually and specify a new password of your choosing, however the
password policy will likely prevent you from setting the password back to what it was.
Inputs
Name
Description
Type
Default Value
cred_file
A file containing the password of the current user
path
$env:LOCALAPPDATA\AtomicRedTeam\$env:USERNAME.txt
new_password
The password to set for the current domain user (default is Season and current year combo)
string
Spring$((Get-Date).Year)!
Attack Commandsrun with powershell
$credFile = "#{cred_file}"
if (Test-Path $credFile) {
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, (Get-Content $credFile | ConvertTo-SecureString)
if($cred.GetNetworkCredential().Password -eq "#{new_password}"){
Write-Host -ForegroundColor Yellow "The new password is the same as the password stored in the credential file. Please specify a different new password."; exit -1
}
try {
$newPassword = ConvertTo-SecureString #{new_password} -AsPlainText -Force
Set-ADAccountPassword -Identity $env:USERNAME -OldPassword $cred.password -NewPassword $newPassword
}
catch {
$_.Exception
$errCode = $_.Exception.ErrorCode
Write-Host "Error code: $errCode"
if ($errCode -eq 86) {
Write-Host -ForegroundColor Yellow "The stored password for the current user is incorrect. Please run the prereq commands to set the correct credentials"
Remove-Item $credFile
}
exit $errCode
}
Write-Host -ForegroundColor Cyan "Successfully changed the password to #{new_password}"
$newCred = New-Object System.Management.Automation.PSCredential ($env:USERNAME, $(ConvertTo-SecureString "#{new_password}" -AsPlainText -Force))
$newCred.Password | ConvertFrom-SecureString | Out-File $credFile
}
else {
Write-Host -ForegroundColor Yellow "You must store the password of the current user by running the prerequisite commands first"
}
Dependencies
Description
Password for current user must be stored in a credential file
Check Prereq Commands
if (Test-Path #{cred_file}) {exit 0} else {exit 1}
Get Prereq Commands
New-Item -Type Directory (split-path "#{cred_file}") -ErrorAction Ignore | Out-Null
$cred = Get-Credential -UserName $env:USERNAME -message "Enter password for $env:USERNAME to use during password change attempt"
$cred.Password | ConvertFrom-SecureString | Out-File "#{cred_file}"
GUID81959d03-c51f-49a1-bb24-23f1ec885578
17
GCP - Delete Service Account Key
iaas:gcp
sh
—
4
Yes
This Atomic will:
- Create a service account
- Create a service account key,
- Store the result of retrieving a single key for that service account as a variable
- Pass that variable for deletion
- Delete the service account
The idea for this Atomic came from a Rule published by the Elastic team.
Identifies the deletion of an Identity and Access Management (IAM) service account key in Google Cloud Platform (GCP).
Each service account is associated with two sets of public/private RSA key pairs that are used to authenticate.
If a key is deleted, the application will no longer be able to access Google Cloud resources using that key. A security best practice is to rotate your service account keys regularly.
Reference: https://github.com/elastic/detection-rules/blob/main/rules/integrations/gcp/impact_gcp_storage_bucket_deleted.toml
Inputs
Name
Description
Type
Default Value
project_id
ID of the GCP Project you to execute the command against.
string
atomic-test-1
service_name
The name of the service account.
string
atomic-service-account
Attack Commandsrun with sh
gcloud config set project #{project_id}
KEY=`gcloud iam service-accounts keys list --iam-account=#{service_name}@#{project_id}.iam.gserviceaccount.com --format="value(KEY_ID)" --limit=1`
gcloud iam service-accounts keys delete $KEY --iam-account=#{service_name}@#{project_id}.iam.gserviceaccount.com --quiet
Cleanup Commands
cd "$PathToAtomicsFolder/T1098/src/T1098-17/"
terraform state rm google_service_account_key.key
terraform destroy -auto-approve
Dependenciesrun with sh
Description
Requires gcloud
Check Prereq Commands
if [ -x "$(command -v gcloud)" ]; then exit 0; else exit 1; fi;
Get Prereq Commands
echo "Please Install Google Cloud SDK before running this atomic test : https://cloud.google.com/sdk/docs/install"
Description
Check if user is logged in
Check Prereq Commands
gcloud config get-value account
Get Prereq Commands
gcloud auth login --no-launch-browser
Description
Check if terraform is installed.
Check Prereq Commands
terraform version
Get Prereq Commands
echo Please install the terraform.
Description
Create dependency resources using terraform
Check Prereq Commands
stat "$PathToAtomicsFolder/T1098/src/T1098-17/terraform.tfstate"
Get Prereq Commands
cd "$PathToAtomicsFolder/T1098/src/T1098-17/"
terraform init
terraform apply -auto-approve
Detects scenario where if a user is assigned the SeEnableDelegationPrivilege right in Active Directory it would allow control of other AD user objects.
Detects modifications to the msDS-ManagedAccountPrecededByLink attribute, which may indicate an attempted or successful abuse of the BaD-Successor msDS-DelegatedManagedServiceAccount (DMSA) vulnerability. (...)
Detects the creation of new msDS-DelegatedManagedServiceAccount objects, which could indicate potential abuse of privilege escalation vulnerabilities in Windows Server 2025. (...)
The following analytic identifies instances where a new owner is assigned to an application registration within an Azure AD and Office 365 tenant. (...)
The following analytic detects the deletion of more than five unique Windows accounts within a 10-minute period, using Event Code 4726 from the Windows Security Event Log. (...)
The following analytic identifies instances where more than five unique Windows accounts are disabled within a 10-minute window, as indicated by Event Code 4725 in the Windows Security Event Log. (...)