Привет! Я думаю, что наберется немало людей, перед которыми стоят интересные задачи по работе с приложениями. Например - анализ трафика для, разумеется, тестирования этих самых приложений! Вам выпало нелегкое бремя - необходимо отдебажить продовую сборку чего-либо и вы начинаете свои поиски решений проблем. А проблем у вас на этом пути будет много. О том, как их можно решить я и пишу.
Классический путь начинается с установки какого-нибудь Charles, настройки в нем proxy-сервера и попытки слушать трафик, однако мы быстро натыкаемся на проблему - все адекватные современные приложения используют HTTPS, а поэтому - на ваше устройство придется установить сертификат, который и позволит слушать трафик. Тут то и начинается самое интересное...
Давайте создадим чек-лист, на который будем ориентироваться в процессе:
⚑ Предварительные подготовления, позволяющие начать установку эмулятора
⚑ Вы находитесь здесь
⚐ Установка эмулятора
⚐ Установка сертификата для MITM
⚐ Проверка работоспособности прослушки трафика
⚐ Разочарование
⚐ Получение root-доступа
⚐ Перенос сертификата в системное хранилище
⚐ Разочарование(?)
⚐ SSL Unpinning
⚐ Profit!!!
Установка Android Emulator
Я не буду описывать всю процедуру установки, надеюсь, вы сможете сделать все подготовительные действия, чтобы оказаться в ситуации, когда вам осталось лишь выбрать определенный тип OS в эмуляторе, а все предыдущие шаги уже выполнены.
Итак:
1. Выбираем любой подходящий вариант, с важной оговоркой - это должна быть сборка без Google Play, но с Google Play Services (далее будет видно). Соответственно - выбираем устройство без треугольника
2. Выбираем любой интересующий образ в котором есть Google Play APIs
3. Устанавливаем параметр Cold Boot
Готово!
⚑ Установка эмулятора
Установка сертификата для proxy-sniffer
Для прослушки трафика я буду пользоваться Fiddler Everywhere. И покажу порядок настройки данной софтины, согласно которому мы закроем еще один пункт нашей дорожной карты.
Тут я сделаю небольшое лирическое отступление - данная программа платная, да и еще по подписке, и стоить будет, в лучшем случае - 10$ в месяц. Но, у вас будет триал в 30 дней, после которого нужно больше золота, поэтому можно использовать любой другой инструмент. Сам я пытался заюзать Postman - в нем тоже есть proxy-tooling, однако, корневые сертификаты, которые генерирует Postman, не пригодны для установки в Android 10 / 11. Однако, служба поддержки уже бдит, и, надеюсь, за отведенные 30 дней триала все заработает как надо (в Postman) и вы сможете пользоваться наиболее удобным (с моей точки зрения) инструментом для решения данной задачи. Когда это случится - я дополню данную статью. А теперь возвращаемся к процессу установки сертификата на устройство (эмулятор).
Нам необходимо раскрыть пункт Advanced Settings в настройках Fiddler, и экспортировать корневой сертификат. В данный момент я пользователь Windows и на данной ОС он окажется на рабочем столе, подсказка об этом показывается по наведению на значок вопроса.
После экспорта сертификата, плавным движением кистей рук, переносим его на запущенный эмулятор - файл окажется в папке .../Downloads
. После чего можно сразу идти в настройки и устанавливать наш серт:
Отлично! Можем поставить галочку у еще одного пункта:
⚑ Установка сертификата для MITM
Проверяем, все ли ок
Самое время проверить, принесли ли наши усилия хоть какие-то полезные плоды. Подопытным кроликом сегодняшнего эксперимента будет приложение Reddit и первое, что мы увидим, если попытаемся загрузить посты:
Пустота.
А также бесконечное количество попыток SSL-handshake в Fiddler. Кажется, пора поставить прочерк сразу напротив двух пунктов нашей дорожной карты:
⚑ Проверка работоспособности прослушки трафика
⚑ Разочарование
-
Я есть root
Мне кажется, что наступил момент рассказать, для чего нам вообще рут? Все дело в том пресловутом изменении Android 7, после которого пользовательские сертификаты перестали быть доверенными. Посему - нам необходимо сделать что-то с нашим установленным сертификатом, чтобы мы смогли использовать его для изучения трафика нашего
рабочегоприложения. И сделать это можно, только если ваш девайс рутован. Тут же заключается и причина использования эмулятора, да и связанные с этим особенности: без эмулятора вам придется иметь постоянно рутованное устройство, если это отдельный выделенный смартфон - то проблем с этим особенно и нет (ну, кроме зарядки, постепенного устаревания и ограничений конкретной модели), однако, если у вас свой личный аппарат - то минусы от root могут быть существенными - не работающая система безопасности, сломанный Google Pay или отвалившиеся камеры... Ну и помимо всего прочего - эмулятор позволяет легко изменить версию Android (правда, придется повторить все действия, перечисленные тут, но у вас уже будет эта статья, а я вот это все пишу её не имея).А теперь приступим. Благодаря прекраснейшему проекту весь процесс сводится к запуску всего лишь одного скрипта, с небольшими подготовительными работами. Также, обращайте внимание на то, что выводится в консоль и если вы пользуетесь Windows - то запускайте не
.sh
, а.bat
. Возможно, WSL будет тут как раз кстати, но моя система, скажем так, с некоторыми особенностями, которые WSL использовать не позволяют (если вы знаете, как завести на Ryzen 5000-серии и WSL и Android Emulator - то прошу написать об этом комментарий).А вот и сами работы:
./rootAVD.sh ~/Library/Android/sdk/system-images/android-30/google_apis/x86_64/ramdisk.img
Плюс, нужно перезагрузить эмулятор. Ну и, у пользователей Windows путь до образа будет примерно таким:
C:\Users\Me\AppData\Local\Android\Sdk\system-images\android-30\google_apis\x86_64\ramdisk.img
На выходе мы получаем рут, который сохраняется при перезагрузке эмулятора, но wipe делать не стоит.
Ставим галку:
⚑ Получение root-доступа
Делаем сертификат доверенным
Для этого нам понадобится перенести его в хранилище доверенных сертификатов. Тут рут нам и нужен (не только тут, но это позже).
Для этого мы запускаем цепочку следующих команд:
adb shell su mkdir -m 700 /data/certs cp /system/etc/security/cacerts/* /data/certs/ mount -t tmpfs tmpfs /system/etc/security/cacerts cp /data/misc/user/0/cacerts-added/* /system/etc/security/cacerts/ mv /data/certs/* /system/etc/security/cacerts/ chown root:root /system/etc/security/cacerts/* chmod 644 /system/etc/security/cacerts/* chcon u:object_r:system_file:s0 /system/etc/security/cacerts/*
После чего наблюдаем следующую картинку в системных сертификатах:
Наш сертификат стал системным, поэтому закроем еще один пункт:
⚑ Перенос сертификата в системное хранилище
И давайте сразу проверим наше приложение:
Отлично! Теперь мы можем слушать HTTPS-трафик любых (ли?) приложений с эмулятора. Давайте, чтобы закрепить результат, попробуем еще одно приложение - Avito (как говорили Ник и Майк - это крепкий орешек).
Кажется, тут что-то пошло не так. Впрочем вы и так все знаете, так как видели гигантский спойлер в самом начале, поэтому ставим еще одну галку:
⚑ Разочарование!
SSL-Unpinning
На данную тему есть множество решений, но, как правило, все они крутятся вокруг одной идеи - пересборки приложения, которое вы хотите изучить. Данный подход весьма громоздкий, сложный и может сподвигнуть к прокрастинации, поэтому нужно что-то такое, что позволит сделать все намного проще и универсальнее. И рецепт этого чего-то прямо тут, бесплатно и без СМС:
Благодаря наличию root установим Xposed
Благодаря Xposed установим модуль для отвязки SSL-привязки
Profit!!! (два пункта тут смотрелись бы уныло)
А теперь давайте по порядку.
Установка Xposed
С учетом нашего изначального плана слушать всё и вся на эмуляторе на этом шаге появляются некоторые сложности - нужно подобрать удачную комбинацию программных решений, которые будут работать и на эмуляторе. Благодаря этой статье вам совершенно точно не придется тратить несколько часов на поиски этих решений и будет достаточно следовать простой инструкции:
Скачиваем последнюю версию Magisk-модуля с интересным названием Riru и устанавливаем его посредством Magisk
Закрываем эмулятор, а затем снова запускаем (данный шаг эмулирует перезагрузку, которая у меня, по каким-то причинам, не работает, если работает у вас - может быть достаточно и её)
Находим в репозитории Magisk модуль с названием
Riru - LSPosed
и устанавливаем егоСнова ребутим эмулятор
Открываем приложение LSPosed, в котором необходимо установить уже Xposed-модуль SSLUnpinning
Переключаем все галки в настройках данного модуля у всех приложений, которые хотим слушать и активируем сам модуль
Ребутим эмулятор
После этого вы оказались в ситуации, когда у вас есть эмулятор с:
Полноценным рутом (Magisk)
Установленным MITM-сертификатом в User-space
Установленным Xposed (LSPosed)
Установленным модулем для SSL-Unpinning
В процессе имея следующий набор картинок:
Можно честно поставить галку:
⚑ SSL Unpinning
Настал час проверить, работает ли этот паровоз:
Работает! Ник и Майк ошиблись! Можем ставить и последнюю галку:
⚑ Profit!!!
Какие есть нюансы? Во первых - при каждом включении эмулятора будет необходимо снова делать сертификаты доверенными (в принципе, после всех этих процедур можно отключить Cold Boot, и тогда не придется, но рано или вам придется перезагрузить эмулятор "жестко", и тогда потребуется поработать и с сертификатами). Возможно, тут есть постоянное решение или это можно, на худой конец, автоматизировать, но я устал. Во вторых - не все приложения в принципе хотят запускаться на эмуляторе. Самый надежный вариант - иметь набор выделенных телефонов на разных версиях Android, все из которых будут иметь весь арсенал инструментов из данного мануала (с небольшими изменениями), но он не всегда возможен.
Под конец - я еще раз продублирую всю инструкцию по пунктам, чтобы был понятен сам алгоритм:
Делаем приготовления (ставим Android Studio), чтобы иметь возможность установить / запустить эмулятор
Устанавливаем эмулятор с параметрами, определенными выше
Устанавливаем интересующие нас приложения на эмулятор методом перетаскивания курсором и убеждаемся, что они в принципе работают и все это будет не зря
Получаем root (Magisk) посредством инструкции, указанной выше
Перезагружаем эмулятор
Устанавливаем Riru
Перезагружаем эмулятор
Устанавливаем LSPosed
Перезагружаем эмулятор
Устанавливаем Xposed-модуль SSLUnpinning
Ставим все галки в модуле у интересующих нас приложений и у самого модуля (включаем его)
Закрываем эмулятор
Выключаем Cold Boot
Включаем эмулятор
Устанавливаем MITM CA-сертификат в User-space (считай - просто устанавливаем)
Делаем сертификат доверенным по инструкции выше
Настраиваем Proxy на эмуляторе согласно параметрам, указанным выше, или вашим собственным (в зависимости от того, каким инструментом для анализа трафика вы собираетесь пользоваться)
Анализируем работу приложения
Если будете устанавливать дополнительные приложения на эмулятор - то необходимо проставить галки напротив них в SSLUnpinning (через LSPosed) и жестко перезагрузить эмулятор, с последующим фиксом сертификатов после перезагрузки. На этом, собственно, все, до новых встреч!
Комментарии (6)
n_nesterow
31.08.2021 19:35+1Похожего можно добиться с mitmproxy. Мне этот способ кажется несколько проще
https://docs.mitmproxy.org/stable/howto-install-system-trusted-ca-android/
alphamikle Автор
01.09.2021 12:33adb root
тоже работает, то получится ли через adb сделать unpinning (чтобы не пересобирать apk - большой вопрос)
HSerg
31.08.2021 21:18+1если вы знаете, как завести на Ryzen 5000-серии и WSL и Android Emulator - то прошу написать об этом комментарий
У меня сейчас как раз Ryzen 5000-серии, WSL и Android Emulator. Но WSL2 не устраивает, так что пользуюсь WSL1. Понадобилась только установка Android Emulator Hypervisor Driver for AMD Processor из SDK. Если же нужен WSL2, то в оф. доке есть раздел про WHPX.
Aquahawk
01.09.2021 14:19+1Для того чтобы не пропихивать сертификат в систему каждый раз, есть magisk модуль https://github.com/NVISOsecurity/MagiskTrustUserCerts
А вообще я всё тоже самое делаю на железном девайсе. В виртуалку установлен kali linux, эта виртуалка прописана дефолт гейтвеем для мобилы и там уже mitmproxy в режиме transparent proxy https://docs.mitmproxy.org/stable/howto-transparent/
PS: за SSLUnpinning спасибо, для apple есть https://github.com/nabla-c0d3/ssl-kill-switch2 а для андроида не знал
smirnov_sergey
Благодарю за подробную инструкцию, которая как раз кстати для меня как разработчика