SPF mapping tool

Since the last time I wrote something about e-mail (March), I mentioned Sender Policy Framework (SPF). This standard allows anyone to publish information about which IP addresses are allowed to send mail on that domains’ behalf.
As SPF is quite complicated in some ways, I could not find a tool that would nicely list all IP-addresses which are allowed, so I made one myself! It clearly shows all directives and what it results in. All nodes are IP-addresses and all edges are directional arrows, showing which node led to each IP-address.
Tool is available on https://t.ted.do/spf/.
The colour of each node represents the result it signifies; green is pass, bright yellow is neutral, grimey yellow is softfail and red is a hard fail.

gmail.com's SPF record
gmail.com’s SPF record

Apart from being useful to check your SPF records, because I used the open-source library visjs, it’s also incredibly fun to play with. Each node has gravity and all edges are springy. Apart from the physics, it’s also fun to map out some domains and see all the different IP-addresses that are included in their SPF record.
Food for thought here: By allowing so many different providers (IP-addresses) in your SPF record, an attacker only has to compromise a single server in all that address space in order to succesfully allow a mailserver to accept his email as being from you.

Mail is hard

Obviously, the biggest reasons for acquiring a domain name are 1) having your own personalized e-mail addresses and 2) showcasing your personal website. For both these reasons, getting the basics working is a piece of cake. Getting things working properly, though, is a completely different story.
Since I acquired my VPS (Virtual Private Server – a virtual server that hides somewhere in the cloud) and had it set up right, with a webserver running in an LXC container, it was time to set up the e-mail part. Following along with tutorials online wasn’t very hard and before I knew it, I had e-mail set up. As I, wrongfully, remembered “reputation” seems to be a thing, I opted to relay all mail through my hosting provider since their reputation would hopefully be better than a fresh SMTP server. After checking whether logging in worked and running some free online tests against the server, I was satisfied that everything was okay.
A couple days later, however, I realized I forgot to set up IPv6 records in the DNS for the webserver and logged into the administration console. The first thing I saw when I logged in was that I had sent 1.007 mails in the last day… I had been hosting an “open relay” for a few days. Checking some popular blacklists (more like gray-lists), it was obvious I had been aiding spammers and my IP-address was blacklisted on a large number of them. Instead of messing with the settings, I opted to just remove the routing to the mailserver to put an end to it immediately. Later, I did some research on how to properly set up a postfix server, but somehow all of the tutorials I found were lacking on one point of the other.
Frustrated with this new development, I decided I would write my own MTA (Mail Transfer Agent). At the time of writing, I’m still working on it, slowly adding more and more features.
This brings me to my point: doing mail properly is hard!
A non-techy person would describe mail as filling in the recipient, writing a subject and writing the mail itself, followed by pressing “Send”.

Simple Mail Transfer Protocol

When I first learned about SMTP, I was having a lot of fun sending all my friends emails from “santa@north.pole” and they would have no idea what was happening. In time, however, there’s been a patchwork of security measures added on top of the 1982 specification, one of which is a completely new specification for SMTP, released in 2001.
In the very basics, sending an e-mail through an SMTP server is the easiest thing you can imagine, all commands are legible and logical, see the next example of me delivering a mail “by hand” to a receiver. As most people think, SMTP is not just the outgoing mail protocol, but the same protocol is used for receiving emails for your domain. In that case, the sender‘s SMTP server connects to the receiver‘s SMTP server to deliver the mail.
First, we need to find out what server to deliver our test e-mail to. This information, like virtually all e-mail meta-information, is stored in a DNS entry for the receivers’ domain. These records are called “MX” (Mail eXchange) records. To find such a record on a Linux machine, we use the dig command;

Continue reading “Mail is hard”

Stop leaking information

In the past I used to write my own simple CMS (Content Management System) for my own website and for friends. This ensured every website did exactly what everyone needed, but had to be maintained by me. WordPress takes all that hassle away and has an incredulous amount of themes and plugins available right out of the box. It also allows for an enormous level of tweaking. Each and every call is pretty much “hookable”, allowing anyone to write a plugin to do anything they wish when a function is called. This all allows for great flexibility, but for me – trying to host WordPress from my seven year old NAS – pages can take a long time to load. Up to ten second per page. Adding plugins from the store that promise caching, were only speeding up the site by a second or so as most of the PHP-code in most of the files was still being executed.
On the other hand, setup for a WordPress-site is so easy;
With the enormous user-base that WordPress has, as new exploits are found and released into the wild, hackers roam free and kidnap WordPress websites by the thousands. These websites are frequently used for phishing scams and hosting malware. In one event, a hacker group who infiltrated high ranking government officials for a country I can’t remember, used a couple compromised WordPress site as their C2 (Command and Control) servers.
With the (currently) most recent patch 4.7.2, a vulnerability was discovered in the REST-API, allowing anyone to post any message to any WordPress-website. Even though most actual WordPress users have no idea what a REST API is and why they are running it on their site, apparently it has been enabled by default starting in WordPress 4.7. A quick look in the admin panel showed no way of disabling this API either.

So… many… features…

There’s a tool available online called WPScan, which does exactly what it says. It lets anyone scan any WordPress installation and it will tell you so many things about the website. Apparently WordPress inserts version numbers everywhere, has dozens of features that are “always-on”, but (for me) lead to no extra functionality.
Extra features are not always a good thing. I mean, sure, for the administrator and the user, they probably are. But as in most cases, more features mean more code to maintain. As the codebase grows, you would expect the same for any bugs which can be exploited.
Googling for how to disable most of the WordPress-features, leads  to writing PHP-code into your /wp-content/functions.php  directly. This most likely works fine, but any WordPress update will update the file, deleting your lines in the process.
As such, I have taken matters into my own hands. Looking through the available plugins did not leave me with a very good feeling. Most plugins promising security either require payment or consist of dozens of files, leaving me no quick way to audit the code. By writing a “plugin” PHP-script, which needs to be enabled in the WordPress admin area, the script does not touch any core WordPress files and should never be manipulated by any update.
Instead of providing the entire file, with no context, I will do a quick rundown of most features I have disabled and why I have done this.

Firstly, complying with WordPress plugin dynamics

So, before we put any code down, WordPress expects to extract some basic information from the file, it looks a little like this:

There’s some information in there, which WordPress expects: an  author, a name and and description it can display for the plugin etc.
In  addition, there’s a quick check for the constant ABSPATH  as this is a constant set by WordPress and if it’s not there, the plugin is not requested  by WordPress and we better not call any functions.

WordPress “features”

There are a number of “features” in WordPress that I do not think of as features, such as:

  1. Generator tags on every page, specifying that WordPress was used to generate this page.
  2. An RSS-feed, which leaks data such as a version number.
  3. A REST-API for which I have no use and do not want anyone else to use.
  4. XMLRPC, which allows for “pingbacks” (saying: I linked to your page from my page!), but in the past have been used for DDoS attacks. Personally,  I have no interest in who would link to me.
  5. Adding query parameters to stylesheets, specifying which WordPress version I’m using.
  6. Providing a nice readme.html file which sits in almost anyones WordPress installation, telling anyone who’s interested what version I am running.

For most of these, they “leak” information that I do not want everyone to know. This includes, for example, my WordPress-version. Even though I update my WordPress whenever I can, this does not mean I am not a human and cannot forget.
For most of the above, I am simply checking the URL and killing the script when it detects a URL being requested that I do not want available. For others, I have simply reduced the file permissions to  “000”  (no read access, no write access, no execute access), meaning my webserver is not able to read the file and thus shows a “Forbidden” screen. This also means WordPress will not be able to update the file or change any permissions on it. Effectively taking it out.

Disabling WordPress “features”

For the readme.html, all I did was reduce the file permissions to 000, allowing nobody to  access to the file.

Hooking into function calls

Most google results for “disabling xxx wordpress” will lead to adding code to pages which consist of add_filter('filter_name', '__return_false');  meaning they will no longer function.
I have combined a few of those here, mostly found through Google:

In addition, as the plugins PHP-code is called on each and every page, before outputting any data to the web browser, I have resorted to simply killing the script on specific requests:

If the URL requested contains /feed , xmlrpc.php  or /wp-json , it simply exits the script and shows no output to the user. This is the most effective way I have found of disabling these “features”.