PHP/SSH 正则表达式脚本/命令从许多文件中删除相同的恶意软件代码

Posted

技术标签:

【中文标题】PHP/SSH 正则表达式脚本/命令从许多文件中删除相同的恶意软件代码【英文标题】:PHP/SSH regex script/command to delete identical malware code from many files 【发布时间】:2012-05-12 10:39:33 【问题描述】:

我的病毒感染了我客户的一台服务器上的数千个文件。

幸运的是,我已经在这个家伙的服务器上处理了很多其他恶意软件,而且这个看起来很容易做简单的正则表达式(他把他的所有网站都放在同一个帐户上 :( 但我正在与他合作解决这个问题)。

但基本上,与我见过的大多数恶意软件不同,它在关闭 ?> 之前注入 php 的 GOOD 代码(很难确定什么是好代码/坏代码),这个当前的恶意软件总是添加一个新的 <?php ... malware ... ?> .

所以基本上,说这里有好的代码:

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

不是在 require 语句之后但在 ?> 之前添加某种 base64_decode eval(当页面碰巧以条件/复杂语句结束时,这会使删除变得困难),这将始终添加以下代码和新&lt;?php ... ?&gt; 像这样:

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

我不想在这里放任何恶意代码,但是,恶意代码总是这样开始的:

<?php @error_reporting(0); if (!isset($eva1fYlbakBcVSir)) $eva1fYlbakBcVSir = "tons and tons of characters";$eva1tYlbakBcVSir = "\x6335\1443\3x6f\1534\x70\170\x65";$SNIPSNIPSNIPSNIP; ?>

我想在每个文件中搜索&lt;?php @error_reporting(0); if (!isset,如果它是页面上的最后一条 PHP 语句,则删除

中的所有内容

【问题讨论】:

我最近处理了其中之一。将其全部复制到您的开发机器,并将其加载到一个不错的 IDE(例如 Eclipse、Netbeans)中。然后进行项目范围的搜索和替换。 我只是从备份中恢复 - 你有备份,不是吗? 一次编辑一个文件,听起来很赚钱。 @Tallboy - 对人友善。否则:( 看起来这个恶意软件在一条线上,这是正确的吗?如果是这样,sed 就是你的朋友。 sed -e "s/&lt;?php @error_reportin.*?&gt;//g" --in-place=_cleaned * 这将从所有文件 (*) 中删除给定模式并存储扩展名为 _cleaned 的原始文件。但是先备份!!并为您的特定系统阅读man sed 【参考方案1】:

以下是使用纯 php 清理整个项目的方法。

在任何情况下,我均不对任何损害承担任何责任,包括: 但仅限于直接、间接、特殊或后果性损害 产生于、产生于或以任何方式与使用 提供的代码,无论是否基于保证、合同、侵权或 否则;伤害是否由人员或财产造成 或其他;以及损失是否来自或产生 的,结果,如果这个代码的使用。 ;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;

?>

祝你好运。

更新(使用正则表达式):

<?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;

?>

【讨论】:

没有问题,希望你把一切都整理好。 顺便说一句,我将如何更改它,以便介于两者之间:&lt;?php @error_reporting(0); if (!isset(?&gt; .. 我认为代码每次都会更改,但开头和结尾始终相同 谢谢!!!你真棒。这是一个巨大的帮助。如果可以的话,请给你的帖子投票 10 次【参考方案2】:

到目前为止,这是最接近的(谢谢 mvds)

sed -e "s/&lt;?php @error_reporting.*?&gt;//g" --in-place=_cleaned *

虽然 --in-place=_cleaned 给出了错误sed: illegal option -- -

【讨论】:

以上是关于PHP/SSH 正则表达式脚本/命令从许多文件中删除相同的恶意软件代码的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本之正则表达式

如何在 linux shell 脚本中使用正则表达式搜索文件 [关闭]

如何使正则表达式与 perl 命令一起使用并从文件中提取数字?

shell脚本及正则表达式

从命令行获取 pom.xml 属性

Shell脚本------正则表达式与常用命令(sort,uniq,tr,cut)