Как стать автором
Обновить

Простая индексация сайта для защиты

Время на прочтение5 мин
Количество просмотров635
Писалось года 2 назад…

Как действует хакер, который нашел баг в сайте? Конечно он пытается получить 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)

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

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

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


Можно конечно занести все это руками в БД, но ведь лучше автоматизировать процесс, тем более, если проект развивается и каждый день обновляется, то намного удобнее взвалить эту работу на простенький скрипт.
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."
";
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 "$read_dir успешно добавлен в БД!
";
}
else { // или если неудачно :(
echo "ERROR in $read_dir
";
}
}
closedir($dir_open);
}


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

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 "".$read[«object»]." не существует!
";
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 "".$read[«object»]." не существует!
";
mail('адрес_админа','тема_тревожного_письма','тело _письма') // шлем письмо // несчастному админу
}
}
}
}


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

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


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

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 "
Была найдена директория которой нет в БД — $objects[$i]

";
}
}
// те же самые действия, но только для файлов
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 "
Был найден файл которого нет в БД — $objects[$i]

";
}
}

}
}


Также можно создать таблицу, в которую будут заносится те файлы и папки, которых нету в БД или те файлы, которые изменились в размерах! Вот как может выглядятье эта таблица:
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)
Теги:
Хабы:
Всего голосов 20: ↑16 и ↓4+12
Комментарии34

Публикации

Истории

Ближайшие события

19 марта – 28 апреля
Экспедиция «Рэйдикс»
Нижний НовгородЕкатеринбургНовосибирскВладивостокИжевскКазаньТюменьУфаИркутскЧелябинскСамараХабаровскКрасноярскОмск
22 апреля
VK Видео Meetup 2025
МоскваОнлайн
23 апреля
Meetup DevOps 43Tech
Санкт-ПетербургОнлайн
24 апреля
VK Go Meetup 2025
Санкт-ПетербургОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
14 мая
LinkMeetup
Москва
5 июня
Конференция TechRec AI&HR 2025
МоскваОнлайн
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область