threat hunting

Detecting Privilege Escalation Attempts

Detect privilege escalation attempts including token manipulation, UAC bypass, unquoted service paths, kernel exploits, and sudo/doas abuse across Windows and Linux.

mitre-attackprivilege-escalationproactive-detectionthreat-huntingtoken-manipulationuac-bypass
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • When proactively hunting for indicators of detecting privilege escalation attempts in the environment
  • After threat intelligence indicates active campaigns using these techniques
  • During incident response to scope compromise related to these techniques
  • When EDR or SIEM alerts trigger on related indicators
  • During periodic security assessments and purple team exercises

Prerequisites

  • EDR platform with process and network telemetry (CrowdStrike, MDE, SentinelOne)
  • SIEM with relevant log data ingested (Splunk, Elastic, Sentinel)
  • Sysmon deployed with comprehensive configuration
  • Windows Security Event Log forwarding enabled
  • Threat intelligence feeds for IOC correlation

Workflow

  1. Formulate Hypothesis: Define a testable hypothesis based on threat intelligence or ATT&CK gap analysis.
  2. Identify Data Sources: Determine which logs and telemetry are needed to validate or refute the hypothesis.
  3. Execute Queries: Run detection queries against SIEM and EDR platforms to collect relevant events.
  4. Analyze Results: Examine query results for anomalies, correlating across multiple data sources.
  5. Validate Findings: Distinguish true positives from false positives through contextual analysis.
  6. Correlate Activity: Link findings to broader attack chains and threat actor TTPs.
  7. Document and Report: Record findings, update detection rules, and recommend response actions.

Key Concepts

Concept Description
T1134 Access Token Manipulation
T1548.002 UAC Bypass
T1068 Exploitation for Privilege Escalation
T1574.009 Unquoted Service Path

Tools & Systems

Tool Purpose
CrowdStrike Falcon EDR telemetry and threat detection
Microsoft Defender for Endpoint Advanced hunting with KQL
Splunk Enterprise SIEM log analysis with SPL queries
Elastic Security Detection rules and investigation timeline
Sysmon Detailed Windows event monitoring
Velociraptor Endpoint artifact collection and hunting
Sigma Rules Cross-platform detection rule format

Common Scenarios

  1. Scenario 1: Potato exploit for SYSTEM token impersonation
  2. Scenario 2: Fodhelper.exe UAC bypass technique
  3. Scenario 3: PrintSpoofer privilege escalation from service to SYSTEM
  4. Scenario 4: CVE kernel exploit for local privilege escalation

Output Format

Hunt ID: TH-DETECT-[DATE]-[SEQ]
Technique: T1134
Host: [Hostname]
User: [Account context]
Evidence: [Log entries, process trees, network data]
Risk Level: [Critical/High/Medium/Low]
Confidence: [High/Medium/Low]
Recommended Action: [Containment, investigation, monitoring]
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.3 KB

API Reference: Detecting Privilege Escalation Attempts

Windows Privilege Escalation Techniques

Technique MITRE ID Detection
UAC Bypass T1548.002 eventvwr.exe, fodhelper.exe
Token Manipulation T1134 SeDebugPrivilege (Event 4672)
Service Modification T1543.003 sc config binpath=
Potato Exploits T1134.001 JuicyPotato, PrintSpoofer
Scheduled Task T1053.005 schtasks /ru SYSTEM

Linux Privilege Escalation Techniques

Technique MITRE ID Detection
SUID Abuse T1548.001 find -perm 4000
Sudo Exploitation T1548.003 sudo -l enumeration
Kernel Exploit T1068 DirtyPipe, PwnKit
Cron Abuse T1053.003 crontab modification

Key Windows Event IDs

Event ID Detection
4672 Special Privileges Assigned
4688 Process Creation
Sysmon 1 Process Create with cmdline

Splunk SPL

index=wineventlog (EventCode=4672 OR EventCode=4688)
| where match(PrivilegeList, "SeDebugPrivilege")
   OR match(CommandLine, "(?i)(fodhelper|juicypotato)")
| table _time User CommandLine Computer

CLI Usage

python agent.py --evtx-file Sysmon.evtx
python agent.py --text-log auth.log
standards.md1.6 KB

Standards and References - Detecting Privilege Escalation Attempts

MITRE ATT&CK Mappings

Technique Name Description
T1134 Access Token Manipulation See attack.mitre.org/techniques/T1134
T1548.002 UAC Bypass See attack.mitre.org/techniques/T1548/002
T1068 Exploitation for Privilege Escalation See attack.mitre.org/techniques/T1068
T1574.009 Unquoted Service Path See attack.mitre.org/techniques/T1574/009

Detection Data Sources

Source Event ID Purpose
Sysmon 1 Process creation with command line
Sysmon 3 Network connection initiated
Sysmon 7 Image loaded (DLL)
Sysmon 10 Process access (LSASS)
Sysmon 11 File creation
Sysmon 12/13 Registry create/set
Sysmon 22 DNS query
Sysmon 25 Process tampering
Windows Security 4624 Successful logon
Windows Security 4625 Failed logon
Windows Security 4648 Explicit credential logon
Windows Security 4672 Special privileges assigned
Windows Security 4688 Process creation
Windows Security 4697 Service installed
Windows Security 4698 Scheduled task created
Windows Security 4769 Kerberos TGS requested
Windows Security 5140 Network share accessed

References

workflows.md2.8 KB

Detailed Hunting Workflow - Detecting Privilege Escalation Attempts

Phase 1: Data Collection and Querying

Splunk SPL Query

index=wineventlog EventCode=4672
| where NOT match(Account_Name, "(?i)(SYSTEM|LOCAL SERVICE|NETWORK SERVICE|\\$)")
| stats count values(Computer) as hosts by Account_Name
| where count > 5
| sort -count

KQL Query (Microsoft Defender for Endpoint)

SecurityEvent
| where EventID == 4672
| where SubjectUserName !in~ ("SYSTEM","LOCAL SERVICE","NETWORK SERVICE")
| where SubjectUserName !endswith "$"
| summarize count(), Hosts=make_set(Computer) by SubjectUserName

Phase 2: Baseline and Anomaly Detection

Step 2.1 - Establish Normal Behavior Baseline

  • Collect 30 days of historical data for the targeted technique
  • Document expected patterns, frequencies, and legitimate use cases
  • Identify known false positive sources and document exceptions
  • Build statistical baseline (mean, standard deviation) for key metrics

Step 2.2 - Identify Anomalies

  • Compare current activity against the 30-day baseline
  • Flag events exceeding 3 standard deviations from normal
  • Prioritize anomalies by risk score and potential business impact
  • Cross-reference with threat intelligence for known IOCs

Phase 3: Investigation and Correlation

Step 3.1 - Deep Dive Analysis

  • For each anomaly, collect full process tree context
  • Correlate with network activity, file operations, and authentication events
  • Check binary signatures, file hashes, and certificate validity
  • Review user account context and access patterns

Step 3.2 - Attack Chain Reconstruction

  • Map findings to MITRE ATT&CK kill chain stages
  • Identify initial access vector if applicable
  • Trace lateral movement and privilege escalation paths
  • Determine data access and potential exfiltration

Phase 4: Validation and Response

Step 4.1 - True/False Positive Determination

  • Verify findings with system owners and IT operations
  • Check change management records for authorized activities
  • Validate user context (authorized actions vs. compromised account)
  • Document determination rationale for each finding

Step 4.2 - Response Actions

  • For confirmed threats: initiate incident response procedures
  • For detection gaps: create or update detection rules
  • For false positives: tune existing rules and update exclusions
  • Update threat hunting playbook with lessons learned

Phase 5: Documentation and Reporting

Step 5.1 - Hunt Report

  • Summarize hypothesis, methodology, and findings
  • Include all queries executed and their results
  • Document IOCs discovered and detection rules created
  • Provide recommendations for security improvements

Step 5.2 - Knowledge Base Update

  • Add findings to threat intelligence platform
  • Update MITRE ATT&CK coverage heatmap
  • Share detection rules via Sigma format
  • Schedule follow-up hunts for related techniques

Scripts 2

agent.py4.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Privilege escalation detection agent for Windows and Linux endpoints.

Detects token manipulation, UAC bypass, sudo abuse, kernel exploits, and
unquoted service paths by analyzing process creation and security logs.
"""

import argparse
import json
import re
from datetime import datetime

try:
    import Evtx.Evtx as evtx
except ImportError:
    evtx = None

WINDOWS_PRIVESC_PATTERNS = [
    (r"eventvwr\.exe|fodhelper\.exe|computerdefaults\.exe", "T1548.002", "CRITICAL", "UAC Bypass"),
    (r"whoami\s+/priv", "T1033", "MEDIUM", "Privilege enumeration"),
    (r"sc\s+(config|create).*binpath", "T1543.003", "HIGH", "Service binary modification"),
    (r"potato.*exploit|juicypotato|sweetpotato|godpotato", "T1134.001", "CRITICAL", "Token impersonation exploit"),
    (r"printspoofer|efspotato", "T1134.001", "CRITICAL", "Named pipe impersonation"),
    (r"schtasks.*\/ru.*system", "T1053.005", "HIGH", "Scheduled task as SYSTEM"),
    (r"reg\s+add.*ImagePath", "T1574.011", "HIGH", "Service registry modification"),
]

LINUX_PRIVESC_PATTERNS = [
    (r"sudo\s+-l|sudo\s+--list", "T1548.003", "MEDIUM", "Sudo enumeration"),
    (r"find.*-perm.*4000|find.*-perm.*/u=s", "T1548.001", "MEDIUM", "SUID binary search"),
    (r"chmod\s+[u+]?s|chmod\s+4\d{3}", "T1548.001", "HIGH", "SUID bit set"),
    (r"linpeas|linenum|linux-exploit-suggester", "T1046", "HIGH", "Privesc enumeration tool"),
    (r"pkexec|CVE-2021-4034|pwnkit", "T1068", "CRITICAL", "Kernel exploit"),
    (r"dirty.*pipe|CVE-2022-0847", "T1068", "CRITICAL", "Kernel exploit"),
]


def analyze_evtx(filepath):
    if evtx is None:
        return {"error": "python-evtx not installed: pip install python-evtx"}
    findings = []
    with evtx.Evtx(filepath) as log:
        for record in log.records():
            xml = record.xml()
            event_id_match = re.search(r'<EventID[^>]*>(\d+)</EventID>', xml)
            if not event_id_match:
                continue
            event_id = int(event_id_match.group(1))
            if event_id not in (1, 4688, 4672):
                continue
            cmdline = re.search(r'<Data Name="CommandLine">([^<]+)', xml)
            image = re.search(r'<Data Name="Image">([^<]+)', xml)
            time_match = re.search(r'SystemTime="([^"]+)"', xml)
            cmd = cmdline.group(1) if cmdline else ""
            proc = image.group(1) if image else ""
            text = f"{cmd} {proc}"
            for pattern, mitre, severity, desc in WINDOWS_PRIVESC_PATTERNS:
                if re.search(pattern, text, re.IGNORECASE):
                    findings.append({
                        "event_id": event_id,
                        "timestamp": time_match.group(1) if time_match else "",
                        "command": cmd[:200], "technique": desc,
                        "mitre": mitre, "severity": severity,
                    })
            if event_id == 4672:
                privs = re.search(r'<Data Name="PrivilegeList">([^<]+)', xml)
                if privs and "SeDebugPrivilege" in privs.group(1):
                    findings.append({
                        "event_id": 4672,
                        "timestamp": time_match.group(1) if time_match else "",
                        "technique": "SeDebugPrivilege assigned",
                        "mitre": "T1134", "severity": "HIGH",
                    })
    return findings


def analyze_text_log(filepath):
    findings = []
    all_patterns = WINDOWS_PRIVESC_PATTERNS + LINUX_PRIVESC_PATTERNS
    with open(filepath, "r", encoding="utf-8", errors="replace") as f:
        for num, line in enumerate(f, 1):
            for pattern, mitre, severity, desc in all_patterns:
                if re.search(pattern, line, re.IGNORECASE):
                    findings.append({
                        "line": num, "technique": desc,
                        "mitre": mitre, "severity": severity,
                        "excerpt": line.strip()[:200],
                    })
    return findings


def main():
    parser = argparse.ArgumentParser(description="Privilege Escalation Detector")
    parser.add_argument("--evtx-file", help="Sysmon or Security EVTX file")
    parser.add_argument("--text-log", help="Text log to scan")
    args = parser.parse_args()
    results = {"timestamp": datetime.utcnow().isoformat() + "Z", "findings": []}
    if args.evtx_file:
        r = analyze_evtx(args.evtx_file)
        if isinstance(r, dict):
            results.update(r)
        else:
            results["findings"].extend(r)
    if args.text_log:
        results["findings"].extend(analyze_text_log(args.text_log))
    results["total_findings"] = len(results["findings"])
    print(json.dumps(results, indent=2))


if __name__ == "__main__":
    main()
process.py3.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Privilege Escalation Detection - Analyzes logs for T1134 indicators."""

import json, csv, argparse, datetime, re
from collections import defaultdict
from pathlib import Path

DETECTION_PATTERNS = [
    r'potato',
    r'PrintSpoofer',
    r'JuicyPotato',
    r'fodhelper',
    r'eventvwr',
    r'sdclt',
    r'ComputerDefaults',
]

def parse_logs(path):
    p = Path(path)
    if p.suffix == ".json":
        with open(p, encoding="utf-8") as f:
            data = json.load(f)
            return data if isinstance(data, list) else data.get("events", [])
    elif p.suffix == ".csv":
        with open(p, encoding="utf-8-sig") as f:
            return [dict(r) for r in csv.DictReader(f)]
    return []

def analyze_event(event):
    cmd = event.get("CommandLine", event.get("command_line", event.get("ProcessCommandLine", "")))
    content = event.get("Task_Content", event.get("Parameters", event.get("RawEventData", "")))
    search_text = f"{cmd} {content}"
    risk = 0
    indicators = []
    for pattern in DETECTION_PATTERNS:
        if re.search(pattern, search_text, re.IGNORECASE):
            risk += 25
            indicators.append(f"Pattern match: {pattern}")
    if not indicators:
        return None
    risk = min(risk, 100)
    return {
        "technique": "T1134",
        "command_line": cmd[:500] if cmd else content[:500],
        "hostname": event.get("Computer", event.get("DeviceName", event.get("hostname", "unknown"))),
        "user": event.get("User", event.get("AccountName", event.get("UserId", "unknown"))),
        "timestamp": event.get("_time", event.get("timestamp", event.get("UtcTime", event.get("Timestamp", "")))),
        "risk_score": risk,
        "risk_level": "CRITICAL" if risk >= 75 else "HIGH" if risk >= 50 else "MEDIUM" if risk >= 25 else "LOW",
        "indicators": indicators,
    }

def run_hunt(input_path, output_dir):
    print(f"[*] Privilege Escalation Hunt - {datetime.datetime.now().isoformat()}")
    events = parse_logs(input_path)
    findings = [f for f in (analyze_event(e) for e in events) if f]
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    slug = "detecting_privilege_"
    with open(Path(output_dir) / f"{slug}_findings.json", "w", encoding="utf-8") as f:
        json.dump({"hunt_id": f"TH-{datetime.date.today()}", "total_events": len(events), "findings": findings}, f, indent=2)
    with open(Path(output_dir) / "hunt_report.md", "w", encoding="utf-8") as f:
        f.write(f"# Privilege Escalation Hunt Report\n\n")
        f.write(f"**Date**: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"**Findings**: {len(findings)}\n\n")
        for finding in sorted(findings, key=lambda x: x["risk_score"], reverse=True)[:20]:
            f.write(f"### [{finding['risk_level']}] {finding['technique']}\n")
            f.write(f"- **Host**: {finding['hostname']}\n")
            f.write(f"- **Indicators**: {', '.join(finding['indicators'])}\n\n")
    print(f"[+] {len(findings)} findings written to {output_dir}")

def main():
    p = argparse.ArgumentParser(description="Privilege Escalation Detection")
    sp = p.add_subparsers(dest="cmd")
    h = sp.add_parser("hunt"); h.add_argument("--input", "-i", required=True); h.add_argument("--output", "-o", default="./detecting_privi_output")
    sp.add_parser("queries")
    args = p.parse_args()
    if args.cmd == "hunt": run_hunt(args.input, args.output)
    elif args.cmd == "queries":
        print("=== Detection Queries ===")
        print("See references/workflows.md for platform-specific queries")
    else: p.print_help()

if __name__ == "__main__": main()

Assets 1

template.mdtext/markdown · 2.6 KB
Keep exploring