Иногда вам необходимо изучить работу серверной части мобильного приложения.
Хорошо, если создатели приложения не заморачивались и все запросы шли через «голый» HTTP. Что, если приложение использует HTTPS для выполнения запросов и отказывается принять сертификат от вашего корневого центра сертификации, который вы тщательно внедрили в хранилище операционной системы? Конечно, можно искать запросы в декомпилированном приложении или с помощью реверс-инжиниринга вообще отключить использование шифрования, но хотелось бы более простой способ.
Что такое закрепление сертификата?
Даже при использовании HTTPS пользователь не защищен от атак «Человек посередине», поскольку при инициализации соединения злоумышленник может подменить сертификат сервера своим собственным.После этого трафик станет доступен злоумышленнику.
Закрепление сертификата поможет справиться с такой атакой.
Эта защитная мера заключается в том, что разработчик «встраивает» в приложение доверенный сертификат. При установке безопасного соединения приложение проверяет, соответствует ли сертификат, отправленный сервером, сертификату в хранилище приложений (или подписан им).
Обход закрепления сертификата
В качестве подопытного мы будем использовать приложение Uber. Мы будем использовать Burp Suite для анализа HTTP-трафика.Также нам понадобятся JDK и Android SDK (я использую все последние версии).
Из Android SDK нам понадобится только утилита zipalign, поэтому при желании можно не скачивать весь SDK, а найти его в Интернете.
Давайте заранее облегчим себе жизнь, добавив в переменную окружения PATH следующие пути к необходимым утилитам:
Откройте Burp, перейдите в «Прокси» — «Параметры» — «Добавить» и добавьте прокси-прослушиватель в интерфейс, который будет доступен экспериментальному Android-устройству (или эмулятору).C:\path\to\jdk\bin %USERPROFILE%\AppData\Local\Android\sdk\build-tools\23.0.2
На устройстве, в свою очередь, настраиваем используемую сеть Wi-Fi для использования вновь включенного прокси.
Скачаем apk-файл через apkpure.com, установим приложение на устройство и попробуем войти в свой аккаунт — приложение зависнет на этапе аутентификации.
В журналах Burp Suite (вкладка «Оповещения») мы увидим несколько отчетов о неудачных рукопожатиях SSL. Обратите внимание на первую строчку — именно через сервер cn-geo1.uber.com в моем случае осуществляется аутентификация, из-за чего я не могу зайти в приложение.
Дело в том, что Burp Suite при перехвате HTTPS-соединений (а мы помним, что все подключения устройств проксируются через него) заменяет сертификат веб-сервера на свой, который, естественно, не входит в список доверенных.
Чтобы убедиться, что устройство доверяет сертификату, выполните следующие действия: В Burp перейдите в «Прокси» — «Параметры» и нажмите «Импорт/экспорт сертификата CA».
Далее в диалоговом окне выберите «Экспорт сертификата».
Скопируйте сертификат на устройство, зайдите в Настройки – Безопасность – Установить сертификаты и установите наш сертификат как сертификат для VPN и приложений.
Мы пытаемся снова войти в нашу учетную запись.
Теперь приложение Uber будет сообщать нам только о неудачной попытке аутентификации, а значит прогресс есть, осталось только обойти закрепление сертификата.
Откроем приложение в вашем любимом архиваторе в виде zip-архива.
В папке res/raw вы можете увидеть файл с говорящим именем ssl_pinning_certs_bk146.bks.
По его расширению можно понять, что Uber использует хранилище ключей в формате BouncyCastle (BKS).
Из-за этого вы не сможете просто заменить сертификат в приложении.
Сначала вам нужно создать хранилище BKS. Для этого скачать банку для работы с БКС.
Теперь мы создаем хранилище BKS, которое будет содержать наш сертификат: keytool -import -v -trustcacerts -alias mybks -file c:/path/to/burp.crt -keystore ssl_pinning_certs_bk146.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath c:/path/to/bcprov-jdk15on-154.jar -storepass spassword
На вопрос о доверии сертификату ответьте «да».
Снова открываем апк в архиваторе и заменяем оригинальное хранилище на наше (с сохранением оригинального названия).
Но на этом все не заканчивается.
Каждый APK должен быть подписан сертификатом разработчика.
К счастью, это делается не для обеспечения безопасности, а для идентификации приложений, поэтому для наших исследовательских целей мы легко можем использовать недоверенный сертификат. Удаляем из апк папку META-INF со старой подписью приложения и начинаем генерировать новую.
Создаем хранилище ключей и генерируем в нем ключ для подписи apk: keytool -genkey -keystore mykeys.keystore -storepass spassword -alias mykey1 -keypass kpassword1 -dname "CN=ololo O=HackAndroid C=RU" -validity 10000 -sigalg MD5withRSA -keyalg RSA -keysize 1024
Мы подписываем наш APK вновь сгенерированным ключом: jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore mykeys.keystore -storepass spassword -keypass kpassword1 Uber.apk mykey1
Теперь осталось только выровнять данные в архиве по четырехбайтовой границе: zipalign -f 4 Uber.apk Uber.apk_zipal.apk
Готово, удалите старое приложение с устройства, установите новое и попробуйте войти в свой аккаунт. Если раньше попытка приложения связаться с cn-geo1.uber.com прерывалась рукопожатием, то теперь вы можете просмотреть и при желании изменить трафик.
Спасибо за внимание!
Теги: #Android #пентест #SSL #информационная безопасность
-
Как «Незнайка» Делал Игру
19 Oct, 24