Назад | Перейти на главную страницу

Как удалить 1 строку кода из файлов PHP, содержащих определенную строку?

По совпадению я заметил, что в некоторые из PHP-файлов сайтов, которые я размещаю, были внедрены вредоносные программы: все они имеют следующую строку перед исходным / правильным кодом:

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

Как лучше всего выполнить рекурсивное сканирование всех моих сайтов и удалить эту строку (это всегда первая строка) из всех файлов, которые ее содержат?

Имею полный root доступ к коробке. Я не уверен, пришло ли это через закрытое отверстие, или ящик все еще уязвим, потому что я хочу провести чистую очистку и внимательно следить за изменениями файлов.

С уважением, Эверт

Вы можете использовать следующую командную строку, чтобы удалить строки, содержащие malware code в целом *.php файлы рекурсивно:

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

Не уверен, что «вредоносный код» - это замена, которую вы использовали для анонимности, поэтому вы можете использовать:

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

Однако я советую вам сделать резервную копию перед запуском этого.

Тогда лучше всего исправить дыру в безопасности.

Это решение будет работать в UNIX-подобных системах. Он также будет работать в системах Windows, если вы установите Cygwin или что-то подобное.

Если оскорбительная линия всегда первая строка, затем "хвост +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