Просмотр полной версии : Антивирус на php.
Идея.
Скажем, у Вас есть свой проект (пусть тот же хеко-саент) который Вы холите и лелеете.
Но Вам постоянно докучают злобные хэккеры, ужасающе втыкивающие кавычку в адресную строку и пишущие алерт(/лол/) в Ваших комментах.
Да мы не идеальны, допустить одну брешь можно и да наверно, скорее, нужно. Писать без ошибок не получается только у тех, кто не пишет ничего. Ну так вот, допустим писали вы свой проект и допустили такую маленькую ошибочку, а злобный хакер применив свой талант втыкивать в нужное место кавычку и хеккерский прием (инто аутфайл) закатал Вам свой шелл.
А теперь надену галстук и скажу немного серьезнее.
Вчера мне пришла нетрезвая мысль написать «антивирус» для своего блога. Из всего выше изложенного бреда, можно уяснить, что данный скрипт будет искать гадкие веб шеллы.
Приступ к алгоритмизации и последующей реализации.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
<title>r0: АнтивирУс f0r pr0j3c7</title>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1251" />
</head>
<body>
<center>
Ant1v1rus
<?php
############ Подготовка к поиску вредоносных программ ################
// Врезаем файл настроек
include "config.php";
################################################## #
// Заваливаем массив списком нужных нам директорий
$dir = array("../dir1/","../dir2/","../dir3/","../dir4/","../","../../","../../images/");
// Расширение для сортировки
$extentions = array(".php");
// масссив из безопасных php-файлов файлов
$safe_files = array("index.php","about.php","add.php", "xek.php", "antivir.php", "comments.php", "xekker.php", "files.php", "admin.php", "myshell.php", "navigation.php", "work.php", "bottom.php","config.php","top.php","main.php","papers.php","search.php","lol.php");
################################################## #
// Каждый элемент массива - как отдельную директорию
foreach ($dir as $get_dir) {
// Открываем хэндл директории
$dir_handle = opendir($get_dir);
// Получаем данные из директории
while ( false !== ($file = readdir($dir_handle)) ) {
// Находим файлы с расширением пэхопэ
$ext = strtolower(strrchr($file, "."));
// Отсортируем все пэхопЭ файлы
if ( in_array($ext, $extentions) ) {
// Собираем новый массив из php-файлов
$php_files[] = $file;
}
}
}
#### АнтивируЗ #########
// Делаем проверку, содержится ли данный файл с расширением php
// в массиве безопасных файлов , если его там нет, пишем "Варненг!"
foreach ($php_files as $files) {
if ( !in_array($files,$safe_files) )
{
echo "<font color=’#147018’ > <b>Ахтунг! Подозрительный файл »» ".$files."</b></font><br />";
}
}
?>
</center>
</body>
</html>
Поясню.
Моя логика была такова: имеется массив с названием папок(он же $dir), из которого затем извлекаются имена файлов, у которым делаем обрезание(по расширению) и если этой php-файл заносив его в новый массив, элементы которого проходят проверку на вшивость из уже имеющегося массива заданных файлов.
P.S Конечно, если хеккер проникает внутрь то он может залить свой шелл как index-файл в любую диру, но это представляет опасность с точки зрения многих искателей приключений, хочется как бы затаиться, поэтому и придумывают имена отличные от index.php =))
ЗУФСУ !
GreenBear
13.04.2007, 00:52
вообще от такой фигни пользы практически нет.
А что мешает хакеру, залившему шелл, добавить его в список разрешенных?
Имхо такую вещь надо реализовывать так: делать скрипт на баше, который раз в Н часов (по крону) проверяет папку на наличие подозрительных файлегов и в случае обнарежения оных отправляет админу письмо.
Примерно, вот так:
my $dir = '/usr/local/bin/apache/htdocs';
my @files = qw(index.php guestbook.php forum.php);
foreach my $toCheck(<$dir/*.php>)
{
my $valid = 0;
foreach my $pattern(@files) { $valid = 1 if $toCheck =~ /$pattern/ }
sendMail(...) unless $valid;
}
проникнувший на саент хэкка может внедрить злостный код прямо в антивирус и он будет писать чтонибудь матное или работать не так как полагается или просто удалить или он просто ... вот так вот =\
2KSURi:
Огасики.. Тогда уж сообщение на сотовый =)
Я не кожу на баше =/
вообще от такой фигни пользы практически нет.
Может и да =) Мне нравиться мыслить
злостный код прямо в антивирус
к0к0й уж0с.. надо уд0лить пока он не написал моей маме, что меня похекали...
2r0
фишка не в мыле, фишка в том, чтобы хакер не имел доступа к скрипту авира.
GreenBear
13.04.2007, 01:08
еще вариант в зенде его зашифровать.
Я нечто подобное писал, даже где-то сохранилось. Мой скрипт искал новые файлы, и если файл подпадал под критерий опасности посылала мне на мыло информацию.
+ проверял размеры всех существующих файлов с теми же размерами хранящимися в базе. Эта проверка раз в сутки запускалась.
Отдельно можно было запустить проверку контента новых и измененных файлов на предмет наличия "опасных функций".
Вещь на самом деле полезна для тех кто любит устраивать на ФТП своего сайта свалку, так что потом в случае чего хрен поймешь что твое а что чужое.
еще вариант в зенде его зашифровать.
Zend не спасение, Zend платный... Проще уж стандартными средствами
Как я понял, скрипт проверяет только определенные диры?
Что мешает сделать mkdir pohek; echo 'evil c0de here' > pohek/xek.pl ?
В идеале он должен рекурсивно проверять все диры и файлы из некой корневой точки
Digimortal
13.04.2007, 17:55
В идеале он должен рекурсивно проверять все диры и файлы из некой корневой точки
это верно, причем проверять на наличие любых изменений в файлах и отслеживать появление новых, т.к. простой парсинг файлов на предмет наличия "опасных" функций легко можно обойти..
guest3297
13.04.2007, 18:14
Ненадо такое писать а тем более класть в паблик.
"Не пили ветку, на которой сидишь."
']Ненадо такое писать а тем более класть в паблик.
"Не пили ветку, на которой сидишь."
А мне идея понравилась... К тому же, я на этой ветке не сижу ;)
Digimortal
13.04.2007, 18:53
уже писали и выкладывали подобные скриптики..
кроме того под *nix ведь тоже бывают антивирусы, которые умеют искать и веб-шеллы..
Подобный скрипт может помочь владельцу сайта, но теперь представьте админа сервера (примерно на 1к сайтов) которого зафлудит мессагами :)
PS: код php вообще не читаем раскраска ужасна (берите пример с vim)
Вспоминаем сниффер!!!
к примеру через SQL-inj или PHP-inj заливаем shell.jpg и .htaccess который будет асоциировать картинку с php файлом. ;)
ну а далее дело техники....
Квартет (с) Крылов ;)
Talisman
13.04.2007, 19:13
аффтар жжот)
нужна рекурсия по дире:
function scan_dir($dirname)
{
//echo ';'.$dirname.'<br />';
GLOBAL $text, $retext;
$dir = opendir($dirname);
while (($file = readdir($dir)) !== false)
{
if($file != "." && $file != "..")
{
if(is_file($dirname."/".$file))
{
echo ''.$file.' : '.(filesize($dirname.'/'.$file)/1024/1024).' MB<br />';
}
if(is_dir($dirname."/".$file))
{
// scan_dir($dirname."/".$file);
}
}
}
closedir($dir);
}
scan_dir('C:\Documents and S............');
код сканера, который я юзал, чтобы названия книжек собрать))
добавить функцию хеширования файла мд5 и проверять чек-сумму, ведь обычно код встраивают в существующие файлы.
проверять на всяк дату изменения (если ты параноик) но это просто обойти.
скрыть сам скрипт антивируса, например в свою домашнюю диру.
или же сверять файлы с копией в надежном месте.
+ верно отмечено, зырить так же нужно и на спец файлы веб-сервера (.htaccess .htpasswd)
Конечно, когда серв под 1 проект, или он под хрутом, то лучше всего вырезать все "ненужные" форуму функции пшп машины.
ЗЫ считаю глупостью рассказывать свои применяемые методы, т.к. это ослабит их защиту)
GreenBear
13.04.2007, 19:18
эти методы и так не дают никакой защиты, разве что от полных нубов, которым дали ссылку на шелл.
fucker"ok
13.04.2007, 19:37
Идея на нова. Проще сделать следить за контрольной суммой ф-лов и директорий. Написать скрипт, который из крона каждые 5 минут будет это проверят. В случае изменения контрольной суммы файла\директории создавать страничку "ворненг! одей сплойтенг детектед!" и закрывать доступ к сайту :)
А твой способ не сработает при банальном протраянивании файла.
Talisman
Если бы все думали как Вы, сейчас php был бы правительственной тайной
код сканера, который я юзал, чтобы названия книжек собрать))
Я думаю, что это не Вы написали =/
Ненадо такое писать а тем более класть в паблик.
Прям уж0с, я думаю кому надо, тот разберется как доделать =)
Можно написать скрипт который будет выводить на вашу страницу...коглда и какой файл изменился посл.раз....
Если допустим это было сделано не с вашего ип, то....эм.....че-нить делаем...
Уйма способов
DRON-ANARCHY
15.04.2007, 12:26
Это уже не антивирусы обсуждаются, а... ну... фильтры что ли...
под антивирусами я бы понимал какие-нить анти-руткиты или типа...
А имена шеллов всегда такие будут?
$safe_files = array("index.php","about.php","add.php", "xek.php", "antivir.php", "comments.php", "xekker.php", "files.php", "admin.php", "myshell.php", "navigation.php", "work.php", "bottom.php","config.php","top.php","main.php","papers.php","search.php","lol.php");
А имена шеллов всегда такие будут?я так понял это имена безопасных файлов а не шеллов.
я так понял это имена безопасных файлов а не шеллов.
myshell.php тоже безопасный файл?))
У него в коде написано
// масссив из безопасных php-файлов файлов
$safe_files = array("index.php","about.php","add.php", "xek.php", "antivir.php",
"comments.php", "xekker.php", "files.php", "admin.php", "myshell.php", "navigation.php",
"work.php", "bottom.php","config.php","top.php","main.php",
"papers.php","search.php","lol.php"); А точнее коммент и имя массива. Вот я и подумал что это разрешаемые файлы. Весь код я не смотрел.
Это уже получается Ids с контролем целостности файлов.
Nightmarе
23.09.2007, 23:56
Идея на нова. Проще сделать следить за контрольной суммой ф-лов и директорий. Написать скрипт, который из крона каждые 5 минут будет это проверят. В случае изменения контрольной суммы файла\директории создавать страничку "ворненг! одей сплойтенг детектед!" и закрывать доступ к сайту :)
А твой способ не сработает при банальном протраянивании файла.
Вот это отличная идея, если кто сможет, реализуйте плиииз!!!
Digimortal
24.09.2007, 00:45
>> Вот это отличная идея, если кто сможет, реализуйте плиииз!!!
ок, напишу на Perl.. +)
George767
24.09.2007, 01:56
Вспоминаем сниффер!!!
к примеру через SQL-inj или PHP-inj заливаем shell.jpg и .htaccess который будет асоциировать картинку с php файлом. ;)
ну а далее дело техники....
Квартет (с) Крылов ;)
Вспоминай) Вообще-то на сервере файлы лежат в изначальном виде (формате), это когда они вызываются по-другому (к примеру через mod_rewrite в .htaccess), их сервер открывает. Так что если это банальный шелл, то он всегда будет на сервере лежать как .php файл.
George767
24.09.2007, 01:59
Я завтра напишу на Php, но в моей версии кроме отправления сообщения на мыла, сайт будет закрыватся (тут естевственно надо под конкретный проект писать)
life_is_shit
24.09.2007, 05:23
4 Nightmarе.
Делать было нечего, сделал
Скрипт пользуеца мускулом, предварительно ему нужны данные для доступа.
Он делает слепок директории и заносит в базу, делая мд5 и определяя размер файлов и директоии.
При проверке эти данные сверяются, если что-то не совпадает то в корне контролируемой директоии создается
.htaccess блокирующий файл для всех (кто хочет может поменять на локалхост) и высылает репорт админу.
<?php
$server = 'localhost'; //хост
$username = 'anti_change'; //юзер мускула
$password = 'password'; //пароль мускула
$database = 'anti_change'; //база мускула
$path = 'C:/TopServer/home/localhost/wordpress'; //реальный путь к контролируемой директории
$mail_to = 'admin@localhost'; //кому писать репорт
$mail_from = 'axtung@localhost'; //от кого
$mail_subj = 'axtung!!!'; //тема письма
mysql_connect($server, $username, $password);
mysql_select_db($database);
function scan_dir($dirname)
{
GLOBAL $text, $retext;
$dir = opendir($dirname);
while (($file = readdir($dir)) !== false)
{
if($file != "." && $file != "..")
{
if(is_file($dirname."/".$file))
{
$sql = "INSERT INTO `first_scan` (`category`, `name`, `md5_file`, `size`) VALUES ('file', '".$dirname."/".$file."', '".md5_file($dirname.'/'.$file)."', '".filesize($dirname.'/'.$file)."')";
mysql_query($sql);
}
if(is_dir($dirname."/".$file))
{
$sql = "INSERT INTO `first_scan` (`category`, `name`, `md5_file`, `size`) VALUES ('directory', '".$dirname."/".$file."', '---', '".disk_total_space($dirname."/".$file)."')";
mysql_query($sql);
scan_dir($dirname."/".$file);
}
}
}
closedir($dir);
}
function check_dir($dirname)
{
GLOBAL $text, $retext;
$dir = opendir($dirname);
while (($file = readdir($dir)) !== false)
{
if($file != "." && $file != "..")
{
if(is_file($dirname."/".$file))
{
$sql = "SELECT * FROM `first_scan` WHERE `name` = '".$dirname."/".$file."' and `category` = 'file'";
$result_file = mysql_query($sql);
$array_file = mysql_fetch_array($result_file);
if ($array_file)
{
if ($array_file['md5_file'] != md5_file($dirname.'/'.$file))
{
$sql_md5 = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('error md5_file', '".$dirname."/".$file." error checksum')";
$res=mysql_query($sql_md5);
}
if ($array_file['size'] != filesize($dirname.'/'.$file))
{
$sql_size = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('error size file', '".$dirname."/".$file." error size file')";
mysql_query($sql_size);
}
}
else
{
$sql_nf = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('file not found', '".$dirname."/".$file." file not found')";
mysql_query($sql_nf);
}
}
if (is_dir($dirname."/".$file))
{
$sql = "SELECT * FROM `first_scan` WHERE `name` = '".$dirname."/".$file."' and `category` = 'directory'";
$result_dir = mysql_query($sql);
$array_dir = mysql_fetch_array($result_dir);
if ($array_dir)
{
if ($array_dir['size'] != disk_total_space($dirname."/".$file))
{
$sql_size = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('error size directory', '".$dirname." error size directory')";
mysql_query($sql_size);
}
}
else
{
$sql_nf = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('directory not found', '".$dirname."/".$file." directory not found')";
mysql_query($sql_nf);
}
check_dir($dirname."/".$file);
}
}
}
closedir($dir);
}
function check_del()
{
$sql = "SELECT * FROM `first_scan`";
$result = mysql_query($sql);
while ($array = mysql_fetch_array($result))
{
if (!is_dir($array['name']) && ($array['category'] == 'directory'))
{
$sql_del_dir = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('directory deleted', '".$array['name']." directory deleted')";
mysql_query($sql_del_dir);
}
if (!file_exists($array['name']) && ($array['category'] == 'file'))
{
$sql_del_file = "INSERT INTO `axtung!` (`category_error`, `description`) VALUES ('file deleted', '".$array['name']." file deleted')";
mysql_query($sql_del_file);
}
}
}
if (isset($action) && ($action == 'first'))
{
mysql_query("DROP TABLE `axtung!`");
mysql_query("CREATE TABLE `axtung!` (
`id` int(11) NOT NULL auto_increment,
`category_error` text,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1");
mysql_query("DROP TABLE `first_scan`");
mysql_query("CREATE TABLE `first_scan` (
`id` int(10) NOT NULL auto_increment,
`category` text NOT NULL,
`name` text NOT NULL,
`md5_file` text NOT NULL,
`size` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=501;
");
scan_dir($path);
echo 'слепок сделан';
}
if (isset($action) && ($action == 'check'))
{
check_dir($path);
check_del();
$mail = '';
$report = '';
$sql_mail = "SELECT * FROM `axtung!`";
$result = mysql_query($sql_mail);
while ($array = mysql_fetch_array($result))
{
$mail .= $array['description']."\n";
$report .= $array['description']."<br>";
}
if (!empty($mail))
{
$fh = fopen ('C:/TopServer/home/localhost/wordpress/.htaccess', "w");
fwrite($fh, "\n"."deny from all");
fclose ($fh);
mail('admin@localhost','axtung!',$mail,"From: axtung@localhost\r\n");
echo 'Ахтунг!!!<br>'.$report.'Внимание доступ к сайту закрыт!!!';
}
else
{
echo 'Все норм, спи спокойно';
}
}
if (isset($action) && ($action == 'clear_error'))
{
mysql_query('TRUNCATE `axtung!`');
echo 'лог очищен';
}
?>
<form action="<?=basename($PHP_SELF)?>?action=first" method="POST">
<input type="submit" value="создать слепок файловой системы">
</form>
<br>
<form action="<?=basename($PHP_SELF)?>?action=check" method="POST">
<input type="submit" value="проверить">
</form>
<br>
<form action="<?=basename($PHP_SELF)?>?action=clear_error" method="POST">
<input type="submit" value="очистить лог из базы">
</form>
Юзай на здоровье.
З.Ы. Просьба на корявости не обращать внимания, ибо писал ночью и особенной ценности скрипт для меня не представлял.
З.Ы.Талисману пасиба за реверсивный поиск, ибо самому было лень)
Nightmarе
25.09.2007, 02:27
Супер, пасиб за скрипт!!!!!!
life_is_shit, в твоем скрипте дырок 5 минимум...
Инклуд и скули уже увидел...
The_HuliGun
25.09.2007, 09:20
Нету там ни одного вызова инклуд функций.
life_is_shit, пасиб за скрипт.
blackybr
25.09.2007, 09:37
В идеале брать чексум файла и проверять на изменение. Скрипт кодится зендом и все. никаких проблем. Зенд платный? О_о
Егорыч+++
25.09.2007, 09:39
Безусловно скрипт не имеет смысла и не от чего не защищает. Защита от инклюда файлов должна быть сделана на основании серии исследований:
1) Проверка контрольной суммы всех файлов.
2) Поиск записей в файлах, которые попадают под возможности шела (типа инклюде, eval , system и т. д.) . Файлы в которых нужны эти функции и места в них помечаются (хотя по любому проверка мд5 такие файлы защитит).
3) Создаем серию ловушек. Типо файлы конфигов и мониторим время их просмотра. В случае измениния времени начинаем думать какая зараза смотрит наши файлы.
Этого будет достаточно. Могу тоже самое продолжить про мониторинг всег sql инъекций, но это на уровне шаре хостинга реализовать сложнее.
life_is_shit
25.09.2007, 14:01
4 Егорыч+++
Полностью прав, но для магазина к примеру скрипт вполне подойдет.
4 Nightmarе & 4 The_HuliGun
всегда пожалуйста, если нада туда чонить дописать пишите в аську, без проблем.
4 Isis
вообще-то скрипт желательно запоролить, или поставить доступ с одного Ip.
недостаток в том, что пароли к базе в открытом виде, но есть зенд)
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot