Доброг дня! Предлагаю превод описание данной уязвимости. Прошу не пиннать за перевод вдруг кому не понравится.
Опасности реализации Bluetooth: раскрытие уязвимостей нулевого дня и пробелов в сфере безопасности в современных пакетах Bluetooth.
Armis Labs Armis Labs показала новый вектор атаки, угрожающий основным мобильным, настольным и операционным системам IoT, включая Android, iOS, Windows и Linux, а также устройствам, использующим их. Новый вектор является точной копией «BlueBorne», поскольку он распространяется по воздуху и атакует устройства посредством Bluetooth. BlueBorne позволяет взломщикам осуществлять контроль над устройствами, получать доступ к корпоративным данным и сетям, взламывает систему безопасности air-gapped” networks проникать в безопасные «воздушные потоки» сети и распространять вредоносное ПО на другие устройства. Атака не требует, чтобы устройство-мишень было в видимом режиме или было сопряженно с устройством взломщика. Кроме того, пользователю-мишени не требуется авторизация или аутентификация подключения к устройству злоумышленника.
Armis Labs определила восемь уязвимостей, которые всё ещё могут использоваться как часть вектора атаки. Эти уязвимости полностью работоспособны и успешно трансформировались в эксплойты. Мы продемонстрируем это в наших будущих сообщениях блога. Это следующие уязвимости:
1. Уязвимость ядра Linux RCE - CVE-2017-1000251
2. Сведения о Linux-стеке (BlueZ) Уязвимость от утечки - CVE-2017-1000250
3. Уязвимость от утечки информации в/через Android - CVE-2017-0785
4. Уязвимость Android RCE №1 - CVE-2017-0781
5. Уязвимость Android RCE №2 - CVE-2017-0782
6. Bluetooth Pineapple в Android - Логическая ошибка CVE-2017-0783
7. Bluetooth Pineapple в Windows - логическая ошибка CVE-2017-8628
8. Уязвимость Apple Low Energy Audio Protocol RCE - CVE-2017-14315
В этой исследовательской статье рассматривается поверхность атаки attack surface по каждой из уязвимостей, раскрывая области в Bluetooth в которых они были найдены. Кроме того, в ней дается подробное объяснение внутренней работы и анализ последствий каждой уязвимости. Мы надеемся, что наши исследования помогут отслеживать другие стеки Bluetooth и выявлять дополнительные слабые места в основных реализациях стеков Bluetooth.
Признание.
Мы хотели бы поблагодарить Алона Ливна за разработку эксплойта Linux RCE.
Введение.
Bluetooth является ведущим и наиболее распространенным протоколом для ближней связи. По некоторым оценкам, в настоящее время используется более 8,2 млрд. устройств Bluetooth, и их число растет с каждым днем. Bluetooth используется в очень широком диапазоне устройств, от самых популярных среди потребителей продуктов (смартфоны, носимые устройства), до самых распространенных устройств на предприятиях (ПК, смарт-телевизоры, принтеры), и даже в объектах критической инфраструктуры в нашей повседневной жизни - медицинская техника, автомобили и многие другие. Bluetooth управляется, лицензируется и поддерживается the Bluetooth Special Interests Group (SIG) Группой особых интересов Bluetooth (SIG), которая включает в себя: участников от нескольких крупных технологических компаний, таких как Microsoft, Intel, Apple, IBM, и других.
Хотя он был впервые представлен миру в 1998 году, Bluetooth продолжает развиваться с BLE и Mesh-топологией в качестве наиболее интересных примеров. BLE (Bluetooth Low Energy) - это новый новый вариант Bluetooth. Он быстро завоевывает позиции на рынке, поскольку позволяет использовать новое поколение устройств, таких как «умные» датчики и пульты дистанционного управления, которые имеют ограниченный источник питания и пропускную способность для подключения к существующим устройствам Bluetooth, таким как смартфоны и ПК. Помимо BLE, новая функция была представлена в Bluetooth 5.0 - это Bluetooth Mesh. Эта новая функция изменяет топологию соединений Bluetooth, позволяя устройствам более низкого уровня соединяться между собой и формировать более крупные сети с более сложной и плотной структурой. Характер топологии Mesh позволяет сети Bluetooth распространяться повсюду и дает соединяться устройствам на дальних линиях связи. Эта новая функция - попытка Bluetooth SIG конкурировать с другими высокоскоростными беспроводными протоколами (такими как Zigbee, Z-Wave, LoRa и другие) в управлении постоянно расширяющимся спектром интеллектуальных устройств IoT и их уникальных требований.
Последние преобразования в области Bluetooth вместе с его долгой историей - вот что делает этот протокол основой короткого диапазона связи в подавляющем большинстве устройств на рынке. Растущая зависимость от беспроводной связи на протяжении всей нашей жизни, вероятно, превратит этот протокол в еще большую их часть и часть устройств, которые мы используем.
Итак, в чем же проблема?
Bluetooth сложен, слишком сложен. Слишком много специфических приложений определено в стеке, с бесконечной репликацией возможностей и функций. Эти чрезмерные сложности являются прямым следствием проделанной огромной работы и наличия большого колличества малополезных функций, которые были заложены в технические требования Bluetooth. В качестве наглядной иллютрации можно привести следующий пример: в то время как спецификация WiFi (802.11) составляет всего 450 страниц, спецификация Bluetooth достигает 2822 страницы.
Усложненность Bluetooth не позволяла исследователям проверять его реализации на том же уровне исследования, что и на других крайне незащищенных протоколах и внешних интерфейсах, с которыми они имели дело. Результатом отсутствия обзора является большое количество уязвимостей, таких, как те, о которых мы рассказываем в нашей статье. The complications in the specifications translate into multiple pitfall junctions Сложности в технических требованиях трансформируются в сложные объединенные ловушки в различных вариантах использования стандарта Bluetooth.
Примером необоснованной усложненности Bluetooth является фрагментация, общая концепция во многих протоколах и слабое место в каждой реализации. Спецификация Bluetooth имеет не менее 4 разных уровней фрагментации, реализованных по всему стеку, как показано в соедующей диаграмме, взятой из спецификации:
Диаграмма
Помимо уровня фрагментации, который существует только внутри хост-машины (уровень драйвера USB), от радио уровня (Link Controller) до уровня L2CAP Bluetooth имеет в общей сложности 3 уровня фрагментации (а также дополнительные уровни фрагментации существуют и в некоторых услугах Bluetooth):
● фрагментация воздушных пакетов в контроллере Link;
● фрагментация уровня HCI (продолжение уровня ACL);
● сегментация L2CAP.
Абсурд идет еще дальше, как в некоторых сервисах Bluetooth, механизм фрагментации можно обнаружить в каждом из слоев Bluetooth на протяжении всей работы. Как например SDP - пакет будет фрагментирован механизмом продолжения SDP, а затем механизмом сегментации L2CAP, а затем снова продолжением ACL, и напоследок Link Controller, выполненный механизмом фрагментации.
Прошлые исследования Bluetooth.
Предыдущие работы концентрировались на поиске потенциальных проблем в самой спецификации Bluetooth, демонстрируя слабость процедуры обмена ключами шифрования в версиях Bluetooth вплоть до версии 2.1. Поскольку Bluetooth представил «Secure Simple Pairing Безопасное и простое спаривание команд"- функцию, которая устраняла многие известные проблемы с сопряжением в спецификации, Сообщество безопасности потеряло интерес к Bluetooth. В последние годы появилась Bluetooth Low Energy, вызвав новый интерес сообщества к Bluetooth в целом. Тем не менее, не выполнялся полный контроль за реализацией различных пакетов Bluetooth.
Эта работа является первым шагом в выявлении потенциальных недостатков в пакетах Bluetooth. Однако, поскольку стек Bluetooth является an immense piece of code таким огромным фрагментом кода, работа, которую мы представляем, может быть лишь верхушкой айсберга.
Демистификация открытости.
Bluetooth по умолчанию включен на многих устройствах, и большинство пользователей предпочитают оставлять его включенным, поскольку это удобный способ подключения наушников, клавиатур и других различных устройств IoT на том же самом знакомом интерфейсе ОС. Существуют различные типы соединений Bluetooth, одним из которых является pairing between them спариванием между ними.
В большинстве ОС, когда пользователь активно пытается подключиться к устройству, его машина обнаруживается через Bluetooth соседними пользователями. В любом другом случае открытость невозможна. Однако устройство с поддержкой Bluetooth почти всегда прослушивает однонаправленный трафик, предназначенный для него, даже если он не установлен в режиме обнаружения (это называется «Режим сканирования страницы»). По этой причине чтобы установить соединение, инициирующая сторона должна знать только BDADDR (адрес устройства Bluetooth, MAC-адрес) целевого устройства. Как только злоумышленник получает его и находится в физической доступности от устройства (диапазон радиочастот), он или она может достичь reach the surprisingly wide attack surface of its listening Bluetooth services. удивительно широкого диапозона поверхности атаки своих слуховых Bluetooth-сервисов.
Некоторые считают, что обнаружение BDADDR не обнаруживаемых устройств затруднительно, в том числе сама спецификация, которая описывает это как одну из «Four different entities четырех разных объектов используемых для обеспечения безопасности на уровне канала», (спецификация Bluetooth Core v5.0, стр. 1649). Предполагаемая трудность возникает из-за сложности протокола Bluetooth на нижних уровнях и из-за предполагаемого отсутствия аппаратного обеспечения, способного «обнюхивать» воздух. Однако очень легко обнаружить BDADDR, даже не обнаруживаемых устройств.
Оборудование Open source hardware с открытым исходным кодом/с открытым источником, такое как Ubertooth, доступно уже несколько лет. Этот инструмент позволяет исследователям "обнюхивают" и мониторить протокол на физическом и канальном уровнях (посредством обнюхивания воздуха для Bluetooth-пакетов). Поскольку «режим монитора» Bluetooth очень ограничен в широко доступных инструментах для исследователей, появление Ubertooth уменьшило барьер входа для многих пользователей (включая нас самих).
Несмотря на то, что соединения Bluetooth зашифрованы, заголовки пакетов (которые являются открытым текстом) содержат достаточно информации, из которой могут быть получены BDADDRs коммуникационных устройств. Если устройство генерирует любой трафик Bluetooth, злоумышленник в физической доступности может получить свой BDADDR и использовать его для отправки одноадресного трафика на устройство.
Таблица 1. Общий формат пакета Basic Rate.
Структура классического пакета Bluetooth в "воздухе". «Код доступа» содержит 24-битный LAP, часть BDADDR.
Если устройство не генерирует никакого трафика Bluetooth, а только "слушает", все же возможно «угадать» BDADDR, "обнюхивая" его WiFi-трафик. Это жизнеспособно, так как появляются MAC-адреса WiFi, незашифрованные "по воздуху" и в силу общепринятой нормы OEMs и производители оборудования MAC-адреса внутренних адаптеров Bluetooth / WiFi либо одинаковы, либо отличаются только в последней цифре (Один - +1 от другого).
Анализ поверхности атаки.
Установив относительную простоту получения Bluetooth-адреса устройства, мы можем теперь погрузиться в широкую поверхность атаки, которая существует в каждом стеке Bluetooth, на всех уровнях протокола. Мы рассмотрим уровни Bluetooth, от L2CAP, до SMP, до SDP, а затем до более высоких уровней, которые мы уже изучили: BNEP и PAN. В каждом слое/уровне мы представим наши выводы и поясним уязвимости, которые мы раскрыли.
Схема.
Основные блоки в стеке Bluetooth, указывающие на расположение различных уязвимостей.
Широко распространенные Bluetooth-стеки.
В некотором смысле, стек Bluetooth эквивалентен стеку TCP\IP, только для связи Bluetooth. В отличие от других протоколов связи низкого уровня, таких как Ethernet, WiFi и 6LoWPAN, Bluetooth не полагается на стек TCP\IP для всех протоколов приложений высокого уровня. Вместо этого широкий диапазон протоколов и приложений были определены Bluetooth SIG, and are referred to collectively и к ним также обращаются как и к стеку Bluetooth.
Таблица.
Изображение X - Архитектура стека Bluetooth.
Стек Bluetooth представляет собой полную альтернативу классическому 7-слойному стеку TCP\IP - начиная с физического уровня и охватывая уровень приложения. Нижние уровни стека - физические и канальные уровни - реализованы в чипах Bluetooth. Эти чипы взаимодействуют с «Хост», которая является фактической операционной системой устройства, через HCI Bluetooth (интерфейс Host-Controller ). Все протоколы выше этого уровня (такие как L2CAP, AMP, SMP, SDP и RFCOMM) осуществляются на стороне "Хост". В каждой современной операционной системе имеется только один стек Bluetooth, в отличие от драйверов сетевых адаптеров, которые имеют разные версии для каждой аппаратной части. Это означает, что любая уязвимость, обнаруженная в одном из этих стеков автоматически влияют на все устройства, работающие со specific специфической/этой ОС, что ставит под угрозу множество устройств на рынке.
Первым значимым стеком является пакет BlueZ от Linux, который использовался ранними версиями Android, и который по-прежнему используется Linux и другими ОС, полученными из него, такими как Samsung Tizen OS. Позже Android разработал свой собственный стек под названием Bluedroid или Fluoride, используемый во всех устройствах Android начиная с версии 4.2 и выше. У Windows есть свой собственный стек Bluetooth, поскольку Windows XP и Apple создали два варианта стека Bluetooth, один для iOS, а другой для OSX.
L2CAP
Обзор.
На стороне хоста самый низкий уровень в стеке Bluetooth - L2CAP. Этот уровень отвечает за управление соединениями с различными службами Bluetooth. Основной транспортирование L2CAP это ACL - Асинхронное ориентированное на соединение логическое транспортирование. ACL - это просто ориентированный на пакет, ненадежный транспортный уровень, над которым передаются почти все данных Bluetooth. L2CAP управляет каналами, ориентированными на соединение, через ACL, которые (каналы) являются логическими сквозными транспортированиями, идентифицированными идентификаторами канала в теле пакета. Роль этих идентификаторов каналов можно сравнить с портом, используемым в приложениях TCP (или UDP), и в целом, L2CAP может рассматриваться как эквивалент Bluetooth для TCP, так как он также выполняет функции QoS и функции управления потоком. L2CAP также реализует (еще одну) фрагментацию и механизмы повторной сборки/повторного ассемблирования программы - и, таким образом, делает возможным перенос больших SDU (Service Data Единицы - L2CAP lingo для «больших пакетов» - используемых различными службами/сервисами на/над L2CAP).
Спецификация Bluetooth резервирует/сохраняет специфические идентификаторы CID (идентификаторы каналов) для фиксированных целей - например, CID 1 всегда будет ссылаться на канал сигнализации, в котором передаются пакеты управления (и через них - могут быть установлены новые соединения). Другие CID управляются и распределяются динамически. Различные сервисы Bluetooth часто имеет фиксированные PSM (протокол/сервисный мультиплексор - другой термин L2CAP, обозначающий номер порта), и имеют конечную точку, желая подключиться к этим службам, отправит сообщение L2CAP ConnectionRequest именно этому специфическому PSM. В ответ на это сообщение динамический CID будет выделен для идентификации соединения к этой конкретной услуге.
При создании нового соединения L2CAP обе конечные точки пытаются координировать согласованную конфигурацию посредством передачи пакетов, называемых запросами конфигурации и ответами конфигурации, и наоборот. Запрос конфигурации содержит несколько элементов, которые определяют точный тип функций соединения, которые будут использоваться.
Взаимная конфигурация.
Процесс настройки выполняется с использованием запросов конфигурации и ответов, указанных в спецификации как L2CAP_ConfReq и L2CAP_ConfResp. Эти сообщения передаются по сигнальному каналу, причем обе конечные точки отправляют запросы конфигурации друг другу, как часть первоначального рукопожатия, и взамен получают ответы на конфигурацию. Ответ на конфигурацию содержит код состояния, который информирует initiator инициатора о том, была ли принята или отклонена его конфигурация. Каждая конечная точка преодолевает свою собственную конфигурацию, то есть параметры конфигурации обеих конечных точек должны быть согласованы.
Рисунок А.1 наглядно покаывает базовый процесс онфигурациию. В данном примере устройства обмениваются MTU информацией. Допускается, что все другие значения - по умолчанию.
Схема.
Рисунок А.1 : Базовый обмен MTU.
Выдержка из спецификации Bluetooth, стр. 1902.
В приведенном выше примере устройство A запрашивает максимальную единицу передачи (MTU) 0x100, которую принимает устройство B, а затем запрос от устройства B для MTU 0x200, которую устройство A также принимает. Два MTU параметра были согласованы в этой транзакции - максимальный размер исходящих сообщений с устройства A на устройство B равен 0x100, а максимальный размер исходящих сообщений с устройства B на устройство A равен 0x200.
Хотя приведенный выше пример представляет собой простой обмен параметрами, устройство может также отказаться от предложенного запроса конфигурации из-за «неприемлемых параметров». Чтобы облегчить повторное согласование, его ответ конфигурации может содержать альтернативное, приемлемое значение для параметра, который он хочет изменить. Например, в следующем код-фрагменте (из BlueZ, стек Bluetooth Linux), запрашиваемое значение MTU проверяется на минимальное значение (chan-> omtu инициируется по умолчанию, когда соединение установлено):
if (mtu < L2CAP_DEFAULT_MIN_MTU) 3407 result = L2CAP_CONF_UNACCEPT; 3408 else { 3409 chan->omtu = mtu; 3410 set_bit(CONF_MTU_DONE, &chan->conf_state); 3411 } 3412 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Выдержка из net / bluetooth / l2cap_core.c
Если запрашиваемое значение MTU действительно, оно привязано к текущим настройкам соединения, и состояние конфигурации MTU помечено как «сделано» в объекте канала, в противном случае значение ответа установлено в UNACCEPT, и значение отбрасывается. В любом случае к ответу конфигурации добавляется элемент MTU, отражающий действительную настройку на другой стороне в случае отклонения конфигурации.
Вышеупомянутая процедура называется «Стандартный процесс конфигурации» соединений L2CAP. В этом процессе конфигурации конечные точки будут отвечать на запрос конфигурации принятием либо отклонением предлагаемой конфигурации. Если конфигурация была отклонена, конечные точки будут "продолжать переговоры" до тех пор, пока они не достигнут согласованной конефигурации.
Однако существует другой тип процесса конфигурации - процесс блокировки конфигурации. Этот процесс требуется для того, чтобы облегчить функцию "Спецификация расширенного потока (EFS)" L2CAP, что позволяет устройствам устанавливать более полное соединение. Функциональные параметры EFS должны быть подтверждены каждым локальным контроллером Bluetooth конечных точек, и таким образом, ответ конечных точек на запрос конфигурации может быть «Ожидает». Поскольку оба параметра EFS были обменены между конечными точками, и была достигнута проверка данных EFS, окончательный ответ будет возвращен каждой из конечных точек.
Уязвимость ядра Linux RCE - CVE-2017-1000251 уязвимость ответа конфигурации BlueZ синтаксический анализ. Уязвимость заключается в реализации функции EFS L2CAP в L2CAP, в l2cap_parse_conf_rsp, которая была введена в версии ядра v3.3-rc1 и, таким образом, влияет на всю версию. l2cap_parse_conf_rsp можно увидеть здесь в сокращенной форме:
static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result) { struct l2cap_conf_req *req = data; void *ptr = req->data; // ... while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); switch (type) { case L2CAP_CONF_MTU: // Validate MTU... l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); break; case L2CAP_CONF_FLUSH_TO: chan->flush_to = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, chan->flush_to); break; // ... } } // ... return ptr - data;
Выдержка из l2cap_parse_conf_rsp (net / bluetooth / l2cap_core.c)
Эта функция получает буфер ответа конфигурации в аргументе rsp, а его длина в len Аргумент. Он извлекает элементы из буфера один за другим, используя функцию l2cap_get_conf_opt, пока не заканчивается аргумент len. Каждый элемент, который он распаковывает из ответа конфигурации, проверяется, а затем запаковывается обратно в буфер ответа, на который указывает аргумент данных.
Однако размер этого буфера ответа не передается функции.
По сути, все элементы в rsp будут скопированы в буфер данных через & ptr (offset to l2cap_conf_req.data) независимо от размера буфера цели.
Обратите внимание, что размер входящего ответа не ограничен - элементы могут быть дублированы, что позволяет злоумышленнику контролировать размер буфера rsp, и как результат количество данных, the amount of data copied onto data скопированных на данные. Начало/происхождение буфера данных - l2cap_parse_conf_rsp вызывается из двух местопожений, оба - в функции с именем l2cap_config_rsp, которая, как следует из ее названия, обрабатывает сообщения об ответе конфигурации. Оба вызова функции похожи, поэтому оба могут использоваться для использования этой уязвимости.
switch (result) { case L2CAP_CONF_SUCCESS: ... break; case L2CAP_CONF_PENDING: set_bit(CONF_REM_CONF_PEND, &chan->conf_state); if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { char buf[64]; len = l2cap_parse_conf_rsp(chan, rsp->data, len, buf, &result); ... goto done;
Выдержка из l2cap_config_rsp (net / bluetooth / l2cap_core.c)
switch Переключатель/Коммутатор проверяет значение результата, которое ранее было распаковано из пакета ответов конфигурации, и таким образом, может контролироваться злоумышленником. Буфер ответа представляет собой небольшой буфер стека, называемый buf , объявленный в пределах оператора if, который приводит к вызову.
Затем конфигурация для текущего канала проверяется на состояние «Ожидание» (как описано выше в процесс блокировки конфигурации). Чтобы получить доступ к этому потоку, злоумышленнику необходимо, чтобы его цель была в состоянии «Ожидание», которое он может выполнить, вызывая следующий код:
if (remote_efs) { if (chan->local_stype != L2CAP_SERV_NOTRAFIC && efs.stype != L2CAP_SERV_NOTRAFIC && efs.stype != chan->local_stype) { ... // We don’t want this branch, easy to avoid } else { /* Send PENDING Conf Rsp */ result = L2CAP_CONF_PENDING; set_bit(CONF_LOC_CONF_PEND, &chan->conf_state); }
Выдержка из l2cap_parse_conf_req (net / bluetooth / l2cap_core.c)
Действие это простое: злоумышленнику лишь необходимо отправить запрос конфигурации с помощью элемента EFS, установив поле типа Stype в L2CAP_SERV_NOTRAFIC.
После достижения состояния «Ожидание» следующий ответ конфигурации, отправленный с полем результата, установленным на L2CAP_CONF_PENDING вызовет уязвимость, ведущий buf [64] будет перезаписан с буфером произвольного размера.
Эта уязвимость позволяет злоумышленнику переполнить 64-байтовый буфер в стеке ядра неограниченным количество данных, если они соответствуют структуре действительного ответа конфигурации L2CAP.
Схема.
Захват процесса атаки - обратите внимание на неправильный ответ конфигурации «Ожидание»
Exploitability возможность использования?
Сегодня переполнение стека, как подробно описанная выше уязвимость, автоматически не преобразуется в выполнение кода. У совеременных операционных систем есть методы, специально предназначенные для предотвращения уязвимостей, связанных с повреждением памяти, что приводит к выполнению кода. Несмотря на это, Ядро Linux отстает в реализации некоторых современных методов предотвращения уязвимостей в конфигурации по умолчанию. Оба stack canaries стековых канарейки - которые защищают от переполнения стека, и KASLR (рандомизация размещения адресного пространства ядра) отсутствует в большинстве устройств под управлением Linux сегодня. Это делает переполнение стека, представленного выше, легким в использовании - как показано в демонстрационном видео.
Следует отметить, что тестирование и запуск этой уязвимости было непростой задачей и требовало Прямое использование уровня ACL для отправки некорректных пакетов L2CAP. Пользователю должен быть создан минимальный стек, реализующий уровни HCI, ACL и L2CAP . Высокий барьер входа для тестирования высокоуязвимых путей(?) кода ядра также несет угрозу безопасности. Мы будем выпускать структуру тестирования, которую мы разработали, наряду с эксплойтным кодом этой конкретной уязвимости в будущем блоге. Эта структура тестирования может помочь исследователям в дальнейшем изучении и пентестинге стеков Bluetooth.
Просмотрите видео о Linux эксплойте здесь:
Влияние.
В случае BlueZ L2CAP включен как часть основного кода ядра Linux. Это довольно опасный выбор. Объединяя полностью открытый протокол связи, такие закрытые/тайные функции, как EFS и функция реализации пространство ядра - это то, что доктор прописал. Эта уязвимость - это классический stackoverflow, возникающий в контексте потока ядра. Это обеспечивает злоумышленнику полный и надежный эксплойт на уровне ядра для любого Bluetooth-совместимого устройства под управлением Linux, не требующего дополнительных шагов. Кроме того, каждый compromised взломанный/альтернативный хост может использоваться для запуска вторичных атак, что делает эту уязвимость, подверженной вредоносному ПО (wormable).
SDP
Обзор.
SDP (Service Discovery Protocol) - это базовый уровень в Bluetooth, который является частью каждого стека. Его цель - позволить устройствам обнаруживать различные службы и приложения, которые поддерживает Bluetooth-устройство. Кроме того, SDP несет ответственность за translate перевод фиксированных UUID (универсальных уникальных идентификаторов) услуг Bluetooth для PSM (мультиплексор протокольных услуг - эквивалент Bluetooth номера порта L2CAP), который может быть динамически выбираемым номером. Затем полученный PSM используется для создания соединения L2CAP с обнаруженной службой.
Чтобы обнаружить службы, клиент SDP отправляет запрос SDP, и ему возвращается соответствующий ответ. SDP определяет еще один механизм фрагментации ответов SDP, возвращаемых сервером SDP, который называется «SDP Продолжение».
Продолжение SDP работает иначе, чем обычная фрагментация:
1. Сначала клиент SDP отправит запрос SDP;
2. Если ответ на этот запрос превышает MTU установленного соединения L2CAP, фрагмент ответа будет возвращен, и структура «состояния продолжения» будет добавлена к SDP ответу.
3. Чтобы получить оставшиеся фрагменты, клиент SDP снова отправит тот же запрос, добавив к нему «состояние продолжения», которое он получил в последнем ответе (этот тип запроса называется "запрос продолжения").
4. Затем сервер SDP вернет следующий фрагмент ответа.
5. Этот поток будет повторяться до тех пор, пока не будут доставлены все фрагменты.
Непонятно, почему Bluetooth затребовал еще один уровень фрагментации, поскольку два дополнительных уровня фрагментации определены ниже SDP - реализованы в L2CAP (который называет его «сегментацией»), и на уровне ACL. Более того, спецификация лишина одной важной детали в механизме продолжения SDP вплоть до исполнителей - конкретная структура состояния продолжения. Спецификация описывает это сухо:
«Формат информации продолжения не стандартизирован среди служб/серверов SDP. Каждый параметр состояния продолжения имеет смысл только для сервера SDP, который его создал».
Спецификация Bluetooth v5.0, том 3, часть B, стр. 1926
Это решение в спецификации SDP является довольно странным, так как возвращаемое состояние продолжения не используется напрямую клиентом SDP, и его цель должна использоваться внутри сервером при обработке запросов "продолжение". Это может привести к злоупотреблению состоянием продолжения, поскольку клиенту остается возвращать его без изменений по каждому запросу продолжения. Два подобных нарушения такого рода привели к двум уязвимостям, связанным с утечкой информации, обнаруженным в пакетах Bluetooth как Linux, так и Android.
Информация об уязвимости в Linux Bluetooth (BlueZ) Уязвимость от утечки - CVE-2017-1000250.
Эта уязвимость является прямым результатом описанного выше сценария - и это очень распространенная ошибка В реализации механизмов фрагментации. Поскольку структура продолжения SDP определяется реализацией, BlueZ решил определить эту структуру как свое состояние продолжения:
typedef struct { uint32_t timestamp; union { uint16_t maxBytesSent; uint16_t lastIndexSent; } cStateValue; } sdp_cont_state_t;
SDP Continuation Struct (структура продолжения SDP, как определено в BlueZ (src / sdpd-request.c)
Эта структура заключает в себе временную метку, которая удобно протекает по временной метке машины, и индекс, представляющий общее число байтов, которые на тот момент были отправлены.
Так как злоумышленник может контролировать состояние продолжения, отправленное по каждому запросу, он может изменить индекс в структуре продолжения и заставить сервер SDP возвращать "an out of bounds отказ в доступе", считанный из буфер ответа:
...
} else { /* continuation State exists -> get from cache */ sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); if (pCache) { uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); pResponse = pCache->data; memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); buf->data_size += sent; cstate->cStateValue.maxBytesSent += sent; if (cstate->cStateValue.maxBytesSent == pCache->data_size) cstate_size = sdp_set_cstate_pdu(buf, NULL); else cstate_size = sdp_set_cstate_pdu(buf, cstate); } else { status = SDP_INVALID_CSTATE; SDPDBG("Non-null continuation state, but null cache buffer"); } } ...
Выдержка из обработчика запроса атрибута поиска SDP - service_search_attr_req (src / sdpd-request.c)
Этот код из обработчика запроса атрибута поиска сервера BlueZ SDP не может проверить достоверность maxBytesSent в cstate (состояние продолжения) и позволяет вышеупомянутой memcpy копировать данные, выходящие за пределы выделенного размера pResponse. Единственное, что злоумышленник должен сделать для осуществления этой утечки информации, заключается в том, чтобы избежать if, который проверяет, все ли данные были отправлены (maxBytesSent data_size) - и это легко сделать, так как он контролирует maxBytesSent. Поскольку pResponse выделяется в "куче", эта утечка информации может привести к раскрытию высокочувствительных данных.
BlueZ состоит из двух частей - одна из которых работает в ядре (как это было замечено в уязвимости L2CAP), а другая в пользовательском пространстве. Процесс Bluetoothd содержит все пользовательские части BlueZ (по существу, все уровни стека выше L2CAP). Этот процесс содержит критические данные, которые могут утекать с использованием этой уязвимости, такие как ключи шифрования, используемые в Bluetooth-соединениях, делающих возможной атаку "на грани разрыва сердца".
Уязвимость. связанная с утечкой информации из Android - CVE-2017-0785
SDP-сервер Android определяет аналогичную структуру состояний продолжения:
typedef struct {
uint16_t cont_offset;
} sdp_cont_state_t;
Структура продолжения SDP (SDP Continuation Struct), используемая в стеке Bluetooth для Android.
В этом случае только смещение продолжения (которое имеет схожее значение с индексом, используемым в BlueZ) отправляется в структуре продолжения. Хотя код обработчика запросов поиска SDP-сервера Android выполняет некоторые проверки на cont_offset, утечка информации все еще возможна. В следующем отрывке, num_rsp_handles будет содержать общее число дескрипторов (то есть записей sdp) ответа SDP:
/* Check if this is a continuation request */
if (*p_req) {
... if (cont_offset != p_ccb->cont_offset) { sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_INX); return; } rem_handles = num_rsp_handles - cont_offset; /* extract the remaining handles */ } ... /* Calculate how many handles will fit in one PDU */ cur_handles = (uint16_t)((p_ccb->rem_mtu_size - SDP_MAX_SERVICE_RSPHDR_LEN) / 4); if (rem_handles <= cur_handles) cur_handles = rem_handles; else /* Continuation is set */ { p_ccb->cont_offset += cur_handles; is_cont = true; } ... for (xx = cont_offset; xx < cont_offset + cur_handles; xx++) UINT32_TO_BE_STREAM(p_rsp, rsp_handles[xx]);
Выдержка из обработчика запроса поиска SDP - process_service_search (stack / sdp / sdp_server.c)
Код содержит копию cont_offset в объекте соединения (p_ccb) и подтверждает, что полученное cont_offset равно текущему состоянию соединения. Таким образом, простое злоупотребление cont_offset невозможно (как это сделано в BlueZ). Однако, поскольку каждый запрос продолжения является по существу новым запросом, к которому добавлено только состояние продолжения, код можно привести к состоянию путаницы/неразберихи путем изменения параметров запроса между двумя последовательными запросами.
Параметр num_rsp_handles вычисляется каждый раз, когда получен запрос , исходя из общего размера конкретного ответа. Размер ответа может варьироваться в зависимости от запрашиваемого поиска услуги, который выполняется, и, в отличие от cont_offset, num_rsp_handles не сохраняется в объекте соединения и проверяется, чтобы оставаться тем же во время чтения фрагментов ответа. В результате этой путаницы состояния, может произойти потеря значимости Of rem_handles:
rem_handles = num_rsp_handles - cont_offset;
Этот код предполагает, что num_rsp_handles и cont_offset - оба относятся к тому же отклику, который отправляется во фрагментах. Из-за вызванной путаницы состояния, а так же из-за того, что rem_handles это uint16_t, этот код теперь предполагает, что потребуется очень большой ответ (до 64 КБ) - и последующий цикл будет копировать out of bounds байты из rsp_handles в пакет исходящего ответа.
Подводя итог, эта утечка информации может быть запущена злоумышленником в этом потоке:
1. Запрос поиска выполняется для некоторой службы.
2. Из-за этого запроса возвращается ответ с состоянием продолжения. Размер этого ответ будет определяться MTU соединения, как показано в выдержке кода выше, поэтому злоумышленник также контролирует размер фрагментов.
3. Второй запрос выполняется для другой службы, а состояние продолжения из предыдущего ответа будет добавлено к этому запросу. Этот второй запрос поиска будет от сервиса, который вернет меньший размер ответа, чем предыдущий ответ, - и это приведет к описанной путанице состояния.
4. Будет предпринята попытка проверки cont_offset, но она пройдет успешно (поскольку тот же cont_offset был добавлен ко второму запросу).
5. Из-за того, что num_rsp_handles в этом втором запросе меньше, чем в первом запросе, произойдет an underflow потеря значимости rem_handles.
6. Теперь код будет принимать очень большой ответ - и for-loop (цикл с параметром), который последует дальше, будет копировать байты из rsp_handles в исходящий ответный пакет.
7. С этого момента злоумышленник может повторить отправку одного и того же запроса и добавить возвращенный cont_offset - продолжая считывать все больше и больше из out of bound байтов с rsp_handles.
Подобно уязвимости, связанной с утечкой информации в BlueZ, эта уязвимость может привести к раскрытию большая часть памяти - в данном случае из стека процессов. Эти данные могут потенциально включать ключи шифрования, адресное пространство и ценные указатели (кода или данных), которые могут использоваться для обхода ASLR при exploiting разработке уязвимости, связанной с разрушением изолированной памяти.
Заключение
Фрагментация всегда является мягким местом в реализации протоколов. Однако ошибочный дизайн фрагментации SDP механизма делает его работу практически невозможной для реализации без ошибок. Даже когда конкретные проверки выполняются (как и в реализации Android) - устранение всех ошибок, которые могут стать результатом путаниц состояний - почти невыполнимая миссия.
SMP
Обзор
SMP (протокол управления безопасностью) позволяет использовать различные механизмы безопасности Bluetooth - аутентификацию, авторизацию и соединение (также известное как «спаривание»).
SMP отвечает за процесс соединения двух устройств, а также за механизмы аутентификации, используемые тогда, когда спаренные устройства подключаются друг к другу. Механизмы безопасности Bluetooth значительно изменились, поскольку исходные версии - и SMP в особенности подвергся множеству изменений. Большая часть пробелов в безопасности Bluetooth были обнаружены в этом слое протокола, главным образом в механизме обмена PIN-кодами, который существовал вплоть до версии 2.1. В этой версии появился новый механизм аутентификации SSP (Secure Simple Pairing). SSP осуществил практически полный контроль над механизмами безопасности SMP. Одним из запутанных преобразований SSP было изменение термина «сопряжение». До SSP «Сопряжение» относилось к обмену и хранению долгосрочных ключей между устройствами Чтобы создать долгосрочную связь между ними. Предшественник SSP «сопряжение» относился к обмену и хранению долгосрочных ключей между устройствами, чтобы создать долгосрочную связь между ними. Поскольку был введен SSP, «сопряжение» было поделено на двое: «спаривание», которое относится к обмену ключами и «связывание» с хранением ключей. Это привело к новому типу спаривания - кратковременному спариванию, которое существует только во время единичного соединение Bluetooth, без связывания.
Существенным изменением, внесенным в SSP, стали новые механизмы обмена ключей. Ранние версии Bluetooth использовали довольно примитивный механизм: обмен PIN-кодами (которые, к сожалению, можно было получить, если перехватить их в эфире). Устройства, у которых не было интерфейса для вставки PIN-кода, просто выбрали PIN-код по умолчанию, который был сложно закодирован в устройстве. SSP использует современные механизмы обмена ключами (известные как «Обмен ключами Диффи-Хеллмана») и предлагает различные методы для проверки безопасного прохождения обменных ключей для подтверждения того, что обмен не был перехвачен третьей стороной.
Эти новые механизмы по-прежнему не решают проблему устройств, у которых нет пользовательского интерфейса, и, таким образом, не могут вставлять PIN-код или проверять безопасный проход a safe passage of one on their display (на) одном/одного из их дисплеев. Механизм аутентификации SSP для таких устройств это «Just Works», самый слабый механизм партии (изделий). Вот почему, использование «Just Works», является последним "средством спасения" в SMP.
А вот как это ("просто") работает:
При выполнении процедуры Secure Simple Pairing две конечные точки обмениваются сообщениями, чтобы собрать их взаимный IO ввод-вывод/вход-выход возможностей.
Схема.
Рисунок 4.12: IO ввод-вывод/вход-выход возможность взаимообмена
Спецификация Bluetooth, версия 5.0, том 2, часть F, стр. 1436
Каждая конечная точка ответит на следующие два вопроса:
● Какой тип интерфейса она поддерживает
● Какой тип аутентификации требуется
Параметры интерфейса следующие:
Таблица.
И возможности требований аутентификации/подлинности таковы:
Таблица.
«Требование аутентификации», которым обмениваются конечные точки, определяет, создают ли они bond связку/соединение/связь (долгосрочный обмен ключами), и требуют ли они «MITM Protection» (Man in the middle protection - высокий уровень безопасности по сравнению с перехватом сообщений).
SSP определяет, в каком методе две конечные точки, которые могут иметь разные интерфейсы, обмениваются ключами:
Таблица.
Таблица 5.7 (показанная частично), Спецификация Bluetooth v5.0, том 3, часть C, стр. 2016
Когда в одной из конечных точек отсутствует интерфейс для обмена ключами (NoInputNoOutput), выбранным механизмом обмена ключами будет «Числовое сравнение с автоматическим подтверждением», которое также называется «Just Works». В приведенной выше таблице также упоминается, какой из этих методов приводит к «аутентифицированному» ключу, и который не приводит. «Аутентифицированный» ключ - это тот, который пользователь смог проверить на безопасное прохождение.
Если одна из конечных точек запросила «MITM Protection», ключ «Unauthenticated»("не аутентифицированный") не может быть использован, если нет - для обмена ключами будет выбрано «Just Works».
It “Just Works” (but sometimes it doesn’t) Это "просто работает", а иногда не работает.
Как указано выше, «Just Works» является подмножеством другого механизма аутентификации в SSP под названием «Numeric Comparison" ("цифровое сравнение"), которое используется, когда устройства не ограничены их возможностями IO. Установив, что «Just Works» станет механизмом аутентификации, конечные точки будут представлять из себя измененную версию процедуры обмена ключами «Числовое/цифровое сравнение». В обычном «цифровом сравнении» используется общий «секретный», PIN-код, которым между собой обмениваются конечные точки, используя Diffie-Hellman, и пользователь подтверждает, что тот же PIN-код появляется на каждом из экранов устройств. Однако в «Just Works» хотя бы у одного из устройств нет пользовательского интерфейса, поэтому проверка PIN-кода не является option альтернативой/опцией. Вместо этого «автоматическое подтверждение» будет представлено/предложено устройствами.
Если одно из устройств имеет достаточные возможности IO ввода-вывода («DisplayYesNo»), оно может разрешить/авторизировать спаривание - но он не будет отображать PIN-код, так как нет возможности проверить его безопасный проход.
Спецификация Bluetooth отмечает это о Just Works:
«Модель ассоциации Just Works использует протокол Numeric Comparison (цифровое сравнение), но пользователю никогда не показывают номер, и приложение может просто попросить пользователя принять соединение (точное выполнение вплоть до конечного производителя продукта)."
Спецификация Bluetooth, версия 5.0, том 1, часть A, стр. 245
Поэтому, несмотря на очевидную необходимость авторизации нового спаривания, спецификация оставляет эту задачу за различными выполнениями, чтобы определить, примет ли пользователь новое сопряженное устройство (независимо от того, будет ли это краткосрочным спариванием или долгосрочным), и как он это сделает.
Например, стек Bluetooth для Android реализует это решение следующим образом:
/* If JustWorks auto-accept */ if (p_ssp_cfm_req->just_works) { // Pairing consent for JustWorks needed if: // 1. Incoming (non-temporary) pairing is detected AND // 2. local IO capabilities are DisplayYesNo AND // 3. remote IO capabilities are DisplayOnly or NoInputNoOutput; if (is_incoming && pairing_cb.bond_type != BOND_TYPE_TEMPORARY && ((p_ssp_cfm_req->loc_io_caps == HCI_IO_CAP_DISPLAY_YESNO) && (p_ssp_cfm_req->rmt_io_caps == HCI_IO_CAP_DISPLAY_ONLY || p_ssp_cfm_req->rmt_io_caps == HCI_IO_CAP_NO_IO))) { BTIF_TRACE_EVENT( "%s: User consent needed for incoming pairing request. loc_io_caps: " "%d, rmt_io_caps: %d", __func__, p_ssp_cfm_req->loc_io_caps, p_ssp_cfm_req->rmt_io_caps); } else { BTIF_TRACE_EVENT("%s: Auto-accept JustWorks pairing", __func__); btif_dm_ssp_reply(&bd_addr, BT_SSP_VARIANT_CONSENT, true, 0); return; } }
Выдержка из btif_dm_ssp_cfm_req_evt в стеке Bluetooth Android (btif \ src \ btif_dm.c)
Пользователь должен будет принять процедуру спаривания JustWorks только в том случае, если выполнены следующие условия:
- Сопряжение не является временным (включая долгосрочный обмен ключами - «связывание/соединение»)
- Возможности локального (Android) IO - DisplayYesNo, а возможности удаленного IO ввода-вывода ограничены (Дисплей Только или без ИО).
Поэтому в случае временной процедуры сопряжения Android будет принимать автоматически , а злоумышленник сможет повысить свои мандаты в стеке Bluetooth Android, поскольку он обошел процесс аутентификации, в то время как его жертва остается в совершенном неведении.
Повторяю, злоумышленник может принудить временное спаривание к устройству-жертве без какого-либо взаимодействия с пользователем.
При эмпирическом тестинге на компьютере с Windows было обнаружено то же поведение:
Таблица.
capture Захват Wireshark процедуры «Just Works» с «Автоподтверждением», против компьютера с Windows 10
Как видно из вышеприведенного capture захвата Wireshark, злоумышленник может подключиться и аутентифицировать свое соединения с компьютером с Windows через Bluetooth. Злоумышленник решает ответить на запрос возможности IO ввода-вывода с помощью: «NoInputNoOutput, MITM Protection Not Required - No Bonding ", и, таким образом, выбирается механизм аутентификации Just Works.
Поскольку компьютер с Windows автоматически подтверждает процедуру, сообщение «аутентификация завершена» почти мгновенно доставляется обратно на компьютер атакующего.
Теперь, когда злоумышленник аутентифицирован (хотя бы с кратковременным ключом), он может получить доступ к некоторым службам высокого уровня, которые выполняет каждая машина. В приведенном выше примере эта кратковременная аутентификация позволяет злоумышленнику получить доступ к службе BNEP (о которой мы расскажем подробнее в следующем разделе).
Мы также обнаружили, что многие другие службы позволят подключению L2CAP достичь состояния «Connected», как только аутентификация будет достигнута посредством «Just Works».
Это справедливо как для Android, так и для Windows и, возможно, для других неизученных стеков, которые могут вести себя таким же образом.
Во многих случаях незащищенные службы в конечном итоге откажутся от доступа к функциям более высокого уровня, которые, подразумевается, что станут доступны через полностью сопряженное устройство (то, которое выполнило «связывание/соединение»). Однако эти проверки зависят от отдельных сервисов/служб, а не от общего базового уровня SMP . Это расширяет потенциальную поверхность атаки, так как больше потоков кода может быть достигнуто в каждом из многих сервисов/служб выполненных в каждом стеке.
Заключение.
Понятно, что у механизма «Just Works» есть свои заслуги, поскольку он позволяет осуществлять обмен ключами с помощью современной и безопасной процедуры (Диффи-Хеллман). Также очевидно, что без какого-либо IO ввода-вывода устройство не может аутентифицировать PIN-код и, следовательно, у механизма нет защиты от MITM. Несмотря на это, когда одна из сторон в процедуре сопряжения имеет возможности IO ввода-вывода, что в общем является обычным делом, необходимо подтвердить сопряжение конечным пользователем этого устройства.
Неясно, является ли поведение «автоподтверждения» в Android и Windows преднамеренным, или это лишь причуда/случайность в Bluetooth, что эти стеки еще не выяснили, как использовать.
Как мы продемонстрируем в следующих разделах, эта темная сторона SSP Bluetooth привела нас к тому, что мы обнаружили значительное число уязвимостей в службах/сервисах, которые в настоящее время подвергаются угрозам из-за такого поведения в Android и Windows.
BNEP
Обзор.
Служба BNEP (протокол инкапсуляции сети Bluetooth) упрощает сетевую инкапсуляцию (обычно на основе IP) по Bluetooth. В большинстве случаев это используется, чтобы разрешить to allow internet tethering (sharing) over Bluetooth. интернету передачу данных через Bluetooth.
Выше/над BNEP лежит профиль PAN, который реализует сетевой уровень, и выполняет различные роли, которые существуют в сети на основе IP, созданной по/через Bluetooth. Цель службы BNEP в этой иерархии заключаетсям в основном в инкапсуляции различных форм Ethernet-пакетов через соединение L2CAP. Для этой цели в BNEP определены различные сообщения для инкапсуляции сжатых и несжатых Ethernet-заголовков.
Схема.
Спецификация BNEP, версия 1.0, стр. 13
На приведенном выше рисунке показано, как заголовок BNEP преобразуется в заголовок Ethernet на основе конкретного типа сообщения BNEP. Таким образом, BNEP является упрощенной и сокращенной формой Ethernet которая передается только через Bluetooth.
Помимо сообщений об инкапсуляции, BNEP также поддерживает control message управляющее сообщение BNEP. Управляющее сообщение облегчает создание PAN-соединения (сетевой уровень, который находится на самой верхушке BNEP) и создание различных функций управления потоком.
Таблица.
Формат сообщения управления BNEP, Спецификация BNEP, Версия 1.0, стр. 17
Чтобы включить несколько управляющих сообщений в единичном сообщении L2CAP, заголовок дополнительного расширения также может добавляться к заголовку BNEP.
Каждый бит расширения («E» на приведенном выше рисунке) включается в заголовке BNEP указывает на начало заголовка расширения, который будет содержать дополнительное управляющее сообщение.
Таблица.
Формат заголовка расширения BNEP, Спецификация BNEP, Версия 1.0, стр. 39
В стеке Android обнаружены две уязвимости RCE в потоке кода, который обрабатывает входящие контрольные сообщения BNEP.
Уязвимость в Android RCE №1 - CVE-2017-0781
Первая уязвимость заключается в следующем вызове memcpy:
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset; ... type = *p++; extension_present = type >> 7; type &= 0x7f; ... switch (type) { ... case BNEP_FRAME_CONTROL: ctrl_type = *p; p = bnep_process_control_packet (p_bcb, p, &rem_len, FALSE); if (ctrl_type == BNEP_SETUP_CONNECTION_REQUEST_MSG && p_bcb->con_state != BNEP_STATE_CONNECTED && extension_present && p && rem_len) { p_bcb->p_pending_data = (BT_HDR *)osi_malloc(rem_len); memcpy((UINT8 *)(p_bcb->p_pending_data + 1), p, rem_len); ... } ...
Выдержка из обработчика сообщений BNEP от Android: bnep_data_ind
Вышеупомянутый поток кода - это процесс обработки входящих сообщений управления BNEP. BNEP_FRAME_CONTROL - это switch case коммутатор для сообщений управления BNEP. Этот конкретный/специфический поток представляет собой попытку обработки/управления уникального use case варианта использования: поскольку многократные сообщения управления могут проходить в единичном сообщении L2CAP (используя бит расширения), состояние соединения BNEP может меняться от одного сообщения управления к другому. Если, например, в качестве управляющего сообщения отправляется SETUP_CONNECTION_REQUEST, любые последующие сообщения управления могут быть проанализированы/разбиты, пока код находится в состоянии CONNECTED (а не в его начальном состоянии, которым является состояние IDLE). Для перехода в состояние CONNECTED требуется успешное завершение процесса аутентификации (как описано в предыдущем разделе), и поскольку этот процесс является асинхронным, состояние в этом контексте будет по-прежнему IDLE. Решение этой проблемы состоит в том, чтобы разбить/проанализировать оставшиеся управляющие сообщения позднее - поскольку процесс аутентификации завершен, и состояние соединения перешло в состояние CONNECTED.
Для этой цели приведенный выше код сохраняет оставшееся unparsed нераспакованное/не разбитое сообщение для последующего использования (в p_pending_data). Однако, в коде есть простая ошибка.
Сначала буфер p_pending_data выделяется в "куче" с размером rem_len. Позже memcpy сделанный в p_pending_data + 1 с размером rem_len.
Таким образом memcpy будет переполнять буфер по размеру (p_pending_data) байтов!
Можно задаться вопросом, как такая ошибка может остаться незамеченной, поскольку она доставляет так много неприятностей каждый раз после запуска этого кода. Кроме того, это приводит к внутренней утечке памяти, поскольку предыдущий указатель p_pending_data никогда не освобождается до тех пор, пока не произойдет другое распределение. Весьма вероятно, что этот код никогда не запускался, ни во время реального использования, и, возможно, даже не запускался при тестировании покрытия coverage.
Поле p_pending_data is of type является видом BT_HDR, длина которого составляет 8 байтов. Кроме того, rem_len, который управляет размером распределения, находится под контролем атакующего, так как это длина оставшихся не проанализированных/не распакованных байтов в пакете, а также источник для memcpy (p) который указывает на пакет, контролируемый атакующем.
Переполнение может быть инициировано путем отправки этого специально созданного пакета в BNEP-соединение:
Рисунок 3.
Таблица.
Поле типа состоит из бита extension_present (который установлен) и типа BNEP_FRAME_CONTROL (01). Поле ctrl_type устанавливается в BNEP_SETUP_CONNECTION_REQUEST_MSG (01). Это позволяет потоку достичь уязвимого вызова memcpy. Поле типа состоит из бита extension_present (который установлен) и типа BNEP_FRAME_CONTROL (01). Поле ctrl_type устанавливается в BNEP_SETUP_CONNECTION_REQUEST_MSG (01). Это позволяет потоку достичь уязвимого вызова memcpy.
Следует также отметить, что con_state по умолчанию не установлен на BNEP_STATE_CONNECTED. Внутри bnep_process_control_packet 0-значный len передает все проверки, в результате чего rem_len декрементируется должным образом. Таким образом, memcpy переполняет "кучу" байтами полезной нагрузки (переполнения).
Примечательно, что, поскольку можно отправить пакет произвольного размера, размер распределения osi_mallocр можно контролировать, так как rem_luxury - это размер полезной нагрузки в пакете. Это позволяет переполнять 8 байтов в "куче" (после) following a buffer буфера любого выбранного размера, что значительно облегчает использование.
Уязвимость Android RCE №2 - CVE-2017-0782
Вторая уязвимость также появляется в потоке, который встречается в bnep_data_ind. Она лежит в integer underflow of rem_len целочисленном нижнего потока rem_len в функции bnep_process_control_packet:
... if (is_ext) { ext_len = *p++; *rem_len = *rem_len - 1; } ... control_type = *p++; *rem_len = *rem_len - 1; ... switch (control_type) { ... default : ... if (is_ext) { p += (ext_len - 1); *rem_len -= (ext_len - 1); } break; } ...
Вторая уязвимость также появляется в потоке, который встречается в bnep_data_ind. После целочисленного нижнего потока rem_len в функции bnep_process_control_packet:...
Выдержка из обработки пакетами управления BNEP от Android: bnep_process_control_packet
Эта функция выполняет обработку всех управляющих сообщений BNEP, а заголовок расширения обрабатывает дополнительные под-сообщения, переданные внутри "родительского" управляющего сообщения. Спецификация BNEP позволяет игнорировать нераспознанные сообщения расширений принимающей стороной, и, таким образом, default выше, пытается пропустить нераспознанные управляющие сообщения, используя длину расширения из заголовка расширения.
Целочисленный rem_len определяется как 16-битный беззнаковый short короткий и представляет собой фактическое количество оставшихся unparsed нераспакованных байтов в пакете, контролируемом атакующим. Значение ext_len равно 8 битам без знака и является частью заголовка расширения, который также управляется атакующим.
Таким образом, надлежащее rem_len может быть внезапно опустошен почти до любого значения выше 0xff00, проделывая любую дальнейшую обработку пакета, зависящего от rem_len unsafe.
Например, если rem_len первоначально равен 10, а злоумышленник устанавливает ext_len равный 12, итоговое значение станет:
rem_len -= (12 - 1) ⇔ rem_len -= 11 ⇔ rem_len == 10 - 11 == 0xffff
В коде bnep_data_ind после вызова bnep_process_control_packet (теперь небезопасный) rem_len действительно используется опасным образом:
... while (extension_present && p && rem_len) { ext_type = *p; extension_present = ext_type >> 7; ext_type &= 0x7F; /* if unknown extension present stop processing */ if (ext_type) { ... break; } p++; rem_len--; p = bnep_process_control_packet (p_bcb, p, &rem_len, TRUE); } p_buf->offset += p_buf->len - rem_len; p_buf->len = rem_len; ... else if (bnep_cb.p_data_ind_cb) { (*bnep_cb.p_data_ind_cb)(p_bcb->handle, p_src_addr, p_dst_addr, protocol, p, rem_len, fw_ext_present); osi_free(p_buf); }
Выдержка из обработчика сообщений BNEP от Android: bnep_data_ind
Получающееся в результате переполненного rem_len затем напрямую устанавливается в len p_buf (фактическая структура пакета). Кроме того, под влиянием оказывается offset field поле смещения p_buf. Это смещение первого, еще не обработанного байта в пакете. Вместе эти поля определяют количество байтов, оставшихся в пакете для обработки верхних уровней.
Следуя значениям из нашего примера выше, если исходная длина была равна 15 (например), окончательное смещение окажется под влиянием следующим образом:
p_buf->offset += (15 - 0xffff) ⇔ p_buf->offset += 16
Поскольку теперь смещение небольшое, а len велико, любой код верхнего уровня, который обрабатывает этот пакет вынужден иметь дело с исключительно большой полезной нагрузкой. На данный момент злоумышленник может обойти большинство (если не все) ограничения MTU пакета В этом случае верхние слои лишь предполагают, что оставшаяся полезная нагрузка имеет достаточный размер.
Сразу после вызова bnep_cb.p_data_ind_cb (обратный вызов обработки верхнего уровня) происходит с неправильным вводом p_buf. Таким образом, можно получить следующий code path код, используя созданный пакет:
static void bta_pan_data_buf_ind_cback( uint16_t handle, const RawAddress& src, const RawAddress& dst, uint16_t protocol, BT_HDR* p_buf, bool ext, bool forward) { ... BT_HDR* p_new_buf; if (sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset) { /* offset smaller than data structure in front of actual data */ p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE); memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS), (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len); ... osi_free(p_buf); ...
Выдержка из обработчика сообщений PAN от Android: bta_pan_data_buf_ind_cback
Как и ожидалось, на данный момент нет никаких хороших проверок по offset и по len. Единственная проверка здесь подтверждает, что offset смещение меньше, чем sizeof (tBTA_PAN_DATA_PARAMS) (то есть 24), что не является проблемой. Однако osi_malloc выделяет буфер p_new_buf размера PAN_BUF_SIZE (который равен 4096) и memcpy копии p_buf -> len байтов в нем, которые должны были стать 0xffff раньше. Короче говоря, это приводит к переполнению 0xf000 байтов в "куче", проходя через 4096-байтовый буфер.
Исходные байты переполняющей memcpy не находятся под прямым контролем злоумышленника, поскольку они значительно превышают границы исходного пакета. Однако, поскольку они копируются из одной и той же области в куче в качестве исходного пакета, создать кучу-спрей (заранее) сущий пустяк, поскольку байты принятых пакетов в действительности контролируются атакующим. В результате уборка кучи до момента переполнения может позволить этой уязвимости вызвать удаленное выполнение кода.
Чтобы создать необходимые условия для достижения уязвимого потока, соединение BNEP должно быть в состояние BNEP_STATE_CONNECTED. Поэтому сначала нужно отправить действенный BNEP_SETUP_CONNECTION_REQUEST_MSG. Как только это состояние будет достигнуто, уязвимость может быть запущена с пакетом, например, как показано в следующем примере (6 байтов):
Таблица.
Поле типа указывает тип пакета BNEP_FRAME_COMPRESSED_ETHERNET, и устанавливается признак extension_present. Поскольку это сообщение отмечено битом расширения, уязвимая функция bnep_process_control_packet будет вызвана и контролируемый ext_len достигет антипереполнения rem_len (как объяснялось ранее). Поле control_type устанавливается в 0x10 для достижения the default clause предложения по умолчанию. Как только антипереполненный rem_len вернется из этой функции, он будет скопирован в pbuf-> len и будет также влиять на Pbuf->offset. Наконец, пакет будет передан в p_data_ind_cb, что приведет к bta_pan_data_buf_ind_cback в текущем состоянии, выполняя overflowing переполняющую memcpy.
Exploitability .
Как описано выше, обе уязвимости могут привести к переполнению кучи данными, контролируемыми атакующем. В первой уязвимости RCE злоумышленник может также контролировать размер распределения переполненного буфера, который может помочь ему с надежной обработкой кучи. При предварительной обработке кучи обе уязвимости могут в конечном итоге привести к управлению кодом. При использовании этих уязвимостей можно выполнить цепочку ROP, которая позволит злоумышленнику запустить любой код, который он хотел бы использовать в контексте стека Bluetooth.
Служба Bluetooth в Android работает под управлением Zygote (сервисный менеджер Android) и на удивление представляет собой 32-битный процесс (даже когда ОС и CPU - ARM-64, например). Это значительно облегчает эксплуатацию, поскольку значительно ограничивает энтропию ASRL, а в некоторых случаях делает он полностью инертной. Что еще более важно, сервис немедленно и автоматически перезапускается Zygote после его сбоя! Это дает атакующему бесконечные попытки атаки, когда надежность эксплойта влияет только на время, необходимое для успешного запуска.
При объединении уязвимости, связанной с раскрытием информации SDP (CVE-2017-0785) с одной из вышеупомянутых уязвимостей, полный байпас смягчения ASLR также может быть достигнут. Указатели, просочившиеся из стека, могут использоваться, чтобы позволить злоумышленнику узнать базовые адреса различных разделов процесса Bluetooth, и они могут использоваться злоумышленником для повышения одной из уязвимостей переполнения кучи до надежного управления кодом.
Видео.
Влияние.
Успешная эксплуатация приводит к удаленному выполнению кода в соответствии с привилегиями службы com.android.bluetooth. Эта услуга используется исключительно на устройствах Android: она имеет доступ к файловой системе (доступ к пользовательской телефонной книге, документам, фотографиям и т. д.), он полностью контролирует сетевой стек (что позволяет перераспределять данные, соединения MiTM и мосты сетей), и он даже имеет возможность имитировать прикрепленную клавиатуру или мышь, которые помогут злоумышленнику получить полный контроль над устройством. Кроме того, поскольку эта служба имеет полный контроль над интерфейсом Bluetooth, злоумышленник может также использовать интерфейс Bluetooth жертвы для атаки на другие устройства в его окружении, что делает этот вектор атаки вредоносной.
Профиль PAN
Обзор.
Следующей иерархией в Bluetooth, расположенной над различными службами, являются профили Bluetooth. Профили - это еще один уровень абстракции в Bluetooth. Например, профиль PAN (Personal Area Network - персональная сеть) определяет, как стек Bluetooth использует BNEP службы для создания IP-сетей на основе Bluetooth.
Персональная сеть (PAN) выполняет различные роли для каждого из ее подключенных членов:
Таблица.
Из документации BlueZ здесь.
В обычной ситуации, когда два устройства участвуют в сценарии соединения через Bluetooth, одно устройство должно быть NAP (точка доступа, маршрутизатор), а другое - PANU (клиент).
The Bluetooth Pineapple Аналоговый аналог Bluetooth - логическая ошибка CVE-2017-0783 & CVE-2017-8628 .
Как объяснялось в предыдущем разделе о SMP, злоумышленник может обойти аутентификацию и выполнить краткосрочное сопряжение с устройством, поддерживающем Android или Windows. Это позволит ему получить доступ к услугам и профилям более высокого уровня, а PAN профиль входит в число этих открытых профилей как в Android, так и в Windows стеках. Не все службы в этих операционных системах раскрываются таким же образом из-за того, что каждая служба определяет, какой «уровень безопасности» требуется для входящих и исходящих подключений, и не все «уровни безопасности» позволяют использовать «Just Works» в качестве основного механизма аутентификации.
Заходя немного глубже, можно найти виновника для довольно низкого требования «уровень безопасности» профиля PAN в стеке Bluetooth Android:
#define PAN_SECURITY (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_IN_ENCRYPT | BTM_SEC_OUT_ENCRYPT)
Выдержка из исходного кода Android Bluetooth (btif / include / btif_pan_internal.h)
Простое требование BTM_SEC_IN_AUTHENTICATE - это минимальное требование безопасности, которое может быть выполнено. К числу релевантных вариантов относятся:
#define BTM_SEC_IN_AUTHENTICATE 0x0002 /* Inbound call requires authentication */ #define BTM_SEC_IN_AUTHORIZE 0x0001 /* Inbound call requires authorization */ #define BTM_SEC_MODE4_LEVEL4 0x0040 /* Secure Connections Only Mode */ #define BTM_SEC_IN_MITM 0x1000 /* inbound Do man in the middle protection */
Выдержка из исходного кода Android Bluetooth (stack / include / btm_api.h)
Выбор более сильного сочетания требований помешал бы злоумышленнику, который аутентифицировал возможность подключения к профилю PAN через «Just Works». Более того, BTM_SEC_IN_AUTHORIZE, возможно, потребует дополнительной авторизации при доступе к этой службе, что позволило бы жертве отклонить (через диалоговое окно пользовательского интерфейса) соединение со злоумышленником.
Мы считаем, что в стеке Windows Bluetooth эта проблема, скорее всего, вызвана аналогичной неправильной конфигурацией в коде.
Из-за этого требования низкого «Уровень безопасности» злоумышленник может использовать возможности профиля PAN на устройстве-мишени без какого-либо разрешения. При попытке подключиться к профилю PAN с помощью полученного кратковременного ключа происходит следующее:
Таблица.
Захват Wireshark попытки подключения к профилю PAN
Передача аутентификации позволяет злоумышленнику добиться успешного подключения к службе BNEP (открытое соединение L2CAP), а затем злоумышленник пытается подключиться к профилю PAN через соединение BNEP (SetupConnectionRequest). Интересно, что инициатор соединения выбирает как роль инициирующего устройства, так и удаленного устройства. В этом случае соединение, в котором сторона атакующего является PANU, а жертвой является NAP, состоялось, но вскоре после этого было разъединено, вероятно, потому, что устройство жертвы обнаружило, что функция привязки отключена.
Однако, поскольку злоумышленник может выбирать обе роли для участников PAN, дополнительные комбинации могут быть предприняты, как показано в этой матрице действующих ролей:
Таблица.
Профиль персональной сети v1.0, стр. 19.
Реверсируя роли и определяя злоумышленника как NAP и жертву как PANU, соединение BNEP успешно работает! Это также работает, когда оба параметра установлены в NAP (хотя эта комбинация отмечена как недопустимая в вышеприведенной таблице). В этом случае устройство-жертва вынуждено рассматривать NAP как новый подключенный к сети сетевой интерфейс, что приводит к запросу DHCP от жертвы:
Таблица.
На данный момент злоумышленник может настроить DHCP-сервер и нажимать вредоносные статические маршруты, DNS-серверы и WPAD. Это по существу эквивалентно атаке WiFi pineapple через Bluetooth, только без какого-либо взаимодействия с пользователем.
Пакет ответов DHCP, контролируемый злоумышленником, может выглядеть так:
Таблица.
Демон клиента DHCP (работает на устройствах, поддерживающих Windows или Android) может принимать многие «варианты» в отличии от назначенного IP-адреса. Такие параметры, как статические маршруты, сетевая маска, шлюз по умолчанию и даже DNS-серверы are overridden переопределяются последней процедурой DHCP, выполняемой демоном.
Также учитываются другие параметры, такие как WPAD (URL-адрес для сценария конфигурации прокси-сервера в рамках всей системы) на Windows. Они могут позволить злоумышленнику открыть всплывающее окно браузера с контролируемой атакующим страницей.
Поскольку злоумышленник по желанию может принудительно выполнить процедуру DHCP , вредоносные настройки будут последними, и, следовательно, будут использоваться машиной-жертвой.
Видео.
Влияние.
Сила Wi-Fi-Pineapple хорошо известна - она может позволить злоумышленнику быть Man in the Middle человеком в центре всего трафика, который предназначен для маршрутизации к определенной сети или в Интернете - и, таким образом, перехватывать, вводить или изменять конфиденциальные данные, которые принимаются или отправляется с устройства-мишени.
Однако у Wi-Fi-Pineapple есть критические ограничения: он работает, "обнюхивая" запросы probe зонда/тестовые WiFi, отправленные устройствами, которые открывают сеть, а затем маскируют эти сети и отвечают от их имени. Поэтому сначала для Wi-Fi-Pineapple необходимо определить probe request тестовый запрос , который не может быть отправлен устройством, которое уже подключено к сети WiFi, и даже тогда это будут только открытые сети MiTM, которые не имеют ключа шифрования и, таким образом, не могут быть аутентифицированы подключенным устройством.
Вышеупомянутый логический недостаток демонстрирует возможность создавать аналог Bluetooth, который совсем не является предметом этих ограничений. Злоумышленник может принудительно подключиться к устройству-мишени, независимо от его состояния (кроме включенного Bluetooth). Атака также не зависит от того, какое устройство было подключено к открытым сетям WiFi в прошлом.
Заключение.
Спецификация профиля PAN детализирует требования безопасности PAN от базовых уровней стека Bluetooth. Тем не менее, этот документ был последний раз обновлен в 2003 году, и его последняя версия - v1.0. Фактически, механизма «Простого безопасного связывания», который используется Bluetooth сегодня, и позволяет осуществлять кратковременную аутентификацию через «Just Works», тогда даже не существовало. Требования безопасности в спецификации PAN не обновлены. Возможно, это привело к довольно низким требованиям уровня безопасности, определяемым как Windows, так и Android стеками для профиля PAN.
Проприетарные протоколы через Bluetooth
Хотя большинство поставщиков полагаются на службы, определенные в спецификации Bluetooth, после реализации своих стеков Bluetooth, некоторые вендоры создают свои собственные уровни протокола в стеке - иногда в самом ядре. Так обстоит дело с Apple, которая реализовала несколько уровней протокола, работающих на ряду с уровнем протокола определенного соединения Bluetooth - L2CAP.
Проприетарные протоколы Apple по Bluetooth
Несмотря на то, что iOS от Apple не была основным направлением наших исследований, мы обнаружили несколько интересных деталей при просмотре его Bluetooth-стека:
● В отличие от Android и Windows, iOS не позволяет проводить (silent молчаливую) аутентификацию через «Just Works» - как только злоумышленник пытается выполнить аутентификацию через «Just Works», пользователь устройства-мишени информируется, что устройство инициировало сопряжение с ним, и только если пользователь разрешает связывание, аутентификация будет успешной. Это, конечно, ближе к тому, что подразумевали разработчики спецификации Bluetooth, и является логичным способом реализации «Just Works».
● Кроме того, аутентификация соединений Bluetooth более тесно связана в iOS с созданием соединений L2CAP - как это и должно быть. В других стеках, которые мы рассмотрели, процесс аутентификации - это то, что может быть иницииировано в разные моменты жизни Bluetooth-соединения. Это может привести к тому, что потоки кода служб стека будут подвергаться воздействию неавторизованных подключений, поскольку они разрешают парсинг входящих пакетов параллельно с завершением процесса аутентификации. Однако в iOS реализация SMP намного строже: в отличии от SDP, соединение L2CAP не допускается, пока не завершен успешно процесс аутентификации. Это значительно ограничивает поверхность атаки неаутентифицированным злоумышленникам, создавая любые возможные уязвимости на более высоких уровнях из невыполнимого стека.
Несмотря на принятие надлежащих мер при разработке и внедрении механизмов безопасности SMP и L2CAP, Apple также реализовала проприетарные протоколы в стеке iOS, которые живут параллельно с L2CAP, которые не подпадают под действие одного и того же механизма безопасности. Поэтому, ужесточая механизмы безопасности в iOS, стек Bluetooth уменьшает открытую поверхность атаки, различные встроенные в него протоколы расширяют его.
Как описано в разделе, посвященном L2CAP, фиксированные CID хранятся в протоколе для конкретных целей. Например, номер CID 1 используется в качестве сигнального канала, а некоторые другие фиксированные CID также определяется:
Таблица.
L2CAP CID, спецификация Bluetooth v5.0, том 3, часть A, раздел 2.1, страница 1728
Собственные протоколы Apple используют диапазон фиксированных CID, которые зарезервированы спецификацией для будущего использования (В частности, CID 0x2A, 0x2B и 0x3A, но, возможно, и другие). Использование фиксированных идентификаторов CID позволяет Apple создать совершенно новую иерархию, которая (в некоторых случаях) полностью заменяет L2CAP.
Например, использование Apple фиксированного CID 0x3A (который называется“Piped Dreams” "Трубопроводные мечты» в некоторых из цепочек, которые указаны в его коде) имеет существенные потоки кода, которые реализованы в нем и во многих отношениях схоже с L2CAP:
Рисунок.
Обзор графика реализации Apple протокола “Pipe Dreams” (в IDA)
Многие из потоков кода, которые разветвляются из вышеперечисленной функции, приводят к тем же обработчикам, связанным с созданием соединений L2CAP. Таким образом, возможно, что путаница состояния, связанная с созданием соединений L2CAP, может быть результатом дублирования кода, который существует между «Pipe Dreams» и L2CAP. Более того, это совершенно новая поверхность атаки, характерная для стека Apple.
Поскольку эти протоколы являются проприетарными, они не документированы, и мы не знаем в полной мере их функциональных целей. Однако в одном из этих протоколов была обнаружена критическая уязвимость удаленного выполнения кода.
Apple LEAP - RCE в Apple Audio Protocol - CVE-2017-14315
Эта уязвимость была обнаружена в новом протоколе, разработанном Apple, который работает на вершине Bluetooth, называемый LEAP (Low energy audio protocol аудио протокол низкого уровня энергии). Этот протокол предназначен для потоковой передачи аудиосигналов на периферийные устройства с низким энергопотреблением, такие как низкоэнергетические гарнитуры, например, Siri Remote.
Некоторая документация по этому протоколу просочилась через patent filingпатентную заявку Apple. Похоже, что цель этого протокола позволить устройствам, которые имеют только Bluetooth Low Energy передачу звука и отправку Аудио команд. Однако как LEAP, так и «Pipe Dreams» по-прежнему подвержены потенциальным атакам злоумышленника, который подключается через классические соединения Bluetooth с целевым устройством. Каждый из этих протоколов реализует некоторые проверки того, что входящие соединения с их фиксированными CID исходят из соединений BLE, а не через соединения BR \ EDR (a.k.a «Classic») Bluetooth. Однако эти проверки не находятся в базовых уровнях этих протоколов, а скорее в отдельных обработчиках их различных обработчиков сообщений.
LEAP, например, выделяет два фиксированных CID для его работы:
● CID 0x2A зарезервирован для сигнального канала LEAP, и через него потоки LEAP (предположительно) могут быть созданы для передачи аудиоданных LEAP.
● CID 0x2B зарезервирован для пакетов аудиоданных LEAP, которые передают пакеты сжатого аудио.
Большая часть кода LEAP заключается в обработке сообщений, отправленных в его сигнальном канале. Как упоминалось выше - большая часть кода проверяет, что входящие сообщения исходят из соединений BLE - которые ограничивает его поверхность атаки. Однако эти проверки не соответствуют всем кодам LEAP.
В обработчике LEAP для входящих аудиоданных (при фиксированном CID 0x2B) эта проверка не эффектина. Это подвергает этот обработчик атакам, и поскольку это фиксированный CID, который не является предметом механизмов безопасности L2CAP или SMP, он полностью не аутентифицирован.
void leap_audio_handler(void *incoming_packet, size_t incoming_packet_length) { … void *audio_chunk = new(0x68); memcpy(audio_chunk, incoming_packet, incoming_packet_length); … audio_handler_callback(audio_chunk, incoming_packet_length); … }
Псевдокод обработчика аудиоданных LEAP (основанный на обратном проектировании iOS v9.3.5)
Рисунок.
Вывод кода сборки вышеперечисленного leap_audio_handler (из iOS v9.3.5)
В файле audio_handler_callback код подтверждает, что этот входящий пакет был получен от аутентифицированного соединения BLE. Однако к этому моменту вышеупомянутая memcpy уже может привести к переполнению кучи. Эта уязвимость - очень простая ошибка: код предполагает, что все входящие звуковые фрагменты LEAP ограничены максимум до 0x68 байтов - когда этот код запускается через классическое соединение Bluetooth, ограничения входящих пакетов не так малы и могут создать значительное переполнение данными, которые полностью контролируются атакующим. Поскольку это переполнение может запускаться несколько раз, эта уязвимость может привести к удаленному выполнению кода в контексте Bluetooth-стека iOS.
Влияние.
Из-за того, что эта уязвимость была смягчена в версии 10 для iOS, полный эксплойт не был разработан нами. Несмотря на это, эта уязвимость по-прежнему представляет большой риск для любого устройства iOS, выпущенного до 10-ой версии, поскольку он/оно не требует какого-либо взаимодействия пользователя или конфигурации любого типа на целевом устройстве и может использоваться злоумышленником для получения удаленного кода в высоко привилегированном контексте (процесс Bluetooth).
Итоговые заметки
Уязвимости, описанные выше, и связанные с ними методы эксплуатации не очень сложны. Они демонстрируют, как у протоколов, которые трудно реализовать, бывают сбои. Разработчики такого сложного стандарта, как Bluetooth, должны в значительной степени полагаться на рекомендации, представленные в спецификации, которая сильно устарела в определенных частях, а в некоторых частях и вовсе отсутствует. Исследователь или злоумышленник, обладающий знаниями о неясных функциях, реализованных в Bluetooth, может попасть(?)в относительно неинициализированная/не изученную поверхность атаки.
Из наших данных видно, что реализация Bluetooth не получила такого же уровня контроля и исследования, которые есть у других внешних протоколов (например, Wi-Fi или TCP \ IP стеки). Это может быть связано с относительной сложностью Bluetooth и высоким барьером входа для исследователя, который пытается изучить Bluetooth. Другим способствующим фактором являются два распространенных заблуждения относительно Bluetooth: во-первых, что соединения в Bluetooth должны происходить между сопряженными устройствами (которых у них нет), а другой - это MAC-адреса устройств (BDADDR) безопасно скрыты, пока они не находятся в режиме обнаружения (а это не так).
Результатом отсутствия надлежащей проверки и тестирования реализации Bluetooth является крупный и всеобъемлющий вектор атаки. Хотя становится все труднее получить полный контроль над устройствами через основные процессы, многие игнорируют, по-видимому, его периферийные части, такие как стек Bluetooth. Атакующие могут атаковать эти разделы устройства и управлять ими через них, поскольку они являются неотъемлемой частью операционной системы - либо как часть самого ядра, либо как высокоприоритетные процессы поверх него. Сообществу безопасности необходимо сделать так, чтобы не осталось открытых дверей и не было угроз уязвимости, которые мы описали здесь, и которые предоставляют злоумышленникам полный контроль.
Мы надеемся, что этот документ станет первым шагом для более широкого и всеобъемлющего аудита проблем безопасности, которые могут таиться в различных стеках Bluetooth, которые являются частью тех 8,2 миллиардов устройств Bluetooth, используюемых сегодня. Мы призываем других исследователей использовать этот документ в качестве руководства по преодолению различных подводных камней, которые могут существовать в реализациях Bluetooth-стеков.