Поиск файлов. Как найти вирус на сайте

Несмотря на то, что статья в разделе «Команды Linux», мне бы хотелось сделать заметку об избавлении сайта от вирусов, скорее чем о команде поиска…

Обычно вирус на сайте делает какой то редирект с вашего проекта на вирусный с целью воровства трафика.

Самый простой вариант — запихнуть редирект в .htaccess. Для удаления такого вируса просто восстановите оригинальный файл и проверьте вашу безопасность (смените пароли, обновите CMS и возможно Linux).

В других случаях вредоносный код может сидеть в php файле. Иногда обнаружить его бывает крайне сложно. Но есть одна зацепка, которая срабатывает — поиск последних измененных файлов.

Вот как это сделать:

Чтобы найти недавно модифицированные файлы, отсортированные в обратном порядке (то есть файл, измененный последним, будет показан первым), используется команда вида:

find /путь-к-директории -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

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

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

  1. Поиск файлов, которые были модифицированы в последние 60 минут в директории /directory и во всех ее поддиректориях:
  2.  
  3. $ find /directory -type f -mmin -60
  4.  
  5.  
  6. Поиск файлов, которые были модифицированы в последние 2 дня в директории /target_directory и во всех ее поддиректориях:
  7.  
  8. $ find /directory -type f -mtime -2
  9.  
  10.  
  11. Поиск файлов, которые были модифицированы в последние 2 дня в директории /target_directory и ее поддиректориях глубиной до 3 уровня:
  12.  
  13. $ find /directory -type f -mtime -2 -depth -3
  14.  
  15.  
  16. Вы также можете задать диапазон времени модификации. Поиск файлов, которые были модифицированы в последние 7 дней, но не позднее чем 3 дня назад:
  17.  
  18. $ find /directory -type f -mtime -7 ! -mtime -3

В остальном команда find имеет следующие плюшки:

find / -name имя_файла

Опция '-name' различает прописные и строчные буквы; чтобы использовать поиск без этих различий, воспользуйтесь опцией '-iname'.

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

Чтобы получить список файлов системы, имена которых начинаются с букв 'top', введите: 

find / -name 'top*'

Чтобы получить список файлов системы, имена которых начинаются с букв 'top', за которыми следуют еще три символа, введите: 

find / -name 'top???'

 Чтобы получить список файлов системы, имена которых начинаются с букв 'top', за которыми следуют пять и более символов, введите: 

find / -name 'top?????*'

Чтобы увидеть все файлы с расширением '.ini' в Вашем рабочем каталоге, независимо от их написания, введите: 

find ~ -iname '*.ini'

Используйте '-regex' вместо '-name' для поиска файлов, имена которых удовлетворяют регулярному выражению, или образцу, описывающему несколько строк.

Чтобы увидеть все файлы в текущем каталоге, имена которых содержат строку 'php' или 'tpl', наберите: 

find . -regex '.*\(php\|tpl\).*'

Чтобы найти файлы определенного размера, используйте опцию '-size', указав после нее требуемый размер файла. Размер файла может быть задан в трех различных формах: если перед ним указан знак плюс ('+'), ищутся все файлы, большие, чем указанный размер; если указан знак минус ('-'), ищутся все файлы, меньшие, чем указанный размер; если префикс не указан, ищутся файлы точно указанного размера. (Единица измерения — блок 512 байт; символ 'k' после размера указывает килобайты, символ 'b' — байты.)

Чтобы вывести список файлов в каталоге `/usr/local', размер которых больше 10,000 килобайт, введите:

find /usr/local -size +10000k

Чтобы вывести список файлов в домашнем каталоге, размер которых меньше 300 байт, введите: 

find ~ -size -300b

Чтобы вывести список файлов системы, размер которых составляет 32 блока по 512 байт, наберите:

find / -size 32

Используйте опцию '-empty' для поиска пустых файлов — т.е. файлов с размером 0 байт. Это полезно для поиска и удаления ненужных файлов.

Чтобы найти все пустые файлы в Вашем домашнем каталоге, введите:

find ~ -empty

Чтобы найти файлы, модифицированные в определенное время, используйте команду find с опциями '-mtime' или '-mmin'; аргумент опции '-mtime' определяет количество прошедших суток (24 часа), а аргумент '-mmin' — количество прошедших минут.

Чтобы вывести все файлы в каталоге '/usr/local', модифицированные точно 24 часа назад, введите:

find /usr/local -mtime -1

Чтобы вывести все файлы в каталоге '/usr', модифицированные 5 минут назад, введите:

find /usr -mmin -5

Если Вы хотите указать промежуток времени, поставьте перед числом либо знак плюс ('+'), определяя большее или равное аргументу время, или знак минус ('-'), определяя время, меньшее или равное аргументу.

Чтобы вывести все файлы в каталоге '/usr/local', модифицированные в течение последних 24 часов, введите:

find /usr/local -mtime -1

Опция '-daystart' определяет отсчет времени с момента начала текущих суток. 

Чтобы вывести все файлы в Вашем домашнем каталоге, модифицированные вчера, введите: 

find ~ -mtime -1 -daystart

Чтобы вывести все файлы в каталоге '/usr', модифицированные в течение года, введите:

find /usr -mtime +356 -daystart

Чтобы вывести все файлы в Вашем домашнем каталоге, модифицированные в период от 2 до 4 дней тому назад, наберите:

find ~ -mtime 2 -mtime -4 -daystart

Чтобы найти файлы, которые новее некоторого файла, введите его имя в качестве аргумента опции '-newer'.

Чтобы вывести все файлы в каталоге '/etc', которые новее файла '/etc/php.ini', введите:

find /etc -newer /etc/php.ini

Чтобы найти все файлы новее определенной даты, используйте следующий трюк: создайте временный файл в каталоге '/tmp' и установите дату его модификации на требуемую с помощью touch, а затем определите его как аргумент для '-newer'.

Вы можете использовать команду find для выполнения других команд над найденными файлами, указав требуемые команды в качестве аргуентов опции '-exec'. Если Вы используететв команде строку {}, эта строка в команде будет заменена именем текущего найденного файла. Окончание команды помечается строкой `';''.

Чтобы найти все файлы в каталоге /html/ с расширением .html, и вывести строки из этих файлов, содержащие слово 'organic', введите: 

find ~/html/ -name '*.html' -exec grep organic '{}' ';'

Чтобы ввести подтверждение выполнения команды для файла, найденного find, используйте ключ '-ok' вместо '-exec'.

Чтобы удалить из Вашего домашнего каталога файлы, доступ к которым осуществлялся более года назад, с подтверждением для каждого файла, введите: 

find ~ -used +365 -ok rm '{}' ';'

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

Чтобы вывести список файлов в Вашем домашнем каталоге, имена которых начинаются со строки 'top', и которые новее файла '/etc/php.ini', введите:

find ~ -name 'top*' -newer /etc/php.ini

Чтобы сжать все файлы в Вашем домашнем каталоге, размер которых превышает 2 Mb, и которые еще не сжаты с помощью gzip (не имеют расширения '.gz'), введите:

find ~ -size +2000000c -regex '.*[^gz]' -exec gzip '{}' ';'

Чтобы найти наибольший файл в каталоге, используйте команду ls с опцией '-S', которая сортирует файлы в нисходящем порядке по размеру (обычно ls выводит список файлов по алфавиту). Добавьте опцию '-l', чтобы вывести размер и другие атрибуты файла:

ls -lS

Чтобы вывести оглавление каталога, начав с файлов наименьшего размера, используйте ls с ключами '-S' и '-r', которые сортируют вывод в обратном порядке:

ls -lSr

Чтобы вывести список каталогов, отсортированных по размеру — то есть размеру всех содержащихся в них файлов — используйте du и sort. Команда du выводит список каталогов в восходящем порядке, начиная с самого маленького; опция '-S' помещает при выводе в первую колонку размер каталога в килобайтах. Укажите требуемое дерево каталогов в качестве аргумента du и перенаправьте вывод в команду sort с ключом '-n', которая отсортирует список по числам.

Чтобы вывести список подкаталогов в текущем дереве каталогов, отсортированный по размеру, введите:

du -S | sort -n

Если Вам нужно, чтобы первыми были указаны самые большие каталоги, используйте ключ '-r': 

du -S | sort -nr

Чтобы быстро определить количество файлов в каталоге, используйте ls и перенаправьте вывод в команду 'wc -l', которая выводит количество строк, пришедших на ее вход. 

Для вывода общего количества файлов в текущем каталоге введите: 

ls | wc -l

Поскольку ls по умолчанию не показывает скрытые файлы, приведенная выше команда не будет их учитывать. Опция '-A' для ls позволит посчитать обычные и скрытые файлы: 

ls -A | wc -l

Чтобы посчитать количество файлов во всем дереве каталогов, а не только в отдельном каталоге, используйте find вместо ls, и укажите специальный ключ для find — строку '! -type d', чтобы исключить вывод и подсчет каталогов.

Чтобы вывести количество файлов в дереве '/usr/share', введите:

find /usr/share \! -type d | wc -l

 Чтобы вывести количество файлов и каталогов в дереве '/usr/share', введите:

find /usr/share | wc -l

Чтобы вывести количество каталогов в дереве '/usr/share', введите:

find /usr/share \! -type f | wc -l

А вот замечательные сниппеты, как вывести размер найденых файлов. Это очень полезно, если мы хотим знать, сколько у нас картинок на сервере.

В зависимости от версии Linux могут работать не все варианты.

Ищем все JPEG или PNG файлы в текущей директории и всех вложенных, выводим последнии 10 строк результата и общий размер найденного. Считает верно

find -name '*.jp*g' -print0 | du -ch --files0-from=- | tail -10

Этот просто выводит размер найденных файлов, но если файлов очень много, то выедет только размер крайнего списка файлов. Поэтому для использования не годится.

find -name '*.png' -print0 | xargs -0 du -ch | tail -n1

А этот вариант выводит размеры всех списков, придется итог подсчитывать калькулятором :-)

find -name '*.jp*g' -print0 | xargs -0 du -ch | grep -P '\ttotal$'

Вот полный его аналог

find -name '*.jp*g' -exec du -ch {} + | grep -w "total"

И еще один вариант. Он самый тормозной, но работает на всех версиях Linux и считает правильно

find -name '*.png' -ls -exec printf '\000' \;      | tr -cd ' -~\000'      | tr '\000' '\n'        | awk  '{ sum+=$7 } END { print "total size: ",sum }'

Так что для использования выбирайте первый вариант или последний, если первый у вас не идёт!