Android: Бекдор в смартфонах Huawei и особенности релизации TrustZone в Samsung

Содержание статьи

Сегодня в выпуске: бэкдор в смартфонах Huawei, исследование устройства защищенной среды исполнения в смартфонах Samsung, простой и надежный способ зашифровать данные приложения, оптимизация приложения для Chrome OS, объяснение разницы между val и const val в Kotlin, а также новые инструменты пентестинга и большая подборка библиотек для разработчиков.

Почитать

Бэкдор в смартфонах Huawei

Huawei’s Undocumented APIs — A Backdoor to Reinstall Google Services — статья разработчика Magisk о том, как Huawei удалось реализовать систему установки сервисов Google Play на недавно выпущенный Huawei Mate 30.

Напомним, что в результате развязанной президентом Трампом торговой войны США и Китая Google была вынуждена разорвать действующие соглашения с компанией Huawei. В результате Huawei больше не может легально устанавливать приложения Google на свои устройства.

Казалось бы, приложения, в том числе Google Play, всегда можно доустановить из сторонних источников. Однако для их работы необходимы сервисы и библиотеки Google, которые должны быть частью прошивки и не могут быть установлены отдельно.

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

Никак иначе, кроме как с помощью скрытого API, реализованного Huawei, или уязвимости, LZPlay работать не мог, и Джон Ву (John Wu), разработчик Magisk, решил выяснить, так ли это.

Оказалось, что LZPlay использует ряд специфичных для Huawei разрешений:

<uses-permission android:name="com.huawei.permission.sec.MDM_APP_MANAGEMENT"/>
<uses-permission android:name="com.huawei.permission.sec.MDM_INSTALL_SYS_APP"/>
<uses-permission android:name="com.huawei.permission.sec.MDM_INSTALL_UNDETACHABLE_APP"/>
<uses-permission android:name="com.huawei.systemmanager.permission.ACCESS_INTERFACE"/>

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

<uses-permission android:name="com.huawei.permission.sec.MDM_INSTALL_SYS_APP"/>
<uses-permission android:name="com.huawei.permission.sec.MDM_INSTALL_UNDETACHABLE_APP"/>

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

Но самое интересное, что использовать эти API могут только приложения, подписанные специальным ключом Huawei. Другими словами, Huawei не только знала о существовании приложения LZPlay, но и одобрила его, выдав разработчикам ключ для подписи.

Особенности реализации TrustZone в смартфонах Samsung

Breaking Samsung’s ARM TrustZone — рассказ об уязвимостях, найденных в реализации TrustZone в смартфонах Samsung. Презентация интересна не столько самими уязвимостями, сколько подробностями о внутренностях системы.

Система TrustZone представляет собой выделенную среду исполнения внутри ARM-совместимых чипсетов, логически не связанную с основной средой исполнения, где работает операционная система смартфона и пользовательские приложения. Android использует TrustZone для запуска систем шифрования и обработки сенситивной информации, которая должна быть защищена от третьих лиц. К TrustZone имеет доступ только ограниченный набор привилегированных сервисов, а хранимая ей информация зашифрована и лежит в недоступной для основной системы памяти.

В случае с Samsung внутри TrustZone работает либо операционная система Kinibi, разработанная компанией Trustonic (Samsung Galaxy S3–S9), либо система TEEGRIS, за авторством инженеров самой Samsung (Samsung Galaxy S10). В презентации речь идет только о Kinibi. Интересные факты:

  • 32-битная микроядерная ОС;
  • разграничение полномочий на уровне системных вызовов;
  • запускает процессы (в том числе драйверов) головной процесс RTM (Run-Time Manager);
  • RTM также отвечает за коммуникацию между процессами с помощью MCI (Mobicore Communication Interface);
  • приложения могут быть запущены из стандартной среды исполнения (для подтверждения аутентичности используются цифровые подписи);
  • приложения Kinibi взаимодействуют со стандартной средой с помощью разделяемой памяти, в которую записываются команды для приложений Kinibi;
  • драйверы реализованы в форме обычных процессов с расширенным набором привилегий.
TrustZone в реализации Samsung
TrustZone в реализации Samsung

Разработчику

Шифрование данных приложения

AndroidX: Security library — рассказ о новой Jetpack-библиотеке androidx.security, содержащей удобные и простые инструменты для шифрования данных приложения.

Библиотека включает в себя два основных класса:

  • EncryptedSharedPreferences — аналог SharedPreferences, автоматически выполняющий шифрование ключей и значений, записываемых в файл настроек;
  • EncryptedFile выполняет автоматическое шифрование файлов с помощью собственных реализаций классов FileInputStream и FileOutputStream.

Пользоваться библиотекой очень просто. Подключаем библиотеку с помощью Gradle:

implementation "androidx.security:security-crypto:1.0.0-alpha02"

Затем создаем ключи шифрования (библиотека автоматически сохранит их в KeyStore, который в современных телефонах использует защищенную среду TEE):

val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

Далее создаем объект класса EncryptedSharedPreferences:

val sharedPrefs = EncryptedSharedPreferences.create( ИМЯ_ФАЙЛА, masterKeyAlias, context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

Все, теперь sharedPrefs можно использовать вместо стандартного объекта SharedPreferences для хранения и извлечения настроек. Все они будут автоматически зашифрованы с помощью ключа, который не удастся узнать, даже получив права root на устройстве.

Так выглядят зашифрованные настройки
Так выглядят зашифрованные настройки

Val vs. const val

To val, or to const val, that is the question — заметка о различиях между val и const val в Kotlin.

Возьмем следующий пример:

val FANCY_VAL = 1
const val FANCY_CONST_VAL = 2

Обе эти переменные немодифицируемые, но вторая объявлена с ключевым словом const в начале. Что это значит на деле? Во-первых, FANCY_VAL станет приватной переменной, для доступа к которой будет создан геттер. Это можно увидеть, если скомпилировать код и затем декомпилировать его в Java:

public final class ConstValKt { private static final int FANCY_VAL = 1; public static final int FANCY_CONST_VAL = 2; public static final int getFANCY_VAL() { return FANCY_VAL; }
}

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

Оригинальный код:

public static void main(String[] args) { System.out.println(ConstValKt.get_FANCY_VAL()); System.out.println(ConstValKt.MY_FANCY_CONST_VAL);
}

Декомпилированный код:

public static void main(String[] var0) { System.out.println(ConstValKt.getFANCY_VAL()); System.out.println(2);
}

Вывод: const val позволяет оптимизировать код, избавившись от ненужных геттеров и обращений к переменным.

Оптимизация приложения для Chrome OS

Optimizing Android app experiences for Chrome OS — статья разработчиков Chrome OS о том, что нужно сделать, чтобы Android-приложение стало удобным для пользователей Chrome OS. Основные моменты:

  • Поддержка клавиатуры. С этим все просто, Android с первых версий поддерживает клавиатуру. Для обработки нажатий клавиш достаточно добавить в активность один обработчик:
override fun onKeyUp(code: Int, ev: KeyEvent?): Boolean { return when (code) { KeyEvent.KEYCODE_J -> { // Обрабатываем нажатие true } else -> super.onKeyUp(code, ev) }
}

Следует иметь в виду, что ноутбуки на Chrome OS оснащены специальной клавишей «Обновить» (код кнопки: KEYCODE_REFRESH). В Android-приложениях эта кнопка по умолчанию обновляет SwipeRefreshLayout.

  • Тачпад. Пользователи Chrome OS ожидают, что свайп двумя пальцами по тачпаду будет проматывать экран. Это поведение автоматически распространяется на Android-приложения, но если необходимо обрабатывать эти действия раздельно, то следует игнорировать MotionEvent с состоянием кнопок, равным нулю (event.getButtonState() == 0).

  • NDK. Если Android-приложение использует нативные библиотеки для платформы ARM, Chrome OS будет применять x86-транслятор для запуска кода библиотеки. Это снижает производительность, поэтому разработчику следует включать в приложение библиотеки для платформ ARM, x86 и AMD64.

  • Разметка. Android уже давно позволяет использовать разную разметку и метод навигации в зависимости от ориентации и размера экрана. Поддержка разных устройств и положений экрана автоматически сделает приложение более удобным в использовании на устройствах с Chrome OS. Также стоит сделать обработчик смены разрешения в колбэке onConfigurationChanged на случай, если пользователь подключит внешний монитор.

Новые Kotlin-библиотеки

10 New Android Kotlin Libraries You Should Check Out This Winter — подборка из десяти новых, написанных на Kotlin библиотек:

  1. Dots Indicator — индикатор, показывающий текущую страницу ViewPager (или ViewPager2).
  2. CalendarView — гибкий, кастомизируемый календарь.
  3. EasyFloat — библиотека для создания плавающих окон.
  4. Timeline-View — библиотека для создания таймлайнов (событий, следующих друг за другом).
  5. Coil-Kt — библиотека загрузки изображений (аналог Picasso и Glide).
  6. Simple Calendar — еще один календарь.
  7. Material Drawer — дровер (выезжающая с левой стороны экрана панель) в стиле Material Design.
  8. What if — функция-расширение для быстрой проверки условий (в том числе в билдерах).
  9. Koin — DI-фреймворк, аналог Dagger без рефлексии.
  10. Arrow-kt — библиотека функционального программирования.

Инструменты

  • Ipwndfu — нашумевший эксплоит axi0mX для взлома загрузчиков iPhone;
  • Decrypt0r — скрипт для автоматической загрузки и расшифровки загрузочных образов iPhone (базируется на эксплоите axi0mX);
  • MOBEXLER — виртуальная машина для пентеста мобильных приложений;
  • Amtracker — инструмент для идентификации семейств малвари;
  • Android-device-check — набор скриптов для проверки настроек безопасности устройства.

Библиотеки

  • SurveyKit — библиотека для создания опросов в стиле ResearchKit для iOS;
  • AddressPicker — простая библиотека для выбора адреса с помощью Google Maps;
  • PinLockView — библиотека для ввода PIN-кодов;
  • Insetter — библиотека для работы с Window Insets (обработки состояний изменения границ экрана приложения);
  • Beagle — инструмент для отладки приложения прямо на устройстве;
  • OkReplay — OkHttp-библиотека для записи и воспроизведения ответов сервера в Unit-тестах;
  • Formula — реактивный фреймворк для управления состоянием фрагментов;
  • Http4k — фреймворк для создания серверных HTTP-приложений на Kotlin по принципу Server as function;
  • Flipper — библиотека для включения/отключения отдельных функций приложения в зависимости от билда или настроек;
  • Uniflow-kt — библиотека data flow для Kotlin;
  • SmoothBottomBar — анимированная панель навигации в нижней части экрана;
  • ElegantDialog — красивый диалог.

Читать новость в источнике Xakep

0