Следующая новость
Предыдущая новость

Unicorn Engine. Анализируем нативные библиотеки в приложениях для Android

30.01.2019 15:52
Unicorn Engine. Анализируем нативные библиотеки в приложениях для Android

Содержание статьи

  • Тестовый стенд
  • Собираем информацию
  • Реверс APK
  • Подключение отладчика
  • Анализ функции
  • Unicorn 101
  • Получение дампов из библиотеки
  • Пишем свой эмулятор
  • Выводы

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

Для начала нужно разобраться, что собой представляет Unicorn Engine. Это эмулятор процессора, он поддерживает множество архитектур и сам является мультиплатформенным. У Unicorn Engine в принципе нет сложных подсистем. Ты сам занимаешься разметкой памяти и загрузкой данных, эмулятор не понимает команды из std, поэтому их необходимо реализовывать самостоятельно или вообще пропускать.

Существует множество решений, которые способны трассировать команды на хостовую систему, загружать исполняемые файлы в память и многое другое, так зачем тогда использовать Unicorn Engine?

При исследовании нативных библиотек часто не нужно эмулировать работу всего процесса. Нам достаточно смоделировать работу какой-то конкретной функции, не используя AVD или полноценные эмуляторы Android/iOS, чтобы получить результат отдельно от основного процесса или устройства.

INFO

Хороший пример можно найти в моей прошлой статье, где был описан метод MITM-атаки на приложение с использованием Xposed.

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

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

В этой статье мы исследуем упрощенный вариант подписи данных.

Unicorn Engine. Анализируем нативные библиотеки в приложениях для Android

INFO

Статья рассчитана на то, что ты знаешь, что такое регистры, как работает стек, и не теряешь сознание при виде ассемблерного кода.

Тестовый стенд

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

В нативном приложении реализован некий кастомный алгоритм подписи. Его сложно назвать криптостойким, но для демонстрации он идеален: не очень объемный, но не слишком простой, как обычный XOR. Все необходимые исходники ты можешь найти на моем GitHub.

Также нам понадобится Android Studio и Android SDK с NDK, установленный Unicorn Engine и устройство или эмулятор для запуска. В этой статье я буду использовать AVD x86.

На устройстве (эмуляторе) должен находиться gdbserver, который можно найти по такому адресу:

<android-sdk>/ndk-bundle/prebuilt/<device-system>/gdbserver 

Я обычно перемещаю его в /data/local/gdbserver на устройстве.

Собираем информацию

Начнем анализ с того, что загрузим наше приложение в Android Studio: File → Profile or Debug APK. Когда проект загрузится, нам нужно исправить Run/Debug Configurations: во вкладке Debugger переключить Debug type в Java. Если этого не сделать, то к приложению будет подключен отладчик из Android Studio и подключить свой мы уже не сможем.

Прежде чем начать, давай попробуем запустить приложение и ввести тестовые данные test/pass. Запишем полученную подпись, так как она нам еще пригодится.

77 21 4f 57 4c 64 00 2e 39 01 4c 4e 7e 00 2e 2f 01 48 4a 7e 00 7b 6c 51 5c 09 37 00 7c 62 50 4b 09 70

Unicorn Engine. Анализируем нативные библиотеки в приложениях для Android

INFO

Если приложение не имеет флага android:debuggable="true", то его нужно добавить, пересобрав приложение и отредактировав AndroidManifest с помощью apktool.

Реверс APK

Для начала найдем основной класс. Он находится в loony/com/nativeexample/MainActivity.

.field getSign:Landroid/widget/Button;
.field loginField:Landroid/widget/EditText;
.field passwordField:Landroid/widget/EditText;
.field sign:Landroid/widget/TextView;

Видим в начале объявление кнопки и двух полей для заполнения.

.line 28
const-string v0, «native-lib»
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

Ниже происходит загрузка библиотеки и объявлен нативный метод .method public native magic(Ljava/lang/String;)[I, который принимает строку, а на выходе возвращает массив чисел. В том же классе есть функция .method private getHexString(I)Ljava/lang/String;, которая принимает массив чисел и возвращает hex-строку.

Посмотрим, что происходит при создании класса, и перейдем в onCreate.

new-instance v1, Lloony/com/nativeexample/MainActivity$1;
invoke-direct {v1, p0}, Lloony/com/nativeexample/MainActivity$1;->(Lloony/com/nativeexample/MainActivity;)V
invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

Создается новый обработчик нажатий, в него передается экземпляр loony/com/nativeexample/MainActivity$1, перейдем туда. Нас интересуют функции, которые отвечают за действия, в нашем случае это только onClick.

В коде видно, что создается org/json/JSONObject;, считываются данные из loginField,passwordField и помещаются в JSONObject с ключами login и password соответственно.

Продолжение доступно только подписчикам

Материалы из последних выпусков можно покупать отдельно только через два месяца после публикации. Чтобы продолжить чтение, необходимо купить подписку.

Подпишись на «Хакер» по выгодной цене!

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

1 год

4990 р.

Экономия 1400 рублей!

1 месяц

720 р.

25-30 статей в месяц

Уже подписан?

Источник

Последние новости