Коротко опишу как с помощью утилиты mitm proxy производить анализ и, при желании, модификацию трафика устройств Яндекс.
Для начала нам потребуется устройство Яндекс с правами root и отключенным selinux. Я ранее намекал на способы получения таких прав на Яндекс Станции 1, Яндекс Станции Макс, Яндекс Модуле 2, Яндекс ТВ Станции. Также возможно получить root на Yandex Mini, да и наверняка на других устройствах, если немного владеешь пайкой.
Не буду описывать процесс установки и настройки mitm proxy, а перейду сразу к делу.
Mitm proxy реализует классическую man-in-the-middle атаку, то есть он вклинивается в SSL/TLS трафик между клиентом и сервером - расшифровывая трафик от клиента/сервера и перешифровывая его. При этом mitm proxy генерирует сертификаты для сайтов по мере надобности, подписывая их своим "самодельным" корневым сертификатом. По умолчанию, устройства Яндекса доверяют только определенным корневым сертификатам, в список которых, естественно, сертификат mitm proxy не входит. Чтобы всё заработало - требуется добавить его в доверенные.
В Android стандартное хранилище доверенных корневых сертификатов находится в папке /system/etc/security/cacerts/, причем каждый сертификат находится в своем файле, имя которого генерируется определенным образом.
Публичная часть корневого сертификата mitm proxy находится в файле ~/.mitmproxy/mitmproxy-ca-cert.cer. Чтобы получить имя файла для его записи в /system/etc/security/cacerts/, требуется на Linux машине с mitm proxy выполнить команду:
openssl x509 -noout -subject_hash_old -in ~/.mitmproxy/mitmproxy-ca-cert.cer
В моем случае я получил значение "c8750f0d" - это будет имя файла. Расширение файла обычно ".0", но если в Android в папке /system/etc/security/cacerts/ уже есть такой файл, то для добавления нового сертификата требуется изменить расшиниение на ".1", ".2" и так далее.
В моем случае имя файла будет c8750f0d.0 - так как ранее файла с таким именем в папке /system/etc/security/cacerts/ не существовало. С таким именем надо положить на устройство файл ~/.mitmproxy/mitmproxy-ca-cert.cer.
Из-за Android Verified Boot, на большинстве современных устройств изменение содержимого раздела /system для добавления туда своего сертификата превращается в нетривиальную задачу. К счастью, тут нам на помощь приходит "bind mount" - можно просто скопировать старое содержимое папки /system/etc/security/cacerts/ например, в /data/local/tmp/cacerts, положить туда наш файл (в примере это c8750f0d.0), после чего выполнить из-под root команду:
mount --bind /data/local/tmp/cacerts/ /system/etc/security/cacerts/
Старая папка cacerts будет подменена и стандартные приложения Android начнут доверять добавленному сертификату mitm proxy.
Заметка от 15.06.2025: старые версии Android (например Android 9, на Яндекс Модуле 2) читают содержимое папки /system/etc/security/cacerts/ только при загрузке системы и добавленный через bind mount сертификат не видят. На таких устройствах файл сертификата надо добавлять перемонтировав /system в rw, отключив проверку vbmeta (там где она есть) и записав файл в /system/etc/security/cacerts/.
Android 11 (на ТВ Станции) - обновляет список доверенных сертификатов динамически, так что описанный выше способ работает.
Если же на устройстве отключен AVB - то можно и внести правки в /system смонтированный на запись, например так:
Последней строкой я устанавливаю правильные атрибуты selinux для файла. Это необходимо, если вы редактируете образ раздела /system, смонтировав его на другом устройстве.
Описанных действий недостаточно для полного счастья - приложение com.yandex.io.sdk имеет свой список доверенных сертификатов в файле /data/data/com.yandex.io.sdk/files/system/ca-certificates.crt - так что требуется дописать содержимое нашего ~/.mitmproxy/mitmproxy-ca-cert.cer в его конец. Я делаю это скриптом такого вида:
Приложение com.yandex.io.sdk при обновлении перезаписывает файл /data/data/com.yandex.io.sdk/files/system/ca-certificates.crt, так что данный скрипт имеет смысл держать под рукой.
И вот уже после этих действий - можно запустить mitm proxy, прописав его IP адрес в качестве default gateway на исследуемом Яндекс устройстве.
Правкой ответа https://quasar.yandex.net/get_sync_info можно включить ADB,
убрать "пришпиленные" иконки рекламных приложений (об этом я, возможно, напишу подробнее позже), но повторю слова, сказанные angellfear - правка раздела "subscription" на подписочном устройстве не приведет к его разблокировке (точнее, приведет только на короткое время) - так как блокировка проверяется позднее при работе с websocket по адресу https://uniproxy.alice.yandex.net/uni.ws, по которому гуляют protobuf-ы. Немного про protobuf я рассказывал ранее (наконец то я выложил свою версию protodump).
Я принципиально против обхода ограничений подписочной модели, так что в эту сторону даже не смотрю.
Mitm proxy умеет показывать значения внутри protobuf (не зная названия полей, поэтому вместо них - цифры), например:
Но если немного доработать код проекта mitmproxy_grpc, то можно получить вполне читаемое содержимое структур gRPC с названиями всех полей:
Возможно, я выложу доработанный mitmproxy_grpc и сопутствующие файлы когда-нибудь в будущем - но мой код, по крайней мере сейчас, работает только на просмотр protobuf без их изменения и заточен только под вебсокет uni.ws.
Также на свежих устройствах Яндекс стал отдельно шифровать запросы, например, на report.appmetrica.yandex.net (параметр encrypted_request=1). В сторону их расшифровки я не смотрел, но, как говорил +Orc: if it runs it can be defeated.