【问题标题】:Grep invert on string matched, not line matched字符串匹配的Grep反转,而不是行匹配
【发布时间】:2015-08-17 01:50:14
【问题描述】:

我会尽量解释为什么我需要帮助。我的一个文件目录通过 XSS 被黑客入侵,并在所有 php 文件的开头放置了一个长字符串。我尝试使用 sed 将字符串替换为空,但它不起作用,因为要匹配的模式包含许多需要转义的字符。

我发现我可以使用fgrep 匹配保存在模式文件中的固定字符串,但我想替换每个文件中匹配的字符串(NOT THE LINE),但是grep-v 会反转行上的结果,而不是匹配字符串的结尾。

这是我在包含被黑的示例文件上使用的命令

fgrep -v -f ~/hacked-string.txt example.php

我需要输出包含位于行尾的<?php(有时是<style> 标记),但-v 选项会在该行的末尾反转,因此输出不会在开头包含<?php

注意

我尝试使用 -o--only-matching 来代替,它们什么都不输出:

fgrep -f ~/hacked-string.txt example.php --only-matching -v

grep 中是否有另一个选项可以用来反转匹配模式的末尾,而不是匹配模式的行?或者,是否有更简单的选项来替换所有 .php 文件中的被黑字符串?

这是hacked-string.txt 中内容的一个小sn-p(为便于阅读添加了换行符):

]55Ld]55#*<%x5c%x7825bG9}:}.}-}!#*<%x55c%x7825)
dfyfR%x5c%x7827tfs%x5c%x7c%x785c%x5c%x7825j:^<!
%x5c%x7825w%x5c%x7860%x5c%x785c^>Ew:25tww**WYsb
oepn)%x5c%x7825bss-%x5c%x7825r%x5c%x7878B%x5c%x
7825h>#]y3860msvd},;uqpuft%x5c%x7860msvd}+;!>!}
%x5c%x7827;!%x5c%x7825V%x5c%x7827{ftmfV%x5e56+9
9386c6f+9f5d816:+946:ce44#)zbssb!>!ssbnpe_GMFT%
x5c5c%x782f#00#W~!%x5c%x7825t2w)##Qtjw)#]82#-#!
#-%x5c%x7825tmw)%x5c%x78w6*%x5c%x787f_*#fubfsdX
k5%x5c%xf2!>!bssbz)%x5c%x7824]25%x5c%x7824-8257
-K)fujs%x5c%x7878X6<#o]o]Y%x5c%x78257;utpI#7>-1
-bubE{h%x5c%x7825)sutcvt)!gj!|!*bubEpqsut>j%x5c
%x7825!*72!%x5c%x7827!hmg%x5c%x78225>2q%x5c%x7

提前致谢!

【问题讨论】:

  • 垃圾字符串中是否有换行符?
  • 如果到处都是相同的字符串,则按长度或两端的几个字符或两者的组合进行匹配。 sed 's/^#@%\(.\{666\}\):|; 或类似的东西。
  • 从被黑中恢复的唯一明智的方法是从已知良好的备份或版本控制中恢复。

标签: regex string bash sed grep


【解决方案1】:

使用 perl:

perl -i.hacked -pe "s/\Q$(<hacked-string.txt)\E//g" example.php

注意事项:

  • $(&lt;file) 位是读取文件内容的 bash 快捷方式。
  • \Q\E 位来自 perl,它们将中间的内容视为普通字符,忽略正则表达式元字符。
  • -i.hacked 选项将就地编辑文件,创建备份“example.php.hacked”

【讨论】:

    【解决方案2】:

    每个文件中的被黑字符串是否相同?

    如果 chars 中被黑字符串的长度是1234,那么您可以使用

    tail -c +1235 file.php > fixed-file.php
    

    针对每个受感染的文件。

    请注意,tail c +1235 告诉从输入文件的第 1235 个字符开始输出。

    【讨论】:

      【解决方案3】:

      我想你要问的是:

      “是否可以使用 grep 实用程序从文件中删除固定字符串(可能包含大量正则表达式元字符)的所有实例?”

      在这种情况下,答案是“否”。

      我想你想问的是:

      “从文件中删除固定字符串(可能包含大量正则表达式元字符)的所有实例的最简单方法是什么?”

      这是一个相当简单的解决方案:

      delete_string() {
        awk -v s="$the_string" '{while(i=index($0,s))$0=substr($0,1,i-1)substr($0,i+length(s))}1'
      }
      
      delete_string 'some_hideous_string_with*!"_inside' < original_file > new_file
      

      shell 语法稍显脆弱;如果字符串包含撇号 ('),它将中断。但是,您可以使用以下命令将原始字符串从标准输入读取到变量中:

      $ IFS= read -r the_string
      absolutely anything here
      

      适用于任何不包含换行符或 NUL 字符的字符串。将字符串放入变量后,就可以使用上述函数:

      delete_string "$the_string" < original_file > new_file
      

      这是另一种可能的衬里,使用 python:

      delete_string() {
        python -c 'import sys;[sys.stdout.write(l.replace(r"""'"$1"'""","")) for l in sys.stdin]'
      }
      

      这不会处理包含三个连续引号 (""") 的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-03
        • 2017-02-13
        • 2013-07-11
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多