Категория > Новости > Препарируем Viber. Мини-гид по анализу приложений для Android - «Новости»

Препарируем Viber. Мини-гид по анализу приложений для Android - «Новости»


19-05-2023, 18:19. Автор: Stephen
лю­бого пуб­лично­го awesome list, поэто­му я не буду заос­трять вни­мание на их наз­вании, если того не тре­бует кон­текст.

Це­левой APK был получен с од­ного из mirror-сай­тов. К выбору источни­ка APK сто­ит отно­сить­ся серь­езно, пос­коль­ку неред­ко сайт может хра­нить:


  • уже уста­рев­шие вер­сии;
  • толь­ко вер­сии для ненуж­ных плат­форм и архи­тек­тур;
  • мо­дифи­циро­ван­ные при­ложе­ния (воз­можно, с содер­жани­ем мал­вари).

На дан­ном эта­пе име­ет смысл про­вес­ти реког­носци­ров­ку цели: изу­чить CVE, а затем про­вес­ти binary diffing ана­лиз 1-day-уяз­вимос­тей.


Читайте также - Вы можете купить 256MB кэш-память для HP SmartArray P410 за наличный или безналичный расчет просто оформив заказ, комплектующие для сервера по доступным ценам.

Разделяемые библиотеки


Пос­ле рас­паков­ки APK в дирек­тории lib мож­но обна­ружить фай­лы биб­лиотек: они не запако­ваны, не зашиф­рованы, не обфусци­рова­ны, не нак­рыты про­тек­тором, что облегча­ет нашу задачу в нес­коль­ко раз. В защиту Viber могу ска­зать, что обыч­но мес­сен­дже­ры не пыта­ются при­менять пас­сивные меры защиты от ана­лиза биб­лиотек, у WhatsApp лишь исполь­зует­ся кас­томный упа­ков­щик, но и то — не ради защиты. Для ана­лиза я выб­рал вер­сии биб­лиотек для архи­тек­туры x86_64 по сле­дующим при­чинам:



  • боль­шее количес­тво инс­тру­мен­тов для этой архи­тек­туры;
  • луч­ше деком­пиляция (это, конеч­но, спор­но, так как мно­гое зависит от выбора инс­тру­мен­та);
  • воз­можность эму­ляции на более высоких ско­рос­тях (моя хост‑машина име­ет архи­тек­туру x86_64);
  • воз­можность час­тично­го ана­лиза на хост‑машине в обход эму­лято­ра;
  • на дан­ном эта­пе нет задачи писать кон­крет­ный экс­пло­ит для пок­рытия боль­шего чис­ла целей, соот­ветс­твен­но, ARM-архи­тек­туры мож­но отбро­сить, если это пот­ребу­ется.

По­нача­лу для повер­хностно­го ана­лиза исполь­зовались такие инс­тру­мен­ты, как 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.solibcrashlytics-handler.solibcrashlytics-trampoline.solibcrashlytics.so — Firebase Crashlytics.


  • libreactnativeblob.solibreactnativejni.solibglog_init.solibjscexecutor.solibjsijniprofiler.solibjsinspector.so — React Native.


  • libfb.solibfbjni.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.solibhermes.so — Hermes JS Engine.


  • libicuBinder.so — ICU extension for SQLite.


  • libimage_processing_util_jni.so — androidx.camera.core.


  • libimagepipeline.solibnative-filters.solibnative-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.solibtensorflowlite_jni.so — TensorFlow.


  • libyoga.so — Yoga.


  • libCrossUnblocker.solibFlatBuffersParser.soliblinkparser.solibnativehttp.solibsvg.solibViberRTC.solibvideoconvert.solibVoipEngineNative.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.


 

libFlatBuffersParser.so


При более деталь­ном ана­лизе выяс­няет­ся, что это open source биб­лиоте­ка FlatBuffers. Оставля­ем ее ана­лиз на потом.


 

libsvg.so


Поль­зуем­ся ути­литой 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++.


Ре­зуль­тат вос­ста­нов­ления RTTI-информа­ции — клас­сы C++ и их методы

На пер­вый взгляд, здесь исполь­зует­ся собс­твен­ная SVG-биб­лиоте­ка, что хорошо. В ходе даль­нейше­го ана­лиза Java-кода (ана­лиз дерева вызовов) выяс­няет­ся, что фун­кции биб­лиоте­ки задей­ство­ваны в основном для заг­рузки ассе­тов при­ложе­ния (дирек­тория ./assets/svg в APK-фай­ле), а это нам не под­ходит. Одна­ко же цепоч­ка вызовов натив­ной фун­кции nativeParseFd → parseFile исполь­зует­ся для пар­синга сти­керов. А вот это уже инте­рес­но! Но я решил оста­вить эту фун­кцию на потом, пос­коль­ку моя инту­иция под­ска­зала: бес­смыс­ленно писать пар­сер SVG с нуля. Соот­ветс­твен­но, исполь­зует­ся что‑то из open source.


Граф вызова фун­кций SVG native в Understand 

libnativehttp.so


В ходе ана­лиза воз­ника­ет воп­рос, с какой целью соз­давалась эта биб­лиоте­ка, ведь кажет­ся, что ее воз­можнос­ти не очень широки: обер­тки над фун­кци­ями обра­бот­ки сетевых дан­ных. Обра­бот­чики при воз­никно­вении событий вызыва­ют все тот же Java-код, а не что‑то натив­ное. Может быть, здесь ког­да‑то были какие‑то фун­кци­ональ­ные воз­можнос­ти, ну или пред­полага­лись? Подоб­ное я уже видел в мес­сен­дже­ре Telegram: legacy-кода хоть отбавляй, от такого боль­шого attack surface понача­лу чешут­ся руки, но пос­ле ана­лиза все вста­ет на свои мес­та. Поэто­му, ува­жаемый читатель, при­нимай во вни­мание, что иног­да могут встре­чать­ся не толь­ко dead code, но и dead libraries, на ана­лиз которых мож­но впус­тую пот­ратить кучу цен­ного вре­мени.



Перейти обратно к новости