For the complete documentation index, see llms.txt. This page is also available as Markdown.
CVEDICTIONARY-ATTACKINSECURE DESERIALIZATIONLINUXLINUX-PRIVESCWEB

Aftermath

Challenge Lab (Easy) - by Streetcoder

The following post by 0xb0b is licensed under CC BY 4.0


Scenario

Objective

You have been assigned a penetration test against a Linux server in the client's network. Your objective is to gain root access. The client has planted three flags on the system, retrieving each of these flags demonstrates impact.

Initial Access

Another team member pulled down a list of names and passwords from DeHashed... but are unsure if any of them are valid.

Summary

Summary

In Aftermath, we begin with a port scan against a Linux host running SSH on port 22, a SMTP server on port 25, and Apache httpd 2.4.52 on port 80. Directory brute-forcing uncovers a Roundcube Webmail instance at /roundcube/. With rate-limiting active on the login form and a set of credentials pulled from DeHashed by another team member, we first enumerate valid users via smtp-user-enum, issuing VRFY commands against the SMTP service which confirms maria as a valid mailbox. Alternatively, valid users can be gathered through Roundcube's password-reset endpoint using FFuF with timing-based analysis, where maria stands out. A Roundcube-specific credential spraying script recovers maria's password, granting access to the webmail interface where the first flag sits in her inbox.

Authenticated as maria, the Roundcube About page reveals version 1.5.9, vulnerable to CVE-2025-49113 a PHP Object Deserialization flaw in the _from parameter with a CVSS of 9.9. We leverage the public exploit to execute commands as www-data, confirm RCE by exfiltrating id output to our web server, and upgrade to a reverse shell via busybox nc caught by Penelope. We find the user flag at /usr/user.txt.

Privilege escalation is straightforward: sudo -l reveals www-data can run /usr/bin/apt-get as root. Following GTFOBins, we execute sudo /usr/bin/apt-get update -o APT::Update::Pre-Invoke::=/bin/sh to abuse the pre-invoke hook, spawning a root shell and recovering the final flag at /root/root.txt.

Recon

We use rustscan -b 500 -a 10.1.33.82 --top -- -sC -sV -Pn to enumerate all TCP ports on the target machine, piping the discovered results into Nmap which runs default NSE scripts -sC, service and version detection -sV, and treats the host as online without ICMP echo -Pn.

A batch size of 500 trades speed for stability, the default 1500 balances both, while much larger sizes increase throughput but risk missed responses and instability.

The target 10.1.33.82 is a Linux host with the hostname kali. Remote access is available via SSH on port 22. A Postfix SMTP server is running on port 25 with STARTTLS support, using a self-signed certificate issued to kali. Web services are provided by Apache httpd 2.4.52 on port 80, serving a page titled "Home".

We visit the page using our browser, and at first glance, it appears to be just a static page.

We perform a directory scan and, after a while, we detect a Roundcube endpoint using the directory-list-lowercase-2.3-medium.txt list.

From here, we can't determine the version to identify potential CVEs, we need access first to do so. We were provided with a list of usernames and passwords in the scenario, but a simple dictionary attack using a script or Hydra is not possible here. This is because rate-limiting protection is active and imposes a 10-second delay. We should therefore limit our requests by first identifing valid users, and then perform a dictionary attack on those users.

Access as maria

We have two options for identifying valid users. First, we can identify valid users via SMTP access; second, we can also identify valid users through a Roundcube endpoint. But more on that later. First, let’s try using it through the open SMTP service.

Username Enumeration via SMTP

To enumerate usernames on the SMTP service we make use of the tool smtp-user-enum. The tool connects to the server and issues VRFY or RCPT TO commands for each username in our list to see which ones the server confirms as valid mailboxes.

And we identify the valid user maria.

Username Enumeration via Password Reset Feature

Alternatively we could request reset. We get redirected to this weird endpoint.

We catch an example request to build our command for FFuF.

We provided the necessary headers for this and tried to enumerate users by the reponse sizes. But it turns out they stay the same. Nevertheless we are able to enumerate the valid users by the reponse time. We limit the thread at five requests per second with a ten-second timeout to keep timing consistent and measurable, while filtering out responses timings less than 1500 miliseconds. And we get a timeout on user maria. That timeout on maria indicates that this might be a valid user since the server spends extra time processing.

Now that we've identified a valid user, let's try a dictionary attack. We can write our own script and bypass the rate limit, or use a pre-existing one. We'll use the following script.

After running the dictionary attack we find a valid password.

We log into Roundcube using the credentials gathered...

... and we spot a mail containing the first flag.

Shell as www-data

We check out the About page and see Roundcube Webmail 1.5.9.

We look for CVEs related to that version and find a pretty juicy one - a public exploit with a CVSS score of 9.9 and a 99% EPSS score, meaning it's almost certainly being abused in the wild. A very promising find. The exploit lets an authenticated user inject a malicious serialized PHP object through the unvalidated _from parameter, which the server deserializes and executes, giving us a remote code execution. Fortunately we are authenticated with maria.

Roundcube Webmail before 1.5.10 and 1.6.x before 1.6.11 allows remote code execution by authenticated users because the _from parameter in a URL is not validated in program/actions/settings/upload.php, leading to PHP Object Deserialization.

We get the following exploit.

We set up a web server to exfiltrate the outputs of the commands run.

We run the id command and redirect the output as an endpoint to our web server...

.. we see we are www-data.

Next, we try to get a reverse shell. We use Penelope as the listener.

We issue a busybox revershell...

... and receive a connection.

The user flag can be found at /usr/user.txt.

Shell as root

While enumerating the system as www-data, we see that the user can run /usr/bin/apt-get as root using sudo. This is a classic and well known privilege escalation vector.

We can use GTFOBins to look up the exploit. We'll use the following version.

This exploit abuses the sudo permission on apt-get by using the -o flag to set a pre-invoke hook that runs /bin/sh as root before the update even begins, spawning the root shell through the apt-get built-in configuration options.

We retrieve a root shell and are able to access the final flag at /root/root.txt.

Last updated