Detection rules › Splunk
Windows Privilege Escalation Suspicious Process Elevation
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.
Known false positives
- False positives may be generated by administrators installing benign applications using run-as/elevation.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Stealth |
Telemetry coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
Rule body
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/
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
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 =if
match(process_integrity_level, "low")1elif
match(process_integrity_level, "medium")2elif
match(process_integrity_level, "high")3elif
match(process_integrity_level, "system")4else
0Stage 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
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
Processes.user | in | "*$", "*LOCAL SERVICE", "*NETWORK SERVICE", "*SYSTEM", "DWM-*" | excludes:Processes.user |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Processes.parent_process_path | in |
| field:"ParentImage" kind:in |
Processes.process_integrity_level | in |
| field:"IntegrityLevel" kind:in |
Processes.process_path | in |
| field:"Image" kind:in |
elevated_integrity_level | cross_field_compare |
| field:"elevated_integrity_level" kind:cross_field_compare value:"integrity_level" |
user | cross_field_compare |
| field:"user" kind:cross_field_compare value:"elevated_user" |