Содержание статьи
WARNING
Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Статистика
Смартфоны и планшеты так быстро ворвались в нашу жизнь, что поведение героев из фильмов пятилетней давности уже кажется анахронизмом. Естественно, что вместе с полезными и не очень привычками пользователь приобрел и новых интернет-врагов.
По статистике, на 85% всех мобильных устройств установлена одна из версий Android, и неудивительно, что большинство атак и зловредов нацелены именно на нашу любимую операционную систему. Конечно, ситуация еще не так плоха, как с Windows лет десять назад, но тенденция пугает.
В январе прошлого года мы разбирали, насколько легко создать криптолокер под Android — программу, шифрующую пользовательские данные. И чуть позже, в апреле 2016 года, «Лаборатория Касперского» подтвердила наши опасения: компания заявила о появлении трояна-локера Fusob, атаковавшего смартфоны пользователей более чем из ста стран.
Многообразие фишинга
Мимикрирование вредоносных программ подо что-то полезное — довольно старый тренд. Лет десять-пятнадцать назад был бум популярности сайтов, которые очень похожи на официальные порталы банков или платежных систем. Такие фишинговые ресурсы старались вытянуть пользовательские аккаунты, а еще лучше — данные кредитных карт.
Но та волна хищений обошла страны СНГ стороной. Просто брать у нас было нечего: Павел Дуров еще ничего не написал, а пластиковые карты популярностью не пользовались. Сейчас же для мошенников ситуация стала по-настоящему «вкусной»: интернет-покупки, мобильный банкинг, всевозможные социальные сети — очень многое теперь доступно через мобильный телефон, подключенный к интернету.
Пока еще не было историй об эпидемиях фишинга, но неприятные звоночки уже есть. Серфинг интернета с мобильных устройств стал намного менее безопасным: сначала веб-мастера адаптировали рекламу под мобильный контент, а затем подтянулись и нечистые на руку люди. Совсем недавно, в начале декабря 2016 года, на одном популярном спортивном ресурсе выскакивало окошко с предложением «обновить устаревший WhatsApp» — естественно, разработчики мессенджера никакого отношения к такой рекламе не имеют.
Такие сообщения генерируются на стороне сервера и выглядят достаточно топорно. Но, попав внутрь устройства, злоумышленник может совершить более элегантную и эффективную атаку. Давай разберемся, насколько сложно в Android подменить рабочее приложение на его вредоносный «аналог».
В мире до сих пор нет ничего более универсального, чем деньги, поэтому стоит попробовать получить доступ к кошельку пользователя. Как списывают деньги при помощи отправки СМС на короткие номера, мы уже говорили, сегодня доберемся до банковской карты.
Почти Google Market
Чтобы убедить пользователя поделиться данными карты, нужно воспользоваться его доверием к популярному и знакомому приложению. Практически в каждом Android-устройстве установлена утилита Google Play — портал доступа к музыке, фильмам и другим приложениям. Это полноценный магазин, позволяющий совершать покупки, и для многих пользователей не будет большой неожиданностью, если приложение попросит ввести данные банковской карты.
Для фишинга не нужно точь-в-точь реализовывать функциональность Google Market — проще написать приложение, расширяющее его возможности без изменения исходного кода. Интересно узнать, как хакеры проворачивают подобное? Тогда поехали!
Выбор
Будет неправильным пытаться подделать приложение, которым владелец устройства совсем не пользуется. Как и при обычном вторжении, мошеннику нужно сначала оценить, в какую среду он попал. Многообразие вендоров, выпускающих мобильные устройства, привело к большим изменениям и в самой ОС. И хотя, со слов маркетологов, все они работают на единой платформе Android, набор запущенных приложений может быть совершенно разным. В Android есть встроенный API для получения списка запущенных процессов — это системный сервис ACTIVITY_SERVICE.
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();
Google в целях безопасности с каждым годом все больше ограничивает возможности приложений взаимодействовать между собой. В документации это явно не указано, но для Android версии 4.0 и новее такой вызов вернет список только из одного приложения — твоего собственного. Не все потеряно — в основе Android лежит ядро Linux, а значит, у нас есть консоль. К ней можно добраться руками с помощью утилиты adb
, входящей в Android Studio.
user@user-workPC ~/Desktop $ adb shell
Команды задаются с помощью утилиты toolbox, запущенной с несколькими аргументами, список процессов выдается командой ps.
root@generic_x86:/ # toolbox ps -p -P -x -c
Результат работы ожидаемо похож на вывод, который дает одноименная линуксовая команда, — таблица с множеством значений, разделенных табуляцией.
media_rw 1730 1176 7668 1876 1 20 0 0 0 fg inotify_re b75c3c46 S /system/bin/sdcard (u:0, s:3)
u0_a15 1798 1202 1298044 30520 0 20 0 0 0 fg SyS_epoll_ b72f9d35 S com.google.android.googlequicksearchbox:interactor (u:3, s:1)
u0_a35 1811 1202 1272580 37692 1 20 0 0 0 fg SyS_epoll_ b72f9d35 S com.android.inputmethod.latin (u:9, s:1)
u0_a8 1871 1202 1428180 77468 0 20 0 0 0 fg SyS_epoll_ b72f9d35 S com.google.android.gms.persistent (u:168, s:163)
Собственно, в этом выводе содержится достаточная для фишинга информация: имя процесса, его идентификатор, приоритет выполнения и так далее. Запустить утилиту можно не только руками, но и из приложения — для доступа к шеллу в стандартном API есть класс Shell.
List<String> stdout = Shell.SH.run("toolbox ps -p -P -x -c");
Линуксоидам часто приходится писать однострочные скрипты, поэтому распарсить такой вывод для них не проблема. Но ООП-разработчики более нежные и наверняка не захотят таким заниматься.
На Гитхабе уже есть проект, в котором реализована необходимая функциональность. Создал его некто Джаред Раммлер (Jared Rummler), за что скажем ему спасибо. Обработка результата выполнения toolbox создана в виде библиотеки, которую можно подключить прямо через Gradle.
compile 'com.jaredrummler:android-processes:1.0.9'
Принцип работы остается тот же самый: на выходе будет список данных, но уже в более привычном для ООП формате.
List<AndroidAppProcess> processes = AndroidProcesses.getRunningAppProcesses();
Вся информация о запущенных процессах обернута в объект класса AndroidAppProcess
. Если посмотреть исходники библиотеки, то ничего лишнего там нет — только парсинг консольного вывода. Информацию о конкретном приложении придется вытаскивать прямым перебором.
for (AndroidAppProcess pr : processes) {
if (pr.getPackageName().equals(ps_name)) {
//do smth
}
}
INFO
Обрати внимание: начиная с Android 7.0 Google ввела ограничение на доступ к информации о процессах других приложений. Теперь ее нельзя получить даже с помощью команды ps и прямого чтения файловой системы /proc. Впрочем, на Android 7+ большая часть юзеров перейдет очень не скоро — если вообще перейдет.
Активные приложения
Успешные фишинговые операции, как правило, хорошо подготовлены — мошенники умеют подобрать момент так, что у пользователя не возникает даже малейших подозрений в подлоге. Поэтому телефон не должен просто так попросить ввести данные банковской карты — это будет очень подозрительно. Фишинговые сообщения появляются под каким-то предлогом, например платные псевдообновления для 1C или фиктивные банковские ресурсы на адресах, схожих по написанию с легальными.
Многозадачность Android тут может сыграть на руку — в ОС могут работать одновременно с десяток приложений, сменяя друг друга. Неопытный пользователь может даже и не понять (да и вообще не задумываться), в каком именно приложении он сейчас работает. Вывод ps
дает информацию, какие именно приложения сейчас активно взаимодействуют с пользователем — то есть ему видны.
u0_a65 ... bg SyS_epoll_ b7366d35 S com.localhost.app.noizybanner (u:248, s:84)
u0_a64 ... fg SyS_epoll_ b7366d35 S com.localhost.app.fragments (u:7, s:11)
Этот параметр находится в 11-й колонке — тут может быть значение bg
(background, скрыт) или fg
(foreground, виден). ОС самостоятельно отслеживает такие состояния приложений, поэтому задача разработчика — только время от времени вызывать ps.
На основе библиотеки получается простенький метод, определяющий состояние искомого приложения.
private Boolean isProccessForeground(String ps_name)
{
List<AndroidAppProcess> processes = AndroidProcesses.getRunningForegroundApps(getApplicationContext());
...
У нас есть возможность сразу выбрать только видимые процессы с помощью одноименного метода. Но он не всегда срабатывает корректно и выдает даже приложения, которые сейчас пользователю невидимы. В этой ситуации нужно проверять значение метода foreground, которое будет true, если какое-либо Activity видно пользователю.
for (AndroidAppProcess pr : processes)
{
if (pr.getPackageName().equals(ps_name)&&(pr.foreground==true)) {
Log.e("ps", " " + pr.getPackageName() + " foreground " + pr.foreground);
return true;
}
...
Теперь есть возможность найти удобный момент для атаки — вызов этого метода покажет, работает ли сейчас пользователь в определенном приложении. Как только метод вернет true, можно запустить любое Activity, которое тут же будет показано пользователю. В этом и заключается суть атаки — продемонстрировать пользователю фишинговое окно под видом уведомления от доверенного приложения.
// Проверяем, открыт ли Google Market
if (isProccessForeground("com.android.vending")) {
Intent i = new Intent();
i.setClass(getApplicationContext(), FakeGUI.class);
startActivity(i);
}
В целом фишинговая атака уже построена. Для ее эксплуатации нужно настроить периодическое отслеживание приложения-жертвы, а также нарисовать GUI окна для ввода данных банковской карты.
Сервисы
Отслеживать состояние приложения несложно, нужно только с определенной периодичностью перезапускать метод isProccessForeground
— это можно реализовать в компоненте Activity или Service. Но долго держать запущенным один и тот же экземпляр Activity не получится, рано или поздно он будет выгружен системой. К тому же это слишком заметно для пользователя.
В Android, как и в «больших» операционных системах, есть сервисы — компоненты, позволяющие незримо для пользователя выполнять какую-то рутинную работу. Обычно это загрузка данных или получение обновлений, но для фишинга тоже пойдет.
Сервисы могут быть разными: так называемый foreground service будет работать в системе всегда и остановится только вместе с выключением телефона. Мы уже подробно разбирали работу сервисов раньше, поэтому сегодня буду краток. Foreground service наследуется от класса Service и должен обязательно иметь иконку, которая будет присутствовать в панели уведомлений устройства.
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Google Play")
.setContentText("Autorization requared");
Notification fullNotif = mBuilder.build();
Устанавливается такой сервис всего лишь одной командой, которая будет выполнена самим сервисом.
startForeground(ID, fullNotif);
Запускать модуль, опрашивающий утилиту toolbox, лучше всего в метод onStartCommand
.
public int onStartCommand(Intent intent, int flags, int startId) {
isProccessForeground("app.package.name")
}
GUI
Приложения для мобильных платформ должны выглядеть примерно одинаково — это требование корпораций, которые для этого придумали отдельные направления дизайна: скевоморфизм, flat design, material design и так далее. Такое, почти армейское, единообразие работает на руку мошенникам — поддельные приложения получаются быстрее и легче благодаря использованию одинаковых инструментов.
Android позволяет создать экземпляр Activity, который будет выглядеть как всплывающее меню. Воспользуемся тем, что такой внешний вид больше характерен не для вновь открытого приложения, а для обычного окна-уведомления.
Такой внешний вид задается стандартным стилем Theme.AppCompat.Light.Dialog.Alert, который можно модифицировать по своему желанию.
<style name="DialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<!-- Цвет кнопок -->
<item name="colorAccent">#FFC107</item>
<!-- Цвет заголовка и текста -->
<item name="android:textColorPrimary">#FFFFFF</item>
<!-- Цвет фона-->
<item name="android:background">#2E7D32</item>
...
</style>
Собственно, предела совершенству нет — популярные Android-приложения целиком следуют стилю material design, который был уже хорошо разобран в нашем журнале. Немного стараний, и даже опытный пользователь не сможет сообразить, что появившееся перед ним окно относится к совершенно другому приложению.
Противодействие
Вендоры мобильных устройств серьезно озабочены новыми проблемами с безопасностью — никому не хочется, чтобы у общества сложился стереотип «Android — опасное устройство». Поскольку мобильные антивирусы, по разным причинам, не могут обеспечить нужный уровень защиты, производители техники пошли по пути искусственных ограничений.
В ОС, установленных в аппаратах крупных игроков рынка, начали появляться дополнительные параметры безопасности. Так, Samsung и Xiaomi создали белые списки приложений — таким программам позволено использовать все инструменты стандартного API. Если же твоего приложения нет в этом списке, могут быть проблемы. В частности, эти ограничения касаются использования сервисов — у приложений, не входящих в белый список, сервисы будут работать, только пока живы Activity.
Конечно, такое неравноправие существенно понижает эффективность фишинга, осложняет деятельность криптолокеров и прочих вымогателей. Но эти неписаные правила игры серьезно бьют по новым разработчикам: как можно создать стабильное приложение, если часть API просто не работает? Жесткие ограничения никогда не были панацеей, рано или поздно пользователь нажмет кнопку «Разрешить всё».
Еще одна причина отсутствия крупных эпидемий мобильных ransomware — большое разнообразие версий Android, каждый вендор стремится переписать ОС, внедряя собственные «инновации». Все-таки создать вирус под Windows XP гораздо легче, чем для сотни устройств разных вендоров, у которых различаются даже версии ядра ОС.
Outro
Как ты видишь, создание фишингового приложения доступно даже очень среднему программисту. Принцип унификации, легкость API и стековое размещение Activity позволяют подделать, пожалуй, любое Android-приложение. Но мы верим, что полученная тобой информация будет использоваться только в благих целях — возможно, именно ты предложишь защиту, которая сделает атаки на Android невозможными. Удачи!