Прошло больше двух месяцев после того, как я опубликовал свой
первый пост о передаче данных местоположения сторонним приложениям.
За это время я пообщался со многими людьми из этой сферы: с членами некоммерческих организаций, сражающихся за права на конфиденциальность данных в разных странах до сотрудников компаний, занимающихся рекламными технологиями. Они подтвердили или опровергли мои слова (в основном подтвердили). Меня даже пригласили в подкаст «
Lock and Code» для обсуждения геолокационных данных и конфиденциальности.
Я ещё раз прошёлся по процессу, описанному в первом посте, и решил сделать его более быстрым и масштабируемым: ручной анализ сотен запросов в Charles отлично подходит для исследований и обучения, но для нахождения «интересных» запросов конкретного приложения мне требовалось слишком много времени.
Я существенно улучшил свою методику (хотя она определённо может быть более эффективной), и в этом посте хочу поделиться ею.
* Деятельность Meta — соцсети Facebook и Instagram — запрещена в России как экстремистская.
▍ TL;DR
Я создал небольшое руководство и Python-ноутбук, которые позволят любому записывать трафик мобильных приложений и находить в нём неожиданные вещи.
Описание выложено в
репозиторий GitHub.
Первоначальная настройка занимает 10-30 минут.
На анализ каждого приложения при помощи этого алгоритма мне требуется примерно 10 минут, но если вы найдёте что-то любопытное, то можете заняться более глубоким многочасовым изучением…
Для начала можете прочитать инструкцию в
readme или представленное ниже руководство.
У меня возникла мысль: для анализа каждого приложения и записи его трафика мне потребовались бы сотни часов, хотя лично меня это и устраивает; давайте не будем вслепую доверять какой-то таблице из Интернета, а разберёмся сами.
Я скопировал Google-таблицу Gravy Analytics и создал простую форму, которую вы можете заполнить сами (никаких личных данных указывать не нужно); она выполняет запись в эту Google-таблицу.
Ссылка на таблицу
Выберите любое приложение, которое уже установлено у вас в телефоне, или просто случайное, проверьте, оставили ли уже другие пользователи комментарии о нём, и запишите трафик.
Вы можете помочь в краудсорсинге поиска информации о типах данных, которые собирают и передают приложения из списка,
заполнив форму.
Эта форма настроена так, чтобы я не мог получить от вас никакой конфиденциальной информации (например, адрес почты или аккаунта Google), но ваш ответ будет виден практически каждому, так что будьте аккуратны!
Удалите из отправляемых данных всю личную информацию (если она есть).
Визуализируем «силу домена»
Прежде чем приступать к объяснению, мне хотелось бы поделиться красивыми визуализациями.
Недавно меня заинтересовала графовая визуализация данных. В процессе анализа трафика мне стало любопытно: каково распределение по всем запросам компаний, занимающихся рекламными технологиями?
Я объединил данные и создал при помощи
PyVis
визуализацию, которая должна ответить на этот вопрос:
Немного контекста:
- Каждый круг — это домен или поддомен. Иерархия представлена включением одних кругов в другие. Пример:
o-sdk.ads.unity3d.com
представлен тремя кругами: o-sdk
внутри ads
, находящегося внутри unity3d
.
- Цветами обозначены приложения (я проанализировал пять), которым соответствуют запросы. Чтобы было лучше видно, я использовал высокую прозрачность; оказалось, что в моём смешении цветов комбинацией их всех становится фиолетовый.
- Размерами или массами кругов обозначена частота появления домена в данных запросов. Можно ли сделать какие-то выводы?
Миром трафика мобильных игр правит Unity. Для сравнения: g / doubleclick
— это Google Ad Network.
Давайте понаблюдаем за этим в движении:
В тот же репозиторий я добавил код визуализации
visualise_domains.ipynb, чтобы вы сами могли создать такую же визуализацию из собранных вами данных. Кроме того, я добавил файл
ad_domains.html с этим графом (моих данных). Просто откройте его в браузере, если хотите поэкспериментировать.
Мне стала интересна и плотность запросов: в первом посте я говорил, что всего за несколько секунд происходят сотни запросов, и теперь я, наконец, смог взглянуть на них:
Названия в легенде обозначают потоки, собранные из пяти игр.
Чтобы было нагляднее, я ограничился 60 секундами, но очевидно, что и после них запросы продолжали выполняться.
Это взгляд на силу доменов под другим углом: посмотрите на список справа.
- Уже очевидно, что Unity — лидер этого странного соревнования: он вызывает больше всего поддоменов и к нему выполняется больше всего запросов.
- Applovin — это компания из Пало-Альто, купившая упомянутую выше Adjust в 2021 году, а в 2024 году показавшая чистую прибыль в 1,58 миллиарда долларов; всего несколько месяцев назад она решила избавиться от своих продуктов для разработки мобильных приложений и полностью сосредоточиться на рекламе.
- Doubleclick.net — это Google Ads
- Как ни удивительно, Facebook*, который встречался мне в запросах от каждой игры, оказался здесь на последнем месте. По крайней мере, на основании этой странной метрики в пяти примерах.
Теперь, когда вы увидели эти непонятные, но красивые графы, давайте перейдём к самому руководству, благодаря которому вы сможете анализировать трафик любого приложения.
Приступаем к работе
▍ Шаг 1: установка mitmproxy на PC
mitmproxy
— это опенсорсный инструмент для перехвата трафика с широкими возможностями и на удивление хорошей веб-версией под названием
mitmweb
.
Учтите, что
mitmproxy
некоторые антивирусы считают зловредным ПО: не бойтесь, это не так.
Перейдите на
официальную страницу для скачивания и выберите подходящий вам формат. Например, на Mac можно просто выполнить
brew install mitmproxy
.
После установки выполните эту команду для запуска
mitmweb
(mitmproxy + веб-интерфейс):
mitmweb --listen-host 0.0.0.0 --listen-port 8080
. Также можно работать с приложением командной строки
mitmproxy
, но я предпочитаю mitmweb, потому что он действительно очень удобен для первоначального исследования (и понимания масштабов RTB-запросов).
Мы используем
--listen-host 0.0.0.0
, чтобы
mitmproxy
не начинала с адреса по умолчанию, то есть localhost
128.0.0.1
— таким образом, вы не будете записывать трафик своего PC, и до выполнения второго шага количество запросов будет равно нулю.
▍ Шаг 2: подготовка мобильного устройства
Далее нужно настроить прокси в устройстве iPhone/Android, а также установить сертификат.
В этом руководстве я буду рассматривать пример с iOS, но настройка телефона с Android выполняется ещё проще и к тому же хорошо задокументирована, см. например,
здесь.
Вероятно, вам придётся включить режим разработчика, в противном случае в настройках не получится включить доверие к сертификату (но может быть, это и не так).
Если этот раздел отсутствует в настройках iOS, то
вот руководство по тому, как это сделать. Кстати, чтобы всё это сработало, iPhone и компьютер должны находиться в одной сети WiFi.
▍ Шаг 3: сбор запросов
- Выполните
ipconfig getifaddr en0
, чтобы узнать локальный IP-адрес PC.
- Далее откройте параметры сетей WiFi в iPhone, прокрутите вниз и настройте вручную прокси со следующими значениями:
server
= только что определённый IP-адрес
port
= 8080
Откройте браузер на iPhone и перейдите на
mitm.it
. Дальнейшие инструкции описаны здесь:
https://jasdev.me/intercepting-ios-traffic
или здесь:
https://support.apple.com/en-us/102390
Для чего это нужно?
Необходимо установить сертификат и включить доверие к нему, чтобы иметь возможность дешифровки трафика, зашифрованного TLS. В противном случае вы увидите лишь передаваемые зашифрованные пакеты.
Поздравляю! Если вы правильно выполнили все шаги, то в интерфейсе
mitmweb
должны начать отображаться запросы. Если вы хотите записывать трафик только одного конкретного приложения, закройте все приложения, нажмите на «Clear flows» и откройте нужное приложение.
Если приложение пока не установлено, то можно отключить прокси на iPhone, скачать приложение, снова включить прокси и нажать на «Clear flows» — в моём случае AppStore отказывался работать с прокси.
Если вы пока не придумали приложение, то выберите любое приложение с «Checked = False» на листе «original list»:
https://docs.google.com/spreadsheets/d/1fJbNT-kmfuWUlIpYr9sduvjZS1ggrmhydCzoDlqaMaA/.
Давайте поищем что-нибудь интересное
Отлично, теперь можно записывать данные!
Мы уже можем искать интересные запросы вручную: например, я практически уверен, что вы увидите этот запрос к Facebook*, какое бы приложение ни анализировали:
Но просматривание запросов в
mitmweb
даже с хорошей (не расширенной) фильтрацией — это очень медленный процесс. Как вы сами увидите, всего за несколько минут наберутся сотни (если не тысячи) запросов.
Когда вам покажется, что достаточно (вы можете даже оставить приложение открытым или поиграть примерно час, чтобы собрать больше данных), закройте приложение и отключите телефон. Затем в
mitmweb
нажмите File → Save.
Так вы получите файл
flows
; переименуйте его в
название_приложения.flow
.
▍ Фильтрация и анализ данных
Откройте
mitm_test.ipynb, или в локальном Jupyter Notebook, или в Google Colab (или там, где вы работаете с
.ipynb
).
Лично мне гораздо удобнее работать с такими данными в локальном окружении. Однако если вы не пишете код/пишете его не на Python, то поверьте, нет ничего проще и быстрее, чем открыть
Colab и импортировать файл.
В файле есть достаточно понятные и подробные инструкции, поэтому не буду повторять процесс целиком, а просто выделю некоторые аспекты:
Очень важный этап: введите максимальное количество ключевых слов, которое сможете придумать. Меня интересовали исключительно геоданные и IP, но вы можете изучить и другие, например, «screen_brightness», «IDFA» и так далее.
Учтите, что возвращаться будут только точные совпадения (представьте количество слов/строк, в которых «lat» или «lon» будут подстроками).
Введя все ключевые слова в список, запустите ячейки ниже; будет создана таблица
df_filtered
с запросами (или ответами), соответствующими ключевым словам.
Вы увидите краткий фрагмент совпадения (
matched_in_request
и
matched_in_response
), а также причину («reason»).
Ниже представлен простой
.loc
, куда можно ввести индекс строки (первый столбец слева), чтобы просмотреть значение столбца целиком: в примере ниже это
"full_reponse"
. Если строка оказывалась слишком длинной, я просто копировал её в Sublime Text и использовал его встроенный поиск для нахождения дополнительного контекста или других неожиданных примеров данных в тексте запроса или ответа.
Вот и всё!
Вы можете помочь со сбором информации о тех типах данных, которые собирают и передают приложения из списка:
заполните форму.
Перед отправкой данных удалите всю конфиденциальную информацию (если она есть).
▍ Дальнейшие улучшения?
Я знаю, что это очень примитивный способ исследования — можно было выполнить всё это при помощи
mitmdump
и автоматического сохранения/фильтрации непосредственно в
.csv
, но я преднамеренно оставил процесс частично ручным.
Формат и структура всех этих запросов очень разнообразны, и чем более автоматизированным способом вы будете их изучать, тем больше вероятность, что вы что-то пропустите.
Поначалу я пробовал фильтрацию по типу контента и кодировке, но заметил, что некоторые совпадающие запросы в список не попадают.
Поэтому я отключил фильтры… и обнаружил следующее:
gs-loc.apple.com
— это конечная точка, используемая Apple для запросов информации о местоположении пользователя. Она вызывалась в течение трёхминутной записи трафика из единственного открытого приложения — игры Make More. Раньше она никогда не встречалась [при анализе других приложений] + эта игра есть в списке Gravy.
Однако я не хочу делать непроверенных утверждений о том, что это приложение отвечает за запрос к Apple — эта конечная точка недоступна напрямую ни из какого приложения, кроме самой iOS, так что для получения информации от неё приложению нужно вызвать специальный метод Apple API и иметь соответствующие разрешения. Или нет?
Как бы то ни было, ответ на этот запрос был закодирован в формате protobuf, поэтому мне, очевидно, пришлось искать способ его расшифровать. И я его нашёл. Но это уже тема для отдельного поста.
Telegram-канал со скидками, розыгрышами призов и новостями IT 💻
