threat hunting

Detecting T1055 Process Injection with Sysmon

Detect process injection techniques (T1055) including classic DLL injection, process hollowing, and APC injection by analyzing Sysmon events for cross-process memory operations, remote thread creation, and anomalous DLL loading patterns.

defense-evasiondll-injectionmitre-t1055process-hollowingprocess-injectionsysmonthreat-hunting
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • When hunting for defense evasion techniques that hide malicious code inside legitimate processes
  • After EDR alerts for suspicious cross-process memory access or remote thread creation
  • When investigating malware that injects into svchost.exe, explorer.exe, or other system processes
  • During purple team exercises testing detection of process injection variants
  • When validating Sysmon configuration coverage for injection detection

Prerequisites

  • Sysmon deployed with comprehensive configuration capturing Events 1, 7, 8, 10, 25
  • Event ID 8 (CreateRemoteThread) enabled for remote thread detection
  • Event ID 10 (ProcessAccess) configured with appropriate access mask filters
  • Event ID 7 (ImageLoaded) for DLL injection detection
  • Event ID 25 (ProcessTampering) for process hollowing on Sysmon 13+
  • SIEM platform for correlation and alerting

Workflow

  1. Monitor CreateRemoteThread (Event 8): Detect when one process creates a thread in another process's address space. This is the primary indicator of classic DLL injection and shellcode injection.
  2. Analyze ProcessAccess (Event 10): Track cross-process handle requests with PROCESS_VM_WRITE (0x0020), PROCESS_VM_OPERATION (0x0008), and PROCESS_CREATE_THREAD (0x0002) access rights. Legitimate processes rarely need these on other processes.
  3. Detect Anomalous DLL Loading (Event 7): Identify DLLs loaded from unusual paths (user temp directories, download folders) into system processes.
  4. Hunt Process Hollowing (Event 25): Sysmon 13+ generates ProcessTampering events when the executable image in memory diverges from what was mapped from disk -- a hallmark of process hollowing (T1055.012).
  5. Correlate with Process Creation: Link injection events to the originating process creation (Event 1) to build the full attack chain from initial execution to injection.
  6. Filter Known-Good Cross-Process Activity: Exclude legitimate software that performs cross-process operations (debuggers, AV products, accessibility tools, RMM agents).
  7. Map to ATT&CK Sub-Techniques: Classify detected injection as classic injection (T1055.001), PE injection (T1055.002), thread execution hijacking (T1055.003), APC injection (T1055.004), thread local storage (T1055.005), process hollowing (T1055.012), or process doppelganging (T1055.013).

Key Concepts

Concept Description
T1055.001 Dynamic-link Library Injection
T1055.002 Portable Executable Injection
T1055.003 Thread Execution Hijacking
T1055.004 Asynchronous Procedure Call (APC) Injection
T1055.005 Thread Local Storage
T1055.012 Process Hollowing
T1055.013 Process Doppelganging
T1055.015 ListPlanting
Sysmon Event 8 CreateRemoteThread detected
Sysmon Event 10 ProcessAccess with memory write permissions
Sysmon Event 25 ProcessTampering (image mismatch)
Access Mask 0x1FFFFF PROCESS_ALL_ACCESS -- full cross-process control

Tools & Systems

Tool Purpose
Sysmon Primary telemetry source for injection detection
Process Hacker Manual investigation of process memory regions
PE-sieve Scan running processes for hollowed/injected code
Moneta Detect anomalous memory regions in processes
Splunk / Elastic SIEM correlation of Sysmon events
Volatility Memory forensics for injection artifacts
Hollows Hunter Automated scan for hollowed processes

Detection Queries

Splunk -- Remote Thread Creation

index=sysmon EventCode=8
| where SourceImage!=TargetImage
| where NOT match(SourceImage, "(?i)(csrss|lsass|services|svchost|MsMpEng|SecurityHealthService|vmtoolsd)\.exe$")
| eval suspicious=if(match(TargetImage, "(?i)(svchost|explorer|lsass|winlogon|csrss|services)\.exe$"), "high_value_target", "normal_target")
| where suspicious="high_value_target"
| table _time Computer SourceImage SourceProcessId TargetImage TargetProcessId StartFunction NewThreadId

Splunk -- Suspicious ProcessAccess Patterns

index=sysmon EventCode=10
| where SourceImage!=TargetImage
| where match(GrantedAccess, "(0x1FFFFF|0x1F3FFF|0x143A|0x0040)")
| where match(TargetImage, "(?i)(lsass|svchost|explorer|winlogon)\.exe$")
| where NOT match(SourceImage, "(?i)(MsMpEng|csrss|services|svchost|taskmgr|procexp)\.exe$")
| table _time Computer SourceImage TargetImage GrantedAccess CallTrace

KQL -- Process Injection via Remote Thread

DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "CreateRemoteThreadApiCall"
| where InitiatingProcessFileName !in~ ("csrss.exe", "lsass.exe", "services.exe", "svchost.exe")
| where FileName in~ ("svchost.exe", "explorer.exe", "lsass.exe", "winlogon.exe")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine,
    FileName, ProcessCommandLine

Sigma Rule -- Process Injection Detection

title: Process Injection via CreateRemoteThread into System Process
status: stable
logsource:
    product: windows
    category: create_remote_thread
detection:
    selection:
        TargetImage|endswith:
            - '\svchost.exe'
            - '\explorer.exe'
            - '\lsass.exe'
            - '\winlogon.exe'
    filter_legitimate:
        SourceImage|endswith:
            - '\csrss.exe'
            - '\lsass.exe'
            - '\services.exe'
            - '\MsMpEng.exe'
    condition: selection and not filter_legitimate
level: high
tags:
    - attack.defense_evasion
    - attack.t1055

Common Scenarios

  1. Classic DLL Injection: Malware uses VirtualAllocEx + WriteProcessMemory + CreateRemoteThread to load a malicious DLL into a target process. Detected via Sysmon Event 8.
  2. Process Hollowing (RunPE): Attacker creates a suspended process, unmaps its image, writes malicious PE, and resumes execution. Detected via Sysmon Event 25.
  3. APC Injection: Malware queues an Asynchronous Procedure Call to threads of a target process using QueueUserAPC. Harder to detect, requires Event 10 monitoring.
  4. Reflective DLL Injection: DLL is loaded directly from memory without touching disk, bypassing ImageLoaded detection. Requires memory-level analysis.
  5. Process Doppelganging: Leverages NTFS transactions to replace a legitimate process image. Detected via process integrity checking.

Output Format

Hunt ID: TH-INJECT-[DATE]-[SEQ]
Host: [Hostname]
Source Process: [Injecting process path]
Source PID: [Process ID]
Target Process: [Target process path]
Target PID: [Process ID]
Injection Type: [DLL/Shellcode/Hollowing/APC]
Sysmon Events: [Event IDs triggered]
Access Mask: [Granted access value]
Risk Level: [Critical/High/Medium/Low]
ATT&CK Sub-Technique: [T1055.xxx]
Source materials

References and resources

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

References 3

api-reference.md2.7 KB

API Reference: T1055 Process Injection Detection with Sysmon

MITRE ATT&CK T1055 Sub-Techniques

Sub-technique Method Sysmon Event
T1055.001 DLL Injection Event 7, 8, 10
T1055.002 PE Injection Event 8, 10
T1055.003 Thread Execution Hijacking Event 8
T1055.004 Asynchronous Procedure Call Event 8, 10
T1055.005 Thread Local Storage Event 8
T1055.012 Process Hollowing Event 1, 10, 25

Sysmon Event IDs

Event 8 — CreateRemoteThread

Field Index Description
SourceProcessGuid 1 GUID of injecting process
SourceProcessId 2 PID of injecting process
SourceImage 4 Path of injecting binary
TargetProcessGuid 5 GUID of target process
TargetProcessId 6 PID of target process
TargetImage 7 Path of target binary
StartAddress 8 Thread start address
StartFunction 9 Thread entry function

Event 10 — ProcessAccess

Field Index Description
SourceProcessId 3 Accessing PID
SourceImage 4 Accessing binary path
TargetProcessId 7 Accessed PID
TargetImage 8 Accessed binary path
GrantedAccess 10 Access rights mask

Event 7 — Image Loaded

Field Index Description
Image 3 Process that loaded DLL
ImageLoaded 5 DLL path
Signed 6 Signature status
SignatureStatus 8 Valid/Invalid/Unknown

Process Access Masks

Mask Right Injection Use
0x0008 PROCESS_VM_OPERATION VirtualAllocEx
0x0010 PROCESS_VM_READ ReadProcessMemory
0x0020 PROCESS_VM_WRITE WriteProcessMemory
0x0800 PROCESS_SUSPEND_RESUME Hollowing
0x001F0FFF PROCESS_ALL_ACCESS Full control

Sysmon Configuration for Injection Detection

<Sysmon>
  <EventFiltering>
    <ProcessAccess onmatch="include">
      <GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
      <GrantedAccess condition="is">0x001F0FFF</GrantedAccess>
    </ProcessAccess>
    <CreateRemoteThread onmatch="exclude">
      <SourceImage condition="is">C:\Windows\System32\svchost.exe</SourceImage>
    </CreateRemoteThread>
  </EventFiltering>
</Sysmon>

Sigma Rule Example

title: CreateRemoteThread into System Process
logsource:
    product: windows
    category: create_remote_thread
detection:
    selection:
        TargetImage|endswith:
            - '\svchost.exe'
            - '\explorer.exe'
            - '\lsass.exe'
    filter:
        SourceImage|startswith: 'C:\Windows\System32\'
    condition: selection and not filter
level: critical
standards.md3.2 KB

Standards and References - T1055 Process Injection Detection

MITRE ATT&CK Process Injection Sub-Techniques

Sub-Technique Name API Calls Sysmon Detection
T1055.001 Dynamic-link Library Injection VirtualAllocEx, WriteProcessMemory, CreateRemoteThread Event 8, 10
T1055.002 Portable Executable Injection VirtualAllocEx, WriteProcessMemory, SetThreadContext Event 10
T1055.003 Thread Execution Hijacking SuspendThread, SetThreadContext, ResumeThread Event 10
T1055.004 Asynchronous Procedure Call OpenThread, QueueUserAPC Event 10
T1055.005 Thread Local Storage TLS callback manipulation Event 10
T1055.012 Process Hollowing CreateProcess (SUSPENDED), NtUnmapViewOfSection, WriteProcessMemory Event 25, 10
T1055.013 Process Doppelganging NtCreateTransaction, NtCreateSection, NtRollbackTransaction Event 25
T1055.015 ListPlanting SendMessage to set list item text Limited Sysmon coverage

Critical Sysmon Events for Injection Detection

Event ID Name Detection Value
1 Process Create Baseline the originating process
7 Image Loaded Detect DLL injection from unusual paths
8 CreateRemoteThread Primary injection indicator
10 ProcessAccess Cross-process handle acquisition
25 ProcessTampering Process hollowing detection (Sysmon 13+)

ProcessAccess Granted Access Masks

Access Mask Permissions Risk
0x1FFFFF PROCESS_ALL_ACCESS Critical - full process control
0x1F3FFF Nearly all access rights Critical
0x0040 PROCESS_VM_READ Medium - credential dumping
0x0020 PROCESS_VM_WRITE High - memory modification
0x0008 PROCESS_VM_OPERATION High - memory allocation
0x0002 PROCESS_CREATE_THREAD High - thread creation
0x143A Combination used by Mimikatz Critical

Common Injection Targets

Process Why Targeted
svchost.exe Many instances, network access, elevated privileges
explorer.exe User context, always running, network access
lsass.exe Credential access (T1003 overlap)
winlogon.exe SYSTEM privileges, always running
spoolsv.exe SYSTEM privileges, rarely monitored
dllhost.exe COM surrogate, frequently overlooked
RuntimeBroker.exe Common in modern Windows, rarely scrutinized

Recommended Sysmon Configuration for Injection Detection

<Sysmon schemaversion="4.90">
  <EventFiltering>
    <RuleGroup name="ProcessInjection" groupRelation="or">
      <CreateRemoteThread onmatch="exclude">
        <SourceImage condition="is">C:\Windows\System32\csrss.exe</SourceImage>
      </CreateRemoteThread>
      <ProcessAccess onmatch="include">
        <GrantedAccess condition="is">0x1FFFFF</GrantedAccess>
        <GrantedAccess condition="is">0x1F3FFF</GrantedAccess>
        <GrantedAccess condition="is">0x143A</GrantedAccess>
      </ProcessAccess>
      <ProcessTampering onmatch="include">
        <Type condition="is">Image is replaced</Type>
      </ProcessTampering>
    </RuleGroup>
  </EventFiltering>
</Sysmon>
workflows.md3.0 KB

Detailed Hunting Workflow - T1055 Process Injection

Phase 1: CreateRemoteThread Detection (Sysmon Event 8)

Step 1.1 - Identify All Remote Thread Creation

index=sysmon EventCode=8
| where SourceImage!=TargetImage
| stats count by SourceImage TargetImage Computer
| sort -count

Step 1.2 - Filter to High-Value Target Processes

index=sysmon EventCode=8
| where match(TargetImage, "(?i)(svchost|explorer|lsass|winlogon|spoolsv|dllhost|RuntimeBroker)\.exe$")
| where NOT match(SourceImage, "(?i)(csrss|lsass|services|svchost|MsMpEng|vmtoolsd)\.exe$")
| stats count values(Computer) as hosts by SourceImage TargetImage
| sort -count

Phase 2: ProcessAccess Analysis (Sysmon Event 10)

Step 2.1 - High-Privilege Cross-Process Access

index=sysmon EventCode=10
| where GrantedAccess IN ("0x1FFFFF", "0x1F3FFF", "0x143A", "0x1F0FFF")
| where NOT match(SourceImage, "(?i)(MsMpEng|csrss|lsass|services|svchost|taskmgr|procexp)\.exe$")
| where match(TargetImage, "(?i)(lsass|svchost|explorer|winlogon)\.exe$")
| table _time Computer SourceImage TargetImage GrantedAccess CallTrace

Step 2.2 - LSASS Access for Credential Theft

index=sysmon EventCode=10
| where match(TargetImage, "(?i)lsass\.exe$")
| where match(GrantedAccess, "(0x1FFFFF|0x1F3FFF|0x0040|0x143A)")
| where NOT match(SourceImage, "(?i)(csrss|lsass|svchost|MsMpEng|WmiPrvSE)\.exe$")
| table _time Computer SourceImage GrantedAccess CallTrace

Phase 3: DLL Injection Detection (Sysmon Event 7)

Step 3.1 - DLLs Loaded from User-Writable Paths

index=sysmon EventCode=7
| where match(ImageLoaded, "(?i)\\(temp|appdata|downloads|users\\[^\\]+\\desktop)\\")
| where match(Image, "(?i)(svchost|explorer|winlogon|services)\.exe$")
| table _time Computer Image ImageLoaded Hashes Signed

Step 3.2 - Unsigned DLLs in System Processes

index=sysmon EventCode=7
| where Signed="false"
| where match(Image, "(?i)\\(svchost|services|lsass|explorer)\.exe$")
| table _time Computer Image ImageLoaded Hashes SignatureStatus

Phase 4: Process Hollowing Detection (Sysmon Event 25)

Step 4.1 - ProcessTampering Events

index=sysmon EventCode=25
| table _time Computer Image Type RuleName User

Phase 5: Correlation and Investigation

Step 5.1 - Build Full Attack Chain

index=sysmon (EventCode=1 OR EventCode=8 OR EventCode=10 OR EventCode=25)
| where match(SourceImage, "[suspected_injector]") OR match(Image, "[suspected_injector]")
| sort _time
| table _time EventCode Image SourceImage TargetImage CommandLine GrantedAccess

Step 5.2 - Memory Analysis

For confirmed injection, capture process memory using:

  • PE-sieve for automated scan of hollow/injected processes
  • Moneta for memory region anomaly detection
  • Volatility malfind plugin for offline memory forensics

Phase 6: Response

  1. Isolate affected endpoint via EDR
  2. Capture memory dump before cleanup
  3. Identify and remove injecting malware
  4. Check for persistence mechanisms deployed by injected code
  5. Sweep environment for same injection technique indicators

Scripts 2

agent.py5.4 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for detecting T1055 process injection via Sysmon event analysis."""

import argparse
import json
import subprocess
import sys
from datetime import datetime, timezone


INJECTION_ACCESS_MASKS = {
    "0x1F0FFF": "PROCESS_ALL_ACCESS",
    "0x001F0FFF": "PROCESS_ALL_ACCESS (full)",
    "0x0800": "PROCESS_SUSPEND_RESUME",
    "0x0020": "PROCESS_VM_WRITE",
    "0x0008": "PROCESS_VM_OPERATION",
    "0x0010": "PROCESS_VM_READ",
}

INJECTION_DLLS = [
    "ntdll.dll", "kernel32.dll", "kernelbase.dll",
]

SUSPICIOUS_API_CALLS = [
    "VirtualAllocEx", "WriteProcessMemory", "CreateRemoteThread",
    "NtMapViewOfSection", "QueueUserAPC", "SetWindowsHookEx",
    "RtlCreateUserThread", "NtQueueApcThread",
]


def query_sysmon_events(event_id, max_events=500):
    """Query Sysmon operational log for specific event ID."""
    if sys.platform != "win32":
        return []
    ps_cmd = (
        f"Get-WinEvent -FilterHashtable @{{LogName='Microsoft-Windows-Sysmon/Operational';"
        f"Id={event_id}}} -MaxEvents {max_events} "
        "| ForEach-Object { @{"
        "TimeCreated=$_.TimeCreated.ToString('o');"
        "Properties=@($_.Properties | ForEach-Object {$_.Value})"
        "}} | ConvertTo-Json -Depth 3"
    )
    try:
        result = subprocess.check_output(
            ["powershell", "-NoProfile", "-Command", ps_cmd],
            text=True, errors="replace", timeout=30
        )
        data = json.loads(result) if result.strip() else []
        return data if isinstance(data, list) else [data]
    except (subprocess.SubprocessError, json.JSONDecodeError):
        return []


def analyze_process_access():
    """Analyze Sysmon Event ID 10 for injection-related process access."""
    findings = []
    events = query_sysmon_events(10)
    for evt in events:
        props = evt.get("Properties", [])
        if len(props) < 11:
            continue
        source_img = str(props[4]) if len(props) > 4 else ""
        target_img = str(props[8]) if len(props) > 8 else ""
        access = str(props[10]) if len(props) > 10 else ""
        safe_sources = ["csrss.exe", "svchost.exe", "lsass.exe", "services.exe", "smss.exe"]
        if any(s in source_img.lower() for s in safe_sources):
            continue
        if access in INJECTION_ACCESS_MASKS:
            findings.append({
                "event": "ProcessAccess",
                "time": evt.get("TimeCreated", ""),
                "source": source_img,
                "target": target_img,
                "access_mask": access,
                "mask_meaning": INJECTION_ACCESS_MASKS.get(access, "Unknown"),
            })
    return findings


def analyze_create_remote_thread():
    """Analyze Sysmon Event ID 8 for CreateRemoteThread injection."""
    findings = []
    events = query_sysmon_events(8)
    for evt in events:
        props = evt.get("Properties", [])
        if len(props) < 8:
            continue
        source_img = str(props[4]) if len(props) > 4 else ""
        target_img = str(props[7]) if len(props) > 7 else ""
        findings.append({
            "event": "CreateRemoteThread",
            "time": evt.get("TimeCreated", ""),
            "source": source_img,
            "target": target_img,
            "severity": "HIGH",
        })
    return findings


def analyze_image_loads():
    """Analyze Sysmon Event ID 7 for suspicious DLL loads in unusual processes."""
    findings = []
    events = query_sysmon_events(7, max_events=200)
    for evt in events:
        props = evt.get("Properties", [])
        if len(props) < 6:
            continue
        image = str(props[3]) if len(props) > 3 else ""
        loaded = str(props[5]) if len(props) > 5 else ""
        if loaded.lower().endswith("amsi.dll") and "powershell" not in image.lower():
            findings.append({
                "event": "SuspiciousImageLoad",
                "time": evt.get("TimeCreated", ""),
                "process": image,
                "loaded_image": loaded,
                "note": "AMSI DLL loaded by non-PowerShell process",
            })
    return findings


def main():
    parser = argparse.ArgumentParser(
        description="Detect T1055 process injection via Sysmon telemetry"
    )
    parser.add_argument("--output", "-o", help="Output JSON report")
    parser.add_argument("--max-events", type=int, default=500)
    parser.add_argument("--verbose", "-v", action="store_true")
    args = parser.parse_args()

    print("[*] T1055 Process Injection Detection Agent (Sysmon)")
    report = {"timestamp": datetime.now(timezone.utc).isoformat(), "findings": {}}

    access = analyze_process_access()
    report["findings"]["process_access"] = access
    print(f"[*] Suspicious process access: {len(access)}")

    threads = analyze_create_remote_thread()
    report["findings"]["remote_threads"] = threads
    print(f"[*] Remote thread creation: {len(threads)}")

    loads = analyze_image_loads()
    report["findings"]["suspicious_loads"] = loads
    print(f"[*] Suspicious image loads: {len(loads)}")

    total = len(access) + len(threads) + len(loads)
    report["risk_level"] = "CRITICAL" if total >= 5 else "HIGH" if total >= 2 else "MEDIUM" if total > 0 else "LOW"

    if args.output:
        with open(args.output, "w") as f:
            json.dump(report, f, indent=2)
        print(f"[*] Report saved to {args.output}")
    else:
        print(json.dumps(report, indent=2))


if __name__ == "__main__":
    main()
process.py5.9 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
T1055 Process Injection Detection Script
Analyzes Sysmon Event 8 (CreateRemoteThread), Event 10 (ProcessAccess),
and Event 25 (ProcessTampering) to identify process injection activity.
"""

import json
import csv
import argparse
import datetime
import re
from pathlib import Path

HIGH_VALUE_TARGETS = {
    "svchost.exe", "explorer.exe", "lsass.exe", "winlogon.exe",
    "csrss.exe", "services.exe", "spoolsv.exe", "dllhost.exe",
    "runtimebroker.exe", "dwm.exe", "smss.exe",
}

LEGITIMATE_SOURCES = {
    "csrss.exe", "lsass.exe", "services.exe", "svchost.exe",
    "msmpe ng.exe", "securityhealthservice.exe", "vmtoolsd.exe",
    "taskmgr.exe", "procexp64.exe", "procexp.exe", "procmon.exe",
}

SUSPICIOUS_ACCESS_MASKS = {
    "0x1fffff": "PROCESS_ALL_ACCESS",
    "0x1f3fff": "Nearly full access",
    "0x143a": "Mimikatz-style access",
    "0x1f0fff": "High privilege access",
    "0x0040": "PROCESS_VM_READ (credential access)",
}


def parse_events(input_path: str) -> list[dict]:
    """Parse Sysmon event logs."""
    path = Path(input_path)
    events = []
    if path.suffix == ".json":
        with open(path, "r", encoding="utf-8") as f:
            data = json.load(f)
            events = data if isinstance(data, list) else data.get("events", [])
    elif path.suffix == ".csv":
        with open(path, "r", encoding="utf-8-sig") as f:
            events = [dict(row) for row in csv.DictReader(f)]
    return events


def detect_injection(events: list[dict]) -> list[dict]:
    """Detect process injection from Sysmon events."""
    findings = []

    for event in events:
        event_code = str(event.get("EventCode", event.get("EventID", event.get("event_id", ""))))
        computer = event.get("Computer", event.get("host", ""))
        timestamp = event.get("UtcTime", event.get("_time", event.get("timestamp", "")))
        user = event.get("User", event.get("user", ""))

        if event_code == "8":
            source = event.get("SourceImage", "")
            target = event.get("TargetImage", "")
            source_name = source.split("\\")[-1].lower() if source else ""
            target_name = target.split("\\")[-1].lower() if target else ""

            if source_name in LEGITIMATE_SOURCES:
                continue
            if source == target:
                continue

            severity = "CRITICAL" if target_name in HIGH_VALUE_TARGETS else "HIGH"
            findings.append({
                "timestamp": timestamp,
                "computer": computer,
                "event_type": "CreateRemoteThread",
                "sysmon_event": 8,
                "source_image": source,
                "target_image": target,
                "severity": severity,
                "technique": "T1055.001",
                "description": f"Remote thread created by {source_name} in {target_name}",
            })

        elif event_code == "10":
            source = event.get("SourceImage", "")
            target = event.get("TargetImage", "")
            access = event.get("GrantedAccess", "").lower()
            source_name = source.split("\\")[-1].lower() if source else ""
            target_name = target.split("\\")[-1].lower() if target else ""

            if source_name in LEGITIMATE_SOURCES:
                continue
            if source == target:
                continue
            if access not in SUSPICIOUS_ACCESS_MASKS:
                continue

            severity = "CRITICAL" if target_name == "lsass.exe" else "HIGH"
            findings.append({
                "timestamp": timestamp,
                "computer": computer,
                "event_type": "ProcessAccess",
                "sysmon_event": 10,
                "source_image": source,
                "target_image": target,
                "granted_access": access,
                "access_description": SUSPICIOUS_ACCESS_MASKS.get(access, "Unknown"),
                "severity": severity,
                "technique": "T1055",
                "description": f"{source_name} accessed {target_name} with {access} ({SUSPICIOUS_ACCESS_MASKS.get(access, '')})",
            })

        elif event_code == "25":
            image = event.get("Image", "")
            tampering_type = event.get("Type", "")
            findings.append({
                "timestamp": timestamp,
                "computer": computer,
                "event_type": "ProcessTampering",
                "sysmon_event": 25,
                "image": image,
                "tampering_type": tampering_type,
                "severity": "CRITICAL",
                "technique": "T1055.012",
                "description": f"Process tampering detected: {image} - {tampering_type}",
            })

    return sorted(findings, key=lambda x: {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2}.get(x["severity"], 3))


def run_hunt(input_path: str, output_dir: str) -> None:
    """Execute process injection detection hunt."""
    print(f"[*] T1055 Process Injection Hunt - {datetime.datetime.now().isoformat()}")
    events = parse_events(input_path)
    print(f"[*] Loaded {len(events)} Sysmon events")

    findings = detect_injection(events)
    print(f"[!] Injection detections: {len(findings)}")

    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    with open(output_path / "injection_findings.json", "w", encoding="utf-8") as f:
        json.dump({
            "hunt_id": f"TH-INJECT-{datetime.date.today().isoformat()}",
            "total_events": len(events),
            "findings_count": len(findings),
            "findings": findings,
        }, f, indent=2)

    print(f"[+] Results written to {output_dir}")


def main():
    parser = argparse.ArgumentParser(description="T1055 Process Injection Detection")
    parser.add_argument("--input", "-i", required=True)
    parser.add_argument("--output", "-o", default="./injection_hunt_output")
    args = parser.parse_args()
    run_hunt(args.input, args.output)


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 1.0 KB
Keep exploring