Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Защита сайта (https://forum.antichat.xyz/showthread.php?t=13612)

brainw0rk 28.01.2006 11:27

Защита сайта
 
author: brainw0rk
STATUS: saving

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

Как действует хакер, который нашел брешь в сайте? Конечно он пытается получить web-шелл! Через какой-либо баг он пытается залить этот злополучный шелл или дописать вредоносный код в какой-нибудь из файлов. Этот шелл он маскирует под ненавязчивым именем, например config.php или что-то в этом роде. Часто администраторы даже не замечают этого. Чтож напишем код, который будет сообщать админу о том, что был изменен какой-то файл (если хакер вписал вредоносный код в уже существующий файл), или был добавлен новый файл.
Для того чтобы понять были ли произведены какие-то изменения в структуре сайта, нужно зафиксировать то, что есть. Заносим в БД все папки и файлы (а также размер файла и дату последней модификации). Пусть таблица с этими значениями будет называться indexer, вот sql-запрос для создания такой таблицы:

[sql request]
create table indexer (object_id int not null primary key, object_name varchar(100) not null, object_type varchar(100) not null, object_path varchar(255) not null, object_size varchar(50) not null, object_date varchar(50) not null)

[description]
Пояснения:
object_id - уникальный номер файла/папки
object_name - имя папки/файла
object_type - тип (папка/файл)
object_path - путь до папки/файла
object_size - размер папки/файла
object_date - дата последней модификации папки/файла

В последующем, мы будем читать диру и сверяться со значениями в БД!
встаим такой код:
Код HTML:

  <form action=indexer.php method=POST>
  <select name=do size=2>
      <option value=udate>Обновить значения в БД</option>
      <option value=check>Сравнить</option>
      <option value=unwrite>Провеить</option>
  </select>

Можно конечно занести все это руками в БД, но ведь лучше автоматизировать процесс, тем более, если проект развивается и каждый день обновляется, то намного удобнее взвалить эту работу на простенький скрипт.

PHP код:

  if(isset($_REQUEST["do"]) && $_REQUEST["do"] == "update") {   
      
$delete_table mysql_query("DELETE FROM indexer");         // удаляем прошлые значения
                                                                  // находящиеся в таблице

      
$dir $_REQUEST["dir"];                                    // имя папки, которую надо                                                                        // проиндексировать
      
      
$chdir realpath($dir);                                    // узнаем реальный путь до                                                                        // папки
      
      
$dir_open opendir(realpath($chdir));                      // открываем диру

      
while($read_dir readdir($dir_open)) {                     // читаем...
         //echo $read_dir."<br>";
         
if($read_dir == "." || $read_dir == "..") {              // если $read_dir равна . или                                                                     // .. то пропускаем...
            
continue;
                                                   }

         
$id_object mysql_num_rows(mysql_query("SELECT id FROM indexer")); // узнаем кол-во                                                                              // записей

         
$object_id++;                                             // увеличиваем
         
$object_name $read_dir;                                 // присваиваем имя...
         
$object_type is_dir($read_dir) ? "directory":"file";    // тип...
         
$object_size filesize($read_dir);                       // размер...
         
$object_date date("d.m.y H:i:s",filemtime($read_dir));  // дату модификации...
         
$object_path str_replace("\\","/",realpath($read_dir)); // и наконец путь

         
if(is_file($read_dir)) {   // действие выполняем, если объект является фалйлом
            
$insert_table mysql_query("INSERT INTO indexer (id, object, object_type, object_path, object_size, object_date) VALUES ('$id_object', '$object', '$object_type', '$object_path', '$object_size byte', '$object_date')");
                                }
         else {                    
// действие выполняем, если объект является папкой
            
$insert_table mysql_query("INSERT INTO indexer (id, object, object_type, object_path, object_date) VALUES ('$id_object', '$object', '$object_type', '$object_path', '$object_date')");
              }

         if(
$insert_table) {   // если все удачно, сообщаем...
            
echo "<font face=Tahoma color=runthes size=2>$read_dir успешно добавлен в БД!</font><br>";
                           }
         else {                
// или если неудачно :(
            
echo "<font face=Tahoma color=runthes size=2>ERROR in $read_dir</font><br>";
              }
                                            }
         
closedir($dir_open);
                                                             } 

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

PHP код:

   elseif(isset($_REQUEST["do"]) && $_REQUEST["do"] == "check") {       
      
// выбираем объекты, которые являеются папками
      
$query_dir mysql_query("SELECT * FROM indexer WHERE object_type='directory'");                   
      if(
$query_dir) { // если запрос выполнен...
         
while($read mysql_fetch_array($query_dir)) {
            if(!
is_dir($read["object_path"])) {   // если такой папки уже нету , значит ее                                                   // удалили!
               
echo "<font face=Tahoma color=black size=2>".$read["object"]." не существует!</font><br>";
               
               
mail('адрес_админа','тема_тревожного_письма','тело_письма'// шлем письмо                                                                                    // несчастному админу
                                              
}
                                                      }
                     }
      
// выбираем объекты, которые являеются файлами
      
$query_file mysql_query("SELECT * FROM indexer WHERE object_type='file'");
      if(
$query_file) {
         while(
$read mysql_fetch_array($query_file)) {
            if(!
is_file($read["object_path"])) {   // если такого ф-а уже нету , значит его                                                          // удалили!
               
echo "<font face=Tahoma color=runthes size=2>".$read["object"]." не существует!</font><br>";
               
mail('адрес_админа','тема_тревожного_письма','тело_письма'// шлем письмо                                                                                    // несчастному админу
                                               
}
                                                       }
                      }
                                                                } 

Ну а теперь проверим, не добавил ли хакер чего-нибдудь странного! Делается это очень просто, сначала мы задаем имя каталога, который хотим проверить, далее значения заносятся в массив. После этого выбираем из БД объекты, которые являются папками, а потом через цикл сверяемся, если мы нашли соответствие значит файл существует и мы присваиваем переменной $error значение 0. После выхода из цикла, проверяем значение переменной $error, если она не изменилась значит папка был удалена! То же самое проделываем с файлами. Кстати, мы забыли о том, что надо сверять размер файлов. Делается это очень просто, после проверки имени файла, сверяем размер:
PHP код:

   $error_size 1;
   
$size sizeof($objects[$i]);
   if(
$size == $db_object["object_size"]) {
      
$error_size 0;
                                          } 

Вот полный код проверки:

PHP код:

   elseif(isset($_REQUEST["do"]) && $_REQUEST["do"] == "unwrite") {
      
$dir $_REQUEST["dir"];                                // получаем название диры
      
$chdir realpath($dir);                                // узнаем реальный путь до диры
      
$dir_open opendir(realpath($chdir));                  // открываем...

      
while($read_dir readdir($dir_open)) {
         if(
$read_dir == "." || $read_dir == "..") {          // если . или .. то пропускаем
            
continue;
                                                   }
      
$objects[] = $read_dir;                                 // пишем в массив
                                            
}
      for(
$i=0$i<count($objects); $i++) {
         if(
is_dir($objects[$i])) {                           // если папка...
            // выбираем из БД только те объекты, которые являются папками
            
$query_object mysql_query("SELECT * FROM indexer WHERE object_type='directory'");
               if(
query_object) {
               
$error 1;
               while(
$db_object mysql_fetch_array($query_object)) {
                  if(
$objects[$i] == $db_object["object"]) {  // если есть такая директория...
                     
$error 0;                              // обнуляем значение
                     
break;                                   // выходим из цикла
                                                           
}
                  else {
                     continue;                                
                       }
                                                                    }
                                }
         if(
$error == 1) {
            echo 
"<font face=Tahoma color=runthes size=2>
                  Была найдена директория которой нет в БД - 
$objects[$i]
                  </font><br>"
;
                        }
                                  }
         
// те же самые действия, но только для файлов
         
if(is_file($objects[$i])) {
            
$query_object mysql_query("SELECT * FROM indexer WHERE object_type='file'");
               if(
query_object) {
               
$error 1;
               while(
$db_object mysql_fetch_array($query_object)) {
                  if(
$objects[$i] == $db_object["object"]) {
                     
$error 0;
                     break;
                                                           }
                  else {
                     continue;
                       }
                                                                    }
                                }
         if(
$error == 1) {
            echo 
"<font face=Tahoma color=runthes size=2>
                  Был найден файл которого нет в БД - 
$objects[$i]
                  </font><br>"
;
                        }
                                  }

                                          }
                                                                  } 

Также можно создать таблицу, в которую будут заносится те файлы и папки, которых нету в БД или те файлы, которые изменились в размерах! Вот как может выглядятье эта таблица:
create table error_object(id int not null primary key, object varchar(100) not null, object_type varchar(100) null, object_size varchar(100) not null, object_date varchar(100) not null, object_path varchar(100) not null)

Zadoxlik 28.01.2006 17:15

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

WizART 28.01.2006 17:48

Цитата:

Сообщение от Zadoxlik
Проще это все сформировать ввиде скажем мд5хеша и пересчитывать его при любом изменении каких-то данных. Да и чел, поимев твой сайт, сам сможет все это дело туды складывать.
А вообще по-мойму это слишком гиморно. Если хостер ведет логи - тогда с этим всем заморачиваться точно не стоит.
Если не ведет - тогда выход - вести логи средствами скрипта, сохраняя их на другом сервере через взаимодействие с другим скриптом (на том сервере), чтобы, получив шелл, хацкор не почистил за собой лог.

Херасе ты написал насчет взаимодействия :) это точно гемор :)))) имхо статья норм, репки добавил!

virgoz 28.01.2006 19:07

Статья понравилась, молодец!
Цитата:

Да brainw0rk ник у тя знакомый
ага, я тоже сразу вспомнил maindw0rk и braindamage :))


Время: 00:36