如何从包含特定字符串的 PHP 文件中删除一行代码?

如何从包含特定字符串的 PHP 文件中删除一行代码?

巧合的是,我注意到我托管的网站中有相当一部分 PHP 文件被注入了恶意软件:它们在原始/正确的代码之前都有以下一行:

<?php eval(gzinflate(base64_decode('[malware code]')));?>

对我的所有站点进行递归扫描并从包含它的任何文件中删除此行(它始终是第一行)的最佳方法是什么?

我有该盒子的完全 root 访问权限。我不确定这是通过现已关闭的漏洞进入的,还是该盒子仍然易受攻击,因此我想彻底清除并密切监视文件是否有变化。

问候,埃弗特

答案1

您可以使用如下命令行以递归方式删除malware code所有*.php文件中包含的行:

find . -name "*.php" -exec sed -i '/malware code/d' {} \;

不确定“恶意软件代码”是否是您用来匿名的替代品,因此您可以使用:

find . -name "*.php" -exec sed -i '/eval(gzinflate(base64_decode/d' {} \;

不过,我建议您在运行此操作之前先进行备份。

那么,最好的选择就是修复你的安全漏洞。

答案2

此解决方案适用于类 UNIX 系统。如果您安装了 Cygwin 或类似软件,它还适用于 Windows 系统。

如果违规行为是总是第一行然后“tail +2”将是摆脱它的最佳方法。

我建议你将“tail”的输出重定向到一个新文件,这样你就可以做一些验证。使用只包含恶意软件行的第三个文件(例如 malware_line.txt)可以让你验证你没有以某种意外的方式更改文件。

如果脚本输出以下消息,您将需要手动检查该文件:

Files FILENAME.orig and FILENAME.check differ

这是一个脚本,它只会删除名为 *.php 或 *.PHP 的文件的第一行(如果恶意软件行存在于文件的其他位置,则会给出替代解决方案,但验证将不起作用。)

find . -name "*.php" -o -name "*.PHP" 2>/dev/null | while read FILENAME
do
    BADFILE=0

    # If the file contians the malware line, we want to remove it
    grep -q 'eval(gzinflate(base64_decode' $FILENAME && BADFILE=1

    if [[ $BADFILE != 0 ]]
    then
        echo "Processing: $FILENAME"

        cp $FILENAME ${FILENAME}.orig  # Save a backup copy of  file

        # Remove the offending "first" line.
        tail +2 ${FILENAME}.orig > ${FILENAME}.fixed
        ##
        ## Alternatively, you could use "grep -v" here instead of the above "tail +2" 
        ## to stip the malware line form anywhere in the file.
        ##grep -v 'eval(gzinflate(base64_decode' $FILENAME > ${FILENAME}.fixed

        # Validate that we did not munge up our file
        cat malware_line.txt ${FILENAME}.fixed > ${FILENAME}.check  # Recreate the bad file

        # Compare the original with the recreated file to prove that you only removed 
        # the malware line
        diff -q ${FILENAME}.orig ${FILENAME}.check && cp ${FILENAME}.fixed $FILENAME

        # Cleanup after ourselves
        rm -f ${FILENAME}.check
    fi
done

相关内容