- Advanced Certificate Bypassing in Android with Frida
- Jamie Holding
- Meet Frida
- Adding Additional SSL Pinning Bypasses
- Sign up for more like this.
- Nursery Night Sky Feature Wall
- Manually Triggering Android Deep Links
- Откручивание SSL пиннинга в Android приложениях
- Проблемы перехвата трафика
- Способы защиты приложений
- Способы обхода механизмов защиты
Advanced Certificate Bypassing in Android with Frida
Jamie Holding
Last year I published a blog post about bypassing certificate pinning using a tool called Objection.
Since then I have encountered Android research opportunities with more complex certificate pinning methods not covered by Objection. So I had to learn more about how this worked to figure it all out.
Meet Frida
Under-the-hood Objection is actually using a tool called Frida.
This is a framework for various platforms allowing code injection. This allows you to do all sorts of fun activities, but the main focus we’re interested in is it’s ability to override the return value of any function within an Android application.
What does this mean for us? Well, if we can override the return result of any Android function we can hopefully find some method called «bool IsSSLValid()» (or something), and force it to always return true. I have my own Frida script with a selection of common SSL pinning technique overrides you can use for yourself. But first, we need to get Frida setup.
Setup Frida on your machine following the official documentation:
Now you’ll want to install frida-server onto your Android device. Follow these instructions to get things setup:
Once you’re setup and frida-server is running on your Android device, you can write JavaScript files to build your injections.
I have a file called ‘pinning.js’ that is loosely based on some of the work in Objection, but with a few adjustments and some additional SSL pinning bypasses.
Download my pinning.js script to your machine and run it using the following command:
frida -U -l pinning.js -f [APP_ID] —no-pause
Note, replace [APP_ID] with the app you wish to inject into.
This script will boot the app, start the injections, then let the app complete it’s bootup. This ensures that our injections are setup as soon as possible before the app starts, so we don’t need to start it and make a mad dash in Objection to get the pinning bypass working before any requests are made.
You should see something like this:
My pinning script supports SSL pinning bypassing for Appcelerator, TrustManagerImpl, trustkit, okhttp3, and Sensepost Trustmanager.
Adding Additional SSL Pinning Bypasses
To add further SSL pinning bypasses you’ll want to analyse the internals of the Android app in question. Use a decompiler tool such as Jadx to load your target Android app’s APK and browse the code.
Here I have an Android app where I have found the SSL pinning in okhttp3. This function is called CertificatePinner::check.
Looking at the code, we can see that the function has no return value, but instead throws an Exception if the certificate is invalid. So all we need to do here is replace the function logic so that it doesn’t do anything and and invalid certificates will stop throwing exceptions.
To do this, we find the class name and override the method:
First we get the class itself (var CertificatePinner), then we overide the ‘check’ function. We need to tell Frida the arguments of the function we’re overriding so it can find the correct signature. In this case, the function takes a Java String and List.
Once we’re in, we can call return, skipping out the real application logic!
Sign up for more like this.
Nursery Night Sky Feature Wall
My little baby girl is on her way (probably here by the time I publish this). We knew we wanted to theme her nursery to something cool. At one point it was going to be dinosaurs, because dinosaurs are awesome. But that sounded complicated and we are really after subtle
Manually Triggering Android Deep Links
Sometimes it’s handy to test triggering a mobile deep link to test some new integration. You may have tried typing the URL into your phone’s web browser (like Chrome) to trigger the app launching, however this doesn’t work! The link needs to be clicked to trigger. However, instead of creating
Источник
Откручивание SSL пиннинга в Android приложениях
Проблемы перехвата трафика
В процессе тестирования на проникновение мобильных приложений на Android часто необходимо выяснить, каким образом приложение общается с сервером, с какими адресами происходит взаимодействие, как выглядят запросы, какие данные передаются. Но не всегда это удается сделать.
В наше время для взаимодействия компонентов веб-приложений используется протокол HTTPS, в основе которого лежат протоколы HTTP и TLS. Просто так перехватить трафик приложения не выйдет, т.к. он зашифрован. Можно, конечно, использовать прокси сервер, который с помощью своего сертификата сможет расшифровать трафик приложения и увидеть все запросы. Однако и средства защиты приложений не стоят на месте. Многие мобильные приложения используют SSL Pinning.
SSL Pinning – это внедрение SSL сертификата, который используется на сервере в код мобильного приложения. Таким образом, приложение не использует хранилище сертификатов устройства и не будет работать с сертификатом, который мы ему подсунули.
Ошибка, которая возникает в случае использования Burp suite для перехвата трафика с помощью собственного сертификата
Способы защиты приложений
Для того чтобы понять, как обходить защиту, необходимо сначала разобраться, какими средствами эта защита осуществляется. Для этого существуют несколько способов.
Для данного способа необходимо добавить файл сертификата в файлы приложения, затем создать KeyStore и добавить в него наш сертификат.
После этого создаем сам TrustManager, который будет работать с нашим KeyStore, в котором находится нужный сертификат.
Далее создается SSLContext, который использует наш TrustManager. Затем указываем для URLConnection SocketFactory из созданного SSLContext.
Основная суть этого метода в том, что мы используем непосредственно сам файл сертификата в проекте, а затем создаем TrustManager, который будет работать только с этим сертификатом.
Данная реализация работает непосредственно с API на достаточно низком уровне, поэтому этот способ надо использовать осторожно.
Вторым способом является использование библиотеки OkHttp. В ней есть удобный CertificatePinner, который с помощью своего конструктора закрепляет за доменом определенный fingerprint сертификата.
Этот fingerprint высчитывается из сертификата, с которым должно работать приложение, а затем пишется непосредственно в код.
Можно указать несколько сертификатов для разных доменов.
Network Security Configuration
С версии Android 7.0 стала возможна настройка конфигурации сети. В папке res/xml/ создается файл network_security_config.xml, в котором прописываются правила и указываются fingerprints, как в случае с OkHttp.
Затем в AndroidManifest.xml прописывается использование данного файла в качестве android:networkSecurityConfig.
Этот способ позволяет редактировать сертификаты, не меняя исходный код приложения.
Способы обхода механизмов защиты
Frida – инструмент для динамического внедрения кода в приложение. Утилита прямо в процессе работы приложения способна отслеживать вызовы методов приложения, модифицировать методы приложения, обращаться к памяти выполняемого приложения и многое другое.
Для обхода SSL Pinning с помощью Frida есть несколько готовых скриптов, создающих кастомный TrustManager, который будет доверять нашему сертификату. Рассмотрим скрипт.
CertificateFactory и X509Certificate нужны для создания экземпляра сертификата из считанного файла.
FileInputStream и BufferedInputStream используются для считывания файла сертификата.
KeyStore – наш кастомный KeyStore, в который положим наш сертификат.
TrustManagerFactory создает экземпляр TrustManager, который будет работать с нашим KeyStore.
SSLcontext – реализация протокола SSL, которая выступает как factory для sslSocketFactory.
Считываем сертификат cert-der.crt, который мы предварительно поместили на устройство, и создаем экземпляр этого сертификата.
Создаем keyStore, в который складываем наш сертификат.
Создаем trustManager, который доверяет keyStore с нашим сертификатом.
Вот здесь начинается настоящее использование Frida. Данный фрагмент перезаписывает метод SSLContext. Теперь при вызове приложением метода сначала будет вызываться информационный лог в консоль, затем выполнится исходный метод, который мы перезаписываем. Но он вызовется не просто так. Вместо второго параметра, который будет передан в функцию, новая функция подставляет кастомный TrustManager с нашим сертификатом. И в конце снова информационный лог в консоль о том, что все прошло удачно.
Таким образом, данный скрипт готовит TrustManager, а затем использует его в методе вместо того, который передается (переменные a и с передаются в вызов исходной функции, а вот переменная b заменяется на кастомный TrustManager).
Frida позволяет переопределять методы, выполнять собственные скрипты. Поэтому с помощью Frida можно обойти защиту, реализованную через OkHttp CertificatePinner.
Главное преимущество этого метода – отсутствие необходимости патчить исходный код apk и пересобирать приложение. А так как нам не нужно пересобирать приложение, значит этому способу не помешают методы защиты приложения от пересборки.
С другой стороны, для данного метода необходимо подключить телефон к устройству с Frida, установить frida-server на телефон, а это не всегда удобно.
Изменение исходного кода и пересборка apk
В случае, если мы хотим один раз произвести обход средств защиты и получить приложение, в котором не будет SSL Pinning, необходимо изменить сам код приложения.
Для этого сначала нужно декомпилировать apk файл. Декомпилируется он в smali код. Smali – ассемблер для android-приложений. Все изменения будут производиться в .smali файлах, так как именно из них будет пересобираться приложение.
Для декомпиляции можно воспользоваться удобной утилитой apktool. Также для декомпиляции работы с разобранным apk, а затем и для сборки можно использовать удобное расширение для Visual Studio Code ApkLab.
Чтобы не копаться в трудночитаемых исходных кодах smali, вышеперечисленные утилиты умеют преобразовывать их в Java-код, который уже гораздо удобнее изучать. Также утилиты предоставляют функциональность деобфускации, которая очень помогает в изучении исходного кода.
ApkLab предоставляет также автоматизированный поиск необходимых участков кода. Рассмотрим что и почему он изменяет.
В первом файле утилита закомментировала исполнение следующих методов: checkClientTrusted, checkServerTrusted, getAcceptedIssuers.
По названиям методов можно предположить, что первый проверяет, является ли клиент доверенным, второй проверяет, является ли сервер доверенным, а третий получает лист доверенных сертификатов. Но не будем гадать и перейдем к Java-коду данных методов.
Теперь мы можем уже с пониманием рассмотреть, почему утилита закомментировала эти фрагменты. Первые два метода внутри ничем не отличаются и вызывают новый метод mo9499a (такое название из-за деобфускации), который слишком большой, чтобы вставлять его здесь. Но, судя по документации, этот метод строит цепочку сертификатов до корневого сертификата, а потом проверяет, можно ли ему доверять. В данном методе при ошибке будет выброшено исключение. Но мы закомментировали вызов данной функции, поэтому никаких проверок сертификат проходить не будет, и поэтому исключений мы не получим.
Метод getAcceptedIssuers должен возвращать массив доверенных сертификатов. Но дальнейшая реализация и использование данного метода работает таким образом, что если мы вернем пустой массив, то программа будет доверять любому сертификату. Именно это и сделала утилита: закомментировала код, в котором происходит получение сертификатов из keyStore (это происходит в методе m7931a), а вместо этого просто возвращается пустой массив.
Автоматический редактор кода заменяет эти фрагменты, т.к. они используются в проверке сертификата. Поэтому, если необходимо самому изменить какие-то фрагменты проверки, сначала лучше изучить, как работают те или иные методы, а затем уже вручную менять их в smali. К тому же обычно не приходится писать много кода вместо методов. В рассмотренном выше примере не делается ничего сложнее комментирования основной функциональности и создания каких-либо переменных-заглушек.
Также можно рассмотреть OkHttp CertificatePinner. В обзоре реализации был представлен фрагмент кода, где в OkHttpClient передается CertificatePinner. Найдя в smali соответствующий метод, можно убрать строчку, в которой CertificatePinner складывается в поле объекта OkHttpClient.
Изменение NSC (Network Security Configuration)
Самый простой способ обхода SSL Pinning.
В случае, если в приложении присутствует NSC, необходимо его изменить. В файле NSC могут быть прописаны base-config и domain-config.
В base-config может быть указано, каким сертификатам приложение может доверять.
В domain-config настраиваются домены.
Для обхода защиты достаточно лишь убрать весь блок .
ApkLab также умеет делать автоматическое изменение NSC файла.
В случае отсутствия файла в проекте утилита создает его с указанным выше содержимым, а также прописывает его в AndroidManifest.xml.
Подмена файла сертификата
В случае, когда защита реализована с помощью TrustManager, использующего KeyStore, в котором лежит доверенный сертификат. Обычно KeyStore вшит в приложение. В .apk KeyStore обычно лежит либо в /res/raw, либо /assets.
Поэтому можно просто положить туда свой сертификат вместо того, который установили туда разработчики.
В связи с тем, что SSL Pinning может быть реализован множеством разных способов, от различных библиотек, до кастомных реализаций привязки сертификата, задача его обхода не всегда простая и очевидная. Каждый раз, рассматривая новое приложение, нужно изучить, какие методы используются, а затем уже применять соответствующие способы обхода, которые тоже не всегда удобны и работоспособны.
Frida достаточно сильный инструмент, но возникает неудобство в виде постоянного подключения телефона к устройству, предварительной конфигурации и прочего. А если в интернете нет готового скрипта для нужных целей, то написание собственного требует хорошего понимания работы Frida.
Непосредственный патчинг apk хорош тем, что его можно сделать всего раз и на выходе будет приложение без SSL Pinning. Однако на этом пути может помешать защита приложения от пересборки. Конечно и ее можно попытаться обойти, раз мы имеем исходный код приложения, но это потребует больше времени и сил.
Изменение Network Security Configuration достаточно простой и рабочий способ, но редко когда приложения ограничиваются только этим способом защиты. Поэтому знание обхода этого способа SSL Pinning необходимо, но недостаточно.
Подмена KeyStore с доверенным сертификатом в файлах приложения тоже легко реализуется. Но опять же данный способ может не сработать в случае, если приложение при запуске проверяет, не было ли каких-либо изменений в файлах приложения (например, высчитывает чек-сумму).
Таблица 1. Область применения
Способ обхода
Способы защиты, которые можно обойти
Источник