Эту уязвимость я нашел при анализе мобильного приложения популярной региональной соцсети. Уязвимость заключается в том, что когда пользователь производит авторизацию в приложении с помощью SMS, необходимые для успешного входа данные генерируются на стороне клиента. Хакер, не имея доступа к смартфону пользователя, может подделать цепочку запросов и ответов приложения и завладеть его учетной записью.
Еще по теме: Вы верите в безопасность мессенджеров?
Приложение распространяется в версиях для iOS и Android, дополнительно может быть использован веб-интерфейс. На сегодняшний день только на Андроид свыше миллиона загрузок. Аналог для iOS находится в списке 200 самых популярных мессендлеров в App Store.
Для анализа приложения использовался метод «черного ящика» — на основе общедоступных приложений и веб-клиента. При исследовании приложений был выявлен используемый SSL Pinning. На Android его удалось частично обойти путем настройки скриптов Frida (см. Способы обхода SSL Pinning Android). На iOS разрабы использовали последние версии средств защиты, для которых пока не существует обхода.
Статья в образовательных целях для обучения этичных хакеров (багхантеров). Баг Баунти — это программа, которую владелец приложения проводит для привлечения сторонних специалистов к поиску уязвимостей. При участии в программе Bug Bounty нужно действовать этично и придерживаться установленных правил. Ни редакция spy-soft.net, ни автор не несут ответственности за ваши действия.
Основная проблема заключалась в том, что для взаимодействия с сервером приложение использовало gRPC (на основе Protobuf). Поскольку тестирование осуществлялось методом «черного ящика», у меня не было proto-файла с описанием структур. Поэтому все обнаруженные уязвимости были выявлены при ручном анализе proto-запросов.
Для работы gRPC я использовал расширение Blackbox Protobuf для Burp Suite (см. Перехват трафика Android-приложения в Burp и Frida). Но версия из репозитория неправильно парсила поля запроса. Для того чтобы она работала корректно, мне понадобилось модифицировать расширение, добавить новый заголовок к сообщениям и поменять алгоритм разбора поля Additional Data в gRPC.
Суммарно на обход SSL Pinning и модификацию расширения для Burp Suite ушла одна рабочая неделя. На ручной анализ gRPC и поиск уязвимостей в мессенджере — около трех недель. По ходу дела в приложении удалось найти три уязвимости высокого уровня опасности, одну — среднего и одну — низкого.
Взлом аккаунта мессенджера с помощью Burp Suite
Так как название полей было неизвестно, на схеме они представлены цифрами (идентификаторами полей).
Для входа в приложение вводится номер телефона пользователя и капча. В ответ сервер возвращает UUID сессии аутентификации.
Для входа в приложение пользователь должен ввести одноразовый код, полученный по SMS. Код отправляется с UUID, полученным из прошлого запроса.
При вводе неверного кода приложение вернет ответ 11. Это код ошибки, означающий, что неверно введен код OTP.
При верном коде в значении поля возвращается null, это значит, что код корректный. Если ошибки нет, приложение создает UUID #2 (помечен красным). И отправляет эти два UUID серверу, в ответ получая сессию.
Как видно из схемы, сервер не возвращает дополнительную информацию при отправке корректного кода. Поэтому я предположил, что UUID #2 генерируется только на основе времени.
Для проведения атаки я с помощью Burp Suite модифицировал ответ, который сервер возвращает при вводе неверного одноразового кода. Это позволило сгенерировать на клиенте верный UUID #2 для сессии и получить доступ к аккаунту.
Шаг 1. Запрос на отправку SMS (создание новой сессии аутентификации)
Первым вызывается метод SendCodeRecaptcha сервиса аутентификации (AuthService).
Запрос SMS выглядит следующим образом.
Этот gRPC-запрос в декодированном виде содержит два поля:
- поле 1 — номер телефона (+79…);
- поле 2 — reCAPTCHA (03A…).
Ответ сервера будет таким.
В декодированном виде ответ содержит два поля:
- поле 2 — UUID сессии аутентификации, который будет использовать при дальнейших запросах (e94f46ce-c9f1-11eb-9433-027eb92e4dfc);
- поле 4 — секунды до того, как можно будет отправить еще одну SMS на тот же номер (120 секунд).
Шаг 2. Ввод одноразового кода из SMS
Далее злоумышленник вводит случайный код подтверждения (OTP) и отправляет запрос.
Запрос на отправку кода подтверждения производится через метод VerifyCode сервиса аутентификации.
Запрос в декодированном виде содержит два поля:
- поле 1 — UUID сессии аутентификации (содержимое поля 2 из ответа сервера на прошлом шаге);
- поле 2 — код подтверждения из SMS (2345).
Хакер перехватывает ответ сервера с ошибкой.
В декодированном виде ответ содержит поле 1 с ошибкой 11 (некорректный код из SMS).
Шаг 3. Подмена ответа сервера с ошибки на успешный
Для атаки злоумышленник подменяет ответ сервера: вместо ответа с ошибкой придет сообщение об успешном вводе кода из SMS.
В декодированном виде:
- поле 1 — определяет ошибки от сервера (пустой массив);
- поле 2 — предположительно передает значение успеха о вводе кода (True).
Шаг 4. Генерация кода подтверждения и отправка запроса на вход в систему
На основе успешного ответа JavaScript генерирует код подтверждения. Данные для входа в приложение отправляет метод SignIn сервиса аутентификации.
Расшифрованные данные содержат два поля:
- поле 1 — UUID сессии аутентификации из прошлых запросов;
- поле 3 — код подтверждения (UUID #2), генерируемый сайтом при успешном вводе кода из SMS.
В ответ на этот запрос сервер возвращает сообщение об успешном входе вместе с токеном JWT. Этот токен позволяет получить полный доступ к аккаунту жертвы.
Для проверки уязвимости я успешно вошел в аккаунт коллеги с его разрешения.
Выводы
Итак, мне удалось продемонстрировать возможность захвата чужой учетной записи. Чтобы закрыть эту дыру, разработчику достаточно перенести на сервер генерацию данных, необходимых для входа в аккаунт. Когда я тестировал эту уязвимость во второй раз, механизм был переработан: генерация второго кода (UUID #2) теперь производится на основе одноразового кода и времени, количество отправок также ограничено.
Спасибо, Danr0, за интересный райтап.
ПОЛЕЗНЫЕ ССЫЛКИ:
- Установка Frida Server на Android
- Взлом приложений iOS с помощью Objection
- Пентест мобильных приложений iOS используя Frida