На проверке Динамический анализ Android-приложений: перехват трафика, Frida-инструментация и обход SSL Pinning

Пентестер в худи за тёмным рабочим столом с двумя мониторами: Burp Suite с перехваченными запросами и терминал с зелёным текстом. Рядом светится экран Android-эмулятора.


На аудите финтех-приложения под Android 14 стандартная связка «Burp-сертификат в системное хранилище + Wi-Fi прокси» не показала ни одного запроса за полчаса. Приложение использовало OkHttp с кастомным CertificatePinner, нативную проверку через BoringSSL и root detection на базе SafetyNet. Три уровня защиты, три разных подхода к обходу - и ни один универсальный скрипт с Frida Codeshare не сработал из коробки. Я перепробовал четыре «готовых решения», прежде чем сел писать хуки руками. Динамический анализ Android-приложений на реальных проектах начинается не с запуска готового скрипта, а с методичной работы по каждому слою защиты.

Требования к окружению для мобильного пентеста Android

[Применимо: авторизованный аудит мобильных приложений, grey/white box] Подробнее - в нашем статье о пентесте мобильных приложений.

Прежде чем лезть в Frida-инструментацию или перехват трафика - среда должна быть настроена. Без этого дальше двигаться нет смысла.

Железо и ОС хоста: Linux, macOS или Windows с Python 3.8+ и adb из Android Platform Tools. RAM: минимум 8 ГБ при работе с эмулятором, рекомендуется 16 ГБ. Для нативного анализа .so-библиотек потребуется Ghidra или IDA - тут уже десктоп с 16+ ГБ.

Устройство: рутованный Android (Pixel 4a/5a - стабильный выбор, проблем с ними меньше всего) или эмулятор Android Studio с образом без Google Play (чтобы работал adb root). На устройстве - Magisk ≥ 25.0 для управления root и модулями.

Софт на хосте: pip install frida-tools frida - клиентская часть Frida. Версия обязана совпадать с frida-server на устройстве по мажору и минору, иначе получите ошибку при подключении (и будете полчаса гадать, что не так). Burp Suite (Community достаточно для базового анализа) или mitmproxy - для просмотра перехваченного трафика. jadx - для параллельного статического анализа: нужно заранее понять, какой HTTP-клиент использует приложение и как реализован пиннинг.

Софт на устройстве: frida-server подходящей архитектуры. Определить архитектуру - adb shell getprop ro.product.cpu.abi (arm64 для большинства современных устройств). Бинарь скачивается с GitHub releases Frida, распаковывается, пушится: adb push frida-server /data/local/tmp/, затем chmod 755 и запуск через adb shell su -c "/data/local/tmp/frida-server &". Проверка связи - frida-ps -U на хосте должна вернуть список процессов устройства. Если вернула - можно работать.

Перехват HTTPS-трафика мобильных приложений: CA-сертификат по версиям Android​

Перехват трафика Android-приложения начинается с того, чтобы устройство доверяло сертификату вашего прокси. По классификации MITRE ATT&CK это техника Install Root Certificate (T1553.004, Defense Evasion) - установка корневого сертификата для перехвата зашифрованного канала. Сам перехват - Network Sniffing (T1040, Credential Access). Процедура установки критически зависит от версии Android, и тут начинается веселье.

Android 11 и ниже​

Работает если: устройство рутовано, системный раздел монтируется на запись (mount -o rw,remount /system).
Не работает если: Android 12+ с read-only системным разделом или устройство с Verified Boot без разблокированного загрузчика.

На Android 11 системный раздел перемонтируется в runtime. Экспортируете сертификат Burp в DER, конвертируете в PEM через openssl x509 -inform DER -in burp.der -out burp.pem, переименовываете файл по хешу субъекта (команда openssl x509 -inform PEM -subject_hash_old -in burp.pem | head -1 даёт значение, добавляете .0), копируете в /system/etc/security/cacerts/. После перезагрузки сертификат появляется в системном хранилище - приложения, доверяющие системным CA, принимают его. Просто и прямолинейно.

Android 13 и выше​

Работает если: установлен Magisk с модулем Always Trust User Certificates (от Jerome Beckers) или аналогом.
Не работает если: устройство без root или приложение использует Network Security Config с жёстко заданными trust anchors, игнорируя системное хранилище.

Начиная с Android 13, Google перевёл системный раздел на read-only на уровне ядра - перемонтировать в runtime невозможно. Решение - Magisk-модуль, который при загрузке копирует пользовательские сертификаты в системное хранилище. Устанавливаете сертификат Burp как пользовательский через настройки безопасности, модуль делает его системным. На Android 14+ процедура усложняется - по данным исследования Tim Perry (HTTP Toolkit), требуется модифицированный подход через init-скрипты Magisk.

После установки CA проверьте, появился ли трафик в прокси. Если да - пиннинга нет, переходите к анализу бизнес-логики. Если нет - впереди обход SSL Pinning.

Frida-инструментация Android: от установки до первого хука​

Frida - фреймворк динамической инструментации, который внедряет JavaScript-код в работающий процесс. В терминах MITRE ATT&CK это сочетание Process Injection (T1055, Defense Evasion) и Hooking (T1179, Credential Access) - мы внедряемся в адресное пространство приложения и перехватываем вызовы функций в runtime.

Два режима работы:

frida-server на рутованном устройстве - слушает на порту 27042, принимает команды от хоста. Штатный режим для лабораторного пентеста.

frida-gadget - shared library, встраиваемая в APK через repacking. Используется когда root недоступен (корпоративное устройство клиента). Objection автоматизирует процесс: objection patchapk -s target.apk вставляет gadget и перепаковывает APK.

Работает если: frida-server запущен с root, версия клиента и сервера совпадают, SELinux не блокирует выполнение.
Не работает если: приложение детектирует Frida - проверяет /proc на наличие frida-server, сканирует порт 27042, ищет характерные строки в памяти процесса. По данным исследования Approov (Frida Detection & Prevention), защитные SDK обнаруживают Frida через проверку загруженных библиотек и Debugger Evasion (T1622). На практике банковские приложения детектят Frida в 7 из 10 случаев - приходится выкручиваться.

Базовая проверка: frida-ps -Ua покажет список установленных приложений с идентификаторами пакетов. Подключение к целевому приложению - frida -U -f com.target.app --no-pause -l script.js. Флаг -f запускает приложение заново (spawn mode), --no-pause возобновляет выполнение немедленно. Spawn mode критичен: если приложение выполняет root detection или integrity check при старте, этот режим позволяет перехватить проверки до срабатывания.

Обход SSL Pinning Android: техники по типам реализации​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

есть несколько перегрузок (overload). В OkHttp 4.x сигнатура может отличаться от 3.x. Если скрипт падает с ошибкой overload not found - откройте приложение в jadx, найдите класс okhttp3.CertificatePinner и посмотрите, какие варианты check() там реально присутствуют. По данным NetSPI, расхождение перегрузок - самая частая причина отказа «универсального» скрипта на конкретном APK. Я с этим сталкивался раза три за последний год - каждый раз приходилось лезть в jadx и сверять сигнатуры.

Для TrustKit от DataTheorem подход аналогичен: хукается метод verify класса com.datatheorem.android.trustkit.pinning.OkHostnameVerifier с возвратом true. Если библиотека незнакомая - frida-trace -U -f com.target.app -j '[I]![/I]certificate*' для трассировки всех методов, связанных с сертификатами. Вывод покажет, какой именно класс и метод отвечает за проверку.

Скрипт frida-multiple-unpinning от Maurizio Siddu (доступен через Frida Codeshare) закрывает сразу несколько реализаций: Java TrustManager, OkHttp, Retrofit, Appcelerator и частично Flutter. Хорошая отправная точка, но на приложениях с кастомной логикой часто даёт промах - относитесь к нему как к первой попытке, а не как к решению.

Когда универсальные скрипты не работают: динамический анализ APK с нативным пиннингом​

Отдельная категория - приложения, где certificate pinning реализован не в Java-слое, а в нативном коде. Тут начинается настоящая работа.

Flutter-приложения используют dart:io HttpClient, который работает через нативный стек BoringSSL и не подчиняется ни системному прокси, ни Java TrustManager. Даже при обходе всех Java-хуков трафик Flutter-модуля просто не пойдёт через Burp - он его в упор не видит. По данным исследования Just Mobile Security, для Flutter эффективен инструмент frida4burp - набор Frida-скриптов, который перенаправляет сокеты напрямую в Burp через runtime socket redirection, минуя системные настройки прокси. Принципиально другой подход: вместо обхода пиннинга перенаправляются сетевые вызовы на уровне сокетов.

Приложения с C/C++ сетевым слоем - банковские приложения иногда выносят критичную логику (авторизация, подпись транзакций) в нативные библиотеки (.so), где SSL реализован напрямую через BoringSSL или OpenSSL. Тут потребуется Interceptor.attach() вместо Java.perform() - работа с адресами функций в .so. Адреса вытаскиваются через Module.findExportByName() или анализом в Ghidra. Целевые функции - SSL_CTX_set_custom_verify или ssl_verify_peer_cert. Универсального скрипта нет - каждый случай требует ручного реверс-инжиниринга Android-приложения. Один .so может занять полдня в Ghidra, прежде чем найдёшь нужную функцию.

Типичные ошибки при перехвате трафика Android​

Версия frida-tools не совпадает с frida-server. Ошибки Failed to enumerate processes или unable to communicate with remote frida-server - первое, что проверяется. frida --version и frida-server --version должны показывать одинаковый мажор и минор. Банально, но на это тратится больше всего нервов.

Приложение падает при запуске с Frida. Часто это root detection или anti-tampering. Решения: (1) Magisk в режиме Zygisk DenyList для скрытия root от конкретного пакета, (2) Frida-скрипт обхода root detection - хук java.io.File.exists для путей /su, /data/local/tmp/frida-server, (3) Frida Gadget вместо frida-server - менее детектируем. На одном проекте пришлось комбинировать все три подхода, прежде чем приложение перестало падать.

Часть запросов не видна в прокси. Возможные причины: приложение использует certificate transparency для отдельных эндпоинтов, WebSocket-трафик не перехватывается Burp (используйте OWASP ZAP с breakpoints для WebSocket - как описывают специалисты Digital Security, это единственный удобный способ точечно перехватывать конкретные WebSocket-сообщения), или часть логики работает через gRPC/Protobuf, и Burp показывает бинарные данные без расшифровки.

Прокси настроен, приложение показывает «нет сети». Проверьте: не поднимает ли приложение локальный VPN-сервис для DNS-фильтрации, и принимает ли Burp-listener соединения на всех интерфейсах (0.0.0.0:8080), а не только на 127.0.0.1.

Метод обхода SSL PinningРаботаетНе работаетИнструмент
CA в системное хранилищеAndroid до 11, приложение без пиннингаAndroid 13+, любой вид пиннингаMagisk модуль
TrustManager hookJava-слой пиннинга, SSLContext.initНативный пиннинг (BoringSSL)Frida + JS
OkHttp CertificatePinner hookOkHttp 3.x/4.xКастомный HTTP-клиент, OkHttp 2.xFrida + JS
Socket redirectionFlutter, нативный HTTP-стекIntegrity checks на уровне TLSfrida4burp
Патч smali-кодаСтатическая проверка в JavaPlay Integrity, runtime integrity checksapktool + jadx

Большинство аудитов мобильных приложений требуют комбинации нескольких методов. Чистый TrustManager-хук покрывает около 40% случаев, OkHttp добавляет ещё 30%, а оставшиеся 30% - кастомные реализации, нативный код и Flutter, где нужен ручной анализ Android-приложения.

Мобильный пентест за последние три года сильно поляризовался. С одной стороны, инструменты доступнее: Frida Codeshare, Objection, frida-multiple-unpinning - запустил и поехал. С другой - разработчики научились защищаться: multi-layer pinning, nonce-based certificate rotation, runtime integrity checks с серверной валидацией. Универсальный скрипт обхода SSL Pinning, который работал в 2020 году на подавляющем большинстве приложений, сейчас закрывает хорошо если половину. Остальное - ручная работа: jadx, анализ smali, поиск конкретного метода проверки, написание точечного хука.

И вот что меня раздражает: большинство отчётов по мобильному пентесту, которые я видел за последний год, заканчиваются формулировкой «SSL Pinning обнаружен, обход не удался». Пентестер попробовал три универсальных скрипта, ни один не сработал, и на этом анализ трафика прекратился. Реальные уязвимости - IDOR, broken auth, утечки токенов в ответах API - остались невидимыми за непройденным пиннингом. Умение написать целевой Frida-хук под конкретную реализацию - это не «продвинутый навык для энтузиастов», это базовое требование к тому, кто берётся за анализ Android-приложений. Без этого половина поверхности атаки остаётся непроверенной, а отчёт превращается в формальность.

Попробуйте взять любое приложение из своего телефона, открыть его в jadx и найти, как реализован пиннинг. Написать хук - дело получаса. Не написать - потерять половину аудита.
 
Последнее редактирование:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab