Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
С ростом популярности операционных систем, растет также и необходимость в обеспечении безопасности системы. С каждым днём количество атак увеличивается, а каждое обновление несет в себе новые «дыры» в системе безопасности. Я Анастасия Худоярова, ведущий специалист по безопасной разработке в Awillix, расскажу о том, как развивалась система безопасности в Android раньше и как можно обойти некоторые ее механизмы сегодня.
С чего все начиналось
Путь по защите Android-а был тернист. На конец 2021 года устройства Android насчитывали более 2,5 миллиарда активных пользователей, что составляет около 75% мирового рынка. Данная ОС стремительно развивалась с 2008 года и претерпела много изменений. В том числе это коснулось системы безопасности.
Начиналось всё с элементарных вещей. Таких как PIN экрана, запуск приложения в изолированной среде, указания определенных полномочий в конфигурационных файлах приложения. Теперь это многоуровневая защита устройства как аппаратная, так и программная.
Android использует ядро Linux, поэтому его архитектура и все используемые механизмы очень похожи.
На уровне ядра были добавлены дополнительные функции, а также усилены меры безопасности, например, касающиеся использования IPC средств межпроцессного взаимодействия (в Android поддерживаются только сокеты) так называемых Binder-ов; были внедрены дополнительные настройки в политике SELinux, чтобы ограничить доступ к сетевым сокетам, обладающим определенными полномочиями.
На уровне приложенийвыполнено разделение на read-only системные приложения и read-write пользовательские приложения, которые запускаются в своих песочницах с четко определенными правами.
Принцип разделений привилегий приложений и принцип наименьших привилегий – это самые важные аспекты в модели безопасности Android. Права запрашиваются приложениями с помощью их объявления в AndroidManifest.xml файле. Этот файл представляет собой описание основной информации о приложении системы. На основе указанных в манифесте разрешений система решает можно ли выдать такие права.
Развитие безопасности в Android
Использование ограничений прав в приложениях оказалось недостаточным для защиты от вредоносных программ — Google продолжает ужесточать меры. Разграничение прав на уровне ОС несомненно эффективно, но не гибко, так как всем приложениям могут понадобиться совершенно разные настройки, которые пользователь захочет максимально быстро настроить под себя. Первые попытки гибкого разделения полномочий были предприняты в Android 4.3 через раздел App Ops.
В App Ops пользователь мог отозвать и выключить всё, что угодно. Однако это было максимально неэффективно для него. Приложение могло «упасть» даже после отзыва чего-то незначительного. В Android 6.0 исправили эту «маленькую» неприятность: теперь приложение запрашивает права в тот момент, когда они ему нужны.
Это казалось хорошим решением, но открылась еще большая уязвимость. Стоит поменять в правилах сборки номер версии на более старый, и приложение будет получать все полномочия разом. Хотели сделать безопасно, но до конца не получилось реализовать эту идею. «Не стоит прогибаться под изменчивый мир, пусть лучше он прогнется под нас», — подумали в Google, и волевой рукой отрубили публикацию приложений для устаревших версий ОС. Сейчас, начиная с Android 10, полномочия у софта под старые версии отзываются, приложение попросту не работает. В 11-ой версии появилась возможность делать разрешение на однократный запуск.
Постепенно Google вводит ограничения на типы разрешений и на информацию об устройстве, которые может получить приложение:
С Android 8 уже нельзя так просто добраться до серийного номера устройства, становятся недоступными некоторые системные переменные;
В Android 9 установлен запрет на использование камер и микрофона, когда приложение находится в фоновом режиме, также нельзя использовать HTTP без TLS;
В Android 10 вводятся ограничения, связанные с доступом к местоположению, запуском активностей фоновыми приложениями, что может вызвать проблемы, например, при работе приложений для умных часов. Важно, что с 10-ой версии в обязательном порядкевводится полнодисковое шифрование. Для удобного и гибкого управления разрешениями был введен и менеджер разрешений, позволяющий гранулировано настраивать каждое приложение.
В Android 11 усложняется доступ к памяти и камере, появляются дополнительные настройки управления подключенными «умными» устройствами в Smart Lock: данная функция способна самостоятельно определить необходимость усиления безопасности.
Постепенно всё больше происходит завязка на различных ключах шифрования, которые представляют критичную информацию. По этой причине вводится доверенная среда исполнения. Она хранит эти данные и сама по себе является выделенной системой, что позволяет избежать утечки ключей при компрометации основной системы. Также для снижения риска нарушения системы используется доверенная загрузка, которая проверяет целостность ОС при запуске устройства.
Новшества системы
Принятых мер оказалось недостаточно для защиты от зловредных приложений, поэтому с 2012 года начинается ввод системы проверки загружаемого софта на подозрительное поведение с использованием статических и динамических анализаторов, в результате работы которых выявляются SMS фрод, фишинг.
Из последних новшеств — введение проверки SafetyNet. SafetyNet представляет собой набор API, позволяющий приложениям проверять устройство на предмет компрометации. SafetyNet жизненно необходим банковскому и финансовому ПО: производится проверка оригинальности устройства по серийным номерам, оригинальность прошивки, наличие root прав, контрольные суммы, проверка того, доверенное ли устройство, по его отпечатку.
Проверка была модифицирована, чтобы обеспечить высокую степень надёжности приложения клиента при взаимодействии с сервером, который обслуживает мобильное приложение, и теперь проверяется достоверность переданных данных с помощью специализированного ключа.
Использование сертификатов и подписей в Android
Механизмы безопасности внедряются не только касательно самой начинки ОС: новым требованиям Google обязаны следовать и разработчики. Например, теперь нельзя просто так взять и добавить доверенный сертификат в системные или собрать apk приложение без специализированной подписи разработчика.
Касаемо APK, изначально Google ввёл использование специализированных криптографических хэшей и подписи разработчика, хэши считались на части файла. Однако после атаки Janus выяснилось, что для верификации DEX файла используется не весь файл. Соответственно, в неиспользуемую часть можно было внести свои изменения. Баг исправили в новом формате цифровой подписи APK signature scheme v2 и v3, теперь цифровая подпись распространялась на весь файл. Просто установить приложение из Apk стало невозможно. Для прохождения всех проверок Google и его полноценного функционирования, оно должно быть верифицировано, а для этого у разработчика должен быть соответствующий ключ.
Начиная с Android 10 появились некоторые особенности механизма добавления сертификатов в системные сертификаты. До Android 4.0 существовали только системные сертификаты, которые были встроены в систему, и пользователи не имели никакой возможности контролировать их. Единственным решением было рутануть устройство и изменить системные папки с этими сертификатами. Затем появилась возможность добавлять пользовательские сертификаты. В Android для управления доверенными данными используется TrustManager, в данном случае именно он будет проверять надежность сертификатов. То есть теперь в Android есть системные сертификаты (/system/etc/security/cacerts/), пользовательские CA сертификаты сохраняются в специализированной директории (/data/misc/user/0/cacerts-added).
Добавление пользовательских сертификатов иногда недостаточно для решения каких-либо задач, например, если надо проксировать трафик, и требуется добавить сертификат именно в системные сертификаты, с чем возникают сложности в последних версиях Android. В соответствии с последними рекомендациями для разработчиков от Google, есть требования сетевых настроек, которые запрещают приложению доверять пользовательским сертификатам: они как бы доверенные, но не сильно. Данное требование относится именно к сетевому трафику приложений. В случае когда необходим доступ к сайту организации с самоподписанным сертификатом, могут быть использованы и пользовательские сертификаты. Возвращаясь к вопросу добавления сертификатов в системное хранилище, возникает проблема — раздел ФС, где хранятся системные сертификаты примонтирован в режиме read-only, поэтому так просто добавить сертификат нельзя. Особенно это усложнилось, начиная с Android 11 и даже 10. Сложность связана с FDE (полнодисковое шифрование), так как процесс монтирования происходит после расшифровки диска в момент загрузки.
Советы атакующим: Как добавить сертификаты read-only в системные директории?
Добавление пользовательского сертификата в системные означает изменение системных директорий, что запрещено. Обойти это можно лишь получив root-права на телефоне. После этого есть два пути: короткий и приятный vs длинный и немного хардкорный. Начну со второго:
После взлома телефона появляется возможность изменять файлы системы. Следовательно, раздел с доверенными сертификатами можно изменить, единственное, надо будет перемонтировать систему, чтобы подтянулись добавленные сертификаты. Поэтому после стандартной установки пользовательского сертификата волшебная последовательность команд и перезагрузка устройства приведут к успешному завершению операции.
adb root # запуск с правами root
adb remount # переводит раздел system в режим read-write
adb ls /data/misc/user/0/cacerts-added # просмотр сертификатов, пользователя
adb pull /data/misc/user/0/cacerts-added/cert.0 # вытащить с устройства на компьютер добавленный сертификат
adb push cert.0 /system/etc/security/cacerts/ # перенести сертификат с ПК на устройство
Простой способ — воспользоваться плагином Magisk AlwaysTrustUserCerts. Он всё сделает сам. От вас требуется только поставить сертификат и перезагрузить телефон. И вуаля — сертификат окажется в нужном хранилище.
Как говорилось выше, существует проверка SafetyNet, которая чутко реагирует на то, скомпрометирован ли телефон. То есть проверяет наличие root-прав. Пентестеру нужно проксировать трафик, то есть нужен доверенный системный сертификат, следовательно, требуются root права. Однако в таком случае не будет проводиться проверка, так как нарушена целостность устройства, а значит и приложение работать не будет. Есть выход — можно воспользоваться Magisk hide и в Burp поставить игнорирование запросов на Google.
Советы разработчику: Как попытаться защитить свое приложение от хакеров
То есть можно обойти все системы защиты и проксировать трафик. Как тогда защитить свое приложение? На помощь приходит SSL Pinning. Certificate pinning — это внедрение SSL сертификата, используемого на сервере, в код мобильного приложения. В этом случае приложение будет игнорировать хранилище сертификатов устройства, полагаясь только на свое хранилище, и позволит создать защищенное SSL соединение с хостом, подписанным только сертификатом, что хранится в самом приложении. Реализуется это за счет того, что приложением проверяются сертификаты из pin list.
Закрепить их там можно несколькими способами:
С помощью TrustManager добавляется файл сертификата в файлы приложения, создается KeyStore для хранения ключей приложения. Дальнейшая работа ведётся через TrustManager, который будет обращаться к хранилищу KeyStore, где находится сам сертификат. TrustManager будет работать только с этим сертификатом и проверять совпадение с ним. Иначе говоря, если будет проксироваться трафик, то появятся соответствующие ошибки.
Другой подход внедрить пиннинг — это использовать библиотеку OkHttp CertificatePinner, которая содержит конструктор, фиксирующий за доменом определенный fingerprint сертификата. Данный отпечаток сертификата внедряется в код.
Последний способ — это Network Security Configuration, где так же, как и в предыдущем способе, фиксируются фингерпринты используемых сертификатов.
И снова рубрика «советы атакующим»
К сожалению разработчиков и к счастью пентестеров, и это можно обойти, например, с помощью Frida, только очень аккуратно. Использование Frida и Magisk Hide в неправильном порядке может навредить вашему устройству и работать ничего не будет. Дело в том, что обе программы используют одинаковый процесс zygote64 для внедрения в код запущенного приложения. Их конфликт может сломать обход SSL Pinning, и скрытие root прав, тут-то SafetyNet нас и поймает.
***
Android прошел огромный путь изменений и улучшений. Система стала в разы более защищенной. Сегодня это уже совсем не «дырявая» система, а сильный конкурент другим мобильным операционным системам, и с ней нужно учиться работать.
Есть вопросы или предложения по новым темам? Пишите в комментарии или в телеграм — ответим всем.