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 - дата последней модификации папки/файла
В последующем, мы будем читать диру и сверяться со значениями в БД!
встаим такой код:
<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."<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);
}
Чтож базу заполнили, теперь надо проверить, уж не удалил ли наш хакер чего-нибудь, кстати советую написать скрипт, который бэкапит самое важное, думаю ты без проблем сможешь написать такой, если нет, то стучи на асю или пиши письмо!
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, если она не изменилась значит папка был удалена! То же самое проделываем с файлами. Кстати, мы забыли о том, что надо сверять размер файлов. Делается это очень просто, после проверки имени файла, сверяем размер:
$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 "<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)
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 - дата последней модификации папки/файла
В последующем, мы будем читать диру и сверяться со значениями в БД!
встаим такой код:
<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."<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);
}
Чтож базу заполнили, теперь надо проверить, уж не удалил ли наш хакер чего-нибудь, кстати советую написать скрипт, который бэкапит самое важное, думаю ты без проблем сможешь написать такой, если нет, то стучи на асю или пиши письмо!
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, если она не изменилась значит папка был удалена! То же самое проделываем с файлами. Кстати, мы забыли о том, что надо сверять размер файлов. Делается это очень просто, после проверки имени файла, сверяем размер:
$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 "<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)