Here’s another *easy* way to help with those pesky wordpress brute-force logins we have been hearing about. Most automated attacks make a lot of assumptions. Like where your blog’s login page is located, and what information is needed to login via that page. It’s really easy to take those assumptions and make them wrong. The trick is doing it in a way that doesn’t mess up your real users, and can be done without modifying source code.
I am writing this for the much-outdated Apache 2.2, since that’s what my server is running. The 2.4 version can easily (and more elegantly I might add) do the same thing, but uses different modules. This example uses only mod_rewrite and mod_usertrack, which should make the scope a little wider, since it’s something that many users will be able to implement in a .htaccess file.
So, this is so laughably simple to setup (only 7 lines in the config file!) that you might think it’s useless (and in a week or two it could be,) but the simple truth is most brute-force hacking tools can’t do a lot of things that a real web-browser does all the time. Like follow 302 redirects, and use session cookies. It’s very easy to do this with Apache in a way that doesn’t break the login process for normal users, but will trip up many automated attack tools.
So the premise is this, if requests are being generated by a real user that user will likely visit via a link (or maybe even a saved bookmark) to the login page, they will fill out a form, and then submit it. If it’s an attack script, it’s likely got the POST target hard-coded. So here’s an easy way to deal with that.
- When a request comes into the login page, check if there is a session setup for it.
- If the session is valid, process the request.
- If it isn’t, perform a 302 redirect to a (rewritten) version of the login page that will set the session. (Discarding, and ignoring the POST form data in the case of a login attempt!)
It’s really that simple. Of course there are some gotchas … the session data (either name or value) should be hard to guess without following the 302, and setting the actual cookie, and the URL that sets the session should also be unique to the site. Unfortunately, mod_usertrack wasn’t built for this, and the session payload is a fixed value (mod_session in 2.4 offers much better options.) So to do this without any external components to Apache 2.2, I decided that a unique cookie name is good enough.
I was nice enough to generate random values for each load of my example here :)
I can already hear your thoughts … but that doesn’t validate anything! True, but if you really want you can do that through by adding on mod_security’s session tracking on top of the above measures. See here and here for more on that.