Удаление текстового блока из файла: sed? - PullRequest
0 голосов
/ 27 декабря 2010

После атаки мне нужно удалить 4 строки текста, добавленные в файлы .htaccess на моем сайте, и я подумал, что SED будет правильным, но не может понять, как это происходит, несмотря на многие попытки.

Добавлены строки

RewriteEngine On
RewriteCond %{HTTP_REFERER} ^http://
RewriteCond %{HTTP_REFERER} !%{HTTP_HOST}
RewriteRule . http://targeturlhere.net/%{REMOTE_ADDR}

Мне удалось создать скрипт для удаления добавленных файлов htaccess, содержащих только эти строки, но для существующих файлов htaccess, в которые он был добавлен, я должен отредактировать файл и не могу его удалить. Я не могу просто удалить строку за строкой или использовать «RewriteEngine On» в качестве маркера начала, поскольку эта инструкция «RewriteEngine On» иногда допустима в других местах файла.

В большинстве случаев эти строки являются последними, но я предполагаю, что в других файлах они могут быть посередине, поэтому я пытался удалить именно этот блок - и у меня был сценарий, который я мог бы использовать в похожем случае.

(Правка: мои 4 строки расположены ниже друг друга, между ними нет пустой строки, но редактор здесь, кажется, либо не показывает разрыв, либо добавляет одну пустую строку)

Любой намек или совет? Спасибо.

Ответы [ 2 ]

1 голос
/ 27 декабря 2010

Если вы не можете вызвать строку «RewriteEngine On» (поскольку она иногда используется законно), то «sed», вероятно, не является подходящим инструментом для работы. Я бы использовал Perl (проверенный код следует):

my $file;
do { local $/; $file = <>; }; # Slurp!

$file =~ s{
            RewriteEngine \s On \n
            RewriteCond \s %{HTTP_REFERER} \s [\^]http:// \n
            RewriteCond \s %{HTTP_REFERER} \s !%{HTTP_HOST} \n
            RewriteRule \s \. \s http://targeturlhere\.net/%{REMOTE_ADDR} \n
          }{}gmsx;

print $file;

Файл захвачен в память; затем ненужные данные удаляются (повторно, на случай, если один из файлов был изменен несколько раз), затем остаток записывается в стандартный вывод. Модификаторы gmsx делают:

  • г - глобальный
  • м - многострочный
  • s - sed-like
  • x - расширенный (пробел игнорируется - используйте \s (или \s+) для соответствия фактическому пробелу.

Это предназначено для обработки по одному файлу за раз (на вызов скрипта). Вы можете заставить его обрабатывать несколько файлов в командной строке с перезаписью оригиналов и т. Д., Если вы будете осторожны; проблемная область - операция 'slurp'. Код предполагает, что вы хотите прочитать все файлы в память и поработать над этим - это правильно, так как вам нужно сопоставить несколько строк.


Комментарий спрашивает:

[У меня уже есть работающий скрипт bash, который перечисляет и сканирует размещенные сайты, затем удаляет файлы, содержащие только эти строки, и я ждал, чтобы добавить эту функцию редактирования. Могу ли я просто использовать Perl внутри этого скрипта или вызвать его?

Если вы можете определить, что файл содержит материал, отличный от четырех строк, которые вам нужно удалить, вы можете вызвать Perl из скрипта для работы с этим файлом:

  • Сохраните код, который я показал в файле fixit.pl:
    • Добавить строку Шебанга #!/usr/bin/env perl
    • Для хорошей дисциплины рассмотрите добавление use strict; и use warnings; после Шебанга и перед кодом. В этом случае это не имеет значения (код чист), но если вы вносите изменения, включите эти строки. Да, но я знаю, что я ошибаюсь.
    • Сделайте его исполняемым и в каталоге в вашей переменной PATH, или узнайте его местоположение.
  • В вашем скрипте:

    ...
    else
        fixit.pl $file > $tmp.1
        mv $tmp.1 $file
    fi
    

У вас могут быть другие способы сделать это, но он должен быть настолько сложным. Я предполагаю, что у вас есть переменная tmp, инициализированная соответствующим образом:

tmp=${TMPDIR:-/tmp}/fixit.$$

Возможно, вы захотите включить trap-сообщения, чтобы обеспечить очистку файла:

trap "rm -f $tmp.?; exit 1" 0 1 2 3 13 15
...code as above...
rm -f $tmp.?
trap 0
exit 0

Первая строка прерываний перехватывает сигналы 1 (HUP), 2 (INT), 3 (QUIT), 13 (PIPE) и 15 (TERM), а также любой выход оболочки самостоятельно (0) и выполняет команду заданные команды (удаление временного файла и выход с состоянием ошибки). Строка stray rm -f гарантирует, что файл отсутствует; trap 0 отменяет ловушку для «самостоятельного выхода из оболочки», а exit 0 успешно завершается. Это означает, что вы можете прервать свою обработку и не оставлять чужие файлы - хорошая практика для любого сценария оболочки, который создает временные файлы.

В качестве альтернативы вы можете использовать:

perl -i.bak fixit.pl $file

Это создаст имя файла «$ file.bak» с оригиналом, и результат будет отправлен к исходному имени файла «$ file». Это избавляет от необходимости использовать ловушки и т. Д. Если вам не нужен файл резервной копии, пропустите «.bak» из командной строки.

0 голосов
/ 28 декабря 2010
sed '1{N;N};N;\|\nRewriteRule . http://targeturlhere.net/%{REMOTE_ADDR}$|d;P;D' inputfile

Эта строка ищет последнюю строку набора из четырех и, когда она найдена, удаляет их. Он проходит через все остальные линии.

Вы можете добавить опцию -i (sed -i ...), чтобы изменить файлы на месте. Вы можете добавить дополнительное расширение для резервного копирования, чтобы сделать его резервным копированием исходного (sed -i .bak ...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...