Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Целевой APK был получен с одного из mirror-сайтов. К выбору источника APK стоит относиться серьезно, поскольку нередко сайт может хранить:
На данном этапе имеет смысл провести рекогносцировку цели: изучить CVE, а затем провести binary diffing анализ 1-day-уязвимостей.
После распаковки APK в директории lib
можно обнаружить файлы библиотек: они не запакованы, не зашифрованы, не обфусцированы, не накрыты протектором, что облегчает нашу задачу в несколько раз. В защиту Viber могу сказать, что обычно мессенджеры не пытаются применять пассивные меры защиты от анализа библиотек, у WhatsApp лишь используется кастомный упаковщик, но и то — не ради защиты. Для анализа я выбрал версии библиотек для архитектуры x86_64 по следующим причинам:
Поначалу для поверхностного анализа использовались такие инструменты, как IDA Pro, Binary Ninja и rizin (Ghidra не взял, потому что задачу следовало решить быстро): загружаешь библиотеку, смотришь экспортированные символы, находишь строки, немного читаешь код. Но затем я перешел к oneline-команде — по сути, большего мне и не требовалось: readelf -W --demangle --symbols $(LIBRARY_SO) | tail -n +4 | sort -k 7 | less
.
После идентификации JNI-функций из библиотек прохожусь rg
/grep
по smali-коду и нахожу файлы, где содержится объявление native-функций:
$ readelf -W --demangle --symbols libnativehttp.so | tail -n +4 | sort -k 7 | rg "FUNC.Java_." | less
33: 0000000000001bb5
55 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_HttpEngine_nativeCreateHttp
34: 0000000000001bec
15 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_HttpEngine_nativeDelete
38: 0000000000001bfb
622 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_HttpEngine_nativeTest
44: 00000000000018c3
109 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_NativeDownloader_nativeOnConnected
39: 00000000000015e8
366 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_NativeDownloader_nativeOnData
35: 0000000000001b0c
40 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_NativeDownloader_nativeOnDisconnected
40: 0000000000001930
476 FUNC
GLOBAL DEFAULT
13 Java_com_viber_libnativehttp_NativeDownloader_nativeOnHead
$ rg "native.*nativeCreateHttp"
app/src/main/java/com/viber/libnativehttp/HttpEngine.java
9:
public static native long nativeCreateHttp();
Дальне нужен поверхностный анализ, чтобы выявить, во‑первых, библиотеку‑цель, во‑вторых, компоненты open source, исследование которых предстоит сделать позднее. Анализировать можно с помощью того же readelf или в Rizin либо Binary Ninja: гуглим имя экспортированного символа и проводим поверхностный реверс‑инжиниринг, чтобы воссоздать общую картину функций библиотеки.
Ниже представлен список разделяемых библиотек с кратким описанием функций или ссылкой на проект с открытыми исходниками.
libc++_shared.so
— C++ standard library.libcrashlytics-common.so
, libcrashlytics-handler.so
, libcrashlytics-trampoline.so
, libcrashlytics.so
— Firebase Crashlytics.libreactnativeblob.so
, libreactnativejni.so
, libglog_init.so
, libjscexecutor.so
, libjsijniprofiler.so
, libjsinspector.so
— React Native.libfb.so
, libfbjni.so
— fbjni.libfolly_futures.so
— Folly: Facebook Open-source Library.libfolly_json.so
— Folly: Facebook Open-source Library, double-conversion.libglog.so
— Google Logging Library.libhermes-executor-release.so
, libhermes.so
— Hermes JS Engine.libicuBinder.so
— ICU extension for SQLite.libimage_processing_util_jni.so
— androidx.camera.core.libimagepipeline.so
, libnative-filters.so
, libnative-imagetranscoder.so
— Fresco.libgifimage.so
— The GIFLIB project, Fresco.libjingle_peerconnection_so.so
— старый компонент (libjingle
) из WebRTC.libmux.so
— FFmpeg из состава fftools
.libpl_droidsonroids_gif.so
— android-gif-drawable.librenderscript-toolkit.so
— RenderScript.libsigner.so
— Adjust SDK for Android.libspeexjni.so
— Speex.libsqliteX.so
— SQLite for Android.libtensorflowlite_gpu_jni.so
, libtensorflowlite_jni.so
— TensorFlow.libyoga.so
— Yoga.libCrossUnblocker.so
, libFlatBuffersParser.so
, liblinkparser.so
, libnativehttp.so
, libsvg.so
, libViberRTC.so
, libvideoconvert.so
, libVoipEngineNative.so
— самописные библиотеки c использованием open source кода.В итоге у нас появляется список интересных библиотек. Составлялся он исходя всего из одного условия: как можно больше самописного кода, меньше компонентов open source. Вот этот список:
libCrossUnblocker.so
;libFlatBuffersParser.so
;liblinkparser.so
;libnativehttp.so
;libsvg.so
;libViberRTC.so
;libvideoconvert.so
;libVoipEngineNative.so
.Прежде чем анализировать какую‑либо функцию, сначала нужно выяснить, может ли атакующий до нее добраться. Для этого отсортируем по приоритету все библиотеки и функции, а затем проверим, откуда вызываются последние. Для анализа Java-кода я буду использовать связку jadx (декомпиляция) + Android Studio (рефакторинг) + Understand (анализ графов связей переменных, функций и данных).
Дополнительно проверим в каждой библиотеке наличие JNI-функций. Может быть, есть те, что используются с помощью RegisterNatives
.
При более детальном анализе выясняется, что это open source библиотека FlatBuffers. Оставляем ее анализ на потом.
Пользуемся утилитой strings и Ghidra, чтобы получить строки из бинарного файла. По ним мы понимаем, что код написан на C++:
[...]
_ZTVN10__cxxabiv121__vmi_class_type_infoE
_ZNSt6__ndk119__shared_weak_countD2Ev
_ZTINSt6__ndk119__shared_weak_countE
__android_log_print
_ZNKSt6__ndk16locale9has_facetERNS0_2idE
_ZNKSt6__ndk16locale9use_facetERNS0_2idE
[...]
Проверим еще и наличие RTTI-информации — в нашем случае удача благоволит нам, таковая имеется. С помощью плагина для Ghidra Ghidra C++ Class and Run Time Type Information Analyzer восстановим структуру классов кода C++.
На первый взгляд, здесь используется собственная SVG-библиотека, что хорошо. В ходе дальнейшего анализа Java-кода (анализ дерева вызовов) выясняется, что функции библиотеки задействованы в основном для загрузки ассетов приложения (директория ./
в APK-файле), а это нам не подходит. Однако же цепочка вызовов нативной функции nativeParseFd
→ parseFile
используется для парсинга стикеров. А вот это уже интересно! Но я решил оставить эту функцию на потом, поскольку моя интуиция подсказала: бессмысленно писать парсер SVG с нуля. Соответственно, используется что‑то из open source.
В ходе анализа возникает вопрос, с какой целью создавалась эта библиотека, ведь кажется, что ее возможности не очень широки: обертки над функциями обработки сетевых данных. Обработчики при возникновении событий вызывают все тот же Java-код, а не что‑то нативное. Может быть, здесь когда‑то были какие‑то функциональные возможности, ну или предполагались? Подобное я уже видел в мессенджере Telegram: legacy-кода хоть отбавляй, от такого большого attack surface поначалу чешутся руки, но после анализа все встает на свои места. Поэтому, уважаемый читатель, принимай во внимание, что иногда могут встречаться не только dead code, но и dead libraries, на анализ которых можно впустую потратить кучу ценного времени.
|
|