Яндекс - 69,9% поискового рынка РФ, 110+ млн пользователей в месяц, десятки сервисов: поиск, браузер, карты, маркет, такси, музыка, почта, диск, алиса, еда, погода, кинопоиск, плюс... Если у вас андроид - Яндекс.Поиск и Яндекс.Браузер почти наверняка стоят с завода. На Samsung, Xiaomi, Honor, Realme...
Мы взяли два APK Яндекса и отреверсили их.
Там прям плохо. Настолько, что MAX и РУСТОР на их фоне выглядит как детский сад.
В одну статью все это не влезает, придется разделить на несколько, а конкретно на 3.
Кстати подарочек - нейросеть от яндекса для т9 в виде GGUF.
Что там было
- Аудио-претриггер буфер - микрофон пишет звук до того как вы сказали Алиса, и этот кусок звука улетает на сервер. При этом размер окна управляется с сервера - может быть 3 секунды, а может и больше.
- WiFi-сканирование - Яндекс сканирует все точки вокруг, собирает BSSID/SSID/RSSI и шлёт на свой сервер для геолокации.
- Платёжные данные (PAN + CVV) до токенизации - до того как карта затокенизируется, PAN и CVV уходят на mobpayment.yandex.net.
- 94 JavaScript Bridge метода - 17 addJavascriptInterface() мостов. XSS на любом поддомене yandex.ru = компрометация устройства.
- Адресная книга в реальном времени - ContentObserver на всё устройство, любые изменения контактов улетают на сервер.
- Logcat эксфильтрация с AES шифрованием - костыльный код.
- Remote config (70+ флагов) - сервер может включить сохранение карт, форсировать Алису, отложить запрос разрешений на 3 года.
АУДИО-СЛЕЖКА PRE-TRIGGER БУФЕР
Голосовой помощник Алиса работает так: микрофон пишет звук постоянно, но не отправляет его пока не услышит «Алиса». Когда вы говорите «Алиса» - вы уже сказали это слово. То что было до слова «Алиса» - попадает в буфер.И Яндекс этот буфер забирает на свои сервера.
Называется pre-trigger buffer. Кольцевой буфер куда микрофон пишет звук непрерывно. Когда wake word срабатывает - приложение вычитывает буфер и отправляет всё что было ДО ключевого слова вместе с командой.
Казалось бы ну ладно, что с того, может быть это для дебага или серверной валидации, только вот почему то ( а почему нам ответят в коментариях разработчики яндекса на что я очень надеюсь ) размер этого окна не фиксирован. Он управляется с сервера через параметры HasPreroll, buffer-size-ms, loggingSoundLengthBeforeTriggerMs. по умолчанию оно стоит 3 секунды, если бы так и было я бы не добваил пункт в статью... только вот его можно регулировать с сервера, сервер может выставить любое. Или вообще выключить pre-trigger.
Буфер по умолчанию 48000 сэмплов (3с)
Смотрим utw.java:42 - там конфигурация буфера Алисы. 48000 семплов при 16kHz = 3 секунды. Это дефолт.
В BaseAudioSource.java:303 создаётся объект захвата с микрофона. audioSource = 1 = MIC, 16kHz, моно, 16 бит.
BaseAudioSource.java:345-367. Работает пока сервис жив. Читает пачки звука, пробрасывает подписчикам.
Куда улетает аудио
Шаг 1: Микрофон -> AudioRecord (PCM 16kHz)
Шаг 2: Кольцевой буфер 48000 сэмплов (pre-trigger)
Шаг 3: Wake word -> PhraseSpotter триггер
Шаг 4: Opus/AAC кодирование
Шаг 5: WebSocket.sendData() -> wss://uniproxy.alice.yandex.net/uni.ws
Шаг 6: Сервер Яндекса (расшифровка + биометрия + хранение)
Для контекста
Разумеется без pre-trigger буфера современный голосовой помощник не может нормально работать - ему нужно слышать контекст до команды. Но моя претензия не к этому, а вот к чему:- Размер буфера управляется с сервера - а не фиксирован кодом. Сервер Яндекса в любой момент может выставить 30 секунд, минуту, сколько угодно.
- Pre-trigger включает биометрию - голосовой отпечаток строится в том числе по pre-trigger контенту.
- Пользователю не сообщается что pre-trigger активен, какого он размера, и что запись уже идёт.
- Наверное вы даже не знали что pre-trigger там вообще существует.
WIFI FINGERPRINTING
Яндекс сканирует все WiFi точки рядом, собирает MAC роутера, имя сети, силу сигнала и отправляет на сервер. У Яндекса есть база расположения WiFi точек - зная какие рядом, вычисляет ваши координаты с точностью до 10-50 метров. Работает внутри зданий, где GPS не ловит. Заходите в торговый центр - Яндекс знает в какой вы магазин зашли.
Куда шлётся
BuildConfig.java - основной endpoint: https://startup.mobile.yandex.net. Резервные: startup-mobile.ap.yandex-net.ru, startup.mobile.webvisor.com.G2.java - SynchronizedDataCache с именем "wifi". Данные кэшируются и отправляются пачками.
Для контекста
В пользовательском соглашении (ToS) всё это официально прописано - мол, это нужно для обучения их алгоритмов, ( на деле для рекламы ). Да и не стоит забвать Google занимается ровно тем же самым. Становится ли от этого легче? Вообще ни капельки.Решать тут вам, но я думаю у вас есть право знать что делает приложение на вашем телефоне ( не стоит забывать что ваша геолокация моментально уходит сторонним компаниям, а базы данных сливают до сих пор ) .
ПЛАТЁЖНЫЕ ДАННЫЕ (PAN + CVV) ДО ТОКЕНИЗАЦИИ
Когда вы вводите карту в приложении Яндекса, PAN (номер карты) и CVV летят на сервер до токенизации. Но не волнуйтесь, это абсолютно легально и соответствует PCI DSS. Яндекс же сертифицирован, все под контролем - примерно так же, как в 2023 году под полным контролем находился их исходный код до того, как утек на торренты.АРХИТЕКТУРА БЕЗОПАСНОСТИ
Проблема в том что весь цивилизованный мир уже давно использует архитектуру на порядок элегантнее и безопаснее:
- Client-side токенизация (iFrames / Hosted Fields, как у Stripe Elements или Braintree): Данные карты вообще не касаются ваших серверов. Поля ввода физически изолированы на стороне провайдера, приложение видит только готовый токен. Поверхность атаки на вашей стороне = ноль. Радиус поражения при взломе бэкенда = ноль.
- Device-level токенизация (Apple Pay / Google Pay / EMVCo): Пользователь вообще не светит картой. Девайс генерирует одноразовую криптограмму на уровне железа (Secure Enclave). Даже если хакер перехватит этот токен по пути, он будет абсолютно бесполезен для любых других транзакций.
- И, для сравнения, Server-side токенизация (как у Яндекса): Данные карты послушно летят через твой бэкенд, API-гейтвей, балансировщики, проходят через SIEM, ELK-stack и вообще через всё, что может в один прекрасный момент упасть с ошибкой и радостно плюнуть {pan, cvv} в файлик с логами.
Какие есть риски?
- Логи. Сервер упал с 500-й ошибкой ровно в момент передачи карты? Поздравляю, {pan: "4276..., cvn: "123"} уже в логе. А лог читают 150 человек. Откуда мы это знаем? из 7e0ac90b489baee8a823381792ec67d465488fef
- Промежуточные сервера. startup.mobile.yandex.net - это не крепость, это обычный бэкенд с кучей эндпоинтов, аналитикой, экспериментами.
- Инсайдер. Охранять один микросервис легко. Охранять всю инфраструктуру приложения, через которую транзитом проходят PAN+CVV - нужно, чтобы 100500 разработчиков, devops'ов и тестировщиков были в PCI DSS scope.
Для контекста
Юридически легально. Есть сертификат, есть изолированный CDE-контур.Но архитектурно это код образца 2012 года. Stripe, Braintree, Adyen уже 10 лет назад доказали, что можно сделать так, чтобы сервер приложения вообще не видел карту.
Если mobpayment.yandex.net взломают - всё, данные утекли. Яндекс взламывали. VK взламывали. АНБ взламывали
VPN DETECTION
За это их уже забуллили все, но грех упуститьПриложение проверяет наличие интерфейса tun0 (стандартное имя для VPN). Если найден - блокирует авторизацию.
Думаю не секрет что Яндекс заставляет отключать VPN и светить реальный IP, потому что полностью прогнулся под требования Роскомнадзора и Кремля по тотальной слежке и цензуре.
DNS HARDCODED
Приложение использует 77.88.8.8 и 77.88.8.1 в обход системного DNS, VPN DNS, DoH и Tor. Это DNS Яндекса. Даже если вы настроили Cloudflare DoH или используете Tor - Яндекс делает запросы к своим DNS напрямую.
Проще говоря, они видят абсолютно все домены куда вы ходите, и есть огромная вероятность, что вся эта «история браузинга» по первому требованию улетает прямо в нужные руки - ну а выводы делайте сами.
NATIVE SURVEILLANCE ENGINE
Самое сладкое разработчики спрятали в native-библиотеке libquarkenstein_daemons.so.
Внутри зашито всё: пайплайны записи аудио с микрофона (с прямой отправкой на сервера), манипуляции с процессами в обход security-модели Android, нативная геолокация и шифрование. Это полноценный движок слежки, заботливо упакованный в один тяжело читаемый файл (в котором, кстати, по классике забыли затереть внутренние debug-пути сборки, денис опять ты?) вообщем это я так, чтобы вы не забывали о том что выйдет 2/3 часть, новости есть тут.
JAVASCRIPT BRIDGE
21 addJavascriptInterface() мостов. 94 @JavascriptInterface метода. Файл assets/api.js - 30+ функций.
Для контекста
Любая XSS-уязвимость на поддоменах yandex.ru - это мгновенный билет к контролю над вашим устройством. Злоумышленникам нет смысла пробивать лбом неприступные главные серверы с их WAF и круглосуточным мониторингом. Достаточно найти одну незапертую форточку на заднем дворе экосистемы.XSS - неизбежнен:
- Кладбище поддоменов: У IT-гигантов их сотни, если не тысячи. От заброшенных промо-акций пятилетней давности до дев-песочниц, где выполнение пользовательского кода - это вообще основная функция.
- Человеческий фактор: В инфраструктуре такого колоссального размера забытого, устаревшего или криво написанного кода невозможно избежать ( без формальной верификации ) . Уязвимый эндпоинт, позволяющий исполнить произвольный веб-скрипт, появится со стопроцентной вероятностью ( или уже тихо существует и ждет своего часа, без намека ).
- Слепой Фейсконтроль" Как только хакерский скрипт запускается на таком уязвимом поддомене, мобильное приложение видит знакомое окончание .yandex.ru и после чего радостно распахивает перед ним все 94 JS-моста, пропуская веб-пейлоад прямиком к нативным функциям.
КОНТАКТЫ
Приложение читает полную адресную книгу (имена, телефоны, email, почтовые адреса, организации, фото), а также журнал звонков. Установлен ContentObserver на ContactsContract.Contacts.CONTENT_URI - любое добавление, удаление или изменение контакта вызывает перечитывание данных. Контактные данные сериализуются через protobuf и отправляются на сервер Яндекса через HTTP POST (с OAuth-авторизацией).VoIP / мессенджеры
Читает не только обычные телефоны, но и номера из WhatsApp, Telegram, Viber через фильтр MIME-типов phone_v2, viber, telegram, whatsapp.
Отправка на сервер
Ссобирает все контактные данные в UploadContactsRequest - протобаф-структуру с полями:
- ContactInfo (ID контакта, id, lookup, displayname, account_type, account_name, times_contacted, timestamps)
- PhoneInfo (номер, тип, приложение-источник)
- LookupInfo (lookup-ключи)
ПАССИВНАЯ ГЕОЛОКАЦИЯ + СОТОВЫЕ ВЫШКИ
Приложение регистрирует пассивного провайдера геолокации - это позволяет перехватывать координаты, полученные другими приложениями на устройстве. Дополнительно собираются данные о сотовых вышках: MCC, MNC, Cell ID, LAC/TAC, что позволяет триангулировать положение устройства с точностью до 100-500 метров даже в помещениях. Пассивный провайдер доставляет обновления от любого приложения, уже имеющего координаты.
LOGCAT ЭКСФИЛЬТРАЦИЯ
Под капотом дёргается Runtime.getRuntime().exec("logcat -d") - попытка снять полный дамп системных логов. Дальше всё это пакуется, шифруется AES и летит к ним на сервер.
Для контекста
В теории, Logcat - это проходной двор, куда пишут логи вообще все приложухи на телефоне. То есть Яндекс должен пылесосить логи вашего банка, VPN, секретных чатов, историю URL-ов и крашиситуация тут прям как с RuStore, повторяться не буду. Звучит страшно, но по факту это так только для юзеров старых ОС (ну или если вы сидите с кастомным рутом и выдаете права направо и налево).
Современный Android давно прикрыл эту лавочку на уровне песочницы: без системных привилегий (READ_LOGS) приложение может читать только свои собственные логи. Так что на актуальных прошивках Яндекс через этот логкат успешно соберет данные только о том, как забаговал сам Яндекс.
Если бы в Яндексе работали тру-профи, они бы изначально на уровне кода ограничили сбор логов только своим приложением. А попытка тянуть logcat -d целиком, в расчете на то, что «ОС сама обрежет лишнее» - это просто наглядный показатель того, как там пишется архитектура
APP INVENTORY
Приложение собирает список ( про то как он обходит ограничение андроид и тд ниже ) установленных пакетов на устройстве через два механизма: PackageManager.getInstalledApplications() и, как fallback, Runtime.getRuntime().exec("pm list packages"). Список приложений позволяет идентифицировать банки, VPN, мессенджеры, магазины, антивирусы и другие приложения пользователя.Основной метод: getInstalledApplications()
Собирает все packageName установленных приложений.
Fallback: shell-команда
Резервный механизм при TransactionTooLargeException или DeadObjectException:
Парсит вывод package:com.example.app, извлекая имена пакетов.
Детектор контент-блокеров
После сбора всех пакетов v000.x() проверяет каждый на наличие meta-data:
- "com.samsung.android.sbrowser.contentBlocker.interfaceVersion" - если "API_1.0", проверяется ContentProvider
- Для подходящих приложений собирается signatureHash и displayLabel
- Результат - список ej40{packageName, displayLabel, signatureHash}
использует getInstalledApplications() для поиска установленных банковских приложений. Сверяет packageName со списком известных банков, результат показывается в UI оплаты.
VK Push SDK
При отсутствии master-host приложения шлёт аналитический ивент "vkcm_sdk_client_no_master_host_found" с параметром "installed_apps", содержащим список packageName всех установленных приложений. Этот ивент уходит на серверы аналитики VK.
CLID-детекция
Сохраняется в SharedPreferences и используется для аналитики/аттрибуции.
не особо легальный обход ограничений Android
«Но покроет ли это ограничения Android 11+, где Google ввёл Package Visibility и запретил приложениям просто так видеть чужие пакеты?»Ещё как покроет! Разработчики Яндекса не дураки, чтобы просить у Google Play опасное разрешение QUERY_ALL_PACKAGES (за которое их выкинули бы из стора). Они поступили технически изящнее: захардкодили гигантский список целевых приложений прямо в тег <queries> своего AndroidManifest.xml.
В Android 11+ если пакет явно объявлен в <queries>, приложение имеет полное официальное право проверять его наличие через PackageManager.
Что именно Яндекс внес в свой список «разрешённого наблюдения»:
- Вся экосистема Яндекса и дочек: Такси, Карты, Лавка, Диск, Почта, Еда, Маркет, Дзен, Плюс, Яндекс Банк, Кинопоиск, Драйв, Мессенджер.
- Абсолютно ВСЕ конкурентные браузеры: Google Chrome (включая Beta/Dev/Canary), Mozilla Firefox, Opera (Mini/Beta/Touch), DuckDuckGo, Vivaldi, Samsung Internet, UC Browser, Via, Mi Browser.
- Все популярные мессенджеры и соцсети: Telegram, WhatsApp (+ Business), Viber, VKontakte, Instagram, Twitter, Reddit, Facebook (+ Lite/Messenger), ICQ, OK.ru.
- Все почтовые клиенты: Gmail (+ Lite), Mail.ru, Outlook, Spark, MyMail, Yahoo Mail, Samsung Email, BlueMail.
- Измерители аудитории и трекеры: Mediascope AppMeter (com.cifrasoft.mpm.mediascope.appmeter) - главная российская система панели аудитории и телеизмерений.
Полный список:
com.yandex.browser.alpha, com.yandex.browser.beta, com.yandex.browser.broteam, com.yandex.browser.canary, com.yandex.browser, com.intertechservices.browser, com.yandex.browser.corp, kz.aitu.browser, com.yandex.searchapp.beta, com.yandex.searchapp.canary, com.yandex.searchapp.nightly, com.yandex.searchapp, ru.yandex.searchplugin.beta, ru.yandex.searchplugin.canary, ru.yandex.searchplugin.nightly, ru.yandex.searchplugin, com.yandex.yazeka, com.intertechservices.searchplugin, com.yandex.browser.lite, ru.yandex.yandexmaps, ru.yandex.taxi, ru.beru.android, ru.beru.yandexnavi, ru.yandex.music, ru.yandex.translate, ru.foodfox.client, ru.foodfox.courier.debug.releaseserver, ru.foodfox.vendor, ru.yandex.taximetr, ru.yandex.taximetr.x, ru.yandex.taximetr.beta, ru.yandex.disk, ru.yandex.disk.beta, ru.yandex.money, ru.yandex.mail, ru.yandex.mail.beta, ru.yandex.weatherplugin, ru.yandex.metro, com.yandex.mobile.drive, ru.yandex.market, ru.yandex.rasp, com.yandex.mobile.realty, ru.yandex.mobile.gasstations, com.yandex.uslugi, com.yandex.lavka, ru.yandex.androidkeyboard, ru.yandex.radio, com.yandex.mobile.job, ru.yandex.key, com.yandex.launcher, ru.yandex.mobile.avia, ru.yandex.fines, com.yandex.yamb, com.yandex.yamb.canary, yandex.auto.mobile, com.yandex.courier, ru.yandex.direct, ru.yandex.med, com.yandex.maps.mrcpublic, com.yandex.widget, ru.yandex.mobile.metrica, ru.yandex.mobile.appmetrica, ru.yandex.mobile.telephony, ru.yandex.checkout.release, ru.yandex.yandextraffic, ru.yandex.subtitles, ru.yandex.edc.driver, ru.yandex.nokiasystemservice, ru.yandex.mobile.ofd, com.yandex.launcher.externaltheme.ny, com.yandex.zen, com.yandex.zen.logged, ru.yandex.svetofor, ru.yandex.telemed.doctor, ru.yandex.driverapp, com.yandex.bus.driver, ru.yandex.newperseusapp, ru.zen.android, com.yandex.bank, com.yandex.bank.dev, com.android.vending, com.google.market, com.huawei.appmarket, com.sec.android.app.samsungapps, com.android.chrome, com.chrome.beta, com.chrome.dev, com.chrome.canary, org.mozilla.firefox, org.mozilla.focus, org.mozilla.fenix, com.opera.browser, com.opera.browser.beta, com.opera.mini.native, com.opera.mini.beta, com.opera.mini.touch, om.microsoft.emmx, com.UCMobile.intl, com.ucturbo, ru.mail.browser, com.duckduckgo.mobile.android, com.mi.globalbrowser.mini, com.sec.android.app.sbrowser, mobi.mgeek.TunnyBrowser, com.transsion.phoenix, mark.via.gp, privacy.explorer.fast.safe.browser, com.vivaldi.browser, com.google.android.gm, com.google.android.gm.lite, ru.mail.mailapp, com.microsoft.office.outlook, com.samsung.android.email.provider, com.my.mail, com.yahoo.mobile.client.android.mail, com.readdle.spark, me.bluemail.mail, com.facebook.orca, com.facebook.mlite, com.facebook.katana, com.facebook.lite, com.viber.voip, com.google.android.apps.messaging, com.whatsapp, com.whatsapp.w4b, org.telegram.messenger, com.icq.mobile.client, ru.ok.messages, com.twitter.android, com.instagram.android, com.reddit.frontpage, com.tumblr, com.vkontakte.android, ru.vk.store, ru.vk.store.qa, com.android.printspooler, com.cifrasoft.mpm.mediascope.appmeter, com.samsung.android.mapsagent, com.idamob.tinkoff.android, ru.tinkoff.mb.kids, ru.rostel, com.yandex.mobile.gasstations, ru.rostel, com.whatsapp, com.whatsapp.w4b, com.idamob.tinkoff.android, ru.tinkoff.mb.kids, com.yandex.bank.dev, com.yandex.bank, com.huawei.appmarket, ru.yandex.music, ru.vk.store, ru.vk.store.qa, com.facebook.katana, com.instagram.android, com.facebook.lite, com.samsung.android.mapsagent
Пытаясь втихую обойти приватность Android 11+, Яндекс сам же выдал себя: захардкодив в <queries> сторонние браузеры, мессенджеры и Mediascope, они открыто выложили доказанный факт целенаправленного шпионажа за пользователем - были бы там только банки и сами Yandex-приложения, вопросов бы не было.
REMOTE CONFIG (70+ ФЛАГОВ)
Приложение управляется с сервера. Сервер может включить сохранение карт, форсировать Алису, отложить запрос разрешений на 3 года, включить pre-trigger на полный буфер, отключить валидацию TLS.
Все 70+ флагов:
alice_proxy, alice_reader, CommittedOriginTracking_fix, delay_notification_first_permission_request, default_search_promo_on_serp, geo_settings, mobile_ads_sdk, morda_feed_ads, send_bidder_token_to_morda, features_onboarding, tab_folders, morda_force_alice, video_summarization, video_tutorial, common_mobile_menu, manage_cpu_affinity, flex_ntp, morda_modes, ssdk_searchapp_buttons_theme, ssdk_theme, alice_solver, turkish_redesign, force_show_neuro_entry_points, video_translation, video_translation_alice_shortcut, alice_videotranslation, video_translation_international, video_translation_target_kz, video_translation_direct_upload, yandex_href_translate, alice, website_reviews, feature_suggest, div_sovetnik, trust_cards_autofill, save_trust_cards_to_yandex, smart_camera, alice_language, alice_pro, image_search, book_reader, readability_ajax_delay, new_default_popup, turbo_apps, morda_update_on_start, tweak_searchapp_controls, search_2_bro, thumbnail_database, searchapp_user_agent, voice_search_2024, facebook_sdk, books_div_banner, modern_voice_search, voice_search, summarization, div_stories_tutorial, external_applinks, sections_v2, omnibox_visibility, ssdk_serp_line, ai_chat_alice, alice_v2, custom_nav_bar, context_search_serp, safe_browsing_delay_verify_local_database, transsion_widget_promo, xiaomi_widget_promo, widget_promo_environment, image_translator, searchapp_profile_login
Для контекста
Remote config - это стандартная технология. Но набор флагов говорит сам за себя. Это не A/B-тестирование кнопок. Это удалённое управление механизмами слежки и разрешениями. Сервер Яндекса может раздать разный набор слежки разным пользователям - одним 3 секунды pre-trigger, другим 30, третьим off.ИТОГИ
Давайте подведём цифры того, что нам удалось раскопать ( многое в статью не влезло, но я подведу итоги того что будет в 2/3 частях ) :- 60+ механизмов слежки (из них 11 критических и 38 высокого риска).
- 387+ сетевых эндпоинтов, 1500+ JNI-точек, 94 JavaScript Bridge API, 587 доменов.
- Звук вокруг вас - ещё до того, как вы произнесли «Алиса» (через pre-trigger буфер).
- Звонки и контакты - через ContentObserver адресной книги.
- Локацию - через сканирование Wi-Fi сетей, GPS и триангуляцию по сотовым вышкам.
- Окружение - полный список ваших приложений (банки, VPN, мессенджеры).
- Платежи - данные карт (PAN/CVV) до токенизации.