Query Details

Mac OS User Added To Admin Group

Query

# *macOS User added to Admin Group*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1078.003 | Local Accounts | https://attack.mitre.org/techniques/T1078/003/ |
| T1069.001 | Local Groups | https://attack.mitre.org/techniques/T1069/001/ |

#### Description
This rule detects when a user is added to the local 'admin' group on a macOS system using either the `dscl` or `dseditgroup` command-line utilities. It specifically looks for command-line arguments indicative of adding a user to the 'admin' group. There is a whitelist for legitimate MDM solutions like 'jamfmanager' to reduce false positives.

#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**

#### References
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.003/T1078.003.md#atomic-test-2---create-local-account-with-admin-privileges---macos
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.003/T1078.003.md#atomic-test-5---add-a-newexisting-user-to-the-admin-group-using-dseditgroup-utility---macos

## Defender XDR
```KQL
//if you are using an MDM Solution whitelist in the following line
let legitimAdmin = dynamic(["jamfmanager"]); 
//User Added To Admin Group Via Dscl
//https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.003/T1078.003.md#atomic-test-2---create-local-account-with-admin-privileges---macos
let NewAdminDSCL = DeviceProcessEvents
| where FileName == "dscl"
| where ProcessCommandLine has_all ("-append", "/Groups/admin", "GroupMembership")
| extend Activity = "User Added To Admin Group Via Dscl";
//User Added To Admin Group Via DseditGroup
//https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1078.003/T1078.003.md#atomic-test-5---add-a-newexisting-user-to-the-admin-group-using-dseditgroup-utility---macos
let NewAdminDSEDIT = DeviceProcessEvents
| where FileName == "dseditgroup"
| where ProcessCommandLine has_all ("-o edit", "-a", "-t", "admin")
| where not(ProcessCommandLine has_any (legitimAdmin))
| extend Activity = "User Added To Admin Group Via Dseditgroup";
//Root Account Enable Via Dsenableroot
NewAdminDSCL
| union NewAdminDSEDIT
```

Explanation

This query is designed to detect when a user is added to the local 'admin' group on a macOS system. It focuses on identifying the use of specific command-line utilities (dscl and dseditgroup) that can add users to the 'admin' group. Here's a simple breakdown of what the query does:

  1. Whitelist Legitimate Tools: It starts by defining a list of legitimate tools (like 'jamfmanager') that might add users to the admin group as part of normal operations, to avoid false positives.

  2. Detecting dscl Usage:

    • It checks for processes where the dscl command is used with specific arguments (-append, /Groups/admin, GroupMembership) that indicate a user is being added to the admin group.
    • If such a process is found, it labels the activity as "User Added To Admin Group Via Dscl".
  3. Detecting dseditgroup Usage:

    • It looks for processes using the dseditgroup command with arguments (-o edit, -a, -t, admin) that suggest a user is being added to the admin group.
    • It excludes processes that involve any of the whitelisted legitimate tools.
    • If such a process is found, it labels the activity as "User Added To Admin Group Via Dseditgroup".
  4. Combining Results:

    • It combines the results from both detections (dscl and dseditgroup) to provide a comprehensive view of any suspicious activity related to adding users to the admin group.

Overall, this query helps in monitoring and alerting on potentially unauthorized changes to the admin group on macOS systems, which could be indicative of malicious activity.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: October 28, 2025

Tables

DeviceProcessEvents

Keywords

MacOSUserAdminGroupDevicesProcessEvents

Operators

letdynamic|where==has_allextendhas_anynotunion

Actions