Adversaries may create user accounts to establish persistence and maintain long-term access to a system. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate potential long-term threats and unauthorized access.
KQL Query
// Query #2: Query for accounts created on machines onboarded with Sense.
// Create account event is noisy, so we need to join it with some other signal.
// E.g. In this query we look for accounts created which name resembles "administrator".
// Using account names similar to known common account names is a common way to be evade the human analyst eye.
DeviceEvents
| where ActionType == "UserAccountCreated"
// To look for account names similar to administrator, we'll simply query for the prefix and suffix,
// because these letters matter most to the human perception: https://en.wikipedia.org/wiki/Typoglycemia
// Calculating distance functions is possible but will be much more complicated -
// and looking for prefix and suffix should work in this case pretty well.
| where AccountName startswith "ad" and AccountName endswith "or" and AccountName !~ "administrator"
// Note: For the UserAccountCreated event we do not know the details of the process / account that was used to create this new account.
| project AccountName, AccountDomain, DeviceName, Timestamp
| limit 100
id: eba83f84-b844-4fc9-96f4-cb51b0b20c1d
name: Create account (1)
description: |
User accounts may be created to achieve persistence on a machine.
Read more here: https://attack.mitre.org/wiki/Technique/T1136.
Tags: #CreateAccount.
Query #1: Query for users being created using "net user" command.
"net user" commands are noisy, so needs to be joined with another signal -.
E.g. in this example we look for use of uncommon & undocumented commandline switches (e.g. /ad instead of /add).
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceEvents
query: |2-
// Query #2: Query for accounts created on machines onboarded with Sense.
// Create account event is noisy, so we need to join it with some other signal.
// E.g. In this query we look for accounts created which name resembles "administrator".
// Using account names similar to known common account names is a common way to be evade the human analyst eye.
DeviceEvents
| where ActionType == "UserAccountCreated"
// To look for account names similar to administrator, we'll simply query for the prefix and suffix,
// because these letters matter most to the human perception: https://en.wikipedia.org/wiki/Typoglycemia
// Calculating distance functions is possible but will be much more complicated -
// and looking for prefix and suffix should work in this case pretty well.
| where AccountName startswith "ad" and AccountName endswith "or" and AccountName !~ "administrator"
// Note: For the UserAccountCreated event we do not know the details of the process / account that was used to create this new account.
| project AccountName, AccountDomain, DeviceName, Timestamp
| limit 100
| Sentinel Table | Notes |
|---|---|
DeviceEvents | Ensure this data connector is enabled |
Scenario: Scheduled Job Creating Temporary User for Maintenance
Description: A scheduled job runs nightly to create a temporary user for system maintenance tasks, which is then removed after the job completes.
Filter/Exclusion: useraccountcreated.username != "maintenance_temp_user" or useraccountcreated.account_creation_time > useraccountcreated.account_deletion_time
Scenario: Admin Task to Create User for New Hire
Description: An administrator creates a user account for a new employee using a script or the built-in user management tool (e.g., net user or Add-LocalUser in PowerShell).
Filter/Exclusion: useraccountcreated.creator_user != "admin_account" or useraccountcreated.creator_tool == "Add-LocalUser"
Scenario: Automated Deployment Tool Creating Service Accounts
Description: A deployment tool (e.g., Ansible, Puppet, or Chef) creates a service account during system provisioning to run background services.
Filter/Exclusion: useraccountcreated.creator_tool != "ansible" or useraccountcreated.account_type == "service"
Scenario: User Account Creation via PowerShell Script for Reporting
Description: A PowerShell script is used to create a user account for reporting purposes, such as granting access to a reporting tool (e.g., Power BI or SQL Reporting).
Filter/Exclusion: useraccountcreated.creator_tool == "PowerShell" and useraccountcreated.account_type == "reporting"
Scenario: User Account Created by a Third-Party Application
Description: A third-party application (e.g., a database management tool or SaaS integration) creates a user account to access its service, which is managed by the application itself.
Filter/Exclusion: useraccountcreated.creator_tool == "third_party_app_name" or `useraccountcreated.account_type