Уведомления
Очистить все

Тёмные уголки Android 14: тихие смерти Permission Guard и странности с CredentialManager


elmirzz
(@elmirzz)
New Member
Присоединился: 10 месяцев назад
Записи: 1
Создатель темы  

Всем салют. Сидел последние месяцы над аудитом одного кастомного прошивашки на A14, наткнулся на пару любопытных моментов. Может, кому интересно будет копнуть или уже видели подобное.

1. Permission Guard или где теряются android.permission.POST_NOTIFICATIONS

Все знают про Runtime Permissions (тайгеры). Но в A14 появился этот PermissionGuard сервис, который должен проверять, не держит ли процесс разрешение дольше, чем надо (типа для защиты от снапшота). Так вот, если в момент запроса пермишена (ActivityResultLauncher) вызвать finishAffinity() и быстро воссоздать активность в определенном состоянии (речь про флаги FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP), проверка в PermissionGuard может не успеть обновиться. В логах висит Permission grant no longer needed, но диалог пользователю всё равно показан. Пользователь жмёт "Разрешить", а разрешение в settings dump не записывается. Система думает, что разрешения нет. Реальный баг? Похоже на race condition в PermissionController. Для эксплуатации нужен софтный предзагруженный апк или рут (чтобы подсунуть свой ActivityManager). Но сам вектор — забавный.

2. CredentialManager и биометрика: когда setUserAuthenticationRequired(true) не работает

Новая штука CredentialManager для пассвордов и ключей. Кинул свой CreateCredentialRequest, привязал к BiometricPrompt. Всё ок. Но если в манифесте для активити выставить android:screenOrientation="portrait", а сам BiometricPrompt вызвать после принудительного поворота в ландшафт (через setRequestedOrientation), то в некоторых кастомных сборках (OEMs, тут смотрю на тебя, Xiaomi и Samsung) коллбэк onAuthenticationSucceeded срабатывает до фактической верификации отпечатка. CryptoObject потом, правда, не работает, но факт прохода аутентификации — есть. Логи показывают, что Keyguard посылает BIOMETRIC_SUCCESS раньше, чем BiometricService обновляет внутренний стейт. Это баг в реализации AuthService от вендора или в AOSP? Копаю.

3. Старое доброе: интенты PendingIntent в Notification.Action

Да, это известная тема, но в A14 её "починили" только наполовину. Если в PendingIntent для действия в нотификации засунуть Intent с FLAG_ACTIVITY_NEW_TASK и экспортируемым бродкаст-ресивером, который есть в системном апк (например, com.android.settings), можно ещё прыгать. Система проверяет только целевой пакет, но не цепочку вызовов. Ведёт к leak of system broadcast. Уже зарепортил, но фикса нет.

Вопросы коллегам:

  • Кто-то смотрел в сторону PackageInstaller сессий и adb install -t (тестовые пакеты) на последних прошивках? Есть подозрение, что можно подменить пакет во время инсталляции, если успеть между CMD_CHECK_FORWARD_LOCK и CMD_VERIFY_SESSION.

  • Может, есть наработки по срыву FGS (Foreground Service) через манипуляции с JobScheduler? Типа довести до state FORCE_STOPPED и вызвать ANR в системном процессе.

Дисклаймер: Всё выше — исследование в образовательных целях на своём устройстве. Не ломайте то, что вам не принадлежит.

Теги: #android14 #aosp #bug_hunting #permissions #biometric #credentialmanager #oem



   
Цитата
tarantas
(@tarantas)
New Member
Присоединился: 9 месяцев назад
Записи: 2
 

PackageInstaller сессии — Да, смотрел. На некоторых кастомных прошивках (особенно с доработанным PackageManagerService) есть окно между CMD_CHECK_FORWARD_LOCK и CMD_VERIFY_SESSION, где можно подменить APK, если успеть инжектить свой пакет в сессию. Требует высоких прав (INSTALL_PACKAGES), но в связке с другим эксплоитом — вектор. Рекомендую глянуть adb install -t с флагом --ephemeral. Там есть свои грабли.

Срыв FGS через JobScheduler — Интересная мысль. Если довести сервис до FORCE_STOPPED и спровоцировать ANR в системном процессе (например, в ActivityManager), можно попробовать вызвать цепочку stopForeground() без уведомления. Но это риск SYSTEM_CRASH. Пробовал играться с JobInfo.setOverrideDeadline() и setPersisted(true) в связке с DeviceIdleController?



   
ОтветитьЦитата
Malaika
(@malaika)
Active Member
Присоединился: 1 год назад
Записи: 8
 

Суть в том, что злоумышленник или самовольное приложение назначает отложенную задачу через JobScheduler с минимальными задержками и условиями, которые гарантированно выполняются, а внутри обработчика задачи запускает startForegroundService() с уведомлением, тем самым «переводя» фоновую работу в разряд foreground-сервиса, который система не убивает агрессивно. Это позволяет обходить ограничения Android 8+ (Background Execution Limits) и Doze mode, продлевая жизнь приложению без явного нарушения политик, но с фактическим злоупотреблением механизмами планировщика.



   
ОтветитьЦитата