VulnDB Stories: How Secrecy Does Not Protect a Popular Mail Server
February 14, 2020 • RBS
“Yet another story from the VulnDB engine room”, I hear you say. Yeah, but this one is about vulnerability details that – as of now – are quite exclusive. And it’s good weekend literature. But set aside the secretive fuss. Let’s scrutinize the vagueness.
It’s not uncommon that we write about vulnerabilities as “unspecified”. This is often due to a lack of provided details to determine things like the possible attack vectors or the nature of the impact. This is vulnerability disclosure 101, and by now it should have been adopted as a standard practice by vendors and researchers (unfortunately, it hasn’t).
It is quite rare that a vendor explicitly classifies a vulnerability in a security advisory as “unspecified”. I mean, shouldn’t they know?
On February 10th, 2020 a security advisory was published on Github for Mailu, titled “Unspecified vulnerability in the fetchmail script” (CVE-2020-5239). Some further details were provided that indicate that:
An authenticated user can exploit a vulnerability in Mailu fetchmail script and gain full access to a Mailu server. Details about the vulnerbaility [sic] and exploitation path will be published later.Mailu security advisory
So the vendor decided to conceal the juicy details, which may or may not pique a hacker’s curiosity. In a way, this is something that strikes the interest of the VulnDB team and started a scavenger hunt for the “unknown” (or rather the “unspecified”).
The title of the advisory and details in the referenced workaround security update instructions point to fetchmail – or rather the fetchmail container – being the cause of the vulnerability. The issue was reported on February 7th, 2020, so if it fixed it, the commit addressing the vulnerability should be traceable in recent Github commits. And, not surprisingly, it was:
But how confident are we that this is the fix in question? Well, the other few fixes were mostly FAQ related, and the above fix is for the fetchmail.py script that fixes an encoding issue in the escape_rc_string() function. Looking at the context, we could see that this function is called on some fetchmail parameters in run(), such as username and email. The input is used to prepare a fetchmailrc file, which is passed to the fetchmail command in the fetchmail() function.
That’s enough information to push a VulnDB entry to our customers, so we did (VulnDB 223444) and included details about the possible command injection.
We could see why the developers preferred to not provide any details. It seems like this wasn’t very hard to exploit, but it wasn’t very hard to find and analyze the commit either. Vendors wanting to keep details secret is understandable as they can be misused by attackers. However, it may also prevent customers from properly understanding the vulnerability or risk. Furthermore, it may do customers an outright disservice if an attacker can trivially determine the details and thereby gain an edge over defenders.
Putting it to the Test
We decided to give it a go later in the afternoon. Mailu is a mail server solution that apparently gained some popularity for its easy setup. On hub.docker.com, the affected component has been pulled over 5 million times.
According to the vendor,
“Mailu is a simple yet full-featured mail server as a set of Docker images.”Mailu
And as promising as this sounds, the setup of the mail server solution was very easy. After setting up a test user, the affected component was easily identified in the web-based user interface under “Fetched accounts”. On that page, authenticated users can enter mail account parameters, which the mail server uses to fetch emails from other email accounts, and the parameters look very familiar:
To quickly get results, we needed to see how the web UI interacts with the affected fetchmail.py script. This was achieved by first entering parameters for a local POP3 server that stalls the handshake. This was basically just a netcat script to see if any connections are established from the fetchmail container.
$ echo “+OK POP3 server ready <[email protected]>” | nc -l -p 9999
By connecting to the fetchmail docker container, the process list would show the following result:
OK, we’re getting somewhere. This shows that the fetchmail.py script passes a temporary file as the run control file (fetchmailrc) to the fetchmail utility.
The contents of that file confirms our assumption that the user controls the fetchmail parameters.
And with that we have our attack vector. But how can we inject our data and achieve command execution?
For that we checked the actual fixing commit.
This looks as if escaping backslash and double-quote characters wasn’t sufficient for parameters passed in the fetchmail run control script. When checking the man page, we found the following text:
You may use backslash escape sequences (\n for LF, \t for HT, \b for BS, \r for CR, \nnn for decimal (where nnn cannot start with a 0), \0ooo for octal, and \xhh for hex) to embed non-printable characters or string delimiters in strings
Warning: while these resemble C-style escape sequences, they are not the same. fetchmail only supports these eight styles. C supports more escape sequences that consist of backslash (\) and a single character, but does not support decimal codes and does not require the leading 0 in octal notation. Example: fetchmail interprets \233 the same as \xE9 (Latin small letter e with acute), where C would interpret \233 as octal 0233 = \x9B (CSI, control sequence introducer).
The important part here is that escaping the double-quotes character does not behave the same way as in the C programming language. With a little bit of trial and error, we confirmed that escaping double-quotes with a backslash character was causing syntax errors in the fetchmail script. This means that it was possible to insert arbitrary options into the fetchmail runscript. With the man page still open, we identified what would be the last step in our journey:
And that’s it. While we won’t publish any exploit at this point, we succeeded to execute arbitrary commands in the fetchmail container with fetchmail user privileges. That’s still not “full access to a Mailu server” as the vendor states but not bad for a short afternoon. Exploitation requires authentication, but if you have “open registration” enabled, this basically means anyone can exploit this. It would be interesting to know the actual install base, and we’re definitely looking forward to seeing more details from the vendor or the researcher.
Based on the nature of this vulnerability, we strongly encourage anyone using this product to immediately update to the fixed version or at minimum disable “open registration” if enabled to reduce the risk.