【问题标题】:Removing long string with sed使用 sed 删除长字符串
【发布时间】:2017-02-17 04:48:11
【问题描述】:

我的一个网站感染了一些恶意代码。代码只添加到所有PHP文件的第一行,如下:

<?php $ulhmjwklj = '#-#O#-#N# .......xqxe-1; ?> /*BEGIN LEGIT CODE HERE*/ <?php....

恶意代码长达数千个字符,包含大量特殊字符和空格,因此我尝试创建一个脚本来删除它:

for i in $(find . -name \*.php); do
  sed -i -E "s/<\?php\s$ulhmjwklj.*\?>//" $i;
  echo $i;
done;

sed 命令将正确删除恶意代码,同时将合法代码留在第一行,但随后在所有后续行中删除所有&lt;?php ... ?&gt; 标记。所以我尝试将sed 命令更改为仅在第一行搜索/替换:

for i in $(find . -name \*.php); do
  sed -i -E "1s/<\?php\s$ulhmjwklj.*\?>//" $i;
done;

现在sed 命令只会在每个文件的第一行运行,但它也会删除任何合法的 PHP 标签,这些标签直接附加到恶意代码之后的第一行。

有人可以解释一下我在哪里出错了吗?

【问题讨论】:

  • 所有文件中恶意代码的长度都固定了吗?还是因文件而异?
  • 另外,您总共有多少个 PHP 文件?他们都受到影响吗?
  • .* 很贪心...
  • Bash 将寻找一个名为 $ulhmjwklj 的变量。如果你逃避它,那么 sed 将把 $ 作为行尾。需要双转义,或者不要使用双引号字符串。
  • 是的,所有 PHP 文件都被感染了,恶意代码是每个文件中的固定字符数。我正在考虑下一步走这条路线......

标签: php bash sed


【解决方案1】:

The results of find should not be put through a loop。而且,正如我在 cmets 中提到的,$ 是 Bash 和正则表达式的特殊字符,因此必须适当处理。

最后,正如 cmets 中提到的 jm666,.* 是贪婪的,所以.*? 将搜索限制为尽可能小。但是this won't work in sed 所以我们需要使用perl 来代替:

find . -name '*.php' -print -exec perl -p -i -e 's/<\?php \$ulhmjwklj.*?\?>//' {} \;

【讨论】:

  • 非常感谢您的回复。不幸的是,这并没有解决问题,首先我必须单独添加 sed “-i -E” 参数,而不是像您建议的那样组合,否则每个 PHP 文件都会在文件名末尾附加一个“E”。一旦我解决了这个问题,上面的查找/替换查询会导致与以前相同的问题,其中合法的 PHP 标记和第 1 行末尾的任何内容也被删除。 :-/ 太奇怪了..
  • 查看我的更新答案。与sed 一样,perl-i 选项启用内联文件编辑,并且可以删除以在不更改文件的情况下进行“试运行”。
  • 成功!!!太感谢了。我希望 sed 能给我一些指示。*?行不通。
猜你喜欢
  • 2017-05-28
  • 2020-11-03
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 2020-04-17
  • 2015-05-08
相关资源
最近更新 更多