Detection rules › Splunk

Windows Privilege Escalation Suspicious Process Elevation

Status
production
Severity
medium
Group by
IntegrityLevel, command_line, computer_name, dest, event_action, join_guid, original_file_name, parent_command_line, parent_process_guid, parent_process_id, parent_process_name, process_guid, process_hash, process_id, process_name, user, user_id, vendor_product
Author
Steven Dick
Source
github.com/splunk/security_content

The following analytic detects when a process running with low or medium integrity from a user account spawns an elevated process with high or system integrity in suspicious locations. This behavior is identified using process execution data from Windows process monitoring. This activity is significant as it may indicate a threat actor successfully elevating privileges, which is a common tactic in advanced attacks. If confirmed malicious, this could allow the attacker to execute code with higher privileges, potentially leading to full system compromise and persistent access.

MITRE ATT&CK coverage

Event coverage

ProviderEventTitle
SysmonEvent ID 1Process creation

Rule body splunk

name: Windows Privilege Escalation Suspicious Process Elevation
id: 6a80300a-9f8a-4f22-bd3e-09ca577cfdfc
version: 12
creation_date: '2024-02-14'
modification_date: '2026-05-13'
author: Steven Dick
status: production
type: TTP
description: |
    The following analytic detects when a process running with low or medium integrity from a user account spawns an elevated process with high or system integrity in suspicious locations.
    This behavior is identified using process execution data from Windows process monitoring.
    This activity is significant as it may indicate a threat actor successfully elevating privileges, which is a common tactic in advanced attacks.
    If confirmed malicious, this could allow the attacker to execute code with higher privileges, potentially leading to full system compromise and persistent access.
data_source:
    - Sysmon EventID 1 AND Sysmon EventID 1
search: |-
    | tstats `security_content_summariesonly`
      count min(_time) as firstTime
    
    from datamodel=Endpoint.Processes where
    
    Processes.process_integrity_level IN ("low","medium","high")
    NOT Processes.user IN ("*SYSTEM","*LOCAL SERVICE","*NETWORK SERVICE","DWM-*","*$")
    
    by Processes.action Processes.dest Processes.original_file_name
       Processes.parent_process Processes.parent_process_exec
       Processes.parent_process_guid Processes.parent_process_id
       Processes.parent_process_name Processes.parent_process_path
       Processes.process Processes.process_exec Processes.process_guid
       Processes.process_hash Processes.process_id
       Processes.process_integrity_level Processes.process_name
       Processes.process_path Processes.user Processes.user_id
       Processes.vendor_product
    
    | `drop_dm_object_name(Processes)`
    | eval join_guid = process_guid,
           integrity_level = CASE(
                match(process_integrity_level,"low"),1,
                match(process_integrity_level,"medium"),2,
                match(process_integrity_level,"high"),3,
                match(process_integrity_level,"system"),4,
                true(),0
            )
    | rename user as src_user,
             parent_process* as orig_parent_process*,
             process* as parent_process*
    
    | join max=0 dest join_guid [
        | tstats `security_content_summariesonly`
          count max(_time) as lastTime
    
        from datamodel=Endpoint.Processes where
    
        (
            Processes.process_integrity_level IN ("system")
            NOT Processes.user IN (
                    "*SYSTEM",
                    "*LOCAL SERVICE",
                    "*NETWORK SERVICE",
                    "DWM-*",
                    "*$"
                )
        )
        OR
        (
            Processes.process_integrity_level IN (
                "high",
                "system"
            )
            (
                Processes.parent_process_path IN (
                    "*\\\\*",
                    "*\\Users\\*",
                    "*\\Temp\\*",
                    "*\\ProgramData\\*"
                )
                OR
                Processes.process_path IN (
                    "*\\\\*",
                    "*\\Users\\*",
                    "*\\Temp\\*",
                    "*\\ProgramData\\*"
                )
            )
        )
    
        by Processes.dest Processes.user Processes.parent_process_guid
           Processes.process_name Processes.process
           Processes.process_path Processes.process_integrity_level
           Processes.process_current_directory
    
        | `drop_dm_object_name(Processes)`
    
        | eval elevated_integrity_level = CASE(
                    match(process_integrity_level,"low"),1,
                    match(process_integrity_level,"medium"),2,
                    match(process_integrity_level,"high"),3,
                    match(process_integrity_level,"system"),4,
                    true(),0
                )
        | rename parent_process_guid as join_guid
    ]
    
    | where
        elevated_integrity_level > integrity_level
        OR
        user != elevated_user
    
    | fields dest user src_user parent_process_name parent_process
             parent_process_path parent_process_guid
             parent_process_integrity_level parent_process_current_directory
             process_name process process_path process_guid
             process_integrity_level process_current_directory
             orig_parent_process_name orig_parent_process
             orig_parent_process_guid firstTime lastTime count
    
    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `windows_privilege_escalation_suspicious_process_elevation_filter`
how_to_implement: |-
    Target environment must ingest process execution data sources such as Windows process monitoring and/or Sysmon EID 1.
known_false_positives: |-
    False positives may be generated by administrators installing benign applications using run-as/elevation.
references:
    - https://attack.mitre.org/techniques/T1068/
    - https://vuls.cert.org/confluence/display/Wiki/2021/06/21/Finding+Privilege+Escalation+Vulnerabilities+in+Windows+using+Process+Monitor
    - https://redcanary.com/blog/getsystem-offsec/
    - https://atomicredteam.io/privilege-escalation/T1134.001/
drilldown_searches:
    - name: View the detection results for - "$dest$" and "$user$"
      search: '%original_detection_search% | search  dest = "$dest$" user = "$user$" src_user = "$src_user$"'
      earliest_offset: $info_min_time$
      latest_offset: $info_max_time$
    - name: View risk events for the last 7 days for - "$dest$" and "$user$"
      search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$", "$user$", "$src_user$") | 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: The user $src_user$ launched a process [$parent_process_name$] which spawned a suspicious elevated integrity process [$process_name$].
    entity:
        field: src_user
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: dest
          type: system
          score: 50
          message: The user $src_user$ launched a process [$parent_process_name$] which spawned a suspicious elevated integrity process [$process_name$].
threat_objects:
    - field: process_name
      type: process_name
analytic_story:
    - Windows Privilege Escalation
    - BlackSuit Ransomware
    - GhostRedirector IIS Module and Rungan Backdoor
asset_type: Endpoint
mitre_attack_id:
    - T1068
    - T1548
    - T1134
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint
tests:
    - attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1068/windows_escalation_behavior/windows_escalation_behavior_sysmon.log
          source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
          sourcetype: XmlWinEventLog
      name: True Positive Test
      test_type: unit

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly`
  count min(_time) as firstTime

from datamodel=Endpoint.Processes where

Processes.process_integrity_level IN ("low","medium","high")
NOT Processes.user IN ("*SYSTEM","*LOCAL SERVICE","*NETWORK SERVICE","DWM-*","*$")

by Processes.action Processes.dest Processes.original_file_name
   Processes.parent_process Processes.parent_process_exec
   Processes.parent_process_guid Processes.parent_process_id
   Processes.parent_process_name Processes.parent_process_path
   Processes.process Processes.process_exec Processes.process_guid
   Processes.process_hash Processes.process_id
   Processes.process_integrity_level Processes.process_name
   Processes.process_path Processes.user Processes.user_id
   Processes.vendor_product

Stage 2: search

| `drop_dm_object_name(Processes)`

Stage 3: eval

| eval join_guid = process_guid,
       integrity_level = CASE(
            match(process_integrity_level,"low"),1,
            match(process_integrity_level,"medium"),2,
            match(process_integrity_level,"high"),3,
            match(process_integrity_level,"system"),4,
            true(),0
        )
integrity_level =
ifmatch(process_integrity_level, "low")1
elifmatch(process_integrity_level, "medium")2
elifmatch(process_integrity_level, "high")3
elifmatch(process_integrity_level, "system")4
else0

Stage 4: rename

| rename user as src_user,
         parent_process* as orig_parent_process*,
         process* as parent_process*

Stage 5: join

| join max=0 dest join_guid [
    | tstats `security_content_summariesonly`
      count max(_time) as lastTime

    from datamodel=Endpoint.Processes where

    (
        Processes.process_integrity_level IN ("system")
        NOT Processes.user IN (
                "*SYSTEM",
                "*LOCAL SERVICE",
                "*NETWORK SERVICE",
                "DWM-*",
                "*$"
            )
    )
    OR
    (
        Processes.process_integrity_level IN (
            "high",
            "system"
        )
        (
            Processes.parent_process_path IN (
                "*\\\\*",
                "*\\Users\\*",
                "*\\Temp\\*",
                "*\\ProgramData\\*"
            )
            OR
            Processes.process_path IN (
                "*\\\\*",
                "*\\Users\\*",
                "*\\Temp\\*",
                "*\\ProgramData\\*"
            )
        )
    )

    by Processes.dest Processes.user Processes.parent_process_guid
       Processes.process_name Processes.process
       Processes.process_path Processes.process_integrity_level
       Processes.process_current_directory

    | `drop_dm_object_name(Processes)`

    | eval elevated_integrity_level = CASE(
                match(process_integrity_level,"low"),1,
                match(process_integrity_level,"medium"),2,
                match(process_integrity_level,"high"),3,
                match(process_integrity_level,"system"),4,
                true(),0
            )
    | rename parent_process_guid as join_guid
]

Stage 6: where

| where
    elevated_integrity_level > integrity_level
    OR
    user != elevated_user

Stage 7: fields

| fields dest user src_user parent_process_name parent_process
         parent_process_path parent_process_guid
         parent_process_integrity_level parent_process_current_directory
         process_name process process_path process_guid
         process_integrity_level process_current_directory
         orig_parent_process_name orig_parent_process
         orig_parent_process_guid firstTime lastTime count

Stage 8: search

| `security_content_ctime(firstTime)`

Stage 9: search

| `security_content_ctime(lastTime)`

Stage 10: search

| `windows_privilege_escalation_suspicious_process_elevation_filter`

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
Processes.userin"*$", "*LOCAL SERVICE", "*NETWORK SERVICE", "*SYSTEM", "DWM-*"

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
Processes.parent_process_pathin
  • "*\\ProgramData\\*"
  • "*\\Temp\\*"
  • "*\\Users\\*"
  • "*\\\\*"
Processes.process_integrity_levelin
  • "high" corpus 21 (sigma 17, kusto 3, splunk 1)
  • "low"
  • "medium" corpus 3 (sigma 3)
  • "system" corpus 29 (sigma 22, splunk 4, elastic 3)
Processes.process_pathin
  • "*\\ProgramData\\*"
  • "*\\Temp\\*"
  • "*\\Users\\*"
  • "*\\\\*"