On Saturday morning I woke up to 120 emails from ASafaWeb, not because it really likes me but because it was in pain! One thing I did very early on with the project was to implement elmah and make sure I get an email notification when anything happens that shouldn’t. It won’t stay this way (for reasons you’re about to see), but it’s a good way of keeping an eye anything that goes wrong very early on.
What elmah does is keeps a nice little log of all the things that happen on your site which shouldn’t; internal server errors, illegal URL formats and most importantly in this context, page not found errors (the classic HTTP 404). You can also log your own custom messages as well, but that’s another story. Elmah makes all this wonderful information available via a custom handler which gives you all the details right within your site (don’t forget to secure this!)
Here’s what I awoke to:
There are two particular points of interest here:
- The paths being requested: elmah is saying no controller exists for these (it’s an MVC app), but the interesting bit is the actual paths themselves. You’ll see lots of references to “sql”, “php” and “admin”.
- The time of each request: All of this happened within the space of about a minute. Something is clearly not right here.
When I drilled down into one of these requests, I saw something similar to this:
Actually, elmah gives you the whole YSOD with stack trace but that’s not very interesting when it’s a 404. The bits above are all the server variables which includes the interesting items you’ll see highlighted, most notably that the user agent is the “Gootkit auto-rooter scanner”. After having a bit of a laugh (“root” is interpreted a bit differently down under), a quick Google reveals all about what Gootkit attempts to do. Essentially it wants to break down the door to your site and infect your pages with redirects to nasty locations.
Of course the other piece of information we get out of all this is the IP address from where all the excitement originated. I couldn’t get this to resolve to a geo-location, but even if it did, it’s quite possibly some poor innocent individual who has just taken a hit of malware.
What I thought was most interesting about all this is that not only has ASafaWeb not launched, I’ve not even published links to the website. Actually that’s not entirely true because it’s on the Twitter account but that’s it. The point is that Gootkit found an altogether obscure site that nobody uses and hammered it with malicious requests. Keep this in mind the next time someone claims their site is “safe” because nobody knows it’s there!
But the other thing I thought was interesting – and this is the crux of this blog post – is that this episode didn’t worry me in the least. Here’s why:
- I don’t have any secrets I need to protect. The best way to keep a secret is to never have it and I’ve consciously decided not to keep secrets for this very reason which includes not keeping track of which sites are being scanned.
- The one secret I do want to protect (ok, so there is just one), is the password of my beta testers. I’ve well and truly taken my own advice here and used ASP.NET’s membership provider which implements cryptographically random salts before a SHA1 hash is created. Edit: this should be SHA256 - the default hashing algorithm changed to SHA256 in .NET 4
- In an absolute worst case, say the apocalyptic destruction of ASafaWeb, I can redeploy to AppHarbor in about 5 seconds. I’m going to talk more about these guys in the near future but I can’t tell you how reassuring it as to have such a powerful, immediate ability to redeploy.
- I know exactly what Gootkit was trying to do to ASafaWeb outside the expected bounds of operation because I have the elmah log. No log = no ability to do this.
So all in all, this was a very uneventful event which is what makes it worth writing about. That and the fact that you can’t hide from the bots! This event and other recent experiences reinforce some key messages about building publicly facing web apps:
- Anything publicly accessible is a target – be ready to get attacked from day one.
- Know your enemy – make sure you have some form of logging that you can easily access and preferably be automatically notified about.
- Don’t keep secrets if you don’t have to – it’s the best possible way not to disclose them!
- Be able to redeploy in a heartbeat – its awesome assurance for when things do go really wrong.
And all of that is dead easy.