Как PT MAZE прячет уязвимости от хакеров

  • #Реверс
  • #PT_Maze

О чем статья

На примере PT MAZE показываем, какие части приложений получают наибольший эффект от использования протектора

Наше исследование популярных Android-приложений показало: шилдинг примерно на 40% сокращает общее число уязвимостей, которые можно выявить сканером MobSF. Давайте заглянем за сухую статистику и разберемся, как протектор PT MAZE работает на самых небезопасных участках приложений. 

Рисунок 1. Доля приложений, содержавших угрозы определенного типа.svg
Рисунок 1. Доля приложений, содержавших угрозы определенного типа

Code

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

hash = bytesToHex(MessageDigest.getInstance("MD5").digest(input.toByteArray(StandardCharsets.UTF_8)))

На рис. 2–3 представлены фрагменты декомпилированного кода до и после шилдинга. PT MAZE скрыл упоминание хеш-функции MD5 в строковых параметрах, названиях классов, методов и полей.

Рисунок 2. Фрагмент кода до шилдинга

 

Рисунок 3. Фрагмент кода после шилдинга

Firebase URL

Некорректная настройка Firebase ведет к появлению дыр в защите. Например, включенный Remote Config или неправильная обработка соединений с Firebase Realtime Database могут стать причиной утечки данных.

Ниже представлены примеры использования Remote Config в коде и ресурсах приложения. 

Рисунок 4. Импорт классов com.google.firebase.remoteconfig.* до шилдинга 
Рисунок 5. Пустой результат поиска классов com.google.firebase.remoteconfig.* после шилдинга

После шилдинга анализатор перестал фиксировать использование классов com.google.firebase.remoteconfig.*. PT MAZE обфусцировал прямые ссылки на соответствующие классы Firebase, поэтому декомпилятор перестал отображать вызовы Remote Config в явном виде. 

Кроме того, механизм шифрования ресурсов скрыл потенциальный Remote Config key — google_api_key. Это еще сильнее усложнит жизнь злоумышленнику.

Рисунок 6. Использование google_api_key до шилдинга
Рисунок 7. Обфусцированное значение google_api_key после шилдинга

Network

Частая проблема реализации безопасного соединения — неверная конфигурация файла network_security_config.xml. Разработчики могут случайно разрешить приложению работать с незашифрованным трафиком или доверять любым системным сертификатам. Подобное упрощение параметров делает соединение уязвимым для перехвата данных и атак типа Man-in-the-Middle.

На рис. 8–9 представлен пример использования встроенных сертификатов @raw/<имя> в файле network_security_config.xml и фрагмент одного из сертификатов.

Рисунок 8. Использование встроенных сертификатов до шилдинга
Рисунок 9. Фрагмент встроенного сертификата до шилдинга

Здесь протектор переименовал сертификаты и зашифровал их содержимое (см. рис. 10–11). 

Рисунок 10. Содержимое network_security_config.xml после шилдинга
Рисунок 11. Фрагмент встроенного сертификата после шилдинга

Secrets

В приложениях могут открыто храниться всевозможные секреты: учетные данные, API-ключи, токены интеграций, строки и криптографические ключи (в strings.xml, ресурсах res/raw/, бинарных файлах или прямо в исходном коде). Эту информацию можно без труда извлечь из APK-файла и использовать для несанкционированного доступа к сервисам. Например, строковое значение в коде может заинтересовать злоумышленника из-за схожести с токеном.

Рисунок 12. Строковое значение в коде приложения

Во время шилдинга механизм шифрования строк скрыл этот секрет (см. рис. 13).

Рисунок 13. Пустой результат поиска

Manifest

Искажение некоторых частей приложения может нарушить его работоспособность, поэтому протектор применяется к ним точечно. Яркий пример — AndroidManifest.xml. Протектор может успешно исказить имена классов, но некоторые данные в любом случае придется оставить открытыми — например, ссылку на assetlinks.json. 

Рисунок 14. Хранение домена и схемы, на которые привязан App Link

Ложноположительные результаты

Стоит сказать несколько слов о слабых местах исследования. Нельзя забывать, что сканеры могут генерировать FP и выдавать некорректные результаты на отдельных участках приложений. К примеру, в одном из случаев MobSF посчитал, что на сервере нет assetlinks.json, поэтому злоумышленник может перехватить deep link. Мы вручную проверили наличие файла и получили идентификатор приложения, а также отпечаток сертификата SHA-256, которые совпадают с APK-файлом.

Рисунок 15. Ручная проверка существования assetlinks.json

Также малопригодным для анализа оказался раздел Certificate: сканер выдавал слишком много ложноположительных срабатываний. К примеру, MobSF обнаружил использование подписи по схеме v1 и зафиксировал уязвимость Janus. Ручная проверка показала, что этого недостатка в приложении нет (см. рис. 16).

Рисунок 16. Проверка подписи приложения на уязвимость Janus

***

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

Проще говоря, при правильном применении протектор может значительно облегчить процесс защиты приложения для AppSec-инженера и усложнить жизнь злоумышленникам ;)

Мы дěлаем Positive Research → для ИБ-экспертов, бизнеса и всех, кто интересуется ✽ {кибербезопасностью}