Изучение веб-панели ботнета Cythosia
Предисловие: наткнулся в гугле на исходники данного ботнета 2011 года и появилось желание изучить их. Как оказалось позже некоторые его уязвимости уже есть на exploit-db, поэтому цель данной статьи по факту является просто изучение ошибок программиста при создании данной веб-панели:) Выкладывать архив или ссылку на исходники не буду (часть их будет в данной статье).
Установка
Распаковав архив, видим следующую картину:
Автор любезно оставил нам в корневой папке архива файл ReadMe.txt со следующим содержанием:
Edit the Admin Password in admin/index.php
Edit all other configs in admin/inc/conf.php
Run dump.sql in your phpmyadmin
Cheers... Post.Mort3m
Все это получилось сделать, но оказалось, что редактировать пароль админа нужно не в admin/index.php, а в /index.php.
Перейдем к следующему пункту
Авторизация для людей
Для того, чтобы авторизоваться, требуется заполнить форму по адресу /index.php:
Рассмотрим код index.php:
<?php
session_start();
$crypt_pw = md5("admin");
if(isset($_POST['submit']))
{
if(isset($_POST['pw']) && md5($_POST['pw']) == $crypt_pw)
{
$_SESSION['hydra_loggedin'] = 1;
header("Location: admin/index.php");
}
else
{
header("Location: index.php");
}
}
?>
. . .
На третьей строке указан текущий пароль, который нужно было поменять при установке. По-умолчанию установлен пароль admin. Уже на этом пункте есть недочет(или защита от скрипткидди?): смысл сравнения хешей теряется, если у нас в файле присутствует пароль в незахешированном виде.
Далее идет проверка хешей и создание сессии для текущего пользователя с переменной hydra_loggedin=1.
Авторизация для ботов
Обычно авторизация для зараженных компьютеров "плавает" на поверхности.
Так оно и оказалось - за добавление новых компьютеров отвечает файл socks5.php в корне сайта со следующим содержимым:
<?php
include("admin/inc/config.php");
include("admin/inc/funcs.php");
if(!empty($_POST['hwid']) && !empty($_POST['cn']) && !empty($_POST['ip']) && !empty($_POST['port']))
{
$query = mysql_query("SELECT * FROM hydra_socks WHERE hwid = '".$_POST['hwid']."'");
if(mysql_num_rows($query) >= 1)
{
$sql = mysql_query("UPDATE hydra_socks SET ip = '".$_POST['ip']."', port = '".$_POST['port']."' WHERE hwid = '".$_POST['hwid']."'");
}
else
{
$sql = mysql_query("INSERT INTO hydra_socks (`hwid`, `country`, `ip`, `port`) VALUES ('".$_POST['hwid']."', '".$_POST['cn']."', '".$_POST['ip']."', '".$_POST['port']."')");
}
if(!$sql)
{
echo "fail";
echo mysql_error();
}
} else {
echo "post all";
}
?>
Уже интереснее) Смотрим на третью строку:
if(!empty($_POST['hwid']) && !empty($_POST['cn']) && !empty($_POST['ip']) && !empty($_POST['port']))
Она проверяет наличие POST параметров hwid, cn, ip, port и в случае их наличия переходит на 5 строку:
$query = mysql_query("SELECT * FROM hydra_socks WHERE hwid = '".$_POST['hwid']."'");
Вот мы и наткнулись на второй недочет: при наличии данных параметров совершается SELECT запрос в базу данных с нефильтруемым параметром hwid .
Перефразирую: мы с вами нашли типичную SQL SELECT injection.
Далее у нас идет либо обновление данных бота (строка 9):
$sql = mysql_query("UPDATE hydra_socks SET ip = '".$_POST['ip']."', port = '".$_POST['port']."' WHERE hwid = '".$_POST['hwid']."'");
Либо в случае отсутствия записей, создает новую запись (строка 13):
$sql = mysql_query("INSERT INTO hydra_socks (`hwid`, `country`, `ip`, `port`) VALUES ('".$_POST['hwid']."', '".$_POST['cn']."', '".$_POST['ip']."', '".$_POST['port']."')");
А т.к. ни один из POST параметров не фильтруется, то у нас есть не одна, а три SQL injection трех разных типов: SELECT, UPDATE и INSERT!
Предоставляю вам наглядный запрос с ответом сервера:
Остальные скрипты вне папки admin
Так же в корневой директории присутствуют файлы ip.php и connect.php.
Вначале рассмотрим содержимое файла ip.php:
<html>
<head>
<title>ip</title>
</head>
<body>
<?php
echo $_SERVER['REMOTE_ADDR'];
?>
</body>
</html>
То есть бот вначале посылает GET запрос на /ip.php, получает свой ip адрес и только после этого отсылает его в скрипт /socks5.php для добавления в базу данных.
И файл connect.php, который отвечает за поддержание соединения с ботом и распределение задач. Приводить содержимое connect.php не буду, скажу только, что в отличии от socks5.php каждый POST параметр уже упакован функцией фильтрации mysql_escape_string() и ip жертвы считывает автоматически (не требуется переходить на ip.php).
Такое чувство, что автор ботнета тренировался на скриптах ip.php и socks5.php и только после начал писать уже более-менее безопасный connect.php .
Файлы админки
Вот как выглядит админ панель после авторизации:
Повторно приведу список файлов в папке /admin/:
Быстренько пройдемся по ним:
create_task.php - html форма создания новой задачи для ботов.
delete_task.php - удаление задачи из базы данных. Получает GET параметр taskID, который впоследствии переводится в integer и посылается в БД. Уязвимости нет.
do_new_task.php - обработчик формы create_task.php, создается новое событие с временем начала и завершения, все формы фильтруются.
export_socks.php - предоставляет список всех зараженных компьютеров, которые поддерживают соединение.
info.php - просто html.
logout.php - очищает параметр сессии hydra_loggedin
show_task.php - высвечивает все текущие задачи, основываясь на целочисленном GET параметре taskID.
showbots.php - выводит список всех (включая оффлайн) зараженных компьютеров. Принимает GET параметр query, который фильтруется и отвечает за сортировку.
socks.php - аналогично export_socks.php, только предоставляет вывод в более красивом варианте.
stat.php - вывод всей статистики ботнета.
tasks.php - вывод всех текущих задач ботов.
Так зачем же я перечисляю задачи данных файлов? Это же никому не интересно!
Все достаточно просто! Все эти файлы (кроме быть может файла logout.php) объединяет общее начало:
session_start();
if(!isset($_SESSION['hydra_loggedin']) && $_SESSION['hydra_loggedin'] != 1)
{
header("Location: http://www.google.com");
}
То есть скрипт проверяет значение параметра сессии hydra_loggedin, и если он не равен единице, то делает редирект на google.com и.. по логике должен завершать свою работу.
Но нет! Далее нет ни exit(), ни die() - скрипты просто продолжают свою работу!
Нам достаточно отключить редирект в нашем браузере, чтобы при переходе на /admin/index.php получить полное управление!
Сказано-сделано: как пример получим список всех зараженных компьютеров
Да, у меня нет ни одного компьютера в ботнет сети - но тк была отрисовка таблицы, то это подтверждает наличие уязвимости!
Подводим итоги
У ботнета присутствует следующее:
1. SQL SELECT injection
2. SQL INSERT injection
3. SQL UPDATE injection
4. Неавторизованный доступ к управлению ботнета
5. Отсутствие robots.txt
6. Наличие пароля по умолчанию
С первыми четырьмя уязвимостями мы с вами уже познакомились, а что же дают нам последние две?
А вот что:
intitle:"cythosia v2 bot webpanel - login"
То есть у нас есть список из ботнет панелей, доступ к которым мы можем получить просто отключив перенаправления в браузере! Сами можете поиграться с ними - пароль у большинства из них стоит по-умолчанию - admin :)
Вывод: таким образом сочетание этих шести недочетов во время написания ботнет веб-панели, дает нам возможность получить контроль над всеми ботнетами, основанными на данном вредоносном программном обеспечении!
- Автор: drakylar
- Комментарии: 2
- Просмотры: 5150