Yesterday, my blog was hacked. I woke up at five am in the morning to write a new post and discovered the following:
Frack. Frack for the sake of the time it takes to fix this (I’ve discovered that time is a very valuable resource, especially in IT).
I’m not going to go into my opinions about the motivation or intentions of the attacker - suffice to say it’d be a scolding essay about maturity and what matters in life.
Point of attack?
My initial thought was that the shared web server had been compromised. Up until this point I used a hosting provider who I had no faith in. The server had had unexpected downtimes (the longest spanning three to four days) and speed problems.
I used a reverse IP checker tool to see if any of the other sites on the same machine were affected. About 10% were.
Server access logs looked normal - nothing like someone was attempting (and finally succeeding) a brute-force-ish approach. Wordpress file modification times and contents were fine, too.
The other possibility is of course the database. Unfortunately, I couldn’t find the string anywhere. I run a network installation of wordpress and the other domains hosted on the same files, database, were fine - so the attack must be living on the database and only on tables associated with my blog.
I wrote a letter to the hosting provider, asking them to look into this from their end and to notify the other affected customers and went to work, deciding to deal with this later.
At it with a rested head
Cross-Site Scripting attacks are a type of injection problem, in which malicious scripts are injected into the otherwise benign and trusted web sites. Cross-site scripting (XSS) attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end-user.
The blog engine had been tricked to store and then serve up a snipet of malicious code that transformed the appearance of the blog dramatically, making it practically useless.
The code that is injected via a XSS attack could be whatever - code that redirects you to a porn website; something that tries to invade your privacy or in this case, just some digital grafiti. The phrase “Algerian to the core” cannot be found from blog files or the database because it is encoded and then decoded on runtime.
Fixing the problem
A search for the encoded text in PMA quickly found the exploited record in the wp_options table.
The attack had targeted a Widget and replaced its contents with a script. Looking under Appearance -> Widgets revealed that my previous widgets had been deleted and replaced with a Text Widget that served the malicious code.
Delete the widget and suddenly everything works again. The blog name and character encoding (Settings -> Reading) also needed changing. The encoding was set to UTF-7.
I never learned the original point of entry - the “how” and “where” the attack entered my system. I put it down to having insecure versions of certain third party extensions and reset my security. The incident caused me quite a bit of inconvenience, but also gave the incentive to finally switch to a better hosting provider. As the morale of the story: don’t assume your stuff is secure, ever. Have backups. Be paranoid. And teach your friends about this stuff, like I hope this post will do.