August 22, 2026
Step-by-Step Beginner’s Guide to Windows Thick-Client Penetration Testing with VWA
Greetings, fellow hackers! I’m Sandy, a Infosec Consultant and bug-bounty hunter.

By Sandeep Vishwakarma
18 min read
Most of us enter application security through websites. We open Burp Suite, capture a request and start changing parameters. That workflow feels familiar after a while. Then somebody gives us a Windows desktop application and asks us to test it.
There may be no URL to paste into a browser. Instead, we find EXE files, DLLs, Windows services, registry entries, named pipes and configuration files scattered across the machine. The application may also keep important business logic — or even credentials — on the endpoint. My first question was simple: where do I even begin?
The answer was to stop looking for one magic tool. Thick-client testing becomes much easier when we watch what the program actually does. Which files does it search for? Which account runs the process? Can an ordinary user modify something later trusted by an administrator-level service? What leaves the machine over the network?
For this walkthrough I'm using Viparva, the intentionally Vulnerable Windows Application (VWA) published by DarkRelay Security Labs. It is a practice target made specifically for Windows thick-client testing. I have written the guide so beginners can follow the reasoning, not just copy commands.
Table of contents
-
What is a thick client?
-
Why thick-client penetration testing matters
-
What we will test in VWA
-
Building a safe Windows laboratory
-
Installing VWA and recording a baseline
-
A repeatable thick-client testing methodology
-
Exercise 1: EXE hijacking
-
Exercise 2: DLL hijacking
-
Exercise 3: insecure local permissions
-
Exercise 4: information leakage in a binary
-
Exercise 5: insecure client-server communication
-
Exercise 6: symlink attack analysis
-
What I would test next
-
Turning evidence into a professional finding
-
Remediation checklist for thick-client developers
-
What I learned from this lab
1. What is a thick client?
A thick client — also called a fat client — is software installed on an endpoint that performs a meaningful amount of processing locally. Examples include accounting tools, trading terminals, VPN clients, database administration software, healthcare applications and enterprise launchers.
A thin web client relies heavily on a remote server. A thick client may contain business rules, parsing logic, cryptographic material, database drivers and update mechanisms on the user's machine. It can still communicate with APIs or backend services, but the local endpoint is a major part of its security boundary.
That creates a useful mental model. During testing, study four layers:
· Files: executables, DLLs, configuration files, logs, temporary files and update packages.
· Operating-system objects: services, processes, registry keys, COM objects, scheduled tasks, named pipes and access-control lists.
· Runtime state: command-line arguments, environment variables, loaded modules, handles and process memory.
· Communication: TCP/UDP traffic, TLS validation, custom protocols, local IPC and backend authorization.
The client machine must be treated as hostile from a defensive point of view. A user can often inspect files, debug their own process and change data they are permitted to write. Security decisions that matter to the business should therefore be enforced again on a trusted server.
2. Why thick-client penetration testing matters
Desktop software frequently runs with more access than a normal web page. An updater may run as SYSTEM; a service may run as an administrator; a launcher may read sensitive local files; and a client may connect directly to a database. A small design error can cross a privilege boundary.
Common issues include:
· A privileged process loads an executable or DLL from a directory writable by ordinary users.
· A Windows service uses an unquoted path containing spaces.
· Credentials, API keys or encryption keys are embedded in a binary or left in memory.
· Sensitive traffic is transmitted in clear text or TLS certificates are not validated correctly.
· A named pipe allows unauthorized users to read, write or impersonate clients.
· Local files or registry keys have overly permissive access-control entries.
· The client trusts values that the server should independently authorize.
· An unsigned installer or update can be replaced without reliable publisher verification.
The impact can range from information disclosure and tampering to persistence or local privilege escalation.
3. What we will test in VWA
The VWA repository identifies the following intentional weaknesses:
· DLL hijacking
· EXE hijacking
· symlink attacks
· Image File Execution Options (IFEO) injection
· unquoted service paths
· man-in-the-middle attacks
· weak named pipes
· weak memory protection
· stack buffer overflow
· absence of digital signatures
· COM hijacking
· process injection
The repository supplies separate 32-bit and 64-bit MSI installers and lists Windows 10 x64, Windows Server 2016 and Windows Server 2019 x64 as tested platforms. Because this is training software and operating-system behavior changes over time, reproduce the lab on a supported disposable image and document the exact build you use.
We will fully walk through discovery for several issues. For dangerous categories such as memory corruption and process injection, we will focus on identification, evidence and safe validation rather than weaponized payload development.
4. Building a safe Windows laboratory
What you need
· A Windows 10 x64 virtual machine
· VMware Workstation, VirtualBox, Hyper-V or another hypervisor
· One administrator account for installation and monitoring
· One standard user account for permission-boundary testing
· The VWA installer from the official GitHub repository
· Microsoft Sysinternals Process Monitor, Process Explorer, Autoruns, TCPView and Sigcheck
· Regshot for registry comparison
· Wireshark for packet capture
· x64dbg for basic binary inspection
· Optional: a Windows Attack Surface Analyzer and a safe compiler for a message-box DLL
DarkRelay's README also mentions Immunity Debugger, Echo Mirage, Google Project Zero's symbolic-link testing tools and MinGW. Download tools only from their official project pages and verify hashes or signatures where they are available.
Isolate the machine
Create a new VM and choose host-only networking if you do not need downloads inside it. If internet access is temporarily necessary, use NAT, download the required material and then disconnect the virtual adapter. Do not use bridged mode. Disable shared folders, shared clipboard and drag-and-drop while testing.
Take a snapshot named something like:
Keep a second snapshot after installing your tools but before installing VWA:
Snapshots matter because some exercises intentionally modify directories or registry data. A clean rollback is more dependable than trying to remember every change.
Create two security contexts
Use the administrator account to install VWA and run diagnostic tools that require elevation. Use the standard account to test whether a low-privileged user can alter an object consumed by a privileged process.
This distinction is essential. Finding that an administrator can replace an administrator-owned file is not a privilege escalation. A convincing finding shows that a less-trusted principal controls an input used by a more-trusted process.
5. Installing VWA and recording a baseline
Download the correct MSI from the official VWA repository. For our 64-bit VM, use ViparvaInstaller_x64.msi. The project instructs users to install the MSI as Administrator.
Before installation:
-
Start Regshot and take the first registry snapshot.
-
Start Process Monitor as Administrator.
-
Clear existing events with Ctrl+X.
-
Enable file-system, registry, process/thread and network activity.
-
Begin capture.
-
Install VWA as Administrator.
-
Stop capture immediately after installation.
-
Save the trace as a native PML file.
-
Take the second Regshot snapshot and compare it with the first.
Now record the installation inventory:
Inspect permissions:
List related processes and services:
Do not rush into exploitation. Your baseline explains what the installer created, which identity runs each component and which paths deserve attention.
6. A repeatable thick-client testing methodology
For every feature, use the same loop:
-
Observe: Capture file, registry, process and network activity while exercising one function.
-
Reduce noise: Filter by the target process, path or operation.
-
Identify a trust boundary: Ask which lower-privileged identity controls an input used by a higher-privileged component.
-
Form a hypothesis: For example, "Beeper.exe requests a missing file from a user-writable directory."
-
Validate safely: Use Calculator, a text file or a message box as a visible proof.
-
Reproduce: Revert the VM and repeat the smallest sequence needed.
-
Document: Preserve commands, timestamps, screenshots, logs, permissions and process identity.
-
Remediate and retest: Confirm that the fix removes the dangerous condition rather than only blocking your first payload.
Procmon produces thousands of events, so filtering is a core skill. Useful filters include:
Start broad enough to understand behavior, then narrow the trace. An event that says NAME NOT FOUND is only a clue. It becomes a vulnerability when the search reaches a location an attacker can write and the resulting code executes across a meaningful privilege boundary.
7. Exercise 1: EXE hijacking
The idea
EXE hijacking occurs when an application launches another program using an unsafe path or assumes an executable will exist in a location that a less-trusted user can control. If a privileged process later launches the attacker-controlled file, the payload inherits the caller's security context.
Discover the candidate
Run Process Monitor as Administrator and add these filters:
Exercise VWA for at least a minute. In the published VWA lab behavior, Beeper.exe attempts to load PipeClient.exe from:
Confirm this in your own trace. Then examine the directory ACL:
Look for a write, modify or full-control permission granted to Users, Authenticated Users or another broad group. Also use Process Explorer to record the user and integrity level under which Beeper.exe runs.
Safe validation
Sign in as the standard user. If your ACL evidence shows that the account can write the file, copy Calculator as the expected executable name:
Return to the administrator session and monitor the relevant process. If Calculator starts as a child of Beeper.exe, capture the process tree and its security context. That demonstrates control of program execution without creating a destructive payload.
Remove the copied file after collecting evidence:
Why it matters
The problem is not simply a missing executable. The exploitable chain is:
Recommended fixes include using a fully qualified trusted path, shipping the required executable in a protected directory, restricting ACLs, validating the child binary and running the caller with the least privilege required.
8. Exercise 2: DLL hijacking
The idea
Windows applications load libraries by name or by full path. If a program asks for Shared.dll without securely resolving its location, Windows may search several directories. A writable directory in that search sequence can allow an attacker-controlled DLL to be loaded.
Discover the load attempt
In Procmon, use:
Start or reinstall the relevant VWA component and observe the paths in order. VWA is designed so that Beeper.exe looks for a missing Shared.dll under C:\ProgramData\Viparva. Confirm all three conditions:
-
The DLL name is requested.
-
The directory is writable by a standard user.
-
The consuming process runs at a higher privilege or crosses another trust boundary.
Build a harmless message-box DLL
Create Shared.cpp inside your lab:
Compile for the architecture of the target process. With 64-bit MinGW-w64:
With a Visual Studio Developer Command Prompt, an equivalent lab build is:
Do not assume that the operating system and target process have the same architecture. Process Explorer can show whether the process is 32-bit or 64-bit.
Validate and prove the load
As the standard user, place the harmless DLL into the writable candidate directory:
Wait for the component to perform its periodic action or restart it using the normal VWA workflow. A message box is visible evidence, but Procmon and Process Explorer provide stronger proof. Capture a Load Image event for the DLL and show that Beeper.exe loaded it from the writable path.
Then delete the PoC and restore the snapshot. Loading code from DllMain is acceptable for this tiny training signal, but production code should avoid complex work there because of loader-lock constraints.
Remediation
Developers should reference trusted libraries with fully qualified paths where possible, keep application directories non-writable to unprivileged users, use secure DLL-loading APIs and flags, remove unsafe current-directory searches, and package all required dependencies. Re-test by confirming that the process no longer probes an attacker-writable path.
9. Exercise 3: insecure local permissions
The first two exercises depend on an underlying weakness: a broad group can modify application data that influences a more-privileged component. Treat that as its own review area rather than only as part of a hijack.
Export ACLs for every application directory:
Ask:
· Can a standard user replace an executable, DLL or configuration file?
· Can they create a file that a privileged process will later open?
· Are permissions inherited unexpectedly from ProgramData?
· Can they delete or rename a protected application object?
· Does an updater trust a user-writable download or staging directory?
For a non-destructive check, create and delete a simple text file as the standard user in each candidate directory. Do not overwrite real binaries. Record the exact access-control entry that grants the permission.
The fix is to grant users only the access the application requires. Program binaries should generally reside under a protected installation directory. If users need to write application data, separate it from executable content and ensure privileged processes treat that data as untrusted.
10. Exercise 4: information leakage in a binary
Static triage first
Before debugging, collect metadata and signatures:
You can also use Sysinternals Sigcheck:
Next, open Client.exe in x64dbg. Navigate to the module, search the current module for string references and review readable strings. VWA intentionally demonstrates that sensitive data can be embedded in a client binary. Record the offset and cross-reference the code that uses the value, but redact the full secret from public screenshots unless disclosure is part of the lab lesson.
Why "obfuscate the string" is not the full fix
If the application needs a reusable secret to authenticate itself, hiding it with Base64, XOR or ordinary obfuscation only increases the time needed to recover it. At some point the client must reconstruct the secret, making it observable in code or memory.
Prefer short-lived, user- or device-bound credentials; operating-system-backed secret storage; server-issued tokens with narrow scopes; rotation; and server-side authorization. Do not embed a universal production credential in every installed copy.
Runtime memory review
With authorization, attach a debugger to the VWA process and search memory after the relevant operation. Test before login, during authentication and after logout. A valuable question is not merely whether a password appears momentarily — it often must — but whether unnecessary copies remain for a long time, appear in logs or can be read by unrelated low-privileged processes.
Avoid collecting real user secrets. Use synthetic lab credentials and securely delete memory dumps when the assessment is complete.
11. Exercise 5: insecure client-server communication
VWA includes Client.exe and Server.exe to demonstrate communication risks. Launch the server using the lab's normal workflow, start packet capture, and then launch the client.
First identify the endpoint:
Use TCPView or Process Explorer to map a connection to the owning VWA process. In Wireshark, filter by the discovered TCP port:
Follow the TCP stream. Ask:
· Is sensitive data readable as plain text?
· Is TLS used?
· If TLS is present, does the client reject an untrusted certificate?
· Can a captured message be replayed?
· Does the server authenticate and authorize every sensitive action?
· Is message integrity protected, or can values be changed in transit?
The original VWA training scenario uses Echo Mirage to inspect the conversation between the client and server. Older interception tools can be unstable on newer Windows builds, so do not spend hours forcing one tool to work. A Wireshark capture inside the isolated VM may already give enough evidence to demonstrate clear-text exposure. Never weaken production TLS or install an interception certificate outside your authorized lab.
A proper fix normally uses TLS with correct certificate and hostname validation, a modern protocol configuration and a secure authentication design. Encryption alone does not fix missing authorization or replay weaknesses.
12. Exercise 6: symlink attack analysis
The idea
A symbolic link or another reparse point redirects a file operation to a different target. A privileged installer or service can be vulnerable if it writes through a path that a standard user can prepare or replace.
VWA's training scenario focuses on its log location:
The security question is: can a low-privileged user control the path while a privileged process later writes to it?
Safe validation approach
Do not redirect the lab write into C:\Windows or overwrite an operating-system file. Use a harmless target in a dedicated folder, for example:
Take a snapshot, use the official symbolic-link testing tool referenced by the VWA project, and reproduce the path redirection only inside the disposable VM. Capture:
· the ACL on the original directory;
· the reparse point and its target;
· the privileged writer's Procmon event;
· the harmless text written at the alternate location.
Then roll back the snapshot. This demonstrates the primitive without risking system availability.
Developers should create privileged directories with restrictive ACLs, safely open files without following attacker-controlled reparse points where appropriate, validate the final resolved path and avoid predictable writable staging locations. Installers should assume pre-existing paths may be hostile.
13. What I would test next
VWA includes more vulnerable modules than I can properly demonstrate in one beginner article. Instead of turning them into a wall of payloads, these are the questions I would use for the next round of testing.
Unquoted service path
Enumerate VWA-related services and inspect PathName. A path containing spaces is suspicious when it is unquoted, but not automatically exploitable. Determine whether Windows could interpret an earlier path segment as an executable and whether a standard user can create that file. Report the full chain, the service account and restart permissions. Fix the issue by quoting the executable path and protecting every directory in it.
IFEO injection
Image File Execution Options can associate a debugger with a named executable. Review relevant keys under:
Determine who can modify the applicable key and what privileged process later launches the target. Do not set persistence on a real system. In the VM, use Regshot and a harmless executable to understand the behavior, then revert. Defenders should restrict registry ACLs and monitor unexpected Debugger values.
Weak named pipe
Use Process Explorer, WinObj or an appropriate pipe-enumeration utility to identify VWA named pipes. Examine the pipe's security descriptor and determine whether an unrelated standard user can connect, read, write or impersonate. Send only benign test data. The server should use a restrictive ACL, authenticate the peer, validate every message and avoid trusting the pipe name as proof of identity.
Weak memory protection
Record process mitigation settings and check whether another process at the same or lower trust level can obtain excessive access to VWA. Look for long-lived secrets and unnecessary process handles. A finding should state which identity can read which data and under what conditions — not merely that a debugger can inspect a process owned by the same user.
Stack buffer overflow
Use a debugger in the isolated VM, provide a gradually increasing benign pattern and record whether the application crashes. Stop after confirming controllable corruption; do not develop a weaponized exploit. Document input length, exception type, affected module and modern mitigations such as DEP, ASLR, stack cookies and Control Flow Guard. The root fix is bounds-safe input handling, not reliance on mitigations alone.
Absence of digital signatures
Run PowerShell's Get-AuthenticodeSignature or Sigcheck across all installed .exe, .dll and .msi files. An unsigned binary is not automatically exploitable, but it weakens publisher verification and update trust. Combine the result with evidence of an insecure delivery or update mechanism when rating impact.
COM hijacking
Capture registry activity and look for COM class identifiers requested by the application. Determine whether registration is resolved from a user-writable location and whether the consuming process crosses an integrity boundary. Use only a message-box in the VM for validation. Developers should avoid unsafe per-user fallback for privileged components and protect registration paths.
Process injection
Treat this module as an observation exercise. Map process access rights, integrity levels and mitigations. Validate with the lab's benign functionality or debugger rather than shellcode. A meaningful finding explains why an untrusted process can obtain dangerous rights to a more-trusted target and what security boundary is crossed.
14. Turning evidence into a professional finding
A good report makes the issue reproducible without forcing the reader to interpret a giant Procmon trace.
Use this structure:
Title: Privileged Beeper.exe loads Shared.dll from a directory writable by standard users
Severity: High (adjust using the actual execution context and environmental prerequisites)
Affected component: Exact version, file path and SHA-256 hash
Description: Explain the insecure search behavior and permissions in two or three sentences.
Prerequisites: State whether local access, a standard account, service restart or user interaction is required.
Steps to reproduce: Include only the minimum deterministic sequence.
Evidence: Provide the Procmon load event, directory ACL, process tree, user/integrity level and screenshot of the harmless message box.
Impact: Explain the trust boundary crossed. Avoid vague claims such as "an attacker can hack the system."
Remediation: Recommend an engineering change and a permissions change, where relevant.
Retest: Show that the fixed application no longer searches or loads from the writable directory.
Separate symptoms from root causes. EXE hijacking and DLL hijacking may both originate from the same insecure directory permissions and unsafe path resolution. Your report should help developers fix the class of issue, not play whack-a-mole with filenames.
15. Remediation checklist for thick-client developers
· Run each process and service with the least privilege required.
· Store executables and libraries only in directories ordinary users cannot modify.
· Use absolute, trusted paths when launching child processes.
· Quote service executable paths and protect every parent directory.
· Use secure DLL-loading behavior and package dependencies explicitly.
· Treat local configuration, environment variables and IPC messages as untrusted input.
· Apply restrictive ACLs to files, directories, registry keys, services and named pipes.
· Use TLS with correct certificate and hostname validation.
· Enforce authentication and authorization on the server for every sensitive action.
· Do not embed reusable universal secrets in client binaries.
· Use short-lived scoped tokens and OS-backed credential storage.
· Sign installers, executables, libraries and update packages.
· Verify update integrity and publisher identity before installation.
· Compile with current memory-safety mitigations and use bounds-safe APIs.
· Remove sensitive data from memory when it is no longer needed.
· Log security events without logging credentials, tokens or personal data.
· Test installation, repair, update and uninstall flows — not only the main UI.
16. What I learned from this lab
When testing is complete:
-
Stop VWA processes and packet captures.
-
Export only the evidence required for your report.
-
Remove synthetic secrets and memory dumps from shared locations.
-
Revert the VM to the clean snapshot or delete it.
The biggest lesson for me is that thick-client testing is really a study of trust. Process Monitor shows what a program searches for. Permissions show who can control the result. Process Explorer shows which identity consumes it. A debugger reveals how the program handles local data, while a packet capture reveals what crosses the network.
None of those facts is automatically a vulnerability. The finding appears when they join into an unsafe chain. In the EXE-hijacking exercise, for example, the missing executable was only the first clue. The writable directory and the more-privileged caller were what made it important.
VWA is a useful beginner target because one small lab covers files, processes, services, memory and communication. I recommend completing one module at a time and writing a short finding immediately afterward. When the test is repeated from a clean snapshot, weak assumptions become obvious very quickly.
Treat this article as a starting checklist, not the final word. During an authorized assessment, record the Windows version, tool versions, failed attempts and timing observations. Those small details are often the most useful part when reproducing a finding.
Happy hacking. Keep the VM isolated, use harmless proofs of concept and test only systems you are authorized to assess.
For personalize training Contact : pentestersandy@gmail.com
References
· DarkRelay Security Labs — VWA GitHub repository
· DarkRelay — Thick Client Penetration Testing
· Microsoft Sysinternals — Process Monitor
· Microsoft — Dynamic-link library security
· Microsoft — CreateProcess executable-name behavior
· Microsoft — Service application security and access rights