PHP/SSH regex script/command to delete identical malware code from many files

I have a virus that has infected thousands of files on one of my client’s server.

Fortunately, I have dealt with a lot of other malware on this guy’s server and this one looks easy to do simple regex on (he put all his websites on the same account 🙁 but I’m working with him to resolve that).

Read More

Basically though, unlike most malware I have seen where it injects php BEFORE the closing ?> of the GOOD code (making it very hard to determine whats good code/bad code), this current malware ALWAYS adds a new <?php ... malware ... ?>.

So basically, say there’s good code here:

<?php
require('./wp-blog-header.php'); 
?>

Instead of adding some kind of base64_decode eval immediately after the require statement but before the ?> (which can make removal difficult when the page happens to end in a conditional/complex statement), this will always add the following code with a NEW <?php ... ?> like so:

<?php
require('./wp-blog-header.php'); 
?><?php ... malware ...?>

I don’t want to put any malicious code up here but, this is how the malicious code always starts:

<?php @error_reporting(0); if (!isset($eva1fYlbakBcVSir)) {$eva1fYlbakBcVSir = "tons and tons of characters";$eva1tYlbakBcVSir = "x633514433x6f1534x70170x65";$SNIPSNIPSNIPSNIP;} ?>

I’d like to search every file for <?php @error_reporting(0); if (!isset and if it’s the last PHP statement on the page, then delete everything within the

Related posts

Leave a Reply

2 comments

  1. Here is how you clean the entire project with pure php.

    In no respect shall I incur any liability for any damages, including,
    but limited to, direct, indirect, special, or consequential damages
    arising out of, resulting from, or any way connected to the use of the
    code provided, whether or not based upon warranty, contract, tort, or
    otherwise; whether or not injury was sustained by persons or property
    or otherwise; and whether or not loss was sustained from, or arose out
    of, the results of, the use if this code. ;p

    <?php 
    //Enter it as it is and escape any single quotes
    $find='<?php @error_reporting(0); if (!isset($eva1fYlbakBcVSir)) {$eva1fYlbakBcVSir ='';?>';
    
    echo findString('./',$find);
    
    function findString($path,$find){
        $return='';
        ob_start();
        if ($handle = opendir($path)) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    if(is_dir($path.'/'.$file)){
                        $sub=findString($path.'/'.$file,$find);
                        if(isset($sub)){
                            echo $sub.PHP_EOL;
                        }
                    }else{
                        $ext=substr(strtolower($file),-3);
                        if($ext=='php'){
                            $filesource=file_get_contents($path.'/'.$file);
                            $pos = strpos($filesource, $find);
                            if ($pos === false) {
                                continue;
                            } else {
                            //The cleaning bit
                            echo "The string '".htmlentities($find)."' was found in the file '$path/$file and exists at position $pos and has been removed from the source file.<br />";
                            $clean_source = str_replace($find,'',$filesource);
                            file_put_contents($path.'/'.$file,$clean_source);
                            }
                        }else{
                            continue;
                        }
                    }
                }
            }
            closedir($handle);
        }
        $return = ob_get_contents();
        ob_end_clean();
        return $return;
    }
    ?>
    

    Good Luck.

    UPDATE (With Regex):

    <?php 
    error_reporting(E_ALL);
    $find='<?php @error_reporting(0); if (!isset((.*?)?>';
    
    echo findString('./',$find);
    
    function findString($path,$find){
        $return='';
        ob_start();
        if ($handle = opendir($path)) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    if(is_dir($path.'/'.$file)){
                        $sub=findString($path.'/'.$file,$find);
                        if(isset($sub)){
                            echo $sub.PHP_EOL;
                        }
                    }else{
                        $ext=substr(strtolower($file),-3);
                        if($ext=='php'){
    
                            $filesource=file_get_contents($path.'/'.$file);
                            //The cleaning bit
                            echo "The string '".htmlentities($find)."' was found in the file '$path/$file and has been removed from the source file.<br />";
                            $clean_source = preg_replace('#'.$find.'#','',$filesource);
                            // $clean_source = str_replace($find,'',$filesource);
                            file_put_contents($path.'/'.$file,$clean_source);
                        }else{
                            continue;
                        }
                    }
                }
            }
            closedir($handle);
        }
        $return = ob_get_contents();
        ob_end_clean();
        return $return;
    }
    ?>
    
  2. So far this is the closest (thank you mvds)

    sed -e "s/<?php @error_reporting.*?>//g" --in-place=_cleaned *

    although –in-place=_cleaned is giving the error sed: illegal option -- -