Обложка: Сам себе пентестер: как за пару дней проверить безопасность мобильного приложения

Сам себе пентестер: как за пару дней проверить безопасность мобильного приложения

В идеальном мире никто не проверил бы безопасность кода лучше тех, кто потратил дни и ночи на его написание. В нашем мире у разработчиков нет времени и опыта для такого аудита, и им занимаются отдельные люди — пентестеры.

Однако с хорошей инструкцией даже джуниор может сам провести базовый пентест за 1–2 дня.

Специалист по тестированию на проникновение компании BI.ZONE Олег Петраков расскажет, какими инструментами пользоваться и на что обращать внимание, чтобы быстро найти несложные уязвимости в мобильном приложении. Гайд поможет раньше узнавать о проблемах в коде, получать меньше правок на ревью и следить за безопасностью продукта, если никто больше этим не занимается.

Дисклеймер про термины Проверку приложения на уязвимости, которую в быту называют пентестом, эксперты по кибербезопасности назвали бы анализом защищенности. Пентест для них — другая задача: доказать, что в приложении есть хотя бы одна уязвимость, из-за которой его можно взломать. Однако наша статья написана не для экспертов по кибербезопасности, поэтому мы используем слово «пентест» в бытовом смысле.

Олег Петраков
Олег Петраков

специалист по тестированию на проникновение компании BI.ZONE

Готовим инструменты

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

  • для iOS — Finder, iTunes, iMazing, Console.app;
  • для Android — adb;
  • для обеих платформ — инструменты для отладки HTTP- и HTTPS-трафика вроде Fiddler или Charles.

Если работаете с Android, еще пригодится бесплатная утилита Android Backup Extractor.

Из специфически пентестерского арсенала вам хватит единственного инструмента — Mobile Security Framework (MobSF). Это автоматизированный универсальный фреймворк, который помогает проводить аудит безопасности мобильных приложений. Загрузив в него ipa-образ для iOS или apk-образ для Android, вы сможете провести динамический и статический анализ сборки. MobSF полезен и для целей безопасной разработки: к примеру, с помощью раздела Files удобно отслеживать, не попадают ли в релизную сборку лишние файлы.

Следим за лишней информацией в релизных сборках

Для начала проверим, не осталось ли в релизной сборке отладочной информации и журналов работы приложения.

В случае отладочной информации нас интересуют такие артефакты, как адреса тестовых стендов и других компонентов, API-ключи тестовых сервисов (например, аналитики) или сообщения, которые использовались при отладке приложения.

Их нежелательно оставлять по нескольким причинам.

  • Во-первых, с отладочной информацией атакующему будет легче изучить логику работы приложения на стороне клиента.
  • Во-вторых, изучив тестовый стенд — узнав, какие сервисы есть за фронтом на продакшне, какие базы данных используются на стороне сервера и пр. — атакующий может получить сведения для построения векторов атаки, обнаружения и эксплуатации уязвимостей.

План действий. Убедитесь, что в вашем приложении такой информации не остается. В этом поможет фреймворк MobSF. Загрузите в него релизную сборку вашего приложения и сделайте следующее:

  • для iOS-клиента — просмотрите все строки, определенные в ipa-образе, в разделе Scan Options / View Strings;
  • для Android-клиента — проверьте строки в разделе Reconnaissance / Strings, а также обратите внимание на раздел Security Analysis / Code Analysis.

В случае с журналами работы приложения мы проверяем, что логи, выручавшие на этапе тестирования, не станут подспорьем для атакующего.

Само по себе журналирование трудно проэксплуатировать. Однако, как и отладочная информация, логи и строковые константы помогают злоумышленнику изучать работу приложения: дают идеи, за что зацепиться при поиске уязвимостей, позволяют расширить поверхность атаки.

План действий. Воспользуйтесь инструментами Console.app для iOS и adb для Android, чтобы увидеть, включено ли логирование в релизной сборке приложения и что туда попадает.

Чтобы логи не уходили в релизную сборку, лучшее решение — грамотно спроектировать класс Logger. Если же исправление нужно быстро, настройте в скриптах релизной сборки удаление методов логирования из кода. Для iOS-приложений это делается через препроцессорный макрос, а для Android — с помощью применения правил ProGuard.

Проверяем ограничение на отправку СМС

Следующим шагом ищем уязвимость к SMS Abuse: она одновременно и очень распространена, и весьма критична.

Это важно для приложений, в которых часть действий завязана на СМС: двухфакторная аутентификация, восстановление пароля, перевод денег и так далее.

Сообщения закупают у провайдера пакетами: например, оплачивают сразу миллион СМС в месяц. При этом на стороне сервера обычно нет ограничений на отправку СМС за единицу времени. Если атакующий запросит миллион сообщений, сервер их все отправит и исчерпает оплаченный пакет. В итоге разработчик потеряет деньги, а в худшем случае еще и клиентов: пока СМС не приходят, пользователи не могут решать свои задачи и переключаются на другой сервис.

План действий. Вспомните все эндпоинты, где операции требуют отправки СМС, и попробуйте отправить сразу по 20 запросов к каждому с одного IP-адреса или от одного пользователя. Если сообщения придут — система подвержена этой атаке.

Полностью защититься от атаки не получится, но можно сделать ее экономически невыгодной для злоумышленника. Для этого введите капчу при множественных запросах для одного пользователя. А еще хорошо, когда неаутентифицированный пользователь не может запрашивать СМС (кроме как для входа, конечно).

Проводим ревизию библиотек

Шаг короткий, но важный: надо убедиться, что ваши фреймворки и библиотеки собраны со всеми мерами безопасности. В противном случае злоумышленнику будет легче эксплуатировать ряд бинарных уязвимостей (пусть и сложных и редких).

План действий. С помощью MobSF посмотрите, какие библиотеки собраны неправильно и чего не хватает: для этого зайдите в раздел Security Analysis / Binary Analysis.

Исследуем компоненты для работы с внешними ссылками

Внешние ссылки (App Links, Deep Links, Universal Links) могли вам потребоваться по разным причинам:

  • чтобы обрабатывать возвращаемые значения при OAuth-авторизации и других подобных протоколах;
  • чтобы пользователям было удобно работать с вашим приложением и другими системами — браузерами, почтовыми клиентами и пр.;
  • чтобы вы могли получать информацию для аналитики, и так далее.

Однако при встраивании компонентов для работы с внешними ссылками надо помнить: по отношению к другим приложениям эти компоненты всегда открыты. Следовательно, атакующий может отправлять им на обработку вредоносное содержимое. А это путь к обходу бизнес-логики приложения.

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

При встраивании компонентов для работы с App Links отдельно убедитесь, что ваш сервер сконфигурирован для проверки подписи вашего приложения (подробнее об этом — в инструкциях для разработчиков на iOS и на Android). Иначе ссылку могут перехватить.

Наконец, если ваше приложение обрабатывает и Deep Links, и App Links, определите для них разные компоненты: в противном случае нивелируются собственные меры безопасности, которые есть у App Links.

Проверяем другие открытые компоненты

В Android-клиентах специально определяют открытые компоненты — activity, сервисы и другие компоненты, которые могут обрабатывать запросы от других приложений, установленных на том же устройстве.

С точки зрения злоумышленника, каждый открытый компонент — это дополнительная поверхность атаки на ваш продукт. Из-за этого специалисты по кибербезопасности рекомендуют придерживаться минимализма и не множить открытые компоненты без необходимости.

План действий. Только вы можете решить, какие компоненты вам действительно важны для работы с другими приложениями и компонентами ОС. А увидеть их все в одном окне можно с помощью MobSF — для этого зайдите в раздел Security Analysis / Manifest Analysis.

Ищем недочеты в работе с компонентом WebView

Этот шаг актуален для приложений, которые задействуют WebView:

  • отображают с его помощью документы — условия использования приложения, документы о согласии обработки персональных данных и пр.;
  • проводят авторизацию через сторонний сайт, например Google, Apple, «Яндекс»;
  • целиком (или отдельный модуль) написаны на фреймворках наподобие React Native.

Для WebView нужны отдельные меры безопасности, а в некоторых ситуациях лучше вообще обойтись без таких компонентов. Сейчас все разберем.

План действий. Если вам нужно показать PDF-документ или статический HTML, не стоит добавлять компонент WebView. Лучше воспользоваться штатными возможностями системы: на iOS — UIDocumentInteractionController, на Android — ACTION_VIEW. Так ваш документ откроется в приложении, которое пользователь чаще всего использует для подобных задач. Это удобнее, проще и безопаснее.

Если задача чуть шире — например, вы показываете отчет, который наполняется динамически — WebView уместен. Главное — убедитесь, что при создании этого компонента вы отключили исполнение JavaScript-кода. Атакующий, как правило, не может повлиять на эти данные, однако отключить поддержку JavaScript-кода стоит из принципа минимальных привилегий.

Для сложных задач предпочтительнее использовать:

  • на iOS — WKWebView-компонент. SFSafariViewController тоже допустим, но он менее универсален: в нем нельзя отключить обработку JavaScript-кода при необходимости;
  • на Android — Chrome Custom Tabs вместо WebView. Если же вы используете WebView, включайте поддержку нескольких окон. Это нужно, чтобы защитить пользователей на старых версиях ОС от недавно найденной уязвимости CVE-2020-6506 (если кратко, то это выполнение произвольного JavaScript-кода в документе верхнего уровня).

Изучаем данные в резервных копиях телефона

Если атакующий получит доступ к резервной копии телефона, он завладеет и всей информацией, которую вы туда сохранили. Опасен ли этот сценарий и оправдан ли риск, зависит от приложения. Но точно стоит обдумать эту перспективу, прежде чем встраивать создание резервных копий. Важно ли вам, чтобы данные вашего приложения могли быть восстановлены на другом телефоне? А вашему пользователю это необходимо?

План действий. Чтобы принять решение, проверьте, какую информацию приложение хранит в резервной копии. На iOS проще всего использовать обычный Finder (или iTunes), на Android — adb. Просмотреть содержимое резервной копии можно с помощью программ iMazing и Android Backup Extractor соответственно.

Ориентируемся на лучшие практики

Заключительный шаг проверки посвятим трем так называемым best practices. Их отсутствие само по себе не говорит об уязвимостях — но если встроить эти практики, защищенность пользователя сильно вырастет. А встраивать их несложно.

SSL Pinning

Без SSL Pinning, то есть механизма привязки сертификата сервера, приложение будет использовать политику проверки сертификата сервера по умолчанию. Это небезопасно: подмена точки доступа и немного социальной инженерии — и ваша разработка станет уязвима к атаке типа «человек посередине» (MitM). В результате такой атаки злоумышленник сможет читать и даже изменять сообщения, которые передаются между мобильным приложением и сервером: конфиденциальность обеспечить не выйдет.

Если решите встроить механизм, не ограничивайтесь HTTP-соединениями. SSL Pinning настраивается вообще для любого протокола, обернутого в TLS: веб-сокетов, XMPP и так далее.

План действий. Чтобы уточнить, настроен ли у вас SSL Pinning, и на iOS, и на Android потребуются одинаковые инструменты — Fiddler, Charles и подобные программы для отладки HTTP- и HTTPS-трафика. Но схема работы будет немного отличаться.

  • На iOS достаточно настроить перенаправление трафика с телефона на HTTP-прокси и установить на устройство сертификат для HTTP-прокси. Если трафик приложения будет зарегистрирован на стороне HTTP-прокси, значит, у вашего клиента SSL Pinning не настроен или настроен неправильно.
  • На Android предварительно надо добавить в манифест network-security-config с настройкой доверия пользовательским сертификатам. После этого выполняйте ту же проверку, что и для iOS.

Размытие изображения в фоне

Применять размытие к приложению в фоне (использовать заставку) — рекомендация, которая подходит не всем. С одной стороны, размытие ухудшает опыт пользователей: им будет труднее переносить информацию в другое приложение, например браузер или блокнот. С другой стороны, размытие не даст захватить изображение в фоне не только пользователю, но и другим приложениям, в том числе вредоносным.

Для графического редактора этот механизм безопасности вряд ли будет актуален, а вот приложению для инвестиций его стоит рассмотреть.

План действий. Решить, подходит вам эта практика или нет, помогут ответы на два вопроса:

  • Нужно ли пользователю одновременно работать с вашим и другими приложениями?
  • Отображает ли ваше приложение конфиденциальную информацию, например финансовые транзакции?

А если не помните, есть ли у вас размытие, самый быстрый способ это проверить — встать на место пользователя: сверните приложение и перейдите к отображению всех запущенных приложений.

Аутентификация на телефоне

Этот пункт касается использования криптографии при аутентификации, поэтому актуален только для приложений на Android: на iOS механизм работает совсем иначе.

Если в вашем приложении есть аутентификация по отпечатку пальца или графическому ключу, убедитесь, что у вас есть привязка к BiometricPrompt.CryptoObject. С ней вы будете пользоваться всеми возможностями криптографии на Android: при успешной локальной аутентификации приложение будет получать доступ к ключу шифрования, на котором расшифровывается объект, соответствующий сессии пользователя (например, refresh-токен).

План действий. Смотрите пример из мануала для Android-разработчиков: тут в деталях показано, как встроить привязку к CryptoObject.

Резюмируя

Если инструкция вдохновила вас на подвиги, полистайте гайд OWASP по пентесту мобильных приложений. Он понятно и в деталях рассказывает, как проверять безопасность продуктов под iOS и Android.

Но пентест не серебряная пуля. Лучшая защита — у тех приложений, которые создаются в рамках подхода security by design: когда безопасность берут в расчет с самого начала разработки.

А как бы вы закрыли перечисленные уязвимости? Предлагайте примеры в комментариях и советуйте, какие еще проверки стоит добавить в список.

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации