Отладка нативной библиотеки Android и iOS с помощью GDB

Отладка нативной библиотеки Android iOS GDB

Сегодня расскажу о том, как при пентесте приложений Android и iOS, получить конфиденциальную информацию из нативных библиотек. Речь пойдет о так называемой «отладке нативного кода Android или iOS».

Еще по теме: Как защитить нативную библиотеку

Способы отладки нативной библиотеки

Существует несколько способов извлечения данных из нативных библиотек, включая бесплатные и коммерческие отладчики:

  • GDB (GNU Debugger) — бесплатный отладчик, требующий настройки и компиляции для Android. Позволяет отлаживать нативный код в реальном времени, предоставляя глубокий анализ выполнения программы.
  • LLDB — встроенный отладчик в macOS, используемый для отладки iOS приложений. Предоставляет функциональность, схожую с GDB, и хорошо интегрируется с инструментами разработки Apple.
  • IDA Pro — коммерческий дизассемблер и отладчик, поддерживающий множество архитектур, включая ARM и x86. Обладает мощными возможностями анализа и отладки нативного кода, популярен среди исследователей безопасности.
  • JEB Decompiler — коммерческий декомпилятор и отладчик, поддерживающий отладку Android и iOS приложений. Предоставляет удобный интерфейс для анализа нативного кода и возможность декомпиляции в более читаемый вид.
  • Frida — инструмент динамического инструментирования, позволяющий внедрять JavaScript код в работающие процессы. Может использоваться для отладки и модификации нативного кода, обеспечивая гибкость в анализе приложений.
  • Android Studio + NDK —  официальная среда разработки для Android, поддерживающая отладку нативного кода с помощью LLDB. Интегрируется с Android NDK для работы с C/C++ кодом, предоставляя комплексное решение для разработчиков.
  • Xcode —  официальная среда разработки для iOS, включающая встроенные инструменты для отладки нативного кода. Поддерживает отладку Objective-C и Swift кода, обеспечивая полный набор инструментов для разработки iOS приложений.
  • Radare2 —  открытый фреймворк для реверс-инжиниринга, поддерживающий анализ и отладку нативных библиотек. Предоставляет CLI интерфейс для продвинутых пользователей, позволяя выполнять глубокий анализ бинарного кода.

В нашем случае, для получения данных во время выполнения приложения Android будет использован GDB.

Нативный код в создании приложений

Нативный код в Android-разработке часто пишется на C/C++ и компилируется в бинарные файлы (.so), которые затем используются в мобильных приложениях. Эти библиотеки могут храниться в папке libs в структуре проекта.

Разработчики используют нативные библиотеки для выполнения критически важных задач, таких как обработка криптографических операций, генерация одноразовых паролей (OTP), и обнаружение рута устройства. Основная причина использования нативного кода — это как оптимизация производительности, так и защита кода от реверс-инжиниринга, поскольку бинарные файлы труднее анализировать, чем Java-код.

Для взаимодействия Java-кода с нативными библиотеками используется Java Native Interface (JNI) — фреймворк, который позволяет вызывать нативные функции из Java и наоборот. Это обеспечивает возможность интеграции высокопроизводительных нативных функций с удобством Java-разработки.

Отладка нативной библиотеки Android с GDB

Теперь давайте перейдем к практике. Я буду использовать уязвимое приложение HPAndro и его активность backdoor7.

Шаг 1: Перекомпилируем приложение с отладочными разрешениями.

Шаг 2: Открываем приложение в JADX-GUI. Используем функцию поиска, чтобы найти код активности backdoor7. Обращаем внимание на использование метода system.loadlibrary("backdoor7") и вызов init().

Метод нативной библиотеки
Метод нативной библиотеки

Шаг 3: В коде находим метод «hello», который принимает пользовательский ввод, передает его в нативную функцию и получает булево значение. Если значение true, приложение показывает скрытый флаг.

Метод Hello
Метод Hello

Шаг 4: Открываем файл библиотеки в Ghidra, radare2, IDA Pro или JEB. Анализируем код: он загружает пользовательский ввод, генерирует 4-значное число с помощью методов strcat, ldr и т.д. В конце видим метод strcmp, который сравнивает ввод пользователя и сгенерированный код, после чего возвращает флаг true или false в Java-код.

Декомпилированный нативный код
Декомпилированный нативный код

Код, который загрузит инструмент, будет на языке ассемблера, а значения хранятся в регистрах или памяти. Значения в левой части — это значения регистров, из которых мы будем получать данные. Я открыл файл lib.so архитектуры x86_64 в IDA Pro. Чтобы увидеть реальный код на языке C/C++, вы можете использовать Ghidra или IDA Pro.

Теперь переходим к отладке с помощью GDB:

Шаг 1: Копируем файл gdbserver из папки Android NDK в /data/local/tmp на устройстве Android через команду adb push.

Путь к файлу
Путь к файлу

Шаг 2: Открываем активность backdoor7 в приложении, вводим любое значение и нажимаем Enter. Это загрузит нужную нам библиотеку.

Шаг 3: Выполняем следующие команды:

Поиск ID процесса
Поиск ID процесса

Запуск сервера GDB
Запуск сервера GDB
Тестовая страница
Тестовая страница

Шаг 4: После установки Cygwin и MSYS/mingw64 добавляем пути в системные переменные среды.

Шаг 5: Запускаем GDB командой:

Путь к каталогу данных
Путь к каталогу данных

Выполнение команды
Выполнение команды

Шаг 6: Подключаемся к устройству Android:

Подключение Android-устройства
Подключение Android-устройства

Проверяем загрузку необходимой библиотеки libbackdoor7 командой info sharedlibrary.

Шаг 7: Переходим в директорию lib приложения на компьютере и запускаем radare2 с соответствующей библиотекой.

Путь к папке библиотеки Android
Путь к папке библиотеки Android

Шаг 8: Анализируем библиотеку командами aa и afl в radare2, находим JNI-вызов.

Шаг 9: Копируем JNI-вызов и добавляем точку останова в GDB.

Приложение Radare2
Приложение Radare2
 Вызов JNI
Вызов JNI
Завершение вызова JNI
Завершение вызова JNI

Шаг 10: Если шаг 9 не сработал, используем альтернативный метод: копируем адрес JNI-вызова из radare2, загружаем символы в GDB, находим реальный адрес библиотеки и добавляем точку останова.

Шаг 11: Выполняем команду continue, вводим случайное значение в приложении и ждем остановки в GDB. Используем команду disassemble для просмотра нативного кода.

Ввод случайного значения
Ввод случайного значения
Точка останова
Точка останова

Шаг 12 В нативном коде находим значение в регистре r12. Также добавляем точку останова на метод сравнения ( test eax eax).

Декомпилированный нативный код Radare2
Декомпилированный нативный код Radare2

Шаг 13: Продолжаем выполнение, вводим случайное значение. Проверяем и удаляем лишние точки останова.

Добавление точки останова для регистров.
Добавление точки останова для регистров.
Адрес памяти регистра r12
Адрес памяти регистра r12

Шаг 14: Когда GDB остановится, выполняем info registers. Находим адрес регистра r12 и конвертируем его в строку:

Преобразование шестнадцатеричного кода в строку
Преобразование шестнадцатеричного кода в строку

Таким образом, мы получаем секретную строку из нативной библиотеки Android-приложения.

Отладка нативной библиотеки Android GDB

 

Флаг раскрыт
Флаг раскрыт

Этот метод позволяет извлекать важную информацию из нативного кода, что может быть полезно при взломе или анализе безопасности приложений.

ПОЛЕЗНЫЕ ССЫЛКИ:

QUASAR

Этичный хакер и компьютерный ниндзя. Новые статьи в нашей Телеге!

Добавить комментарий