服务器的PHP入侵了。有没有办法定位特定的字符串+标签?

时间:2017-05-17 06:47:08

标签: php bash grep

我的一位朋友(他不喜欢强密码......)让他的服务器被黑了,我正试图帮助他。

基本上,服务器上的很多php文件都在第一行的两个php标签之间添加了很多东西。

这样的事情:



1. <?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php
2. Line 2 and beyond, the file is unchanged.
&#13;
&#13;
&#13;

所以我的问题是:有没有办法通过grep - 或其他东西 - 只是针对第一个php标签,其间的一切都删除它?在上面的例子中,在第1行:所有但是第二个打开php标记。

我知道我可以将第1行作为目标,只需用开放的php标签替换,但为了避免任何问题,我更喜欢目标并删除我想要的确切内容。

有太多文件可以手工完成。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我完全同意Ben Hillier的评论。 (我的意思是特别是备份的部分,因为我对PHP知之甚少。)但是......

可以使用以下 sed 命令:

sed 's/^<?php .* ?>\(<?php.*\)$/\1/'

或者,可以使用 awk

完成
awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'

或附加条件NR==1以确保测试/替换仅在第一行完成:

awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'

其中一个命令(巧妙地与find结合使用)应该可以胜任。

请注意 sed awk 所需的明显转义。

而且,正如Ben Hillier已经建议的那样:不要忘记之前备份。

演示:

$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' \
> | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php

$ echo '<?php' | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php

$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php

$ echo '<?php' | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php

$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php

$ echo '<?php' | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php

$ cat >test.txt <<EOF
> <?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php
> // contents
> // contents
> // contents
> ?>
> EOF

$ cat test.txt | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php
// contents
// contents
// contents
?>

$ cat test.txt | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
// contents
// contents
// contents
?>

$ cat test.txt | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
// contents
// contents
// contents
?>

$

最后但并非最不重要的是人类读者的awk脚本:

# catch 1st line with a duplicated "<?php"
NR==1 && /<\?php .* \?><\?php/ {
  # replace the line by everything including and after 2nd "<?php"
  $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0)
}
{ print } # print any line