В устройствах Apple есть прекрасная функция Airdrop — она сделана для пересылки данных между устройствами. При этом никакой настройки и предварительного сопряжения устройств не требуется, все работает из коробки в два клика. Для передачи данных используется надстройка над Wi-Fi, и поэтому данные передаются с огромными скоростями. При этом используя некоторые трюки, можно не просто пересылать файлы, но и узнать телефонный номер человека, находящегося с тобой в одном вагоне метро.
Последний год я использую эту функцию для интересных знакомств по пути на работу, в общественном транспорте, в общепитах. В среднем за день у меня получается заводить несколько новых знакомств, и иногда я выхожу из метро в компании нового человека.
Под катом я расскажу за всю хурму.
Как работает AirDrop
AirDrop это протокол для передачи файлов внутри одноранговой сети. Он может работать как по обычной локальной сети, так и по воздуху между любыми устройствами Apple. Мы будем разбирать последний случай, когда два устройства не подключены в общую сеть, а просто находятся рядом, например два человека c телефонами едут в вагоне метро и не подключены к общему Wi-Fi.
Первый этап передачи через AirDrop — рассылка BLE пакета
Чтобы инициировать передачу данных через AirDrop, телефон инициатора посылает широковещательный BLE-пакет, в котором содержится захешированная информация об iCloud аккаунте и телефонном номере владельца устройств инициатора, с предложением установить подключение через протокол AWDL (Apple Wireless Direct Link), что-то вроде Wi-Fi Direct из мира Android. Структура этого BLE-пакета очень интересна, мы разберем ее дальше.
На стороне получателя AirDrop может быть в трех состояниях:
- Выключен — не будет обнаруживаться вообще
- Только для контактов — принимать файлы только от контактов из записной книжки. При этом контактом считается номер телефона или email, к которому привязан icloud аккаунт. Здесь работает та же логика привязки аккаунтов, что и с мессенджером iMessages.
- Для всех — телефон будет обнаруживаться для всех
Настройки приватности AirDrop. Состояние по умолчанию установлено «Для контактов».
В зависимости от настроек приватности, телефон либо продолжит установку соединения через AWDL, либо просто проигнорирует BLE-пакет. Если для AirDrop установлена настройка «для всех», то на следующем шаге устройства соединятся друг с другом через AWDL, поднимут между собой IPv6-сеть, внутри которой AirDrop будет работать как обычный прикладной протокол с помощью mDNS через стандартный протокол IP.
Для экспериментов вы можете посмотреть за тем как работает AWDL на макбуке. Весь обмен по этому протоколу происходит через интерфейс awdl0, который можно легко снифать с помощью Wireshark или tcpdump.
На данном этапе мы знаем три сущности:
Bluetooth LowEnergy (BLE) пакет — этот пакет содержит данные, на основании которых телефон решает, есть ли инициатор в его списке контактов или нет.
Apple Wireless Direct Link (AWDL) — фирменная замена Wi-Fi Direct от Apple, включается если общение по BLE прошло успешно.
AirDrop — прикладной протокол, который работает внутри обычной IP-сети с использованием mDNS, HTTP и т.д. Может работать внутри любой Ethernet-сети.
Структура BLE-пакета
Может показаться, что этот BLE-пакет пролетает только один раз от инициатора к получателю, а дальше обмен происходит только по AWDL. В действительности соединение AWDL живет очень мало, всего несколько минут или меньше. Так что в случае, если получатель файла захочет вам ответить, он так же выступит инициатором и пошлет BLE-пакет.
Как телефон на принимающей стороне понимает, есть ли номер/email инициатора в его списке контактов или нет? Я очень удивился, когда узнал ответ: инициатор шлет свой номер и email в виде хеша sha256, но не целиком, а только первые 3 байта.
Структура BLE-пакета от инициатора AirDrop. По хешам от телефонного номера и email ответчик понимает, есть ли инициатор в его списке контактов.
Например, если ваш Apple-аккаунт (он же iCloud, он же iMessages) привязан к номеру +79251234567, хеш от него будет считаться так:
echo -n "+79251234567" | shasum -a 256
07de58621e5d274f5844b6663a918a94cfd0502222ec2adee0ae1aed148def36
И в итоге в BLE-пакете улетит значение 07de58 для телефонного номера. Этого кажется мало, но часто этих трех байт достаточно, чтобы узнать реальный номер телефона.
Важно также помнить, что настройка приватности AirDrop не влияет на данные в BLE-пакете. Хеш от телефонного номера будет содержаться в нем, даже если установлена настройка «Для всех». Также BLE-пакет с хешем телефонного номера посылается в случае открытия окна Share (Поделиться) и при вводе пароля к Wi-Fi сети.
Подробный разбор структуры BLE-пакетов и возможных атак на него читайте в исследовании Apple Bleee и русский перевод на Хабре.
В исследовании Apple Bleee опубликованы готовые скрипты на python для автоматизации анализа данных в BLE-пакетах. Я очень рекомендую изучить исследование и попробовать программы, там много чего интересного.
AWDL (Apple Wireless Direct Link)
AWDL — это такая проприетарная надстройка Apple над обычным Wi-Fi, реализующая что-то вроде Wi-Fi Direct. Я до конца не знаю как она работает, там особый способ анонсирования и согласования каналов, и работает это только на проприетарных драйверах Apple. То есть только макбуки/айфоны могут соединяться через AWDL.
Грустные владельцы телефонов Android пока еще только мечтают о нормально работающей функции Wi-Fi Direct.
Но не так давно ребята из seemoo-lab написали полностью открытую реализацию AWDL и назвали ее Open Wireless Link (OWL). Для запуска OWL, адаптер Wi-Fi должен поддерживать мониторный режим и инъекции пакетов, поэтому запускается не на каждом железе. На сайте есть примеры настройки на raspberry pi. Работает это существенно хуже оригинального AWDL, например время установки подключения растягивается на ~10 секунд вместо пары секунд у оригинала, но работает.
Также эти ребята написали с нуля реализацию протокола AirDrop на питоне, называется OpenDrop. Его можно использовать как в связке с OWL, для запуска AirDrop на линуксе так и с оригинальным AWDL на macOS.
Как подкатывать через AirDrop
Типичная ситуация с подкатыванием через AirDrop
Хватит скучной теории, пора приступать к практике. Итак ты вооружился всем необходимым оборудованием и готов выдвигаться подкатывать шары с помощью высоких технологий.
Для начала нужно запомнить основные моменты:
- AirDrop сработает только если телефон разблокирован — лучше всего, если цель непрерывно смотрит в телефон. Чаще всего это происходит в местах где скучно, например в метро.
- Нужно время — обычно, положительная конверсия происходит на 3-5 отправленной картинке, поэтому нужно хотя бы 5 минут спокойного нахождения на одном месте. Положительной конверсий я считаю момент, когда вы договорились через AirDrop продолжить общение в мессенджере. Это сложно реализовать на ходу, потому что не сразу понятно, кто принял твоей пейлоад, и скорее всего вы разминетесь раньше, чем сможете о чем-то договориться.
- Персонализированный креатив работает лучше — я называю пейлоадом тот медиаконтент, который ты отправляешь через AirDrop. Просто картинка с мемом, скорее всего, ни к чему не приведет, контент должен быть релевантным ситуации и иметь понятный call to action.
Способ классический — только телефон
Подходит всем у кого есть айфон, не требует особых навыков кроме социальных. Переводим AirDrop в режим Everyone и спускаемся в метро. В обычный день (до самоизоляции) в вагоне московского метро я наблюдал примерно такую картину:
List of targets
Как видно, почти все телефоны броадкастят имя владельца, по которому мы легко можем определить его пол и подготовить соответствующий пейлоад.
Пейлоад
Как я писал выше, уникальный пейлоад работает лучше. В идеале картинка должна обращаться к владелице по имени. Раньше мне приходилось ваять креатив с помощью графического редактора в приложении «заметки» и какого-то огрызка мобильного фотошопа. В итоге, к моменту пока нужная картинка была отрисована, уже нужно было выходить из вагона.
Моя подруга Аня koteeq, специально по моей просьбе, написала Телеграм-бота, который генерирует нужные картинки с подписью на лету: @AirTrollBot. Спасибо ей огромное за то, что я теперь могу подкатывать шары намного технологичней, чем раньше.
Достаточно отправить боту строчку с текстом, и он сгенерирует ее в виде картинки точно подходящей по соотношению сторон для превью в окне AirDrop. Можно выбрать персонажа на картинке нажатием кнопок. Также опционально можно включить добавление вашего Телеграм-логина на картинку в углу.
Payload generator
Самый жир был в том, что картинка показывалась сразу на экране жертвы без каких-либо действий. Не нужно даже было нажимать «принять». Можно было видеть мгновенную реакцию на лице от загрузки пейлоада. К сожалению, с версии iOS 13 картинки от незнакомых контактов больше не показываются на экране. Вот, как это выглядело раньше:
Payload delivered on iOS ≤12
Сейчас вместо превью показывается только имя устройства отправителя. Поэтому единственный способ обратиться к жертве с iOS ≥13 по имени, это задать его в настройках вашего устройства, например назвать телефон «Юля, привет». Hint: в названии устройства можно использовать эмодзи. Конечно такой способ не настолько яркий, как с картинкой, но сильно повышает шанс нажатия кнопки «принять».
Дальнейшее описание действий выходит за рамки технической статьи и зависит только от вашей фантазии, импровизации и юмора. Могу сказать только, что те, кто вступают в эту игру и начинают отвечать вам картинками или посылать заметки, как правило очень веселые, открытые и интересные люди. Те, кто посмотрев картинку просто не отвечают, или того хуже, просто отклоняют сообщение, обычно скучные снобы и ханжи. Также нередко играет роль фактор страха: хрупкие пугливые люди боятся взаимодействовать с таким наглым анонимным незнакомцем.
Автоматическая дикпик-машина
Если тебе лень генерировать и рассылать пейлоады вручную, и ты хочешь автоматизировать процесс, можно изготовить автоматическую дикпик-машину, которая в фоне будет рассылать картинки по AirDrop всем, кто находится в радиусе действия. В качестве аппаратной платформы будем использовать raspberry pi zero, но подойдет любой комп с линуксом, главное чтобы Wi-Fi карточка поддерживала мониторный режим и инъекции пакетов.
Рассылатель дикпиков по Airdrop на базе raspberry pi zero w + батарейный шилд UPS Lite
Есть программы AirDrop флудеров для Jailbreak айфонов, они работают стабильнее, чем открытые варианты на raspberry pi
Настройка OWL на raspberry pi подробно описана на сайте проекта, но я предпочитаю использовать сборку Kali Linux для Raspberry Pi Zero, потому что в ней уже установлены патчи nexmon, для активации мониторного режима Wi-Fi на rpi0.
Важно помнить, что Airdrop (вернее AWDL) у пациентов активируется только после получения BLE-пакета. Поэтому мы должны его посылать с интервалом в несколько секунд. Это можно сделать с помощью утилиты py-bluetooth-utils. Используя функцию start_le_advertising(), я посылаю строку данных из примеров apple bleee: 000000000000000001123412341234123400
.
После того, как вы получили работающий OWL-демон, дальше можно запускать мой форк opendrop. В репозитории лежит скрипт flooder.py
, который рассылает всем картинку kak_dela.jpeg
.
По моим наблюдениям raspberry pi zero w работает нестабильно в мониторном режиме. Примерно через 20 минут активной работы флудера, вылетает подсистема Wi-Fi. Проблема описана у автора pwnagotchi, и предположительно вызвана перегревом. Нужно предусмотреть watchdog или использовать более стабильное железо
Режим маньячелло — я знаю твой номер
Если ты хочешь показать себя неадекватным маньяком и навсегда отбить желание продолжать с тобой общение, можно попытаться узнать номер телефона человека, который находится рядом.
Как мы уже узнали ранее, в BLE-пакетах, которые посылает инициатор, содержатся первые три байта от sha256 телефонного номера. Этот хеш можно поймать в момент, когда жертва нажмет кнопку «поделиться» и запустит сканирование airdrop устройств или тапнет в поле ввода Wi-Fi пароля от новой сети (таким образом apple ищет друзей в радиусе действия, у которых можно запросить пароль от сети).
Тебе потребуется каким-либо образом тригернуть посылку хеша от жертвы, и поймать его. Я использую утилиты из репозитория Apple Bleee. Так как Bluetooth MAC-адреса устройств рандомные и постоянно меняются, тебе придется найти другой способ определить нужное устройство в этом списке. Задача упрощается тем, что iOS транслирует текущее состояние телефона вроде: выключен экран, включен экран, lock screen, разблокирован и т.д. Поэтому просто наблюдая за действиями жертвы можно сопоставить текущее состояние устройства с устройством в таблице. Проще всего поймать момент, когда юзер достал телефон из кармана, включил экран и разблокировал телефон пальцем или лицом. Все это будет видно в сниффере.
Значок Х означает, что пойман пакет с хешами телефона.
Их парсер иногда ломается, но чаще всего работает. Я не буду полностью пересказывать суть уязвимости, так как это подробно разобрано авторами Apple Blee, опишу лишь свой опыт. Скажу только, что я использую USB Bluetooth-адаптер на чипе CSR 8510, так как у меня он работает сильно стабильнее, чем встроенный в макбук Bluetooth-адаптер, проброшенный в виртуальную машину.
Итак мы поймали хеш от телефона жертвы и получили заветные три байта от хеша номера телефона.
Перехваченный BLE-пакет с хешем номера телефона, с помощью утилиты read_ble_state.py
Мы знаем, что в России все мобильные номера начинаются с кода +79 и, скорее всего, у нашей жертвы телефон имеет такой же код. Получается, мы имеем диапазон номеров от +79000000000 до +79999999999, около миллиарда номеров.
Чтобы сузить диапазон, берем только коды, реально зарегистрированные за каким-либо оператором и выбрасываем остальные. В итоге диапазон становится в два раза меньше, около полумиллиарда номеров.
Дальше генерируем sha256 от всех номеров и сохраняем от каждого хеша только первые 3 байта. Заносим этот список в Sqlite базу, для ускорения поиска строим индекс.
Так выглядят данные в базе:
Все российские телефонные номера и первые три байта хеша
Дальше, имея хеш жертвы, мы можем поискать все совпадения в базе. Обычно на один хеш выходит 15-30 совпадений.
Все номера, совпавшие с хешем жертвы
Очевидно, что не все эти номера реально используются. Мы можем отсечь лишние с помощью HLR-запроса или невидимой SMS. Из 30 номеров в сети оказалось 5.
Результат выполнения HLR-запроса. Зеленым выделены номера в сети.
Я бы мог продолжать просеивать номера, например, добавить их все в Telegram/Whatsapp и посмотреть аватарки, проверить через базы вроде Getcontact и так далее. Но проще оказалось просто позвонить поочередно на все пять номеров и смотреть когда у жертвы зазвонит телефон.
Target located
Todo
- Флудер на raspberry pi очень нестабильный, нужно попробовать другие одноплатники.
- Нативный флудер для iOS будет намного лучше, но я не смог найти работающий на iOS 12-13 даже с джейлбрейком.
- Скрипт flooder.py очень тупой. Наверное, он бы мог генерировать именную картинку, беря имя из имени устройства получателя и вырезая слово iPhone.
- Способ определения номера телефона можно оптимизировать, проверяя только факт привязки номера к iMessage. Скорее всего, это даст близкое к 100% попадание.
Заключение
Это идеальное развлечение для метро. Есть вау-эффект, любопытным людям такое интересно. Много импровизации, бывали очень курьезные случаи. Оказывается многие люди готовы подыгрывать и даже отменять свои планы чтобы выйти на твоей станции метро и подняться выпить кофе. За год я познакомился с кучей народу и с некоторыми продолжаю общаться.
Иногда я отключаю отображение Телеграм-логина и развлекаюсь вот так.
Автор: Павел Жовнер