Zipping
Last updated
Last updated
Let's start by enumerating ports using Nmap
:
Nmap
scan results indicate that port 22 is open and the SSH
service is running on it, and port 80 is also open with the Apache
HTTP server running.
Let's open the address 10.129.229.87
using the web browser. The website appears to be a watch store:
Most of the navbar options on the website are inactive. However, there are 2 interesting navbar options: Shop
and Work with Us
.
Clicking on the navbar option Shop
redirects us to /shop
:
Clicking on the offered product allows you to view the product details and add it to the cart:
After adding the product to the cart, we can place an order:
The second navbar option Work with Us
redirects us to /upload.php
, which indicates that this site uses PHP
. According to the information on the website, the application should only accept zip
files containing pdf
files.
First, let's check how the website works when you upload a file with the assumed requirements. Let's prepare an example pdf
file, e.g. szczygielka.pdf
and then let's zip
it using the following command:
After adding the zip
archive to the website and click the Upload
button, we receive a hyperlink that allows us to go to the preview of the PDF
file.
Preview of the content of the szczygielka.pdf
file:
The ability to preview a pdf
file may indicate that the uploaded zip
archive is being unpacked on the server. We should now check whether it is possible to add files in a format other than the declared one on the website. Due to the fact the website uses PHP, we want to check whether uploading files in PHP format is possible. If we managed to execute the uploaded PHP file, it would allow us to obtain a remote code execution and so reverse shell.
Let's download the reverse shell from this website and change the IP address and port to the one on which we will listen:
Let's try to upload a file with the PHP extension first:
After trying to upload a pdf
file without packing it into a zip archive, we receive an error Error uploading file
. So let's now pack the php-reverse-shell.php
file into a zip
archive:
Then let's upload the rev-shell.zip
archive to the website:
We received the error again, but it is different than the first one and indicates that the unpacked file must have a pdf
extension. Let's also check if it is possible to upload only one file in the archive.
Let's prepare a new archive called two-files.zip
:
Upload it to the website:
This time we also received an error. This time the error indicates that the archive should only contain one PDF file.
Let's check if we can send an archive containing a file with a double extension. To a file containing a reverse shell php-reverse-shell.php
let's add the second pdf
extension and then pack it into a zip archive:
The rev-shell.zip
file is successfully uploaded to the website:
It turns out that we can upload a PHP file to the website, but its last extension must indicate the PDF file format. If we could separate the two extensions from each other, we might be able to execute a file containing the PHP code. Let's take a closer look at the zip
format because it is sent to the website and then the file is extracted from it.
The structure of the zip
file is as follows:
The structure of Central Directory
:
The article points out that parsers can be confused by placing two different names in each structure referring to the same data, i.e. to this file. Depending on how the zip file is handled, the files it contains can be read, e.g. only based on the Local File Header
.
In this case, we will try to use these differences in handling zip
files to exploit the target machine. So let's prepare a zip
archive containing the reverse-shell.php.pdf
file, and then use the hexadecimal editor to edit the filename of the file contained in this archive. However, we do not know whether we should edit the filename in Local File Header
or in File Header
in Central Directory
. So we have to check 2 options.
Since we want to execute the PHP file on the target, we want to prepare the name of the file in such a way that in the case of the php-reverse-shell.php.pdf
file, the pdf
extension will be omitted. To do this we will try to add one of the whitespace characters, more specifically the space (x00) in one of the filenames php-reverse-shell.php.pdf
in the zip.
Let's run the listener on the port we placed in the php-reverse-shell.php.pdf
file:
Let's open the rev-shell.zip
file in a hex editor. As we expected, the zip
file contains 2 occurrences of the file name php-reverse-shell.php.pdf
:
Adding a space in the filename php-reverse-shell.php.pdf
, located in the Central Directory
:
After saving the changes to the zip
file, let's upload it to the website:
Let's open the given address to the uploaded file:
We received a Not Found
error in the browser, but in the listener we get the reverse shell:
Let's upgrade the shell via the following command:
We got shell as rektsu
user.
Port 22 on the machine is open, so we can generate an SSH
keypair for this user. In the -f
argument, we provide the name of the files in which the private and public keys are to be saved:
After generating the SSH keys, we receive two files: rektsu
, which is the private key, and the rektsu.pub
file, which is the public key. Let's create a file ~/.ssh/authorized_keys
and add the public key to it to enable logging in with the rektsu
private key on this machine:
To get the private key, we can prepare the HTTP server on our target via the following command:
Then download it:
As a rektsu
user, we can log in as follows, using the downloaded private key:
User flag can be obtained from/home/rektsu/user.txt
. Using null-byte injection in zip
file upload was an unintended solution, which was patched:
Let's start by checking sudo
permissions for our user:
The output of the sudo -l
command indicates that the user svc
can run /usr/bin/stock
with sudo
permissions without a password. Let's check what type of file is /usr/bin/stock
:
An attempt to run the binary /usr/bin/stock
with sudo
fails, because we are asked to enter a password:
Let's download the stock
file to our attack machine using scp
:
We will decompile and analyze the downloaded file using Ghidra
. In one of the decompiled functions, checkAuth
function we find the string St0ckM4nager
which appears to be a password:
After entering the found string as a password, we can run the stock
binary:
After testing all possible options in the software, it seems unlikely that the offered functionalities can be used to escalate privileges, so let's check what system calls occur during the execution of this program. To do that we are going to use strace
.
It turns out that strace
is already installed on our target:
So let's run stock
using strace
:
Recent write
and read
system calls indicate that we should provide a password, so let's do it. After entering the password, further system calls appeared:
One of these systems calls seems to be interesting:
The output from the strace
indicates that stock
binary is trying to open the file /home/rektsu/.config/libcounter.so
but cannot find this file. The extension of the file libcounter.so
indicates that it is a shared library.
So we can write our own shared library /home/rektsu/.config/libcounter.so
in C/C++, which will be called indirectly using binary stock
. Since stock
will run with sudo
privileges, calling libcounter.so
should allow us to escalate privileges. To elevate our privileges, we will want to invoke bash in privileged mode with the following command:
To create the libcounter.so
library, let's first prepare the lib.c
file on our attacking machine with the following code:
Using a destructor
in this file will cause the begin
function to be called when the shared library is unloaded, which usually happens when exiting the program.
Let's save the file and then compile it to object format using g++
:
And then let's create the library libcounter.so
using the object file lib.o
:
Send the prepared library to the /home/rektsu/.config/
directory located on our target using scp
:
Now let's execute binary stock with sudo
permissions, provide the required password, and then let's exit the binary:
After exiting the program, we become the root
user.
All previous steps lead us to the root
user. The root flag can be obtained at /root/root.txt
.
Search results for bypassing file upload filters for zip
files on the Internet led us to a great . From the article, we find out that in the zip
format, two structures may be responsible for storing the names of files contained in the zip
archive. These are Local File Header
and File Header
in Central Directory
. The article indicates that the Local File Header
is prefixed to each of the stored files, earlier in the file and the Central Directory
is located at the end of the file.