Безопасность связующего для Android

Является ли межпроцессное общение, предоставляемое Binder в Android, защищенным от людей в результате средних атак? Есть ли какая-либо документация, которая предоставляет эту информацию?

Ответы

Ответ 1

Binder использует модель безопасности на основе возможностей. Каждый объект связующего представляет собой возможность; передача этого объекта другому процессу предоставляет процессу доступ к этой возможности. С этой точки зрения вы предотвращаете попадание человека в средние атаки, не передавая важный объект связующего на человека посередине. Если процесс не получает объект связующего, он никак не может получить к нему доступ.

Что касается вопроса о перекрестной привязке к перекрестному связыванию, обсуждаемого в документе, если я понимаю конкретный сценарий, о котором они говорят, я думаю, что их добавление об пользовательском пространстве немного слабее, чем я бы согласился. Они делают ошибку, я думаю, глядя на специальный код С, написанный для ServiceManager. Формально я бы рассмотрел код пространства пользователя С++ (состоящий, в частности, Parcel), как часть архитектуры Binder. Этот код, в частности, обязательно будет иметь дело с такими попытками спуфинга, когда вы вызываете его readBinder() и связанные с ним методы.

Я не согласен с утверждением, что это недостаток, что ядро ​​не полностью обеспечивает целостность данных. Единственный способ, который я мог себе представить, - это определить стандартную типизированную структуру данных для транзакций связующего, чтобы она могла читать и проверять содержимое посылки. Это, по моему мнению, слишком много знаний в ядре и для реальной выгоды. Независимо от того, сколько вы там разместите, пользовательское пространство должно будет выполнить некоторую проверку входящей транзакции, чтобы убедиться, что она соответствует ее ожиданиям. Сегодня это делается на уровне проверки того, что операции примитивного чтения данных на Parcel (readBinder(), readString16(), readInt() и т.д.) Написаны для предотвращения атак. Нажатие большей проверки на ядро ​​по-прежнему потребует проверки в пространстве пользователя, что типы данных верны, и теперь вы действительно перенесли некоторые возможности для атак (из-за ошибок в этом коде) из пространства пользователя в ядро.

Одна из последних замечаний в отношении безопасности связующего заключается в том, что важно понимать, что на уровне платформы существует еще одна важная модель безопасности, реализованная поверх инфраструктуры связующего. Это система на основе разрешения /uid, где службы могут проверять uid входящих вызовов, чтобы проверить их на соответствие разрешенным разрешениям.

Эта модель безопасности имеет еще одну уязвимость, которая должна иметь дело с обманом. Типичным сценарием будет приложение, получающее IBinder для службы диспетчера активности (так как каждый может получить это). API службы Activity Manager глубоко основан на проверке uid входящих вызовов, чтобы определить, что разрешено - например, если сделан вызов bindService(), он проверяет, имеет ли этот uid разрешение на привязку к данная услуга. Злоумышленное приложение может попытаться сыграть в игры здесь, передав менеджер активности IBinder другому системному сервису, например, как IWindow в оконный менеджер. Если он знает транзакции, которые сделает вторая системная служба, он может настроить все так, чтобы он вызывал вызов, который, по его мнению, имеет значение resizeWindow(), но на самом деле становится вызовом bindService(), когда он приходит в действие менеджер (если эти два вызова сопоставляются с одним и тем же идентификатором транзакции).

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

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

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

В других случаях и объект IBinder будет использоваться совместно с любыми заинтересованными процессами, но обеспечит безопасность в точке вызова на основе uid. Если вы используете helpl для обеспечения стандартной реализации таких интерфейсов, ваша собственная реализация такой безопасности может быть выполнена на основе того, какое значение вы хотите применить к uids. Например, вы можете использовать стандартное средство для связанных разрешений с помощью uids и спросить менеджера пакетов, если входящий uid имеет разрешение.

Ответ 2

В Binder есть один выявленный недостаток безопасности, который может сделать его восприимчивым к атаке MITM: http://crypto.hyperlink.cz/files/xbinder.pdf. Чтобы указать TFA:

злоумышленник может управлять целью для дальнейшего прохождения или вызова своего защищенного связующего (что злоумышленнику не предлагается напрямую звонить). Мы называем это перекрестной привязкой подписи (XBRF)

Далее автор утверждает, что в Android против этой атаки есть защита, но

в некоторых ситуациях тщательная манипуляция данными транзакции, подготовленными атакующим процессом, может по-прежнему приводить к успешному использованию XBRF

Создается впечатление, что Binder кажется относительно безопасным для тщательно написанного кода, но существует определенный риск.