Следующая новость
Предыдущая новость

Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга

01.11.2018 13:02
Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга

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

  • Инструменты
  • Почитать
  • Titan M: security-чип в смартфонах Pixel
  • Control Flow Integrity для ядра Linux
  • Уроки фаззинга
  • Смартфон, ворующий рекламные деньги
  • Разработчику
  • Kotlin и его типы
  • Управляем приоритетами потоков
  • Contracts — новая функция Kotlin 1.3
  • Цифровые подписи APK: прошлое и настоящее
  • Пять библиотек анимации
  • Библиотеки

Сегодня в выпуске: новый security-чип в смартфоне Pixel 3, защита от атак с использованием ROP в ядре Linux, уроки фаззинга, смартфон, ворующий рекламные деньги, прошлое, настоящее и будущее пакетов APK. А также несколько статей для программистов: управление приоритетами потоков, разбор системы типов Kotlin и рассказ о Contracts — новой функции Kotlin 1.3.

Инструменты

  • android-device-check — скрипт для проверки настроек безопасности смартфона на Android;
  • AES Killer — плагин Burp Suite для расшифровки трафика мобильных приложений с помощью ключа, извлеченного из приложения;
  • awesome-iot-hacks — коллекция ссылок на информацию о багах различных IoT-устройств.

Почитать

Titan M: security-чип в смартфонах Pixel

Building a Titan: Better security through a tiny chip — рассказ о security-чипе Titan M, который используется в смартфонах Pixel 3 и Pixel 3 XL. Чип разработан и производится самой Google, а в число его функций входят:

  • хранение счетчиков откатов, используемых системой доверенной загрузки Android Verified Boot;
  • хранение секретных данных и ограничение попыток доступа к ним с помощью Weaver API;
  • реализация функций модуля Strongbox Keymaster, который отвечает в том числе за хранение и генерацию ключей шифрования, а также за функцию Android Protected Confirmation, позволяющую математически доказать, что пользователь действительно увидел тот или иной диалог подтверждения и что ответ на этот диалог не был перехвачен и каким-либо образом изменен;
  • обеспечение работы механизмов защиты от сброса до заводских настроек, который не позволяет третьим сторонам использовать потерянный или украденный смартфон.

По сути, Titan M — это аналог Secure Enclave, который Apple уже несколько лет предустанавливает в свои смартфоны. Благодаря тому что Titan M — это выделенный микрокомпьютер (на базе ARM Cortex-M3), не связанный с основным процессором, он гораздо более устойчив к любым атакам, включая «неисправляемые» Rowhammer, Spectre и Meltdown.

Google обещает открыть код прошивки Titan M в скором времени.

Titan (слева) и Titan M (справа)

Control Flow Integrity для ядра Linux

Control Flow Integrity in the Android kernel — статья разработчиков Android о применении технологии Control Flow Integrity для защиты ядра Linux от атак с использованием метода ROP (Return Oriented Programming).

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

Технология Control Flow Integrity (CFI) предназначена для борьбы с такими эксплоитами. При ее включении компилятор строит граф вызовов функций и встраивает код сверки с этим графом перед каждым вызовом функции. Если вызов происходит по отклоняющемуся от графа адресу, приложение завершается.

Ранее разработчики Android уже включили CFI для нескольких системных компонентов в Android 8. В Android P покрытие расширилось и теперь включает в себя медиафреймворки, а также стек NFC и Bluetooth. Теперь поддержка реализована для ядра версий 4.9 и 4.14.

Уроки фаззинга

Writing the worlds worst Android fuzzer, and then improving it — занимательная статья о том, как обычно проводят фаззинг и какую информацию взломщик может получить с его помощью.

Началось все с того, что автор решил устроить фаззинг файловой системы Android и попробовать прочитать и записать во все встреченные файлы случайный набор байтов. Расчет здесь на то, что в Android (а точнее, Linux) несколько виртуальных файловых систем (/dev, /proc, /sys) хранят не реальные, а синтетические файлы, с помощью которых можно изменять настройки ядра и работать с железом.

Как оказалось, долго фаззер работать не мог и в определенный момент просто блокировался при попытке чтения файла. Чтобы решить эту проблему, автор распараллелил фаззер на 128 потоков, и… смартфон ушел в kernel panic. То же повторилось с каждым из протестированных смартфонов.

Анализ лога из /proc/last_kmsg показал, что произошло что-то вроде heap corruption, и, если поковырять дальше, можно написать эксплоит для получения прав root в системе. А DoS-эксплоит фактически уже существует.

Но что, если файла /proc/last_kmsg нет? Например, в Galaxy S5 такой файл отсутствует, а значит, мы не сможем узнать, обращение к какому файлу привело к панике ядра. В этом случае для начала сокращаем область работы фаззера, пробуем, например, только каталог /sys. Это срабатывает, проблема в одном из его файлов. Проходимся по подкаталогам и выясняем, что ядро падает при записи в один из файлов /sys/kernel, а если точнее — /sys/kernel/debug/.

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

Последним файлом оказался /sys/kernel/debug/smp2p_test/ut_remote_gpio_inout. Теперь написать DoS-эксплоит проще простого.

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

Смартфон, ворующий рекламные деньги

Avast Threat Labs finds Android device firmware that reroutes ad network revenue to unknown accounts — интересная история в блоге Avast о прошивке дешевого китайского телефона, которая не только содержит привычную всем рекламу на экране блокировки и умеет скрыто устанавливать приложения, но и перенаправляет выручку от рекламы в сторонних приложениях на другие аккаунты.

Прошивка включает в себя несколько хуков, которые срабатывают, когда то или иное приложение обращается к настройкам (SharedPreferences), файлам внутри своего пакета (AssetManager и ZipEntry) или передает данные между своими компонентами в бандлах (Bundle). Код хука ищет в полученных данных токен рекламной сети и подменяет его своим, так что все деньги от показа рекламы получает не разработчик приложения, а третье лицо.

Специалисты из Avast не сообщают модель устройства, на которое была предустановлена эта прошивка. Известно лишь, что смартфон работал на Android 6 и продавался в Европе. Хотя, судя по файлу с информацией о приложениях, токены которых перехватывала прошивка, основной целью были китайские пользователи.

Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга
Файл с информацией, какие где найти токены и на какие значения их заменить

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

Kotlin и его типы

Typical Kotlin — статья о системе типов языка Kotlin и ее особенностях. Несколько интересных моментов:

  • Nullable и не nullable типы в Kotlin — это действительно разные типы данных, причем не nullable тип — это всегда подтип nullable. Например, Double — это подтип типа Double?, а тот, в свою очередь, подтип типа Number?, который подтип типа Any?. Таким образом, значение типа Double можно сохранить в переменной типа Number?.
  • Когда ты создаешь какой-либо класс, ты автоматически создаешь его nullable или наоборот близнеца. Другими словами, объявив класс Hello, ты также объявишь тип Hello?.
  • Технически любая функция в Kotlin имеет тип возвращаемого значения. Если не указано явно, этим типом становится Unit. Вот его исходный код:
public object Unit {     override fun toString() = "kotlin.Unit" } 
  • В Koltin есть специальный тип, который не может иметь никакого значения. Это тип Nothing (и его близнец Nothing?). Функция, объявленная с возвращаемым типом Nothing, никогда не закончит исполнение, так как значение, которое нужно вернуть, не существует. Nothing удобно использовать, чтобы подсказать компилятору и среде разработки, что функция никогда не закончит свое исполнение (или закончит выбросом исключения). В этом случае среда разработки будет подсвечивать такие функции, подсказывая разработчику, что ее исполнение не закончится.
  • Nothing — это так называемый bottom type, то есть подтип любых других типов. А return и throw — это полноценные выражения, которые возвращают тип Nothing. Комбинируем эти два утверждения вместе и получаем два вполне рабочих примера кода:
fun calculate(someParam: Int?) {     val x = someParam ?: throw IllegalArgumentException("someParam must not be null")     val y = x * 2     println(y) } 
fun calculate(someParam: Int?) {     someParam ?: return     val y = someParam * 2     println(y) } 
Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга
Иерархия типов в Kotlin

Управляем приоритетами потоков

Exploring Android Thread Priority — статья о том, как Android распределяет приоритеты между потоками и как эти приоритеты изменить. Суть в следующем. В Android (а точнее, в Linux) у каждого потока исполнения есть собственный приоритет, который варьируется в пределах от –20 до 19, где меньшее число означает более высокий приоритет.

Плюс ко всему ядро Linux объединяет потоки в так называемые контрольные группы (cgroups) в зависимости от разных условий, таких, например, как видимость приложения на экране. Размещение потоков того или иного приложения в определенной группе автоматически накладывает на них ограничения. Так, потоки, помещенные в группу Background (то есть относящиеся к приложениям в фоне), получают всего 5% от общего процессорного времени.

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

  • Thread.setPriority() — принимает значения от 1 до 10, где 10 — самый высокий приоритет;
  • Process.setThreadPriority() — принимает стандартные для Android/Linux значения от –20 до 19.

Соотношение этих двух шкал приоритетов такое:

Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга

Пример изменения приоритета потока:

public class ThreadPriority {         Thread thread = new Thread(new Runnable() {             @Override             public void run() {                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                 // Твой код здесь             }         }, "worker-thread");         thread.start();     } } 

В оригинальной статье также приведены примеры изменения приоритета HandlerThread, Intent Service и других.

Contracts — новая функция Kotlin 1.3

Discovering Kotlin Contracts — статья о новинке Kotlin 1.3 под названием «контракты» (contracts). Они решают проблему, с которой сталкивался любой разработчик. Простой пример:

@Test fun testMyTokenLength() {     val token : String? = getMyToken();      assertNotNull(token)     assertEquals(42, token.length) } 

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

Error(5, 22): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

Так происходит потому, что, по мнению компилятора, token может иметь значение null, а значит, мы должны проверить его на null перед тем, как вызывать метод length. Ну либо обойти предупреждение компилятора, написав так: token!!.lenght. А это не очень красиво.

В то же время мы, в отличие от компилятора, знаем, что token к моменту вызова метода length уже не может быть null, потому что проверка на null была в прошлой строке. Контракты нужны как раз для того, чтобы передать наше знание компилятору.

Контракты базируются на идее эффектов (effects), которые представляют собой своего рода кусочки знаний, относящиеся к той или иной функции. На данный момент существует четыре эффекта:

  • Returns(value) — функция успешно завершается и/или возвращает значение такого-то типа;
  • ReturnsNotNull — функция возвращает не null значение;
  • ConditionalEffect(effect, booleanExpression) — если эффект сработал, то следующее выражение верно;
  • CallsInPlace(lambda, kind) — ограничение на место и количество вызовов лямбды.

Не стоит пытаться это понять, просто взгляни на следующий код:

fun assertNotNull(actual: Any?) {     contract { returns() implies (actual != null) }     org.junit.Assert.assertNotNull(actual) } 

Это обертка для стандартной функции assertNotNull из пакета JUnit. Мы добавили к ней контракт, который сообщает компилятору и среде разработки, что если функция успешно завершается, значит, переданное ей в аргументе значение не равно null. Если подставить эту обертку вместо оригинала в приведенный в начале пример, компилятор ругаться не будет.

Цифровые подписи APK: прошлое и настоящее

Android APK signature scheme v3: context and new opportunities — краткая история цифровых подписей приложений для Android и объяснение нового формата цифровой подписи в Android 9.

Изначально пакет с приложением для Android (APK) представлял собой почти точную копию пакета JAR, который, в свою очередь, был просто архивом ZIP с несколькими дополнительными файлами в каталоге META-INF. Эти файлы содержали список всех файлов пакета, их криптографические хеши, а также открытый криптографический ключ, с помощью которого были подписаны списки хешей.

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

Но есть проблема. Атака Janus показала, что существует возможность внедрить код в APK, не изменяя его цифровую подпись. Для этого можно дописать DEX-файл в начало секций ZIP-файла, и Android не учтет их при верификации файла, но при этом файл можно будет запустить как исполняемый: это будет одновременно и пакет с приложением, и исполняемый файл.

Для решения этой и схожих проблем Google предложила формат цифровой подписи APK signature scheme v2. Его суть в том, чтобы добавить к APK-файлу дополнительный блок, который будет содержать цифровую подпись всего APK целиком, а не отдельных его частей.

Поддержка scheme v2 появилась в Android 7, а уже в Android 9 добавилась поддержка APK signature scheme v3. Новый формат цифровой подписи похож на предыдущий, но обладает одной отличительной чертой: он поддерживает ротацию криптографических ключей. Это позволяет разработчикам без проблем менять цифровую подпись для своих приложений, не заставляя пользователей удалять старую версию приложения перед установкой новой.

Android: security-чип в смартфоне Pixel 3, защита от ROP в ядре и уроки фаззинга
APK signature scheme v1

Пять библиотек анимации

Android Top Animation Libraries — краткий обзор пяти библиотек, позволяющих реализовать анимацию в приложении:

  • Lottie for Android — парсит и рендерит анимации в формате Adobe After Effects (экспортированные в JSON с помощью Bodymovin);
  • Material Animations — эффекты перехода между активностями;
  • Android View Animations — коллекция различных эффектов анимации;
  • RecyclerView Animators — набор анимаций для RecyclerView;
  • Rebound — реализация реалистичных эффектов пружины.

Библиотеки

  • FeatureAdapter — RecyclerView-адаптер, предназначенный для создания комплексных списков;
  • FBToast — библиотека для создания сложных кастомных сообщений;
  • view-effects — добавлять различные визуальные эффекты для фона виджета (например, блюр);
  • FingerprintIdentify — библиотека для работы с датчиками отпечатков пальцев, способная работать не только с нативным API Android, но и с API Samsung и Meizu (до Android 6.0);
  • Protein — плагин Android Studio, генерирующий код — заглушки для Retrofit2 и RxJava2;
  • AppJoint — фреймворк для создания модульных приложений;
  • Krate — враппер для работы с настройками из Kotlin, выполненный с использованием делегированных переменных;
  • SnapTabLayout — реализация табов приложения в стиле Snapchat;
  • Android-GoldenEye — простая в использовании библиотека для работы с камерой;
  • Android-Goldfinger — библиотека для работы с датчиком отпечатков пальцев;
  • android-gpuimage — библиотека для обработки изображений на графическом процессоре, аналог GPUImage для iOS;
  • ok-gradle — плагин для Android Studio, запускаешь, вбиваешь имя нужной библиотеки и получаешь строку, которую необходимо добавить в build.gradle для ее подключения.

Источник

Последние новости