[Перевод] Send My: Произвольная передача данных по сети Apple Find My 

  • Можно загружать произвольные данные с устройств, не подключенных к интернету, широковещательно посылая сообщения Find My по технологии BLE (Bluetooth с низким энергопотреблением) на расположенные поблизости устройства Apple, которые затем загружают данные для вас
  • Мы выпустили прошивку для ESP32, превращающую микроконтроллер в модем (работающий только на загрузку) и приложение для macOS, предназначенное для извлечения, декодирования и отображения загруженных данных: https://github.com/positive-security/send-my
  • В силу природы той парадигмы приватности и безопасности, на которых  основан дизайн системы оффлайн-поиска Find My, представляется маловероятным, что такое злоупотребление ею можно будет полностью предотвратить 
tcastkpfzoe5ghv2-ctcx9nd-he.png

Find My modem (ESP32) // Модем Find My (ESP32)

Nearby Apple Devices // Расположенные поблизости устройства с Apple

Mobile Tower or Wifi Access Point // Сотовая вышка или точка доступа Wifi

macOS device with data retrieval app // Устройство macOS с приложением для извлечения данных

Data flow // поток данных

.

Введение


После состоявшегося недавно релиза технологии AirTags от Apple я заинтересовался, можно ли злоупотреблять системой оффлайнового поиска «Find My», чтобы загружать в Интернет произвольные данные с устройств, не подключенных к WiFi или мобильному интернету. Эти данные могли бы широковещательно транслироваться по Bluetooth с низким энергопотреблением и подхватываться устройствами Apple, расположенными поблизости. Эти устройства, стоит им подключиться к Интернету, сразу переправляли бы эти данные на сервера Apple, откуда их впоследствии можно извлечь. Такой прием мог бы использоваться небольшими сенсорами в неконтролируемых окружениях, чтобы не тратить лишнюю энергию на использование мобильного Интернета. Кроме того, она могла бы быть интересна для кражи данных из мест, защищенных клеткой Фарадея, стоит туда только заглянуть человеку с айфоном. 
Теоретически такое должно быть возможным: если удастся эмулировать два AirTags, то можно закодировать данные, активировав в конкретный момент времени лишь один из них. В таком случае устройство-получатель должно проверить, какой AirTag был активен в какое время, и декодировать данные обратно в исходный вид. Однако такая схема представляется исключительно ненадежной и, пожалуй, непригодной к использованию в реальных практических ситуациях по причине очень узкой полосы передачи данных (особенно с учетом ограничения в 16 AirTag на Apple ID представлялось, что объем передаваемых данных не может превышать нескольких бит в час).

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


‍Результат: извлечение ранее переданных/загруженных данных при помощи специального приложения Mac

Описание сети оффлайнового поиска


К счастью, этот протокол уже был в значительной степени воспроизведен методом реверс-инжиниринга группой исследователей из Дармштадтского Технического Университета, опубликовавших статью «Who Can Find My Devices?» в марте 2021 и для проверки концепции выпустивших реализацию OpenHaystack с открытым исходным кодом. При помощи этой реализации можно создавать собственные компоненты, отслеживаемые в сети Apple Find My. Огромная благодарность этой команде! Именно благодаря их работе смогла состояться наша, и на OpenHaystack основана как наша прошивка (также сделанная для проверки концепции), так и приложение для Mac.

В слегка упрощенном виде принцип работы оффлайновой системы поиска Find My таков:

  1. При сочетании метки AirTag с устройством Apple, совместно генерируется пара ключей на эллиптических кривых, причем, открытый ключ остается на AirTag (а также используется разделенный секрет для генерации сменяющихся открытых ключей)
  2. Каждые 2 секунды AirTag посылает широковещательное сообщение по низкоэнергетическому протоколу Bluetooth, причем, содержимым этого сообщения является открытый ключ (детерминированно меняется каждые 15 минут при помощи заранее разделенного секрета)
  3. Расположенные поблизости айфоны, макбуки, т.д., распознают широковещательное сообщение Find My, определяют свое текущее местоположение, шифруют его широковещательно переданным открытым ключом (при помощи механизма ECIES) и загружают на сервер зашифрованный отчет о местоположении 
  4. В ходе поиска устройств сопряженное Устройство Владельца генерирует список сменных открытых ключей, которые AirTag, должно быть, использовал в последние дни, и запрашивает у сервиса Apple их хеши SHA256. Бэкенд Apple возвращает зашифрованные отчеты о местоположении для тех ключей, чьи идентификаторы были запрошены. 
  5. Устройство владельца дешифрует отчеты о местоположении и выводит приблизительное местоположение. 

19a150097f8e9d8b2d75ed720014c4a1.png

Apple’s servers // Серверы Apple

Finder devices // Ищущие устройства 

Owner device // Устройство владельца

Lost device // Потерянное устройство

  1. // Сопряжение при начальной настройке
  2. // Широковещание. Представление Bluetooth с открытым ключом
  3. // Загрузка зашифрованных отчетов о местоположении
  4. // Скачивание и дешифрование отчетов о местоположении

Рис. 1. Упрощенная схема потока задач, решаемых при оффлайновом нахождении устройств 

Этот весьма красивый дизайн обладает характерными свойствами безопасности, в частности:

  • Защита от отслеживания, направленная против находящихся поблизости злоумышленников, обеспечивается сменными открытыми ключами 
  • Невозможность определить местоположения пользователей Apple 

Однако для нас в данном случае наиболее интересно вот что: Apple не знает, какие открытые ключи относятся к вашему AirTag, и, соответственно, какие отчеты о местоположении адресованы вам. Таким образом, оконечная точка, запрашивая отчеты о местоположении по конкретному id ключа, не выполняет при этом никакой авторизации (но вы должны аутентифицироваться по вашему Apple ID, чтобы получить доступ к оконечной точке). 

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

Проектирование протокола кражи данных 


На основе сказанного напрашивается вывод, что единственный носитель, которым мы можем воспользоваться, чтобы зашифровать данные — это широковещательно распространяемый открытый ключ EC (напр., мы не можем повлиять на GPS-координаты, поскольку их добавляет «ищущее» устройство).

В следующем разделе будем считать бекенд Apple разделяемым хранилищем значений открытых ключей, где в качестве ключа применяется хеш SHA256, а в качестве значения — зашифрованный отчет о местоположении, причем, основные операции таковы:

  • Можно проверить, существуют ли отчеты о местоположении для конкретного хеша whether SHA256 
  • Можно добавить отчеты о местоположении к конкретному хешу SHA256, широковещательно транслируя соответствующий открытый ключ 

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

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

Не существует гарантий по поводу того, когда конкретные широковещательные сообщения будут загружаться на бекенд Apple в виде отчетов о местоположении (и будут ли вообще). Дело в том, что некоторые пакеты могут не дойти ни до одного устройства с Apple, а у ищущих устройств могут быть сильно варьирующиеся задержки между получением широковещательного сообщения и загрузкой отчета о местоположении, что может зависеть от восходящей соединяемости или режима питания. Таким образом, наша кодировка данных не должна зависеть от того, какие отчеты о местоположении прибывают и в каком порядке, а также позволять восстанавливать частично полученные потоки данных — те, некоторые биты в которых совершенно утрачены. Чтобы добиться этого, я решил зашифровать по одному биту данных на каждую широковещательную передачу, вместе с индексным значением, указывающим, какой бит сообщения задан. Благодаря дополнительному сообщению и ID модема, система пригодна для многократного применения множеством пользователей, обрабатывая множество сообщений.

Итак, отправляя конкретный бит, мы создаем 28-байтный массив вида »[4b индекс бита] [4b ID сообщения] [4b ID модема] [заполнение нулями…] [значение бита]», оперируем им как открытым ключом и отправляем представления BLE, например, для широковещательной передачи информации «бит 0 сообщения 0 равен 1».

Для отправки полного сообщения программа просто перебирает все свои биты и отправляет по представлению на бит с открытым ключом, в котором зашифрованы индекс и значение этого бита.

fc8ba2d2636b40f09b8cbe2d6d669f9c.png

Message to encode // Сообщение, которое нужно закодировать

Generated public key to broadcast // Сгенерированный открытый ключ для широковещательной передачи

Bit index // Индекс бита

Bit value // Значение бита

Кодирование бит сообщения в широковещательно передаваемую полезную нагрузку

При выборке данных приложение-получатель будет генерировать такие же 28-байтные массивы (по два на бит, где возможными значениями бита являются 0 и 1) и запрашивать сервис Apple с хешами SHA256 этих «открытых ключей». Только к одному из этих ключей должны быть прикреплены отчеты о местоположении, что затем поддается интерпретации (напр., бит с индексом 0 равен 1).

cc67c0fc39d690e382f1810048d4e7db.png

Potential bits to query // Биты, которые потенциально можно запрашивать

Potential public keys to test // Открытые ключи, которые потенциально можно протестировать

Query Apple Backend // Запрос к бекенду Apple

Decode public key existence back to original data // Расшифровываем открытый ключ, получая исходные данные

Извлечение ранее отправленных данных с устройства с macOS, подключенного к Интернету

Примечание: можно передавать не только всего один бит на сообщение, а, например, посылать целый байт, в котором будут записаны последние 8 бит открытого ключа. Притом, что для этого требуется более широкая полоса передачи данных, на стороне получателя теперь придется запрашивать 255 разных идентификаторов ключей, чтобы выбрать/подобрать простым перебором один байт (сравните с 16 ID ключей при побитовой кодировке).

Реализация


Сторона отправителя


На стороне отправителя я решил использовать ESP32 — совершенно обычный и дешевый микроконтроллер (а быстрый тест показал, что он может менять адрес BT MAC гораздо быстрее, чем, скажем, Raspberry Pi, основанная на Linux). При загрузке прошивка, основанная на OpenHaystack, широковещательно передает жестко закодированное заданное по умолчанию сообщение, а затем слушает последовательный интерфейс (в виде цикла), не поступят ли какие-то новые данные для широковещательной передачи — и так продолжается, пока не будет получено новое сообщение. При широковещательной передаче открытого ключа его требуется разделить на части и закодировать первые 6 байт в адресе Bluetooth MAC (все биты кроме первых двух, поскольку стандарт Bluetooth требует, чтобы первые два бита были установлены в 1). Отсылаем вас к разделу 6.2 из статьи Дармштадтского Технического Университета,  где эта самодельная кодировка описана подробнее.

Я добавил к моей полезной нагрузке статический префикс, чтобы не нарваться на проблемы со спецификацией BT, а также включил инкрементный битовый индекс в первые 6 байт открытого ключа, в результате чего получилось так, что у каждого передаваемого бита свой адрес BT MAC, просто на случай, если где-нибудь в стеке стоит ограничение частоты, основанное на MAC-адресах.


Вывод модема ESP32 в последовательной консолиа

Сторона извлечения данных


Приложение для Mac также основано на OpenHaystack и использует тот же фокус с плагином AppleMail, чтобы отправлять к бекенду Apple правильно аутентифицированные запросы на извлечение местоположения. Пользователь получает приглашение ввести 4-байтный ID модема (может быть установлен в процессе прошивки ESP), после чего приложение автоматически выберет, декодирует и отобразит сообщение с id 0. Затем пользователь может выбрать другие сообщения или сменить модем.

Сообщение выбирается по 16 байт (128 бит) за раз (при этом запрашивается 256 id ключей), пока не останется ненайденных отчетов (за целый байт).

Небольшое осложнение: срок действия открытого ключа

 
Реализовав и сторону отправителя, и сторону получателя, я провел первый тест, широковещательно передав и попытавшись получить 32-битное значение. Спустя пару минут, я смог достать 23 из 32 бит, каждый — однозначно верный и примерно с 100 отчетами о местоположении, но не получил ни одного такого отчета на оставшиеся 9 бит.

Заподозрил, что некоторые из сгенерированных открытых ключей были отклонены расположенными поблизости устройствами Apple на этапе шифрования ECIES как недействительные открытые ключи — и это удалось быстро подтвердить, попытавшись загрузить каждую из сгенерированных полезных нагрузок как закодированные при помощи SEC-1 открытые ключи на кривой P224 при помощи пакета Python fastecdsa: для каждого бита, по которому у меня не нашлось отчетов о местоположении, микроконтроллер широковещательно передал открытый ключ, выбрасывающий исключение InvalidSEC1PublicKey при импорте ключа fastecdsa.

Небольшой контекст применяемого здесь шифрования:

  • 28-байтный EC public представляет координату X конкретной точки, закодированную при помощи SEC1. 
  • У открытого ключа SEC1 обычно также есть «знаковый» бит, от которого зависит, какая из двух возможных координат Y для данной конкретной координаты X должна кодироваться. Этот бит при широковещании не передается и не важен применительно к сроку действия открытого ключа 
  • При декодировании сжатого открытого ключа соответствующая координата Y вычисляется с использованием фиксированных параметров кривой и проверяется, действителен ключ. Некоторые сгенерированные открытые ключи этот тест не проходят. Подробнее об этом рассказано в разделе 3.2.2 в статье «Валидация открытых ключей на эллиптических кривых»:

560e90faca38a54fcb4d75bd68422263.png

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

  1. Перед широковещательной отправкой полезной нагрузки проверьте, на самом ли деле та точка эллиптической кривой, что ей соответствует, является валидной для используемой кривой. Если нет, то увеличивайте счетчик на единицу до тех пор, пока не найдется действительный открытый ключ. Это детерминированный процесс, схожим образом он выполним и оффлайн при помощи приложения для извлечения данных, перед тем, как запрашивать id ключа 
  2. Интерпретировать полезную нагрузку как закрытый ключ (а не открытый). Тогда как сжатый 28-байтный открытый ключ интерпретируется как координата X потенциальной точки на кривой, 28-байтный закрытый ключ интерпретируется как скаляр, участвующий в умножении точки эллиптической кривой на скаляр и, следовательно, всегда результирует в точку, действительно расположенную на кривой (открытый ключ)

Преимущество второго варианта заключается в том, что на каждый полученный бит мы также могли бы дешифровать и отчеты о местоположении, чтобы определить, в какой точке был получен данный бит, но для этого требуется несколько больше вычислительной обработки. Реализуя такой вариант, я обнаружил, что из-за багов в реализации умножения эллиптических кривых в используемой для этого библиотеке uECC, для некоторых закрытых ключей ESP вычисляла иные открытые ключи, нежели BoringSSL на Mac и fastecdsa на Python (случайно вкрался дифференциальный фаззинг?). Эти открытые ключи даже считались недействительными собственной функцией uECC uECC_valid_public_key (). Следовательно, в этом пилотном проекте я остановился на варианте 1.
2bf4cdeb3aadb5e3f46778430770ac9f.png

Message to encode // Кодируемое сообщение

Generate public key to encode // Генерируем открытый ключ для кодирования

BT MAC address // адрес BT MAC

Test validity, else increment counter // Проверить, действителен ли ключ, если нет — увеличить счетчик на единицу

Advertisement payload // Полезная нагрузка для представления

Кодирование и отправка сообщения

Тестирование / Производительность


Когда у нас реализована проверка валидности открытого ключа, все работает безупречно. Я не делал обширного тестирования производительности и не вдавался в измерения, но вот некоторые оценки:
  • Скорость передачи на микроконтроллере в настоящее время составляет  ~3 байт в секунду. Можно было бы достичь и более высоких скоростей, просто кэшируя результаты кодирования или кодируя всего один байт на каждое представление 
  • В моих тестах скорость приема была ограничена из-за медленного аппаратного обеспечения Mac. На извлечение 16 байт одним запросом уходит ~5 секунд
  • Задержка обычно составляет от 1 до 60 минут, в зависимости от того, сколько вокруг устройств, и от других случайных факторов. На следующем графике показано распределение задержки между широковещательной передачей открытого ключа и загрузкой соответствующего отчета о местоположении. Правда, отметьте, что кривая построена по данным о загрузке отдельных отчетов, и не дает точных данных о том, когда именно такой отчет можно будет скачать (чтобы это определить, обычно достаточно уже первого отчета о местоположении от любых расположенных поблизости устройств Apple)

34863df685d15f863c29a6bc69f962b2.png

CDF // Кумулятивная функция распределения

Median… min // Медиана… 26,3 мин.

Publication delay (min) // Задержка до публикации (мин.)

Рис. 8. Задержки при поступлении всех отчетов, рассмотренных в § 7.1 как кумулятивная функция распределения

Задержки при поступлении отчетов, измеренные командой из Дармштадского Технического Университета, по материалам «Who can Find My Devices?»

Потенциальные способы применения


Притом, что в основном мне было интересно проверить осуществимость описанного, полагаю, потенциально наиболее распространенное практическое применение — загрузка показаний датчиков или любых данных с устройств IoT без широкополосного модема, SIM-карты, тарифного плана или Wifi-соединяемости. Учитывая, что Amazon использует подобную сеть под названием Sidewalk, использующую устройства Echo,  на такие технологии вполне может быть спрос. Поскольку в кэше ищущих устройств скапливаются полученные широковещательные сообщения, оставаясь там, пока не будет установлено подключение к Интернету, датчики могут отправлять данные даже из районов, где нет покрытия мобильными сетями, если в таких местах ходят люди с устройствами.

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

Также представляется, что протокол оффлайнового обнаружения может использоваться для истощения трафика на расположенных поблизости айфонах, подключенных к небезлимитным тарифам. При ограничении количества отчетов о местоположении, которые можно отправить с одного ищущего устройства (255 отчетов/отправок, поскольку счетный байт равен 1), а также притом, что размер каждого отчета превышает 100 байт, широковещательная передача множества уникальных открытых ключей может приводить к значительному увеличению трафика, исходящего со смартфона. Хотя, я и не заметил никакого ограничения по частоте для исходящих отчетов о местоположении, я также не тестировал, сколько данных при этом может быть потреблено.

Как сгладить проблему


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

Apple проектировала систему, исходя из принципа экономии данных. Они не могут читать незашифрованные местоположения и не знают, ни какие открытые ключи относятся к вашему AirTag, ни даже с каким открытым ключом связан конкретный зашифрованный отчет о местоположении (поскольку получают только хеш SHA256 открытого ключа).

В таком свете заявленное ограничение в 16 AirTags на Apple ID представляется интересным, так как мне кажется, что на данный момент Apple не в силах обязывать к его использованию. 

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

  • Аутентификация представления BLE. В настоящее время ищущие устройства не различают, например, AirTag и его клон на основе OpenHaystack, тем самым допуская спуфинг в виде многих тысяч несуществующих AirTag для кодирования и передачи данных. Можно попробовать подписывать открытые ключи, но, учитывая, что размер представления BLE уже исчерпан, отметим, что AirTag низкоэнергетические и не подключены к Интернету, а широковещательно передаваемые ключи постоянно проходят ротацию, так что задача не из легких.
  • Ограничение частоты при получении отчетов о местоположении  Тогда как Apple не знает, связан ли id запрошенного ключа к id одного из запрашивающих пользовательских AirTag, можно кэшировать id запрошенных ключей и обеспечивать, чтобы в течение 15 минут можно было запросить не более 16 новых id ключей и Apple ID (но для первичного поиска в последнее время допустимое количество id стало гораздо больше). Притом, что такой подход реализовать проще, здесь есть лазейка: использовать по принципу карусели множество свободных Apple ID и задействовать их для извлечения данных.

Заключение


В этой статье мы ответили на вопрос о том, можно ли загружать произвольные данные при помощи устройств с Apple, принадлежащих другим пользователям: однозначно да.

Реализована прошивка модема ESP32 и приложение для извлечения данных под macOS, они выложены на Github,  можете с ними поэкспериментировать.

Обращаю внимание, что эта реализация — лишь «доказательство осуществимости», и сам «протокол» ни шифруется, ни аутентифицируется. Например, можно исследовать данные модема с ID 0×42424242, просто введя его ID (может быть, тем временем кто-то также сможет продемонстрировать, что в этом протоколе отсутствует аутентификация).

Последнее замечание: Готовя этот пост, я заметил, что «байт состояния», включаемый в представление BLE очевидно используется, например, как индикатор уровня заряда. В сочетании с детерминированно генерируемыми закрытыми ключами, которые проходят ротацию, здесь, вероятно, открывается еще одна брешь для утечки данных (по байту на представление), но этот подход я не тестировал.


Облачные серверы от Маклауд быстрые и безопасные.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

et1aypandyuamqprsz3m2ntm4ky.png

© Habrahabr.ru