BanMoron

Yet another blockchain yada yada?

Not at all! This time it’s not about blockchains or Emercoin. After all, we can be doing something apart from our main project, can’t we?

This time, we have built a nifty tool to protect your Web server against the omnipresent hackers, who are on the constant lookout for website exploits to get access to your servers and do something obscene to them. The tool is called BanMoron, and here’s how it works.

BanMoron is a small C program whose source code is shorter than this article. Its goal is to prevent attempts to hack the web server through typical vulnerabilities of web platforms such as Wordpress, PhpMyAdmin, and the like.

Its algorithm is pretty simple:

  1. The program is installed upstream of the web server as a 404 (“page not found”) handler. Thus, it is launched whenever a hacker tries to access a non-existing page or script.
  2. Once started, it analyzes the REQUEST_URI, looking for substring patterns commonly used for accessing and hacking certain system sections (such as setup.php).
  3. After finding a pattern, the program applies its associated response module. If no pattern is found, it just shows the usual 404 page.

At the moment we have built the following response modules:

  • ban_moron_pf — adds the client’s IP address to the pf firewall’s blocking table. This blacklists the hacker’s IP address, and all further requests from that address are ignored. To prevent firewall overflow, the program daily removes IP addresses that made no connection attempts within the last 3 days. Removal is done via a crontab command — an example for pf is provided in pf.crontab.
  • zip_bomb — responds with a zip bomb, an endless file stream looking like a heavily compressed HTML file with infinitely nested tables. This is meant to deplete the resources of the hacker’s computer and incapacitate the attacking script. Unfortunately, this approach is not that much effective against malware that uses CURL, which just ignores the zip stream. But it can still work pretty well against those who want to, say, download a Bitcoin wallet using the browser.
  • zip_ban — a combination of the two. First sends a zip bomb and then bans the IP address.

The program has a modular design, so it’s easy to add new patterns and response modules.

It is also lightweight, with a binary file of just 6 kilobytes (what was the last time you saw a 6-kilobyte program?), and requires only one shared library, libc. Thus, it doesn’t reduce the web server’s performance compared to a standard 404 HTML page.

To make it even quicker, we used the Rabin–Karp pattern matching algorithm. It allows finding multiple patterns in one run, with O(N) complexity. Universal hashing makes it virtually impossible to come up with a special REQUEST_URI that would decrease the hash function’s efficiency.

You can download the program for free from Emercoin GitHub.

Here are answers to some frequently asked questions:

— Why “BanMoron”?

Because the goal is to keep morons at bay and not let them break something in your server.

— Why do you call hackers morons?

Because they are. They take a ready script written by other people and don’t even bother, or are just not smart enough, to customize it. And the request structure makes it obvious which exact script they had used. They are much like those “activists”-slash-hooligans who take rebar pieces and shatter ground-floor windows. Both activities are indicative of the same level of intelligence.

— How is it better than fail2ban?

Fail2ban uses a different approach. It runs a background daemon that monitors logs for activity patterns and bans corersponding IP addresses. In order to work, fail2ban must detect an activity by processing many requests. Given that Apache buffers log entries, and that reading from the log is not far from instantaneous, fail2ban has a latency of several seconds. Besides, it needs several 404 events to happen in order to detect an activity and respond. But those who write exploits do not sit on their hands. Some of them have now adopted the practice of sending a lot of parallel requests. One of the goals might well be to embed the exploit before fail2ban responds.
In addition, fail2ban is written in Python and requires its interpreter to be constantly running in the background, making it even slower and more resource-intensive.
BanMoron, in turn, only starts when an action is required and does not use system resources all the time. Finally, it bans the hacker right after their first request. Now that’s the speed you need.

— Why did you write it in C?

For several reasons.
Only binary programs allow process priority to be increased using the sticky bit. In interpreted programs, the sticky bit is just ignored. And we need it in order to change the permissions from www to root, to add IP addresses to the morons ban table.
A compiled binary program is lightweight and does not require starting the interpreter with its own heap of shared libraries.
C is a classic language that is available in all operating systems.

— Why did you hard-code the rules? Wouldn’t it be better to add them to a config file?

Right, and how would we tell the program where to look for it? The web server doesn’t allow the transfer of configuration parameters to the program from itself. We could of course use mod_rewrite and send the parameter via QUERY_STRING, or something along these lines. But we thought this would be both administration-heavy and inefficient. We would need to read .htaccess, start mod_rewrite, alter the string, and then have the program open and read the file according to that string. It’s like when Admiral Benson says in Hot Shots!, “Holy Cow! My cap blew off! Swing her round. We’ll pick it up.” We just don’t think it’s worth it.

— Why did you use some “pf” for a firewall?

Because we built BanMoron on FreeBSD, whose default firewall is pf, which perfectly suits our needs [https://www.quora.com/Which-is-better-OpenBSDs-pf-or-Linuxs-iptables]. If you want the program to work with iptables or any other firewall, just write corresponding modules (a handler and config examples), make a pull request to GitHub, and we’ll gladly accept your contribution. The humanity will thank you.

Oleg Khovayko, Emercoin CTO
(Russian version here)