Editor’s note: This post was originally published on Scott Helme’s blog, and was reprinted to ZDNet with permission.
I was recently invited to take part in some research by BBC Click, alongside Professor Alan Woodward, to analyse a device that had quite a lot of people all excited. With slick marketing, catchy tag lines and some pretty bold claims about their security, nomx claim to have cracked email security once and for all. Down the rabbit hole we go!
You can find the official nomx site at https://www.nomx.com and right away you will see how secure this device is.
“Everything else is insecure.”
“The world’s most secure communications protocol.”
“Nomx ensures absolute privacy for personal and commercial email and messaging.”
“DID YOU KNOW THAT EVERY SINGLE MAJOR EMAIL PROVIDER HAS BEEN HACKED?”
That’s a lot of pretty big claims for such a small amount of space on the homepage so I was more than happy to get involved in investigating the device. I met with the BBC in London and they provided the retail packaged device that was to become mine for testing purposes. It’s pretty nice looking with some fancy packaging and you’d hope so too with a starting price of $199!
Starting the investigation
Before I even powered the device on the first thing I wanted to do was open it up and see what was inside the case. If possible it’d be nice to take a backup of any flash storage or firmware on the device to have a backup that I could revert to if I break something and also a reference point of how the device was when I received it if needed. I flipped it over and started to open up the case expecting to find a fairly basic PCB inside. It had micro-USB for power and an Ethernet port on the side, with the box measuring 14cm x 14cm (5.5″ x 5.5″).
Now, as soon as I looked at this device I already had a really bad feeling. First of all, through the vent holes on the top I could see that the PCB inside took up about 25 percent of the footprint of the device, the case was considerably larger than the PCB inside it, which seemed odd. Second, the MAC address on the bottom looked familiar – really familiar. Putting that little thought to the back of my mind I cracked open the case by removing the standard screws in the bottom to confirm my initial suspicion.
Turns out that MAC address was really familiar because the prefix is from the Raspberry Pi Foundation. They own the B8-27-EB assignment which you can search for on the IEEE website. Select ‘MAC Address Block Large (MA-L)’ from the drop down menu and filter on ‘Raspberry’.
To be clear, I have absolutely no problem with the Raspberry Pi at all, it’s an awesome little device and I’ve used it in a few projects of my own. I wasn’t however expecting to find one nestled in the corner of a large box that claims to provide a completely secure and proprietary email protocol! Because the device is just a Raspberry Pi under the hood that made taking a backup really easy. I simply popped out the Micro SD card and put it in my card reader and used Win32DiskImager to take a full clone of the card.
Firing up the device
Now I had a backup of the memory card I could go to town on the device itself and not worry about causing irreparable damage. In the worst case scenario I could always flash back to a stock image and start again without any problems. Knowing it was an Raspberry Pi I grabbed a spare monitor and keyboard and decided to hook straight up to the device and boot it, I was pretty surprised when it started booting into Raspbian. Once I hit the login prompt I tried the default credentials to no avail took a few shots at the root password too, no joy. It’s pretty easy to reset the root user password on an Raspberry Pi though so I took the card out, tinkered with it on my PC and booted it back up again to a root shell.
Yes, there are a few things to be concerned about in those images but the main point is I had a root shell so I could reset the root user password and SSH in to the Raspberry from my main PC instead of using a crappy monitor and keyboard. I dropped my SSH key in there and also fired up WinSCP from my desktop to take a full dump of the OS contents to work with. The device was running Nginx so I wanted to look where the web root was to browse through the source and I also saw a couple of other programs starting on boot like dovecot and postfix. There were quite a few interesting things to look through!
I wanted to see exactly what was running on the device so I did a quick run down of the software that was installed and how it was configured, here’s the list of what I could find:
- Raspbian GNU/Linux 7 (wheezy) – last updated 7th May 2015
- nginx version: nginx/1.2.1 – released 5th June 2012
- PHP 5.4.45-0+deb7u5 – released 3rd September 2015
- OpenSSL 1.0.1t – released 3rd May 2016
- Dovecot 2.1.7 – released 29th May 2012
- Postfix 2.9.6 – released 4th February 2013
- MySQL Ver 14.14 Distrib 5.5.52 – released 6th September 2016
It’s interesting to see such outdated versions of software on there, if the device was built even remotely recently I’m not sure how you’d end up with such seriously old versions installed. I had a look for any auto-update mechanism that I could find but couldn’t see anything on there. Perhaps the device will trigger some kind of update later when I go through the setup in the web interface so all may not be lost just yet. For now, it was interesting to know that everything on there seemed to be pretty standard for your everyday mail server, there were certainly no hints of anything proprietary.
Setup — server
After my quick dig around at the command line I decided to open up the browser and go through the setup process. You have to get the IP of the device from your router or DHCP server and connect to it in the browser.
We can’t login just yet though as we don’t have an account on the device so we have to manually navigate to the Setup page…
Further down the setup page we can create our own ‘superadmin’ account and all we need is the setup password.
The only problem is I couldn’t find the setup password anywhere so I had to hit the lost password link. This prompts me to create a new setup password and then instructs me to edit a PHP file on the device and paste the password in there!
Now, I’m not sure how someone is supposed to edit this PHP file right now because I can’t see the SSH instructions anywhere nor can I see the setup password anywhere either. To save you all the trouble I extracted the hash of the original password whilst I had SSH access and you can see it here:
It turns out this was pretty easy to break after I had a quick dig in the source to see how they generated the hash.
So, yeah. I also had a dig around in the config file and stumbled over this which is used during the setup process.
Anyway, the main point for now was that I managed to crack the setup password, which was
death, with a quick tweet asking for help or I could have set my own if I needed so I could create an account and login to the device.
With my ‘superadmin’ account created I could now begin the process of setting up my unhackable (not) email server. Interesting that my browser thinks the login page isn’t secure huh.
Once logged in the site is pretty barren and the only real option is to add my new domain that will be used for my email address.
So I followed through the instructions and hit the ‘New Domain’ button where I was presented with the following screen.
I’ve no idea why the device can only support domains purchased through GoDaddy (I do) but I followed the instructions and purchased my domain, inserting the API keys into the screen as requested.
At this point I won’t bore you with the rest of the terrible web interface but you setup a few mailboxes with credentials that can then be configured in your favourite mail client. Everything seems pretty darn standard for “The world’s most secure communications protocol.”
The setup instructions also ask me to open a series of ports in my router and forward them to the nomx device:
- port 26 / TCP
- port 465 / TCP
- port 587 / TCP
- port 993 / TCP
- port 995 / TCP
These must be the ports for their protocol! (Hint: these are standard email server ports) So, I decided to set my email account up in Thunderbird and sure enough, it didn’t work. I couldn’t for the life of me get this thing to work properly even just sending a basic email until I realised that they don’t ask you to open port 25 in the instructions which is required as the standard SMTP port! I will detail more on what port 26 is for later but once I opened up port 25 I could at least send and receive email. Well, I could almost send and receive email.
Setup – client
I use Thunderbird as my local mail client so I got to work on adding my shiny new and super secure email address. It’s pretty easy going and just requires the usual parameters to setup an email address.
Everything looks good, but then something really unexpected happened that I just can’t explain. Contrary to the claims all over the nomx website, Thunderbird is throwing up some warnings telling me that the email server needs a security exception. Shocker.
The same thing also happens again when I try to send an email!
The only problem with trying to send an email from a dynamic, residential IP address (the default here in the UK) is that you look incredibly ‘spammy’. ISPs and email providers just don’t expect email to be sent from an IP like this and it’s often something that malware would do. As a result, it gets blocked. It doesn’t just go to the Spam Folder either, in a lot of cases the mail is rejected and sent back. This was exactly the case when I tried to send an email to my own Hotmail address and it was immediately returned.
This is great news, I can’t send emails from my new super awesome secure email server to anyone with a Microsoft email account because they just return it. The story is pretty similar across the board with the email either being returned or put straight in the spam folder of the recipient. I tried against Gmail and a few other large providers and found that not one of them made it to the inbox anywhere. After I got a few emails bounced I thought I’d check to see if my IP had been flagged yet and to my surprise it had already been placed on three blacklists!
This really isn’t good unless you plan on constantly chasing your IP off blacklists or frequently changing your IP address to avoid it being blacklisted too widely. Certainly things we don’t want to be thinking about.
The IP address point above got me thinking, changing my public IP at home can basically happen at any point, I can power cycle my router and get a new one if I like. This device must have some kind of mechanism to poll a DDNS provider and give me a host name that always resolves to my home address. I could see in the DNS that I had 2 A records set,
localmail, that I hadn’t set and one of them was my public IP and the other was the internal IP assigned to my nomx device (bit of an information leak?). I certainly hadn’t set these so it must have been done for me. I ran grep over the code that powers the web interface and couldn’t find any matches for the subdomains so I took a guess and dumped out the crontab of the root user which turned up something.
There was a script being run 60 seconds after the device boots and then again every 15 minutes which certainly sounds like a good candidate for a DDNS client! I dumped the script out which turned out to be a rather hacky python script. In short it did a few things:
- Read in some config files from /var/nomx which listed public IP, domains etc…
- Checked to see if current public IP and other variables matched those on disk.
- If they don’t match it polls the GoDaddy API and sets/updates the DNS records.
- It also configures some UFW rules to ensure the necessary ports are open.
So, those GoDaddy API tokens that we required earlier were so the device can use GoDaddy as a DDNS provider! I can’t begin to explain how wrong this so I’m not even going to try. It’s dreadful.
The “trick up the sleeve” of this device is the ability for two people that own one to perform a “handshake” between their devices to setup a secure connection.
“To send to other nomx users who have secure accounts on their nomx PES, you will need to create, what we call, a handshake between your nomx device and the other nomx device. You can do this by entering the Public IP of the other nomx device and the email address or domain (if entire domain is hosted on other nomx device).”
Now, providing the email address and public IP of the other device didn’t really seem like it was going to help us establish any kind of “handshake.” I was expecting perhaps some kind of out of band communication of a pre-shared key or token for verification but no, nothing. You simply enter the email/domain of the other person and their current IP address (that they have to find from somewhere).
Once I’ve entered those details I’m returned to the main screen where I now have an entry representing the “handshake” I just did.
The weird thing is that absolutely nothing happened on the network when I did this. Nothing. There was no outbound traffic of any kind, and yes I’ve tried it with valid details in the field, but I can also confirm that nothing happens by looking at the source code. Nothing happened when I did this because nothing was supposed to happen. The entire
create-handshake.php file is only 64 lines of code long. Of those over 20 are white space or comments and there’s a few more for includes of the header/footer etc… The only thing of any significance that takes place in this file is that a new row is inserted into the database in the
handshake table. Sure enough, I now had an entry in a table called
handshake on the device.
The only problem was after running grep over the code directory I couldn’t find any instances of where this is used other than when you create the handshake or when they are listed on the main page. None of the rest of the code makes reference to it. It did seem odd though that the default SMTP port is 25 and there was a reference here for port 26, which is listed in the nomx documentation as the port required “for nomx to nomx communication.” As I was already way on my way to believing this was just a bog standard web server installed on a Raspberry pi inside a big case doing absolutely nothing fancy, I relied on some of my postfix knowledge and started to dig around in the postfix config directories. Inside
/etc/postfix/mysql I did find a file called
mysql_handshake.cf which contained the following.
This appears to be doing something like what we want and is taking the smtp, destination and port columns and joining them together. Looking at my earlier output from the handshake table that’d give me something like
smtp:184.108.40.206:26 which would mean it was sending emails to port 26 at the destination and not port 25. After running over the entire postfix directory with grep though I couldn’t find anywhere that this config file was mentioned, I would have expected to see it referenced in
main.cf but no. To see what postfix was doing on port 26 I had a look at
master.cf and sure enough, there was something defined for port 26.
So, it certainly looks like it’s doing something on port 26, although it looks like it’s doing a whole lot of nothing out of the ordinary. To try and solve it and provide conclusive proof, we setup 2 nomx devices and went through the handshake procedure. We then closed port 26 on the firewall and tried to send an email. If the device actually uses port 26 then the email will fail, if it uses port 25 it will send just fine. After testing this the email did fail to send so it does mean that it is sending to port 26, which is absolutely no benefit whatsoever. The other interesting point this raised was that the IP address is hard-coded into the database and never updates so as soon as the IP of the other party changes, everything will break.
Web app testing
The next item on my list was the web application and having access to the source code made this a whole lot easier to test. After a cursory skim I could see that it was vulnerable to XSS and CSRF in countless places. This alone presented a pretty significant risk given that the web interface is effectively used to control the mail server.
With the ability to abuse CSRF you can carry out any action that is present in the web interface, which includes adding and removing domains, adding and deleting mailboxes and adding and configuring an SMTP mail relay. Just think about that one for a second. To prove the device was vulnerable to CSRF, beyond seeing there were no mitigations in the code, I fired up Fiddler and crafted a HTTP request to create a new mailbox with my session ID.
This created a new mailbox for [email protected] and set the user credentials so I could now login to send and receive emails from this address. This means I can now create arbitrary mailboxes on your domain and then send and receive emails from them.
That’s pretty devastating when I can create anything I want like [email protected], [email protected], [email protected] or any one of the countless and highly offensive names I can think of to then send emails from your domain. Of course, with the ability to create a mailbox comes the ability to delete a mailbox which I can also do with CSRF. Launching this attack is pretty easy and I create a basic page to provide my personal details for the handshake and could simply direct a nomx user there. If they want to setup a handshake they will view the page that contains my details, and the CSRF attack, and then login to their nomx device allowing for successful delivery.
I wanted to take this one step further though and not have to have the user do anything at all. I wanted them to simply visit a page, even for a brief second, and have their device totally compromised. Turns out it wasn’t that hard…
Undocumented admin account
After delving into the database on the device and browsing through a few tables, I saw something that horrified me. There was another admin account alongside my own that I hadn’t created.
I extracted the hash and posted it to Twitter to see if I could crowd-source the input and it didn’t take very long for someone to come back to me with the answer.
The password was, quite literally, “password”. Sure enough I immediately opened up the web interface and I could indeed login with the username
[email protected] and the password
password. I had full control of the device. This is inexplicably bad for more reasons than I care to list but coupled with the above CSRF attack I now don’t need to depend on the user to be logged in to the device to perform administrative functions, I can simply login to the device with these admin credentials and do anything I like. All this requires is two simple iframes on a page.
I owe a thanks to Paul for helping me perfect the payload here, I was tackling it the wrong way until he gave me this much easier solution.
With these two iframes embedded on a page, if I were to visit that they would first authenticate me to the nomx device and then create a new mailbox of my choosing. I can then login to my brand new mail account on that domain and use it. You can also change the password of existing mailboxes because it doesn’t ask for the current password to change it, allowing me access to all of your emails. You can configure an outbound mail relay for the device to intercept future communications and a whole bunch more.
All an attacker needs to do with this is know the IP of the nomx device. Given that you get the client IP address thanks to the WebRTC extension of HTML5, iterating through the rest of what is probably a class C address space is easy and can be done in a flash.
Let’s not forget the nomx device also sets a
localmail subdomain in DNS that contains the internal IP of the device! This is about as a bad as it can get and results in total compromise of the device for simply visiting a single webpage for a second or so, no user action required.
Update: Doing an update like this, prior to publication, is a little unusual because I’d normally just make the changes and not need to mention the update as the article isn’t finished yet. I’ve decided to add an “update” though to show you an interesting few steps in the process that I had to go through. I was a bit confused about how the whole setup process would work for a user receiving one of these devices, I had to extract and crack a hash to get it to work. I’ve seen poor documentation for new devices before, something that can be forgiven, but I soon learnt that my device didn’t come with any paper documentation and it turns out it should have. I got a copy of the paper documentation and started reading. It also didn’t mention the setup page anywhere because, as it turns out, you aren’t supposed to use it at all. Your username and password to login to the device are listed in the documentation and it’s so bad I had to scan a copy just to show you.
So this admin account I’d found was actually supposed to be there! Not only is this utterly ridiculous there’s also nothing prompting the user to change this password in the documentation nor are they required to change it on first login either. If the user never changes this password then you can use CSRF to attack the device with the default credentials. “Aha,” I hear you think, what if they do change the password! Well, it turns out that’s not a problem either.
Creating an undocumented admin account
As I mentioned further up the page, there was the setup.php file that I originally used to create my own account but now seems to be redundant given our default admin account. For my CSRF attack to be 100 percent reliable though, and work around the user possibly having changed their password (unlikely), I could just create my own admin account on the device via CSRF.
This will now create me a brand new admin account on the nomx device that is completely undetectable to the end user as there is nowhere to view/edit admin accounts on the device. I can now use this admin account for any subsequent CSRF attacks and be sure that the credentials will work and allow me to authenticate. This allows for a full compromise of any nomx device by an external attacker via CSRF or a local attacker on the network can either authenticate with the default account or create themselves an admin account to login with.
There were a few other issues I came across whilst testing this device, some of which would be simple to fix and others not so much.
- There are no automatic updates configured anywhere on this device that I can find. It’s running hideously outdated software and there appears to be no mechanism to update it at all.
- The device doesn’t setup and configure SPF, DKIM or DMARC, which a good email provider/server should do.
- The Relay Settings page writes user input into a config file without any sanitisation. This config file is then read in by Postfix. At a minimum I’ve managed to corrupt the config so Postfix won’t start but perhaps there is an additional attack vector here.
- The code is riddled with bad examples of how to do things and it seems was developed by one guy called ‘shawn’ whose name appears throughout. They narrowly avoided one persistent XSS vulnerability by stripping tags followed by the comment
/* should we even bother? */.
- There are a lot of edited and half baked files where the .php extension has been changed, presumably to stop them being visited in the browser. What this results in is the browser simply downloading the files instead.
- The device uses self-signed certs throughout and they aren’t even device specific. It’s using the default
ssl-cert-snakeoil.keyin the Postfix config.
- Their main company website has the themes default 404 page with links to download it and to the Gantry theme framework: https://nomx.com/404
- The device depends on the GoDaddy API to update its DNS record, if this changes or goes down/away then you have no mechanism to update DNS. There’s also the issue of the 1 hour DNS TTL when your IP changes which means emails don’t make it through for a short period.
- The device only sets the 2 subdomains (
localmail) in DNS. With no MX record set it’d be wise to set an A record for the bare domain to help with external mail delivery too. Ideally they should just set an MX record…
- Each user has a configured mailbox size of 10MB and without being able to SSH into the box you can’t change this. Good luck sending any attachments.
- They have what looks like an old config file on the disk that contains what looks like genuine user credentials.
- The root user had various files containing things like the bash and mysql history in the home directory which contained several domains/emails of people who I assume helped to test the device.
- The file
/var/mail/rootcontains notification emails going back almost 2 years.
- There are several files in the web root that have bad extensions so can be directly downloaded in the browser.
- How could I not mention security headers! There are a few headers that really should be set here like CSP and XFO at a minimum. Setting others like XCTO and XXP certainly wouldn’t hurt either…
- There are certain times when the box seems to throw 500 errors for no reason like when you try to access robots.txt, which doesn’t exist.
Is this a scam?
It would be very easy to conclude that this is a scam. The device is running standard mail server software running on a Raspberry Pi, most of which is outdated. They have presented at countless tech shows and can be constantly found making bold statements of “absolute security” yet didn’t pick up a CSRF vulnerability in their web interface.
Take this snippet for example:
We have things like “secure protocol and device”, this box is using SMTP with self-signed certificates. The “nomx network” and “absolute assurance”– as far as I can tell the company isn’t even eating their own dog food! You might not think they’d want to run some Raspberry Pi in a box in their office, but fear not, they also have a business solution.
On one of the pages on their site, that doesn’t seem like it’s intended to be public just yet ( link), they also announce a $10,000 bounty!
Needless to say I will be buying one of those when they release it to claim the bitcoin, assuming the device doesn’t cost $10,000!
One good thing
The only good thing I can say about this product is that it does not create an MX record for your domain, upholding the “no MX” in the name. I’ve no idea why not having an MX record for your domain is a good thing, but, it doesn’t create one nonetheless. The python script that runs every 15 minutes only adds A records for
localmail, nothing else. Interestingly, the GoDaddy API client that they use doesn’t support MX records anyway, so I’m not sure if it was built around that limitation or it was a happy coincidence. This means of course that almost no email providers can send emails to you because there is no MX record, which is kind of how email works.
Following are the details for the disclosure timeline, all times GMT.
14 March 2017 19:32: Response from [email protected] asking for details.
15 March 2017 15:02: Skype call with Will to demo CSRF PoC and highlight various issues. Initially I was told this was a ‘client side issue’ and that I had a ‘problem with caching’ but assured him this was a genuine threat.
18 March 2017 18:10: No followup from Skype call so I emailed to confirm details. Advised I’d like to work to 30 day disclosure policy due to severity of issues.
19 March 2017 23:24: Email from Will advising he would get back to me “in the next couple of days”.
30 March 2017 18:39: No response from Will after 11 days so chased via email.
30 March 2017 22:28: Will claims to have a sent a response and has forwarded the same email to me again which doesn’t arrive.
31 March 2017 00:25: Will copies the text of the previous email into a new email which does arrive. Key points:
- “We’ve started to update/upgrade/replace any nomx devices which may have been affected by this issue.”
- “We’ve advised them that they should not use the nomx admin while surfing any other sites which contain malware or were otherwise compromised”
- “We’ve already completed 100% of the initial notification effort and we are prepared to provide new nomx devices for any affected users free of charge.”
- “We’ve also checked and, to date, there have been ZERO devices affected by this issue.”
- “In appreciation, I’d also like to provide you personally with a new nomx device. Just send me your address. Alternatively, we can send you a new header file for the interface which prevents any potential CSRF.”
- “As we developed and continue to develop nomx, we have had two of the largest security firms provide remote and “in hand” vulnerability assessments on nomx. We are providing them with your findings as well.”
31 March 2017 10:59: Replied to point out inconsistencies in email:
- There is no apparent update mechanism, asked how to update my device.
- Asked for a copy of the notification sent to consumers.
- I’m unsure how they know “ZERO” devices are affected, asked for clarification and details of the investigation.
- I gave consent for my details to be passed to the 2 penetration testing companies so that they could liaise directly with me if needed.
- Address provided for shipping replacement device.
- Asked why advice to not browse multiple sites given if CSRF has been patched.
31 March 2017 16:52: Asked for confirmation of receipt of earlier email given apparent email issues.
4 April 2017 11:13: Asked for confirmation of receipt of earlier email given apparent email issues.
4 April 2017 16:16: Will asked for “a few days” to respond.
11 April 2017 14:13: Will responded asking for a 30 day extension to the disclosure. He also said he would submit a CVE and “credit” me with the finding.
11 April 2017 14:19: I responded asking what the 30 day extension was required for as 100% of users had been notified and a patch or replacement device was available as per prior emails. Given the notification and advice provided the issue should already be considered public. Advised that unless there was a reason for the extension I would disclose as planned.
18th April 2017 12:44: Dan Simmons, senior producer of BBC Click, emailed Will to let him know that he would be covering it on the show and revealed that Alan and I were working with him. The email outlined all of our concerns and contained some questions from BBC Click.
20th April 2017 02:07: Will responded: “Thank you and I will be in touch in the next few days – and we can wrap this up.”
26th April 2017 15:00: Publication of this blog post. Outstanding points:
- I have not yet had shipping confirmation of my new device, despite providing my address.
- I have not yet received a copy of the notification sent to customers about the issue.
- There has been no notice on their website or social media about the update/recall or replacement.
- My device has not received any updates and is still vulnerable.
- No details have been provided about their investigation to determine no devices were affected.
- There has been no further response to myself or the BBC.
It seems that Will has a patent pending for this device which you can read here. The introductory text seems to raise a few questions of its own.
You can catch the full details on BBC Click this weekend on the iPlayer!
I’ve published my full PoC code and the contents of the devices microSD card in a GitHub repo.