Detection rules › Splunk

Windows Default Group Policy Object Modified

Status
production
Severity
medium
Group by
AttributeValue, DSName, ObjectDN, computer_name, dest, user_sid
Author
Mauricio Velazco, Splunk
Source
github.com/splunk/security_content

The following analytic detects modifications to default Group Policy Objects (GPOs) using Event ID 5136. It monitors changes to the Default Domain Controllers Policy and Default Domain Policy, which are critical for enforcing security settings across domain controllers and all users/computers, respectively. This activity is significant because unauthorized changes to these GPOs can indicate an adversary with privileged access attempting to deploy persistence mechanisms or execute malware across the network. If confirmed malicious, such modifications could lead to widespread compromise, allowing attackers to maintain control and execute arbitrary code on numerous hosts.

MITRE ATT&CK coverage

Event coverage

Rule body splunk

name: Windows Default Group Policy Object Modified
id: fe6a6cc4-9e0d-4d66-bcf4-2c7f44860876
version: 13
creation_date: '2023-03-28'
modification_date: '2026-05-13'
author: Mauricio Velazco, Splunk
status: production
type: TTP
description: The following analytic detects modifications to default Group Policy Objects (GPOs) using Event ID 5136. It monitors changes to the `Default Domain Controllers Policy` and `Default Domain Policy`, which are critical for enforcing security settings across domain controllers and all users/computers, respectively. This activity is significant because unauthorized changes to these GPOs can indicate an adversary with privileged access attempting to deploy persistence mechanisms or execute malware across the network. If confirmed malicious, such modifications could lead to widespread compromise, allowing attackers to maintain control and execute arbitrary code on numerous hosts.
data_source:
    - Windows Event Log Security 5136
search: |-
    `wineventlog_security` EventCode=5136 ObjectClass=groupPolicyContainer AttributeLDAPDisplayName=versionNumber (ObjectDN="CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=*" OR ObjectDN="CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=POLICIES,CN=SYSTEM,DC=*")
      | stats min(_time) as firstTime max(_time) as lastTime
        BY ObjectDN SubjectUserSid AttributeValue
           Computer DSName dest
      | rename AttributeValue as versionNumber
      | `security_content_ctime(firstTime)`
      | `security_content_ctime(lastTime)`
      | `windows_default_group_policy_object_modified_filter`
how_to_implement: To successfully implement this search, the Advanced Security Audit policy setting `Audit Directory Service Changes` within `DS Access` needs to be enabled. Furthermore, the appropriate system access control lists (SACL) need to be created as the used events are not logged by default. A good guide to accomplish this can be found here https://jgspiers.com/audit-group-policy-changes/.
known_false_positives: The default Group Policy Objects within an AD network may be legitimately updated for administrative operations, filter as needed.
references:
    - https://attack.mitre.org/techniques/T1484/
    - https://attack.mitre.org/techniques/T1484/001
    - https://www.trustedsec.com/blog/weaponizing-group-policy-objects-access/
    - https://adsecurity.org/?p=2716
drilldown_searches:
    - name: View the detection results for - "$Computer$"
      search: '%original_detection_search% | search  Computer = "$Computer$"'
      earliest_offset: $info_min_time$
      latest_offset: $info_max_time$
    - name: View risk events for the last 7 days for - "$Computer$"
      search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$Computer$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
      earliest_offset: 7d
      latest_offset: "0"
finding:
    title: A default group policy object was modified on $Computer$ by $SubjectUserSid$
    entity:
        field: SubjectUserSid
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: Computer
          type: system
          score: 50
          message: A default group policy object was modified on $Computer$ by $SubjectUserSid$
analytic_story:
    - Active Directory Privilege Escalation
    - Sneaky Active Directory Persistence Tricks
asset_type: Endpoint
mitre_attack_id:
    - T1484.001
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint
tests:
    - name: True Positive Test
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1484.001/default_domain_policy_modified/windows-security.log
          source: XmlWinEventLog:Security
          sourcetype: XmlWinEventLog
      test_type: unit

Stages and Predicates

Stage 1: search

`wineventlog_security` EventCode=5136 ObjectClass=groupPolicyContainer AttributeLDAPDisplayName=versionNumber (ObjectDN="CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=*" OR ObjectDN="CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=POLICIES,CN=SYSTEM,DC=*")

Stage 2: stats

| stats min(_time) as firstTime max(_time) as lastTime
    BY ObjectDN SubjectUserSid AttributeValue
       Computer DSName dest

Stage 3: rename

| rename AttributeValue as versionNumber

Stage 4: search

| `security_content_ctime(firstTime)`

Stage 5: search

| `security_content_ctime(lastTime)`

Stage 6: search

| `windows_default_group_policy_object_modified_filter`

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
AttributeLDAPDisplayNameeq
  • versionNumber corpus 2 (sigma 1, splunk 1)
EventCodeeq
  • 5136 corpus 30 (splunk 24, kusto 5, elastic 1)
ObjectClasseq
  • groupPolicyContainer corpus 6 (sigma 3, splunk 3)
ObjectDNeq
  • "CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=*"
  • "CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=POLICIES,CN=SYSTEM,DC=*"