Статьи

Обнаружение взломанных файлов через CRON / PHP

Как сертифицированный этический хакер, я искал скрипт, который помог бы мне обнаружить несанкционированные изменения файлов. Я нашел скрипт (вероятно, в примечаниях пользователя на php.net), который я изменил, чтобы он работал очень хорошо на моем «тестовом сервере» (Windows), а также на моем «производственном» сервере (Linux).

Логика проста: «Создайте базу данных хэшированных значений для уязвимых файлов (тех, которые хакеры изменят для выполнения кода на вашем сервере) и регулярно сравнивайте эти значения с реальными хешами и сообщайте о добавленных, измененных и удаленных файлах».

Очевидно, что код для обхода структуры каталогов сервера и предоставления хеш-значений гораздо сложнее, чем приведенное выше утверждение. Я пойду через код для производственного сервера.

Настройка базы данных

В целях безопасности используйте для этого отдельную базу данных, которая не разделяет учетные данные доступа ни с какой другой базой данных. Используйте cPanel для создания новой базы данных и нового пользователя с надежным паролем (я рекомендую 16-символьный пароль, созданный strongpasswordgenerator.com ) и безобидным именем, таким как baseline. Затем используйте PHPMyAdmin SQL для создания двух таблиц:

  CREATE TABLE baseline (
         file_path VARCHAR (200) NOT NULL,
         file_hash CHAR (40) NOT NULL,
         acct VARCHAR (40) НЕ ПУСТО
         ПЕРВИЧНЫЙ КЛЮЧ (file_path)
     );

     CREATE TABLE протестирован (
         проверено DATETIME НЕ NULL,
         аккаунт VARCHAR (40) НЕ ПУСТО
         ПЕРВИЧНЫЙ КЛЮЧ (проверено)
     ); 

Первая таблица, «baseline», содержит большое поле для вашего path/to/filenamesfile_hashacct Установите file_path

«Проверенная» таблица будет содержать DATETIMEacct

Инициализируйте файл PHP:

Во-первых, определите несколько констант

  • PATHDocumentRoot Только не забывайте использовать обратную косую черту Windows, потому что Apache и PHP будут искать прямую косую черту.
  • Константы доступа к базе данных SERVER'localhost'USERPASSWORDDATABASE

и несколько переменных

  • Массив расширений файлов для изучения. Поскольку не все файлы являются исполняемыми на сервере, я сканирую только файлы .php.htm.html.js Обратите внимание, что пустой массив заставит сканировать ВСЕ файлы (лучше всего для безопасности, но использует больше всего ресурсов сервера).
  • Каталоги исключить. Если у вас есть каталог, содержащий вредоносные программы, позор вам! В любом случае, если вам необходимо исключить каталог по какой-либо причине, у вас есть возможность перечислить их в массиве. Не опускайте никакие каталоги только потому, что вы храните только изображения или PDF-файлы, потому что хакер также может поместить туда свои файлы!
  • Инициализируйте переменные, которые вы собираетесь использовать: необходимо инициализировать массив $filearray()$report$acctacct

Давайте начнем!

  <? PHP

 // инициализировать

 $ dir = new RecursiveDirectoryIterator (PATH);

 $ iter = new RecursiveIteratorIterator ($ dir);

 while ($ iter-> valid ())

 {

     // пропускаем ненужные каталоги

     if (! $ iter-> isDot () &&! in_array ($ iter-> getSubPath (), $ skip))

     {

         // получаем конкретные расширения файлов
         if (! empty ($ ext))

         {

             // PHP 5.3.4: if (in_array ($ iter-> getExtension (), $ ext))

             if (in_array (pathinfo ($ iter-> key (), PATHINFO_EXTENSION), $ ext))

             {
 
                 $ files [$ iter-> key ()] = hash_file ("sha1", $ iter-> key ());

             }

         } еще {

             // игнорируем расширения файлов

             $ files [$ iter-> key ()] = hash_file ("sha1", $ iter-> key ());

         }

     }

     $ Iter-> следующая ();

 } 

Мы только что использовали функцию RecursiveIteratorIterator()$dir Первое, что он делает, это проверяет, был ли каталог заблокирован из итерации, а затем ветвится в зависимости от того, были ли указаны расширения файлов. В результате получается двумерная матрица файлов ( $filespath/name.ext

Я отмечу здесь, что прокомментированные операторы echo использовались на моем тестовом сервере Windows без связи с SMTP-сервером, но вам нужно раскомментировать их, если вам нужно проверить правильность работы.

Количество файлов может быть предоставлено сразу массивом файлов:

  $ report. = "Файлы имеют".  считать ($ файлы).  "records.rn"; 

Вывод на ваш тестовый монитор или на электронную почту только что получил первое непустое значение: количество хэшированных файлов.

Последнее сканирование хэша

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

  $ results = mysqli_query ($ db, "SELECT проверено ОТ проверено ГДЕ acct = '$ acct'
     ЗАКАЗАТЬ ПО ТЕСТИРОВАНИЮ DESC LIMIT 1 ");

 если ($ результаты)

 {

     в то время как ($ результат = mysqli_fetch_array ($ Результаты))

     {

         $ испытания = $ результат ['проверено'];

     }

 $ report. = "Последний протестированный $ test.rn";

 } 

Сравните хешированные файлы с записями базы данных

Пока что мы узнали только текущее количество файлов и дату и время последнего сканирования. Значение, которое мы ищем, — идентифицировать измененные файлы, то есть те, которые были добавлены, изменены или удалены. Давайте создадим массив различий.

  // выявить различия

 if (! empty ($ files))

 {

     $ result = mysqli_query ($ db, "SELECT * FROM baseline");

     if (! empty ($ result))

     {

         foreach ($ result как $ value)

         {

             $ baseline [$ value ["file_path"]] = $ value ["file_hash"];

             }

             $ diffs = array_diff_assoc ($ files, $ baseline);

             снята с охраны ($ базовый);

         }

     }



 // сортируем различия в удаленные, измененные и добавленные массивы

 if (! empty ($ files))

 {

     $ results = mysqli_query ($ db, "SELECT file_path, file_hash FROM baseline WHERE acct = '$ acct'");

     if (! empty ($ results))

     {

         $ baseline = array ();  // из базы данных

         $ diffs = array ();  // различия между $ files и $ baseline

                                   // $ files это текущий массив file_path => file_hash

         while ($ value = mysqli_fetch_array ($ results))

         {

             if (! array_key_exists ($ value ["file_path"], $ files))

             {

                 // Удаленные файлы

                 $ diffs ["Удалено"] [$ value ["file_path"]] = $ value ["file_path"];

                 $ baseline [$ value ["file_path"]] = $ value ["file_hash"];

             } еще {

                     // Измененные файлы

                     if ($ files [$ value ["file_path"]] <> $ value ["file_hash"])

                     {

                         $ diffs ["Изменено"] [$ value ["file_path"]] = $ value ["file_path"];

                         $ baseline [$ value ["file_path"]] = $ value ["file_path"];

                     } еще {

                             // неизмененные файлы

                             $ baseline [$ value ["file_path"]] = $ value ["file_hash"];

                     }

             }

         }

         if (count ($ baseline) <count ($ files))

         {

             // Добавленные файлы

             $ diffs ["Added"] = array_diff_assoc ($ files, $ baseline);

         }

         снята с охраны ($ базовый);

     }

 } 

После завершения массив $diffs

Результаты электронной почты

Вам нужно будет добавить расхождения в отчет и электронное письмо.

  // отображаем расхождения

 if (! empty ($ diffs)) {

 $ report. = "Обнаружены следующие расхождения: rnrn";

 foreach ($ diffs as $ status => $ disabled)

 {

     if (is_array ($ disabled) &&! empty ($ disabled))

     {

         ($ тест)?  echo "<li>".  $ статус.  "</ li>": $ report. = "* $ status * rnrn";

         ($ тест)?  echo "<ol>": '';
         foreach ($ влияет как $ path => $ hash) $ report. = "• $ pathrn";

     }

 }

 } еще {

     $ report. = "Файловая структура не повреждена. rn";

 }



 $ mailed = mail ('[email protected] ', $ acct.' Integrity Monitor Report ', $ report); 

Обновите базу данных

Вы еще не закончили!

  //          обновление базы данных

 // очистить старые записи

 mysqli_query ($ db, "DELETE FROM baseline WHERE acct = '$ acct'");



 // вставить обновленные записи

 foreach ($ files as $ path => $ hash)

 {

     mysqli_query ($ db, "INSERT INTO baseline (file_path, file_hash, acct)
         VALUES ('$ path', '$ hash', '$ acct') ");

 }



 mysqli_query ($ db, "INSERT INTO испытания (проверено, acct) ЗНАЧЕНИЯ (NOW (), '$ acct')");



 mysqli_close ($ дБ);

 ?> 

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

Теперь, когда у вас есть код, куда вы его загружаете? Даже не рассматривайте возможность размещения этого кода в своем веб-пространстве (под DocumentRoot), так как это будет означать, что любой может получить доступ к вашему файлу и удалить сохраненную информацию, чтобы аннулировать ваши хэш-сканы. Для простоты поместите его в тот же каталог вашей учетной записи, в котором находится каталог public_html

Активировать

Теперь, когда у вас есть код, его нужно регулярно активировать. Вот где функция CRON сервера превосходна! Просто используйте вашу cPanel, чтобы создать новую работу CRON, установите время в середине ночи, когда ваш сервер должен почти бездействовать (вы не хотите вмешиваться или задерживать действия посетителей, что также означает, что вы должны ограничить себя одно сканирование в день) и используйте следующую директиву:

  / usr / local / bin / php -q /home/account/hashscan.php 

где /usr/local/bin/php/home/account/hashscan.phphashscan.php

Заворачивать

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

Мы отсканировали файлы, избегая ненужных каталогов, и сравнили хэши с базовым уровнем в базе данных. Закрывая процесс, мы обновили таблицы базы данных и либо отобразили (на тестовом сервере), либо отправили результаты по электронной почте (с рабочего сервера). Наша работа в CRON будет активировать ваше сканирование хешей на регулярной основе.

Этот ZIP-файл содержит вышеуказанные CreateTable.sqlhashscan.phpCRON.txt

Это лишь часть защиты вашего веб-сайта, поскольку он будет информировать вас только об изменениях типов файлов, которые вы указали. Прежде чем вы зайдете так далеко, вы должны убедиться, что ваши файлы не содержат вредоносных программ (сканирование хостов, установленное вашим хостом, может сделать это, но убедитесь, что вы храните чистую мастер-копию в автономном режиме), убедитесь, что никто, кроме вас, не может загружать файлы через FTP (используя ОЧЕНЬ надежные пароли) и регулярно обновляйте «консервированные приложения» (потому что их патчи закрывают уязвимости, найденные и используемые хакерами и их легионами «сценаристов»).

Итак, БЫТЬ ПАРАНОИДОМ! Может быть, никто не хочет вас поймать, но есть те, кто ищет «пинки» и ищет легкую добычу. Ваша цель — избежать этой классификации.