Долгое время Android имел славу медленной, небезопасной и в целом убогой ОС, предназначенной для тех, кто не смог накопить на iPhone. Но так ли это сейчас и был ли Android на самом деле так плох? В этой статье мы не будем касаться плавности работы интерфейса и возможностей ОС, но проследим за историей едва ли не самой больной части Android — системы безопасности.
Безопасность Android
Понять смысл и назначение защитных механизмов Android проще всего в ретроспективе. А именно — изучив, как была реализована защита (или ее отсутствие) в первых версиях ОС и как и зачем она менялась впоследствии.
Итак, Android 1.0 — платформа, выпущенная осенью 2008 года вместе со смартфоном HTC Dream (T-Mobile G1). Безопасность обеспечивается пятью ключевыми подсистемами.
1. PIN-код экрана блокировки для защиты от несанкционированного физического доступа.
2. Песочницы (изолированная среда исполнения) для приложений. Каждое приложение запускается от имени созданного специально для него пользователя Linux. Приложение имеет полный контроль над файлами своей песочницы ( /data/data/имя.пакета), но не может получить доступ к системным файлам и файлам других приложений. Единственный способ покинуть песочницу — получить права root.
3. Каждое приложение обязано указывать список нужных для его работы полномочий в манифесте. Полномочия позволяют использовать те или иные системные API (доступ к камере, микрофону, сети и так далее). Хотя соблюдение полномочий контролируется на нескольких уровнях, включая ядро Linux, явно запрашивать их у пользователя не нужно; приложение автоматически получает все перечисленные в манифесте полномочия, и пользователю остается либо установить приложение, предоставив ему все полномочия, либо не устанавливать его вовсе.
Контроль доступа на основе полномочий не распространяется на карты памяти и USB-накопители. Они используют файловую систему FAT, которая не позволяет назначить права доступа к файлам. Любое приложение может читать содержимое всей карты памяти.
4. Приложения должны быть подписаны ключом разработчика. Во время установки новой версии приложения система сверяет цифровые подписи старой и новой версий приложения и не допускает установку, если они не совпадают. Такой подход позволяет защитить пользователя от фишинга и кражи данных, когда троян прикидывается легитимным приложением и после «обновления» получает доступ к файлам оригинального приложения.
5. Язык Java и виртуальная машина обеспечивают защиту от многих типов атак, перед которыми уязвимы приложения на небезопасных языках, таких как C и C++. Переполнение буфера или повторное использование освобожденной памяти в Java невозможны в принципе.
В то же время значительная часть операционной системы, включая системные сервисы, виртуальную машину, мультимедийные библиотеки, систему рендеринга графики, а также все сетевые подсистемы, написана на тех самых небезопасных C и C++ и работает с правами root. Уязвимость в одном из этих компонентов может быть использована для получения полного контроля над ОС или выполнения DoS-атаки. HTC Dream был «взломан» благодаря тому, что сервис Telnet, предустановленный на смартфон, работал с правами root. Все, что нужно было сделать, — это найти способ его запустить, а затем к смартфону можно было подключиться по сети и получить шелл-доступ с правами суперпользователя.
РЕКОМЕНДУЕМ:
Защита от метарефлексии в Android 11
Если же говорить о стандартных приложениях, то они хоть и не имели прав root и работали под защитой виртуальной машины в собственной песочнице, так или иначе обладали очень широкими возможностями, свойственными десктопным операционным системам. При наличии нужных прав стороннее приложение могло сделать очень многое: прочитать списки СМС и звонков, прочитать любые файлы на карте памяти, получить список установленных приложений, работать в фоне неограниченное время, выводить графику поверх окон других приложений, получать информацию практически обо всех системных событиях (установка приложения, включение-выключение экрана, звонок, подключение зарядного устройства и многое другое).
Строго говоря, все эти API не были уязвимостями в прямом смысле слова. Наоборот, они открывали широкие возможности для программистов и, как следствие, пользователей. Но если в 2008-м эти возможности не создавали особых проблем, поскольку рынок смартфонов был ориентирован на энтузиастов и бизнесменов, то уже через несколько лет, когда смартфоны получили распространение среди всех групп населения, стало понятно, что приложения необходимо ограничивать в возможностях.
Полномочия
Есть два способа ограничить приложения в правах и не дать им влиять на систему и пользовательские данные:
- Урезать возможности всех приложений до минимума, как это было сделано в J2ME.
- Позволить пользователю контролировать доступные приложению возможности (путь iOS).
Android, несмотря на мощную систему разделения полномочий внутри ОС, не позволял ни того, ни другого. Первые намеки на систему гранулярного контроля полномочий появились только в Android 4.3 вместе со скрытым разделом настроек App Opps.
С помощью этих настроек пользователь мог отозвать у приложения любые доступные ему полномочия по отдельности. Однако назвать эту систему удобной и дружелюбной пользователю нельзя: управление разрешениями было чересчур гранулярным, приходилось ориентироваться среди десятков разрешений, смысл которых часто оставался непонятен. При этом отзыв любого разрешения мог привести (и часто приводил) к падению приложения, так как в Android просто не было API, который бы позволил программисту понять, имеет его приложение разрешение на выполнение того или иного действия или нет. В итоге систему App Ops удалили из Android уже в версии 4.4.2, и только в Android 6 ей на смену пришла существующая до сих пор система полномочий.
В этот раз инженеры Google пошли другим путем и объединили смежные полномочия, получив в итоге семь метаполномочий, которые могут быть запрошены прямо во время работы приложения. В основе системы лежал новый API, позволивший программистам проверять доступные приложению полномочия и запрашивать их, когда нужно.
Побочным эффектом такого подхода стала… бесполезность новой системы. Дело в том, что она работала исключительно для приложений, собранных под Android 6.0 и выше. Разработчик приложения мог указать в правилах сборки директиву targetSdkVersion 22 (то есть Android 5.1), и его приложение продолжило бы получать все полномочия в автоматическом режиме.
Google была вынуждена реализовать систему именно таким образом, чтобы сохранить совместимость со старым софтом. По-настоящему система начала действовать только спустя два года, когда Google ввела требование минимального SDK в Google Play, то есть просто запретила публиковать приложения, собранные для устаревших версий ОС. Окончательно решили вопрос только в Android 10: стало возможно отзывать полномочия у софта, собранного для Android 5.1 и ниже.
В Android 11 система полномочий была расширена и теперь позволяет предоставлять разрешение на ту или иную операцию только на один раз. Как только приложение будет свернуто, оно потеряет разрешение, и его придется запрашивать снова.
Ограничения
Система управления разрешениями — только часть решения проблемы. Вторая часть — запреты на использование опасных API. Можно долго спорить, стоит ли позволять сторонним приложениям получать IMEI телефона с помощью разрешений, или необходимо запретить делать это вовсе. Для Google, входящей в эпоху тотального помешательства на прайваси, ответ был очевиден.
Несмотря на то что компания и раньше вводила запреты на использование тех или иных API (можно вспомнить, например, запрет на включение режима полета и подтверждение отправки СМС на короткие номера в Android 4.2), активные боевые действия начались только в 2017 году.
Начиная с восьмой версии Android скрывает многие идентификаторы устройства от приложений и других устройств. Android ID ( Settings.Secure.ANDROID_ID) — уникальный идентификатор Android теперь различен для каждого установленного приложения. Серийный номер устройства ( android.os.Build.SERIAL) недоступен приложениям, собранным для Android 8 и выше. Содержимое переменной net.hostname пусто, а DHCP-клиент никогда не посылает хостнейм DHCP-серверу. Стали недоступны некоторые системные переменные, например ro.runtime.firstboot (время последней загрузки).
С Android 9 приложения больше не могут прочитать серийный номер устройства без полномочия READ_PHONE_STATE. В Android 10 появилось ограничение на доступ к IMEI и IMSI. Чтобы прочитать эту информацию, теперь требуется разрешение READ_PRIVILEGED_PHONE_STATE, недоступное сторонним приложениям.
Для получения MAC-адреса Bluetooth в Android 8 и выше требуется разрешение LOCAL_MAC_ADDRESS, а MAC-адрес Wi-Fi рандомизируется при проверке доступных сетей (чтобы избежать трекинга пользователей, например покупателей в торговых центрах).
В Android 9 Google пошла намного дальше и запретила использовать камеру, микрофон и любые сенсоры, пока приложение находится в фоне (оставив возможность использовать камеру и микрофон «видимым сервисам» — foreground service). В Android 10 к этим ограничениям добавился запрет на доступ к местоположению в фоне (теперь для этого нужно разрешение ACCESS_BACKGROUND_LOCATION) и запрет на чтение буфера обмена в фоне (нужно разрешение READ_CLIPBOARD_IN_BACKGROUND).
Еще одно важное нововведение Android 9 — полный запрет на использование HTTP без TLS (то есть без шифрования) для всех приложений, собранных для новой версии Android. Это ограничение тем не менее можно обойти, если указать в файле настроек безопасности сети ( network_security_config.xml) список разрешенных доменов.
Android 10 ввел запрет на запуск активностей (по сути — запуск приложений) фоновыми приложениями. Исключения сделаны для bound-сервисов, таких как Accessibility и сервисы автозаполнения. Приложения, использующие разрешение SYSTEM_ALERT_WINDOW, и приложения, получающие имя активности в системном PendingIntent, тоже могут запускать активности в фоне. Также приложения теперь не могут запускать бинарные файлы из собственного приватного каталога. Это уже привело к проблемам в работе популярного приложения Termux.
С Android 11 приложения больше не могут получить прямой доступ к карте памяти (внутренней или внешней) с помощью разрешений READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE. Вместо этого следует использовать либо личный каталог приложения внутри /sdcard/Android (он создается автоматически и не требует разрешений), либо Storage Access Framework, не допускающий доступ к данным других приложений.
Интересно, что Google ограничивает сторонние приложения не только средствами операционной системы. В конце 2018 года в Google Play появилось требование, гласящее, что все приложения, использующие разрешения на чтение СМС и журнала звонков, должны относиться к одному из разрешенных типов приложений и в обязательном порядке проходить ручную премодерацию. В результате из маркета удалили многие полезные инструменты, авторы которых просто не смогли обосновать перед Google необходимость использовать те или иные разрешения.
Шифрование данных
Права доступа и другие ограничения времени исполнения — хорошая защита до тех пор, пока злоумышленник не получит физический доступ к устройству. Но что будет, если забытый пользователем смартфон попадет в руки подготовленного хакера? Многие устройства во времена первых версий ОС имели уязвимости в загрузчике или не блокировали его вовсе. Поэтому снять дамп NAND-памяти было проще простого.
Для борьбы с этой проблемой в Android 3.0 появилась встроенная функция шифрования данных, основанная на проверенном годами и сотнями тысяч пользователей модуле Linux-ядра dm-crypt. С Android 5 эта функция стала обязательной, то есть Google потребовала включить ее для всех устройств с поддержкой хардварного ускорения шифрования (это в первую очередь 64-битные процессоры ARM).
Система шифрования была достаточно стандартной. Раздел userdata шифровался с помощью модуля dm-crypt алгоритмом AES-128 в режиме CBC с привлечением функции ESSIV:SHA256 для получения векторов инициализации (IV). Ключ шифрования был защищен с помощью KEK-ключа, который мог быть получен из PIN-кода с помощью прогонки через функцию scrypt или сгенерирован случайным образом и сохранен в TEE. При этом, если пользователь купил смартфон на базе Android 5.0 с активированным по умолчанию шифрованием и затем установил PIN-код, последний также использовался для генерации KEK.
Функция scrypt для получения ключа из PIN-кода используется с Android 4.4. Она заменила ранее применявшийся алгоритм PBKDF, уязвимый для подбора на GPU (шестизначный цифровой PIN за десять секунд, шестизначный знаковый — четыре часа с помощью hashcat), тогда как scrypt, по заявлению создателей, увеличивал время подбора примерно в 20 000 раз и вообще не подходил для GPU из-за высоких требований к памяти.
К сожалению, при всех стараниях Google система полнодискового шифрования (FDE — Full Disk Encryption) продолжала страдать от ряда концептуальных недостатков.
- FDE не позволяло использовать разные ключи шифрования для разных областей данных и пользователей. Например, зашифровать раздел Android for Work с помощью корпоративного ключа предприятия или расшифровать критические для основной функциональности смартфона данные без запроса пароля пользователя.
- Посекторное шифрование сводило на нет все оптимизации, реализованные на уровне драйверов файловых систем. Устройство практически непрерывно выполняло расшифровку секторов и зашифровывало их вновь, модифицируя содержимое раздела. Поэтому с FDE всегда заметно падала производительность и сокращалось время автономной работы устройства.
- FDE не поддерживало проверку подлинности содержимого секторов. Их слишком много, и среди них время от времени появляются сбойные, переназначаемые контроллером в резервную область.
- Криптографическая схема AES-CBC-ESSIV была уязвимой к утечке данных, так как допускала определение точки их изменения. Она позволяла выполнять атаки подмены и перемещения.
Решением стала система пофайлового шифрования в Android 7 (FBE — File-Based Encryption). Она использует функцию шифрования файловых систем ext4 и F2FS для раздельного шифрования каждого файла по алгоритму AES, но уже в другом режиме — XTS. Этот режим разрабатывался специально для шифрования блочных устройств и не имеет типичных для режима CBC уязвимостей. В частности, XTS не позволяет определить точку изменения данных, не подвержен утечке данных, устойчив к атакам подмены и перемещения.
Вплоть до последнего времени Google позволяла производителям смартфонов использовать любой механизм шифрования, но с Android 10 FBE стало обязательным. Более того, начиная с Android 9 шифрование обязательно не только для устройств с хардварной поддержкой шифрования, но и вообще для всех устройств.
Такая возможность появилась благодаря разработанному в Google механизму шифрования Adiantum. Он базируется на применении быстрой хеш-функции NH, алгоритме аутентификации сообщений (MAC) Poly1305 и потоковом шифре XChaCha12. В тестах на процессоре ARM Cortex-A7 Adiantum показывает пятикратное превосходство в скорости шифрования над AES-256-XTS.
Доверенная среда исполнения
Важным новшеством системы шифрования Android 5 стала возможность хранить ключ шифрования в доверенной среде исполнения (Trusted Execution Environment — TEE). Речь идет о выделенном микрокомпьютере внутри мобильного чипа или рядом с ним. Он имеет собственную ОС и отвечает исключительно за шифрование данных и хранение ключей шифрования. Доступ к такому микро-ПК имеет лишь небольшой сервис внутри основной системы, так что компрометация системы не приводит к утечке самих ключей.
Наиболее известная реализация TEE — TrustZone, которая используется в чипсетах Qualcomm (ее, кстати, уже взламывали). Другие производители могут взять собственные. Например, в смартфонах Samsung это реализация TEE под управлением операционной системы Kinibi, разработанной компанией Trustsonic (Samsung Galaxy S3–S9), либо системы TEEGRIS, за авторством инженеров самой Samsung (Samsung Galaxy S10 и выше).
Смартфоны линейки Pixel (начиная с Pixel 3/3XL) используют выделенный чип Titan M, который разработала и производит сама Google. Это мобильная версия серверного чипа Titan, в ней в том числе хранятся ключи шифрования и счетчик откатов, который использует система доверенной загрузки Verified Boot (о ней чуть позже), а также реализована функция Android Protected Confirmation, позволяющая математически доказать, что пользователь действительно увидел диалог подтверждения и что ответ на этот диалог не был перехвачен и изменен. Чип имеет прямую электрическую связь с боковыми клавишами смартфона и блокирует их при попытках взлома.
Titan M — своего рода аналог чипа Secure Enclave, который Apple уже несколько лет предустанавливает в собственные смартфоны. Благодаря тому что Titan M — это выделенный микрокомпьютер (на базе ARM Cortex-M3), не связанный с основным процессором, он устойчив к атакам типа Rowhammer, Spectre и Meltdown.
Доверенная загрузка
Еще в Android 4.4 Google реализовала механизм Verified Boot. На каждом этапе загрузки «первичный загрузчик → вторичный → aboot → ядро Linux → система Android» операционная система проверяет целостность следующего компонента (загрузчики по цифровым подписям, ядро по контрольной сумме, систему по контрольной сумме ФС) и может предпринять действия, если компонент был изменен.
Долгое время механизм находился в стадии развития и только с выпуском Android 7 научился полагаться на хардварное хранилище ключей (TEE) и запрещать загрузку при компрометации одного из компонентов (если этого захочет производитель устройства).
Начиная с Android 8 в составе Verified Boot появилась официальная реализация защиты от даунгрейда, когда система явно запрещает установку старых версий прошивок.
Даунгрейд опасен тем, что может быть использован для получения доступа к смартфону с помощью «возвращения старых багов». Допустим, человек украл телефон, понял, что он зашифрован, запаролен, а загрузчик заблокирован. Кастомную прошивку установить не получится (не совпадают сертификаты), но можно откатить смартфон к старой версии официальной прошивки, в которой был баг, позволяющий обойти блокировщик экрана (такой был в прошивке Samsung, например), и с его помощью получить доступ к содержимому смартфона.
Защита от срыва стека
Шифрование данных и режим доверенной загрузки спасут от злоумышленника, который не сможет обойти экран блокировки и попытается снять дамп с уже выключенного устройства или загрузить устройство с альтернативной прошивкой. Но они не защитят от эксплуатации уязвимостей в уже работающей системе.
Уязвимости в ядре, драйверах и системных компонентах зачастую позволяют получить права root. Поэтому Google занялась укреплением этих компонентов почти сразу после релиза первой версии Android.
В Android 1.5 системные компоненты были переведены на использование библиотеки safe-iop, реализующей функции безопасного выполнения арифметических операций над целыми числами (защита от integer overflow). Из OpenBSD была позаимствована реализация функции dmalloc, затрудняющая атаки с задействованием двойного освобождения памяти и атаки согласованности чанков, а также функция calloc с проверкой на возможность целочисленного переполнения во время операции выделения памяти.
Весь низкоуровневый код Android с версии 1.5 собирается с применением механизма компилятора GCC ProPolice для защиты от срыва стека на этапе компиляции. Начиная с версии 2.3 в коде задействованы «железные» механизмы защиты от срыва стека (бит No eXecute (NX), доступный с ARMv6).
РЕКОМЕНДУЕМ:
Какую информацию сливают китайские Android смартфоны
В Android 4.0 Google внедрила в Android технологию Address space layout randomization (ASLR), которая позволяет расположить в адресном пространстве процесса образ исполняемого файла, подгружаемых библиотек, кучи и стека случайным образом. Благодаря этому эксплуатация многих типов атак существенно усложняется, так как атакующему приходится угадывать адреса перехода для выполнения атаки. Кроме того, с версии 4.1 Android собирают с использованием механизма RELRO (Read-only relocations), который позволяет защитить системные компоненты от атак, основанных на перезаписи секций загруженного в память ELF-файла. С Android 8 поддержка ASLR также распространяется на ядро. В Android 4.2 появилась поддержка механизма FORTIFY_SOURCE, позволяющего отследить переполнение буфера в функциях копирования памяти и строк.
Начиная с ядра Linux 3.18 в Android включен софтверный вариант функции PAN (Privileged Access Never), защищающий от прямого доступа к памяти процессов из режима ядра. Хотя само ядро обычно не использует эту возможность, некорректно написанные драйверы могут это делать, что приводит к появлению уязвимостей.
Все ядра 3.18 и выше также включают функцию Post-init read-only memory. Она помечает участки памяти, которые были доступны для записи во время инициализации ядра, как read-only уже после инициализации.
Начиная с восьмой версии Android собирают с применением технологии Control Flow Integrity (CFI), предназначенной для борьбы с эксплоитами, использующими технику ROP (Return Oriented Programming). При включении CFI компилятор строит граф вызовов функций и встраивает код сверки с этим графом перед каждым вызовом функции. Если вызов происходит по отклоняющемуся от графа адресу, приложение завершается.
В Android 9 использование CFI расширилось и покрывает медиафреймворки, а также стек NFC и Bluetooth. В Android 10 поддержка была реализована для самого ядра.
Похожим образом работает технология Integer Overflow Sanitization (IntSan), предназначенная для защиты от целочисленного переполнения. Компилятор встраивает в результирующий код приложений функции проверки — подтвердить, что исполняемая арифметическая операция не вызовет переполнения.
Впервые технология была использована в Android 7 для защиты медиастека, в котором обнаружили целый комплекс удаленных уязвимостей Stagefright. В Android 8 она также используется для защиты компонентов libui, libnl, libmediaplayerservice, libexif, libdrmclearkeyplugin и libreverbwrapper. В Android 10 проверками удалось покрыть 11 медиакодеков и стек Bluetooth. По словам разработчиков, уже существовавшие в Android 9 проверки позволили нейтрализовать 11 различных уязвимостей.
В Android 7 медиастек был разделен на множество независимых сервисов, каждый из который имеет только необходимые ему полномочия. Идея здесь в том, что уязвимости Stagefright были найдены в коде медиакодеков, которые теперь не имеют доступа к интернету, так что не могут быть проэксплуатированы удаленно. Подробнее об этом можно почитать в блоге Google.
Начиная с Android 10 медиакодеки используют аллокатор памяти Scudo, затрудняющий атаки типа use-after-free, double-free и переполнение буфера.
SELinux
Еще один большой шаг в сторону защиты от возможных уязвимостей в системных компонентах ОС — технология SELinux.
SELinux разработана Агентством национальной безопасности США и уже давно используется во многих корпоративных и настольных дистрибутивах Linux для защиты от самых разных видов атак. Одно из основных применений SELinux — ограничить приложениям доступ к ресурсам ОС и данным других приложений.
С помощью SELinux можно, например, сделать так, чтобы веб-сервер имел доступ только определенным файлам и диапазону портов, не мог запускать бинарные файлы, помимо заранее оговоренных, и имел ограниченный доступ к системным вызовам. По сути, SELinux запирает приложение в песочницу, серьезно ограничивая возможности того, кто сможет его взломать.
Вскоре после появления на свет Android разработчики SELinux начали проект SEAndroid. Его суть — перенести систему в мобильную ОС и разработать правила SELinux для защиты ее компонентов. Начиная с версии 4.2 наработки этого проекта входят в состав Android, но на первых порах (версия 4.2–4.3) они использовались исключительно, чтобы собирать информацию о поведении компонентов системы (а затем составить правила). В версии 4.4 Google перевела систему в активный режим, но с мягкими ограничениями для нескольких системных демонов (installd, netd, vold и zygote). На полную же катушку SELinux заработал только в Android 5.
В Android 5 предусмотрено более 60 доменов SELinux (проще говоря — правил ограничений) почти для каждого системного компонента, начиная от первичного процесса init и заканчивая пользовательскими приложениями. На практике это означает, что многие векторы атак на Android, которые в прошлом использовались как самими пользователями для получения root, так и разного рода малварью, больше не актуальны.
Так, уязвимость CVE-2011-1823, имевшая место во всех версиях Android до 2.3.4 и позволяющая вызвать memory corruption в демоне vold, а далее передать управление шеллу с правами root (эксплоит Gingerbreak), не могла бы быть использована, будь она найдена в Android 5 — здесь, согласно правилам SELinux, vold не имеет права запускать другие бинарные файлы. То же самое справедливо и для уязвимости CVE-2014-3100 в Android 4.3, позволяющей вызвать переполнение буфера в демоне keystore, и 70% других уязвимостей.
SELinux значительно снижает риск, что злоумышленник захватит устройство, проэксплуатировав уязвимости в низкоуровневых компонентах системы (многочисленных написанных на С и С++ демонах, исполняемых от имени root), но в то же время затрудняет получение root, так сказать, «для себя». Более того, отныне права root сами по себе не гарантируют полного контроля над системой, так как для SELinux нет разницы между обычным юзером и суперпользователем.
Seccomp-bpf
Seccomp — еще одна технология ядра Linux, позволяющая ограничить список доступных приложению (и в перспективе опасных) системных вызовов. С помощью seccomp можно, например, запретить приложению использовать системный вызов execve, который часто применяют эксплоиты, или заблокировать системный вызов listen, дающий возможность повесить на сетевой порт бэкдор. Именно seccomp лежит в основе системы изоляции вкладок в браузере Chrome для Linux.
Технология использовалась в Android с седьмой версии, но применялась исключительно к системным компонентам. В Android 8 seccomp-фильтр был внедрен в Zygote — процесс, который порождает процессы всех установленных в систему приложений.
Разработчики проанализировали, какие системные вызовы нужны для загрузки ОС и работы большинства приложений, а затем отсекли лишние. В итоге в черный список попали 17 системных вызовов из 271 на ARM64 и 70 из 364 на ARM.
Пример использования Seccomp в сервисе MediaExtractor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
static const char kSeccompFilePath[] = "/system/etc/seccomp_policy/mediaextractor-seccomp.policy"; int MiniJail() { struct minijail *jail = minijail_new(); minijail_no_new_privs(jail); minijail_log_seccomp_filter_failures(jail); minijail_use_seccomp_filter(jail); minijail_parse_seccomp_filters(jail, kSeccompFilePath); minijail_enter(jail); minijail_destroy(jail); return 0; } |
Файл mediaextractor-seccomp.policy:
1 2 3 4 5 6 7 8 9 10 11 12 |
ioctl: 1 futex: 1 prctl: 1 write: 1 getpriority: 1 mmap2: 1 close: 1 10munmap: 1 dupe: 1 mprotect: 1 getuid32: 1 setpriority: 1 |
Google Play Protect
В феврале 2012 года Google включилась в борьбу со зловредными приложениями: начал работать сервис онлайн-проверки приложений Bouncer. Он запускал каждое публикуемое в Google Play приложение в эмуляторе и прогонял через многочисленные тесты в поисках подозрительного поведения.
В ноябре того же года появился сервис онлайн-проверки софта на вирусы прямо на устройстве пользователя (Verify Apps). Изначально он работал только на 4.2, но к июлю 2013-го был интегрирован в пакет Google Play Services и стал доступен для всех устройств от 2.3. С апреля 2014-го проверка выполянется не только на этапе установки приложения, но и по расписанию, а с 2017 года за проверками можно следить через интерфейс системы под названием Google Play Protect (раздел «Безопасность»).
Вместе с новым интерфейсом Google вытащила наружу еще несколько индикаторов работы антивируса. Версия Play Store для Android 8 и выше показывает статус проверки приложения на странице приложения, а также выводит красивый зеленый щит с надписью «Все хорошо, парень, ты защищен» в списке установленных приложений.
Проблема здесь только в том, что согласно тесту антивирусов за март 2020 года Google Play Protect занимает последнее место в рейтинге, обнаружив только 47,8% новых вирусов (не старше четырех недель). Это мало, даже если учитывать, что Google не может применять для обнаружения такие же эвристические алгоритмы, как у других антивирусов (большинство антивирусов считают подозрительными даже приложения, имеющие права на отправку СМС).
Smart Lock
Сегодняшний пользователь привык к датчикам отпечатков пальцев и сканированию лица для разблокировки смартфона, но шесть лет назад заставить пользователя защитить смартфон с помощью PIN-кода или пароля было сложно. Поэтому инженеры Google создали не самую надежную (а в некоторых случаях и совсем ненадежную), но действенную систему под названием Smart Lock.
Появившийся в Android 5 Smart Lock — это механизм для автоматического отключения защиты экрана блокировки после подключения к одному из Bluetooth-устройств (умные часы, автомагнитола, TV box) на основе местоположения или по снимку лица. Фактически это официальная реализация функций, которые неофициально были доступны в сторонних приложениях (например, SWApp Link для разблокировки с помощью часов Pebble) и прошивках от производителей (мотороловский Trusted Bluetooth).
Теперь функциональность этих приложений доступна в самом Android, а все, что остается сделать пользователю, — установить на экран блокировки PIN-код, ключ или пароль, активировать Smart Lock в настройках безопасности и добавить доверенные Bluetooth-устройства, места и лица.
По словам Google, Smart Lock позволил поднять уровень использования паролей для блокировки экрана среди пользователей в два раза. Однако стоит иметь в виду, что из всех методов разблокировки, доступных в Smart Lock, более-менее надежным можно считать только разблокировку с помощью устройства Bluetooth. И это только в том случае, если твоя цель — защитить украденное устройство, а не отстаивать перед полицейским свое право на частную жизнь.
Итого: сегодня Android использует три вида разблокировки экрана с разным уровнем надежности и, соответственно, уровнем доступа:
- Пароль или PIN-код — считается наиболее надежным и поэтому дает полный контроль над устройством без всяких ограничений.
- Отпечаток пальца или снимок лица — менее надежный, система запрашивает пароль после каждой перезагрузки телефона, а также через каждые 72 часа.
- Smart Lock — наименее надежный метод, поэтому на него накладываются те же ограничения, что и на биометрический метод, плюс он не позволяет получить доступ к аутентификационным ключам Keymaster (например, тем, что используются для платежей), а пароль запрашивается не через 72 часа, а уже через четыре.
WebView
С первых версий Android включал в себя компонент WebView на базе WebKit, позволяющий сторонним приложениям использовать HTML/JS-движок для отображения контента. На нем же базировалось большинство сторонних браузеров.
В Android 4 WebView был серьезно модернизирован и заменен на движок из проекта Chromium (версия 33 в Android 4.4.3). С пятой версии WebView не просто базируется на Chromium, а еще и умеет обновляться через Google Play (в автоматическом режиме, незаметно для пользователя). Это значит, что Google может закрывать уязвимости в движке так же быстро, как уязвимости в Google Chrome для Android. Все, что потребуется от пользователя, — это подключенный к интернету смартфон с Android 5 или выше.
С Android 8 рендерер-процесс WebView изолирован с помощью Seccomp. Он работает в очень ограниченной песочнице, которая не допускает обращения к постоянной памяти и сетевым функциям. Кроме того, WebView теперь также может использовать технологию Safe browsing, знакомую всем пользователям Chrome. Safe browsing предупреждает о потенциально небезопасных сайтах и требует явно подтвердить переход на такой сайт.
SafetyNet
Начиная с Android 7 в Google Play Services есть API под названием SafetyNet, который выполняет одну простую задачу: проверяет, оригинальное ли устройство (сверяет серийные номера), не была ли его прошивка изменена и есть ли у пользователя права root. Используя этот API, разработчики могут писать приложения, которые в принципе не заработают на модифицированных прошивках или, к примеру, прошивках, давно не получавших исправления безопасности (patch level).
Долгое время SafetyNet определяла надежность устройства с помощью эвристических методов, которые всегда можно было обмануть: Magisk успешно скрывал наличие root и факт разблокировки загрузчика от SafetyNet на протяжении нескольких лет.
С недавнего времени SafetyNet перестал полагаться на простую проверку состояния загрузчика (которую умеет обманывать Magisk), а вместо этого использует приватный ключ шифрования из защищенного хранилища KeyStore, чтобы подтвердить достоверность переданных данных. Обойти эту защиту можно, лишь получив доступ к приватному ключу, который хранится в выделенном криптографическом сопроцессоре (TEE), а сделать это практически невозможно.
Все это означает, что совсем скоро все сертифицированные Google устройства на базе Android 8 и выше просто перестанут проходить проверку SafetyNet и Magisk будет бесполезен при работе с банковскими клиентами и другими приложениями, использующими SafetyNet.
Kill Switch
В августе 2013 года Google запустила веб-сервис Android Device Manager, с помощью которого пользователи получили возможность заблокировать смартфон или сбросить его до заводских настроек. В качестве клиентской части на смартфоне сервис использовал обновляемый через Google Play компонент Google Play Services, поэтому функция стала доступна для любых устройств начиная с Android 2.3.
С Android 5 в сервис также включена функция Factory Reset Protection. После ее активации возможность сброса до заводских настроек будет заблокирована паролем, что, по мнению Google, помешает полноценному использованию смартфона или его продаже. Ведь однажды привязанный к аккаунту Google смартфон уже не может быть отвязан без сброса настроек.
Проблема здесь только в том, что загрузчик большинства смартфонов можно разблокировать вполне официально. А после этого его можно полностью перепрошить.
Выводы
Усилия Google в итоге дали результат. Большую часть уязвимостей в смартфонах теперь находят не в самом Android, а в драйверах и прошивках конкретных устройств. По общему количеству уязвимостей Android уже плетется позади iOS, а цены за сами уязвимости в Android превысили цены за уязвимости в iOS.
РЕКОМЕНДУЕМ:
Динамические и модульные обновления Android
Современный смартфон на Android (если, конечно, это не китайский ширпотреб) неприступен практически со всех сторон. С него не получится снять дамп памяти, его нельзя окирпичить, выполнить даунгрейд, взломать с помощью обхода экрана блокировки. Ослабить всю эту систему защиты способен лишь сам производитель устройства.