Thick Client Penetration Testing Checklist
A comprehensive, checkable list for testing Windows, Java, and .NET thick client applications.
Each section ends with a "Handy tools and commands" block with copy-paste examples. Replace placeholders such as app.exe, <PID>, and <host> with your target's values.
Table of Contents
- Information Gathering
- GUI Testing
- File System Testing
- Registry Testing
- Network and Traffic Testing
- Binary and Assembly Protection Testing
- Memory Testing
- Reverse Engineering and Code Testing
- Authentication and Authorization
- Data Storage and Secrets
- Backend Communication and Injection
- DLL and Process Security
- Cryptography
- Logging and Error Handling
- Software Update Mechanism
- Inter-Process Communication (IPC)
- Privilege Escalation and Persistence
- Protocol Handlers and Argument Injection
- Framework-Specific Tests
- Local and Embedded Servers
- Licensing and Business Logic
- Reporting
1. Information Gathering
- Identify the architecture (two-tier or three-tier)
- Identify the language and framework (.NET, Java, C/C++, Electron, Python)
- Detect packer, compiler, and protections with Detect It Easy or CFF Explorer
- Identify all network endpoints and protocols (HTTP/S, TCP, UDP, FTP/S)
- Map every input and entry point (forms, files, IPC, network, command line)
- Observe the process, child processes, and loaded modules
- Identify the authentication and authorization mechanisms
- Note the install location, config files, and data folders
- Check whether the app runs with admin or elevated privileges
- Run Strings on the binary for quick wins (URLs, keys, paths)
Handy tools and commands:
# Identify language, packer, and compiler
diec.exe app.exe # Detect It Easy (CLI)
# Pull interesting strings (Sysinternals Strings)
strings.exe -n 8 app.exe | findstr /i "http https password key token secret connectionstring"
# See loaded modules, child processes, handles
# GUI: Process Explorer (procexp64.exe) -> select process -> lower pane (DLLs / Handles)
# Live network endpoints for the process
netstat -ano | findstr <PID>
# Confirm privilege level
# GUI: Process Explorer column "Integrity" (Medium / High / System)
2. GUI Testing
- Reveal hidden form objects
- Enable disabled controls and buttons
- Unmask password fields
- Look for sensitive information shown in the UI
- Bypass access controls using intended GUI features
- Test client-side input validation and sanitization
- Try privilege escalation (unlock admin features as a normal user)
- Try payment, price, or quantity manipulation
- Check improper error handling in the UI
- Inspect the UI tree with Spy++, WinSpy++, or Snoop WPF
Handy tools and commands:
Spy++ : inspect and edit Win32 window styles (unhide, enable controls)
WinSpy++ : reveal masked password fields, change control styles
Snoop / snoopwpf : inspect and edit live WPF visual tree and bindings
Window Detective : view and change window properties
BulletsPassView : reveal password-box contents (standard Win32 fields)
Tip: to enable a disabled button, clear its WS_DISABLED style in Spy++/WinSpy++.
Tip: to unmask a password box, remove the ES_PASSWORD style or change the password char.
3. File System Testing
- Check file and folder permissions (read and write for low-privilege users)
- Look for sensitive data in config files (app.config, .ini, .xml, .json)
- Look for hardcoded credentials, keys, or connection strings on disk
- Look for cleartext storage of sensitive data
- Check temp files and cache for leaked data
- Check local databases (SQLite and others) for sensitive data
- Verify code signing and strong naming
- Test file and content replacement
- Test for race conditions on file access
- Watch file activity with Procmon while using the app
Handy tools and commands:
# Weak permissions on the install folder (writable by low-priv users = risk)
icacls "C:\Program Files\App"
accesschk.exe -uwds "Users" "C:\Program Files\App" # -w writable, -s recurse
# Grep config and data files for secrets
findstr /s /i /n "password key token secret connectionstring" "C:\Program Files\App\*.config" "%APPDATA%\App\*"
# Verify the digital signature
Get-AuthenticodeSignature "C:\Program Files\App\app.exe"
sigcheck.exe -a -h app.exe
# Watch file access live (Procmon filter)
# Filter: Process Name is app.exe AND Operation is CreateFile / WriteFile
# Local database: open .db / .sqlite with DB Browser for SQLite
4. Registry Testing
- Check read access to the app's registry keys
- Check write access to the app's registry keys
- Look for secrets or config stored in the registry
- Diff the registry before and after running the app with Regshot
- Try registry manipulation to bypass authentication
- Try registry manipulation to bypass authorization or licensing
- Check permissions on keys with AccessEnum
Handy tools and commands:
# Read the app's keys
reg query "HKCU\Software\App" /s
reg query "HKLM\SOFTWARE\App" /s
# Check write access to a key (accesschk, -k for registry)
accesschk.exe -k -w "Users" "HKLM\SOFTWARE\App"
# Diff before/after: Regshot -> 1st shot -> run app -> 2nd shot -> compare
# Watch live registry writes in Procmon (Operation is RegSetValue)
5. Network and Traffic Testing
- Enumerate ports and services on the backend with Nmap
- Capture traffic with Wireshark and look for cleartext data
- Confirm whether traffic is encrypted (TLS) end to end
- Test TLS strength with testssl.sh (versions, ciphers, certificate)
- Intercept HTTP/S with Burp (use the NoPE extension if proxy-unaware)
- Intercept non-HTTP traffic with Echo Mirage or MITM Relay
- Test for certificate pinning and try to bypass it
- Check whether the client accepts an invalid or self-signed server certificate
- Check whether the client falls back to cleartext if TLS fails
- Tamper with requests and responses and observe behavior
- Test for injection and IDOR over the wire
- Test WebSocket and gRPC traffic if used
- Check live connections with TCPView
Handy tools and commands:
# Backend port and service scan
nmap -sV -sC -p- <host>
# TLS configuration and certificate check
testssl.sh <host>:443
# For a proxy-unaware client, force its traffic through Burp:
# - Proxifier or ProxyCap to redirect the process to 127.0.0.1:8080
# - Burp: Proxy > Options > enable invisible proxying, add the NoPE extension
# - Or edit the hosts file to point the backend domain at your proxy
# Non-HTTP TCP/TLS:
# Echo Mirage (inject into the process) or mitm_relay (relay to Burp)
# Cert pinning bypass at runtime with Frida:
frida -f app.exe -l frida-unpinning.js --no-pause
6. Binary and Assembly Protection Testing
- Verify ASLR is enabled
- Verify DEP is enabled
- Verify SafeSEH
- Verify Control Flow Guard (CFG)
- Verify High Entropy VA
- Verify strong naming (for .NET)
- Verify Authenticode signing with Sigcheck
Handy tools and commands:
# Summarize all binary protections at once
winchecksec.exe app.exe
winchecksec.exe -j app.exe # JSON output for reports
# PowerShell alternative
Import-Module .\Get-PESecurity.psm1
Get-PESecurity -file "C:\Program Files\App\app.exe"
# Strong naming for .NET
sn.exe -vf app.exe
# Signature and hashes
sigcheck.exe -a -h app.exe
7. Memory Testing
- Log in with known credentials and search memory for them
- Search memory for passwords, keys, tokens, and PII
- Confirm the region and protection of any hit with WinDbg
!address - Check whether secrets are cleared after logout (search again)
- Create a full memory dump and search it offline
- Try memory manipulation to change values (for example an isAdmin flag)
- Try to bypass authentication or authorization by editing memory
- Set breakpoints on interesting functions with WinDbg or x64dbg
- Hook and tamper with functions at runtime using Frida
- Check for process replacement or hollowing indicators
- Check crash dumps and Windows Error Reporting for leaked secrets
- Check that the app disables memory paging for secrets (VirtualLock)
Handy tools and commands:
# Create a full memory dump
procdump.exe -ma <PID> out.dmp # Sysinternals ProcDump
# or Task Manager > Details > right-click process > Create dump file
# WinDbg: attach or open a dump
windbg -pn app.exe # attach to a live process by name
windbg -z out.dmp # open a dump
# WinDbg: search memory for a secret
s -u 0 L?7fffffff "Winter2024!" # Unicode search (most Windows text)
s -a 0 L?7fffffff "Winter2024!" # ASCII search
!address 000001f23a4b02c0 # confirm region + protection of a hit
du 000001f23a4b02c0 # read the hit as a Unicode string
# .NET managed heap (after loading SOS)
.loadby sos clr
!dumpheap -type System.String
!do <addr> # a String prints its text
# Frida: hook and read a function's arguments at runtime
frida -f app.exe -l hook.js --no-pause
8. Reverse Engineering and Code Testing
- Decompile .NET assemblies with dnSpyEx, dotPeek, or ILSpy
- Deobfuscate protected .NET assemblies with de4dot
- Decompile Java or JAR files with JADX or JD-GUI
- Disassemble native binaries with Ghidra, IDA, or Radare2
- Recover source code, passwords, and keys
- Identify exported functions and try to call them without authentication
- Build a wrapper to call public methods without authentication
- Patch and rebuild the app to bypass a check
- Test for missing or weak obfuscation
- Look for dangerous functions (strcpy, sprintf, system, exec)
Handy tools and commands:
# .NET: decompile and auto-deobfuscate
# dnSpyEx (GUI): open app.exe, browse code, edit, and save
de4dot.exe app.exe # writes app-cleaned.exe
# Java: decompile
jadx-gui app.jar # GUI decompiler
# or extract: jar xf app.jar
# Native: list exported functions of a DLL
dumpbin /exports app.dll # Visual Studio tools
# Ghidra / IDA / radare2 (r2 app.exe; aaa; pdf @ main) for disassembly
# Find dangerous native functions in the decompile
findstr /s /i "strcpy sprintf system exec WinExec ShellExecute" *.c *.cpp
9. Authentication and Authorization
- Test for broken or weak authentication
- Test for default or hardcoded credentials
- Test whether auth checks are done on the client only
- Bypass login using memory, registry, or binary patching
- Test how the client stores and reuses session tokens (local storage, reuse, expiry)
- Test for missing function-level access control enforced only on the client
- Test privilege escalation paths (unlock admin features as a normal user)
Handy tools and commands:
# Client-side auth check bypass ideas:
# - dnSpyEx: find the method that returns the login/role result, edit it to
# always return true, then save the assembly and run.
# - x64dbg: set a breakpoint on the compare after the check, flip the ZF flag
# or NOP the conditional jump, then patch to file.
# - Memory: find an isAdmin / isLoggedIn flag and set it (WinDbg eb <addr> 01).
# Server-side authz (IDOR, function-level): capture the request in Burp and
# change identifiers or call admin-only endpoints as a normal user.
10. Data Storage and Secrets
- Find hardcoded secrets in the binary or config
- Check Windows Credential Manager and DPAPI usage
- Check for secrets in logs
- Check for secrets in environment variables
- Check that sensitive data at rest is encrypted
- Check backup, export, and temp files for leaked data
Handy tools and commands:
# Windows Credential Manager
cmdkey /list
# DPAPI-protected blobs (decrypt in the user's context)
# SharpDPAPI.exe or mimikatz "dpapi::*" during authorized testing
# Environment variables the app may read
Get-ChildItem Env:
# Grep common data folders for secrets
findstr /s /i "password key token secret" "%APPDATA%\App\*" "%PROGRAMDATA%\App\*" "%LOCALAPPDATA%\App\*"
11. Backend Communication and Injection
Focus on the inputs the thick client sends to its database or server. In a two-tier app the client talks directly to the database, so injection is a client-side concern. In a three-tier app, test the backend only through the client's own interfaces and traffic.
- Test for SQL injection (direct client-to-database in two-tier, or via the backend)
- Test for command injection through client inputs
- Test for insecure deserialization (.NET BinaryFormatter, Java objects)
- Test for XXE where the client or server parses XML
- Test for IDOR and broken access control on backend resources the client calls
- Test for business logic flaws in the client-to-server workflow
Handy tools and commands:
# SQL injection on the backend (proxy the request through Burp, save it, then)
sqlmap -r request.txt --batch
# Insecure deserialization gadget generation
ysoserial.net -f BinaryFormatter -g TypeConfuseDelegate -c "calc.exe" # .NET
java -jar ysoserial.jar CommonsCollections1 "calc.exe" > payload.bin # Java
# XXE: submit an XML body with an external entity and watch for file read / SSRF
12. DLL and Process Security
- Test for DLL hijacking and search-order abuse
- Test for DLL preloading and side-loading
- Watch for missing DLLs with Procmon (NAME NOT FOUND filter)
- Check permissions on the install directory (writable equals hijack risk)
- Check for insecure service configuration and permissions
- Check for insecure named pipes or IPC
- Test for process injection weaknesses
Handy tools and commands:
# Find missing DLLs the app tries to load (classic hijack candidates)
# Procmon filter: Result is NAME NOT FOUND AND Path ends with .dll
# Is the install directory writable by normal users?
accesschk.exe -uwdq "Users" "C:\Program Files\App"
# Service misconfig (weak permissions, unquoted path)
sc qc <serviceName>
accesschk.exe -uwcqv "Users" <serviceName>
wmic service get name,pathname,startmode | findstr /i /v """ # unquoted paths
13. Cryptography
- Identify the crypto algorithms and modes used
- Check for weak or broken algorithms (MD5, DES, ECB)
- Check for hardcoded keys or IVs
- Break on crypto APIs to read keys at runtime (bcrypt, schannel)
- Check for weak random number generation
- Check that keys are stored and cleared safely
Handy tools and commands:
# In the decompiled code, search for weak primitives:
# MD5, SHA1, DES, RC4, ECB mode, hardcoded byte[] keys/IVs, Random() for keys
# Read keys at runtime by breaking on the crypto API (WinDbg):
bp bcrypt!BCryptDecrypt
bp bcrypt!BCryptGenerateSymmetricKey
g
db rdx L20 # inspect the key/IV/data buffer at the breakpoint
# Or trace all crypto calls with API Monitor (filter the Cryptography group)
# Or hook CryptoAPI / bcrypt functions with Frida and log key material
14. Logging and Error Handling
- Check for verbose stack traces that leak information
- Check for sensitive data written to logs
- Check whether debug mode is left enabled
- Check log file permissions
- Test improper exception handling paths
Handy tools and commands:
# Find log files and scan them for secrets
Get-ChildItem -Recurse -Include *.log,*.txt "%APPDATA%\App","%PROGRAMDATA%\App","C:\Program Files\App"
findstr /s /i "password token exception stacktrace at " "%APPDATA%\App\*.log"
# Check log file permissions
icacls "%PROGRAMDATA%\App\logs"
# Trigger errors with malformed input and watch for detailed stack traces in the UI or logs
15. Software Update Mechanism
- Identify how the app checks for and downloads updates
- Check whether updates are fetched over HTTPS
- Check whether update packages have a verified digital signature
- Try to serve a malicious update through a man-in-the-middle position
- Check whether the update process runs with elevated privileges (update-to-EoP)
- Check the update download folder permissions (writable equals binary planting)
- Check for downgrade or rollback to a vulnerable version
Handy tools and commands:
# Watch the update check in Burp or Wireshark: is it HTTP or HTTPS?
# MITM the update endpoint (hosts file or proxy) and return a modified installer.
# If the client runs the file without verifying its signature, that is RCE.
# Verify whether the downloaded update is signature-checked:
sigcheck.exe -a downloaded_update.exe # is it signed, and does the app enforce it?
# Check the download/staging folder permissions
accesschk.exe -uwdq "Users" "%LOCALAPPDATA%\App\Update"
16. Inter-Process Communication (IPC)
- Enumerate named pipes and check their permissions and authentication
- Test COM and DCOM objects for insecure access and privilege abuse
- Test RPC and local RPC endpoints
- Test WCF or .NET remoting endpoints if used
- Check shared memory and memory-mapped files for exposed data
- Test window messages (WM_COPYDATA) and mailslots
- Check whether IPC endpoints validate the caller and its integrity level
Handy tools and commands:
# List named pipes
pipelist.exe # Sysinternals
[System.IO.Directory]::GetFiles("\\.\pipe\") # PowerShell one-liner
# Check a pipe's permissions
accesschk.exe -w \pipe\<pipeName>
# COM / DCOM inspection
# OleViewDotNet (GUI) to browse COM classes, interfaces, and access permissions
# RpcView (GUI) to enumerate RPC interfaces and endpoints
17. Privilege Escalation and Persistence
- Check for unquoted service paths
- Check service binary and folder permissions (writable equals code execution as the service account)
- Check service configuration change rights with accesschk
- Check scheduled tasks created by the app for weak permissions
- Test the installer and updater for writing to weakly protected locations
- Check for UAC bypass or silent auto-elevation
- Check autostart entries (Run keys, startup folder) for write access
- Check whether the app runs as SYSTEM or admin unnecessarily
Handy tools and commands:
# Automated privilege-escalation checks
.\winPEASx64.exe # winPEAS
powershell -ep bypass -c "Import-Module .\PowerUp.ps1; Invoke-AllChecks"
# Unquoted service paths
wmic service get name,displayname,pathname,startmode | findstr /i /v "c:\windows\\" | findstr /i /v """
# Service permission and config
sc qc <serviceName>
accesschk.exe -uwcqv "Users" <serviceName>
# Scheduled tasks and autostart
schtasks /query /fo LIST /v
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run"
18. Protocol Handlers and Argument Injection
- Enumerate custom URL or protocol handlers the app registers (for example myapp://)
- Test protocol handler input for argument and command injection
- Test command-line arguments for injection and unsafe behavior
- Test file association handlers with crafted files
- Test deep links that trigger sensitive actions without confirmation
Handy tools and commands:
# Find custom protocol handlers registered under HKCR
reg query "HKCR" | findstr /i "URL Protocol"
reg query "HKCR\myapp\shell\open\command"
# Trigger a handler with a crafted argument
start "" "myapp://open?file=..\..\sensitive"
# Test how the app parses its command line (look for injection into a shell/path)
app.exe --config "test&calc.exe"
19. Framework-Specific Tests
Electron:
- Extract and inspect the ASAR archive (app.asar) for source and secrets
- Check nodeIntegration and contextIsolation settings
- Check for remote content loaded into privileged windows (XSS to RCE)
- Check the Electron and Chromium version for known CVEs
Java:
- Test RMI and JMX endpoints
- Test for insecure deserialization of Java objects
- Decompile JAR or class files and look for secrets and logic
.NET:
- Inspect config files (app.config) for connection strings and settings
- Check for insecure BinaryFormatter or SOAP deserialization
- Check ClickOnce deployment and manifest trust settings
Handy tools and commands:
# Electron: extract and read the app source
npx asar extract app.asar out
electronegativity -i out # scan for insecure Electron settings
# Java: deserialization payload
java -jar ysoserial.jar CommonsCollections1 "calc.exe" > payload.bin
# .NET: deserialization payload
ysoserial.net -f BinaryFormatter -g TypeConfuseDelegate -c "calc.exe"
20. Local and Embedded Servers
- Check whether the app opens a listener on localhost or a broader interface
- Test any local web or API server for authentication and CSRF
- Check for sensitive actions reachable from the browser or other local apps
- Check the bound interface (localhost only vs 0.0.0.0)
Handy tools and commands:
# What is the app listening on, and on which interface?
netstat -ano | findstr LISTENING | findstr <PID>
# Probe the local endpoint
curl http://127.0.0.1:<port>/ -v
# If it is 0.0.0.0, it is reachable from the network, not just localhost.
# Test the endpoint for missing auth and CSRF (a web page can call localhost).
21. Licensing and Business Logic
- Test client-side license, trial, or activation checks for bypass
- Test feature flags and paywalls enforced only on the client
- Test for hidden or debug menus and backdoor functionality
- Check clipboard for sensitive data left after copy operations
- Test workflow and state manipulation for logic flaws
Handy tools and commands:
# License/trial bypass ideas:
# - dnSpyEx / x64dbg: find the IsLicensed / IsTrialExpired check and patch it.
# - Registry/file: locate the trial timestamp and reset or delete it (Procmon
# and Regshot help find where it is stored).
# - Feature flags stored client-side: flip them in config, registry, or memory.
# Clipboard leakage: after a copy action, inspect the clipboard
powershell -c "Get-Clipboard"
22. Reporting
- Record clear reproduction steps for every finding
- Capture evidence (screenshots, dumps, tool output)
- Rate severity and impact
- Provide remediation guidance for each finding
- Note the environment, versions, and scope tested
Handy tips:
# Save tool output as evidence alongside screenshots:
winchecksec.exe -j app.exe > evidence\binary-protections.json
sigcheck.exe -a app.exe > evidence\signature.txt
# Keep the memory dump (out.dmp) and the exact WinDbg search command used.
# Record app version, build, OS version, and the account privilege level tested.