Query Details

RULE 10 AD GPO Modified By Non Admin

Query

// =========================================================
// RULE-10 | AD-GPO-Modified-By-NonAdmin
// Description : Group Policy Object (GPO) modification by a
//               non-administrative account — Event 5136
//               (Directory Service Object Modified) on a
//               groupPolicyContainer object where the
//               SubjectUserName is NOT in Domain Admins or
//               Group Policy Creator Owners.
//               GPO write access allows pushing scheduled
//               tasks, startup scripts, local admin group
//               membership, and registry changes to every
//               machine in the linked OU — potentially
//               thousands of endpoints.
// Severity    : High → Critical when linked to high-value OUs
//               (Domain Controllers, Tier-0 servers)
// Frequency   : Every 15 minutes, look-back 15 minutes
// MITRE       : T1484.001 — Group Policy Modification
// Tables      : SecurityEvent
// =========================================================

let LookBack = 15m;

// Known admin groups allowed to modify GPOs
// Update this list to match your environment
let AuthorisedGPOModifiers = datatable(Account:string)
[
    "Group Policy Creator Owners",
    "Domain Admins",
    "Enterprise Admins",
    "SYSTEM"
];

// Collect recent GPO write events
let GPOModEvents = SecurityEvent
    | where TimeGenerated > ago(LookBack)
    | where EventID == 5136
    | where ObjectClass =~ "groupPolicyContainer"
    | where OperationType == "%%14674"              // Write / attribute added/changed
    | extend
        ModifiedAttribute = AttributeLDAPDisplayName,
        GPO_DN            = ObjectDN,
        ActorAccount      = SubjectUserName,
        ActorDomain       = SubjectDomainName;

// Check if actor is in an authorised group via recent 4728 events
let AuthorisedMembers = SecurityEvent
    | where TimeGenerated > ago(30d)
    | where EventID in (4728, 4732, 4756)
    | where TargetUserName has_any ("Group Policy Creator Owners",
                                    "Domain Admins", "Enterprise Admins")
    | summarize by AuthMember = tolower(MemberName);

// Filter out authorised modifiers
GPOModEvents
| extend ActorNorm = tolower(ActorAccount)
| join kind=leftanti (AuthorisedMembers) on $left.ActorNorm == $right.AuthMember
| where not(ActorAccount has_any ("SYSTEM", "S-1-5-18"))
// Flag sensitivity of target OU based on GPO DN
| extend
    TargetHighValueOU = GPO_DN has_any (
        "OU=Domain Controllers", "Tier-0", "Tier0",
        "OU=Servers", "Critical"
    ),
    Severity = case(
        GPO_DN has_any ("Domain Controllers", "Tier-0", "Tier0"), "Critical",
        "High"
    ),
    WhySuspicious = strcat(
        "GPO_Modified_By_NonAdmin; ",
        "GPO: ", GPO_DN, "; ",
        "Attribute: ", ModifiedAttribute, "; ",
        "Actor: ", ActorAccount, "; ",
        iff(TargetHighValueOU, "HighValue_OU_Linked; ", "")
    )
| project
    TimeGenerated,
    Severity,
    WhySuspicious,
    ActorAccount,
    ActorDomain,
    GPO_DN,
    ModifiedAttribute,
    TargetHighValueOU,
    Computer
| order by TimeGenerated desc

Explanation

This query is designed to detect and flag modifications to Group Policy Objects (GPOs) made by non-administrative accounts. Here's a simplified breakdown of what it does:

  1. Purpose: The query identifies instances where a GPO is modified by an account that is not part of the authorized administrative groups. This is important because unauthorized GPO modifications can lead to significant security risks, such as unauthorized changes being pushed to multiple machines.

  2. Authorized Groups: It defines a list of groups that are allowed to modify GPOs, such as "Domain Admins" and "Group Policy Creator Owners". Any account outside these groups making changes is considered suspicious.

  3. Event Monitoring: It looks for specific security events (Event ID 5136) that indicate a GPO modification. It checks these events every 15 minutes, looking back over the last 15 minutes.

  4. Filtering: The query filters out events where the modifying account is part of the authorized groups or is the system account.

  5. Sensitivity and Severity: It assesses the sensitivity of the GPO based on its distinguished name (DN). If the GPO is linked to high-value organizational units (OUs), such as "Domain Controllers" or "Tier-0", the severity is marked as "Critical". Otherwise, it's marked as "High".

  6. Output: The query outputs details of the suspicious activity, including the time, severity, reason for suspicion, the account that made the modification, and the specific GPO and attribute that were changed.

In summary, this query helps in identifying potential security breaches by flagging unauthorized modifications to GPOs, especially those linked to critical parts of the network infrastructure.

Details

David Alonso profile picture

David Alonso

Released: March 24, 2026

Tables

SecurityEvent

Keywords

SecurityEvent

Operators

letdatatable[]ago===~extendsummarizebytolowerjoinkind=leftantionnothas_anycasestrcatiffprojectorder bydesc

Actions