# 02. Threat model — Montana Android v6.5.0 ## Атакующие — классификация ### A. Пассивный сетевой наблюдатель (DPI на ISP) **Капабилитности:** - Виден весь трафик клиента до публичного интернета - Может выполнять traffic analysis (timing, size patterns) - Не может выполнить активное соединение к клиенту извне (NAT) **Защита:** - Reality protocol — handshake выглядит как обычный TLS-1.3 к `www.googletagmanager.com`. SNI Echo маскирует destination. - Pinned fingerprint Chrome 120+. JA3/JA4 хэши совпадают с реальным Chrome. **Открыто:** - Timing-based traffic analysis (всплески запросов соответствуют WebRTC, видео, и т.п.) - Если DPI имеет ML-классификатор Reality (известно научное исследование GFW 2024) — обнаружение возможно ### B. Активный сетевой наблюдатель (active probing) **Капабилитности:** - Может выполнять TCP-зондирование `91.132.142.42:443` (Helsinki публичный IP) - Может сравнивать ответы с эталонными `www.googletagmanager.com:443` **Защита:** - Reality terminate на правильный destination через **SNI Echo** — если клиент шлёт неправильный сертификат, xray прозрачно проксирует к real `googletagmanager.com:443`. - На случай proxy-fallback: nginx `:80` decoy → отдаёт `"It works!"` HTML. **Открыто:** - Атакующий с full state inspection (видит timing handshake и сравнивает с эталонным DNS+TLS к googletagmanager) может различить. ### C. Malicious Android app на том же устройстве **Капабилитности:** - Своё data dir (изолировано Android sandbox) - Возможно `MANAGE_EXTERNAL_STORAGE` (Android 11+) — доступ к `/sdcard/`, не к нашим private data - На rooted устройстве — полный доступ к `/data/data/quest.montana.vpn/` **Защита (если не root):** - Android sandbox 0700 на data dir - localStorage WebView хранится в `/data/data/quest.montana.vpn/app_webview/Default/Local Storage/` — недоступен другим приложениям **Открыто (если root):** - Seed 24 слов читается прямо из localStorage — **plain text**, не шифрован - Atomic recovery — атакующий получает все деньги, владельцу остаётся ничего **Severity:** **средний** (зависит от того, root ли у пользователя; на стоковом Android защищено sandbox). ### D. Forensic / физический доступ к устройству **Капабилитности:** - Полная image копия `/data/data/quest.montana.vpn/` - Анализ offline **Защита сейчас:** - Никакой кроме Android FBE (File-Based Encryption) которое работает только при выключенном устройстве и неизвестном пароле user. **Открыто:** - На разблокированном устройстве или с известным паролем — seed читается тривиально. **Severity:** **высокий** для пользователей хранящих значительный баланс. Closure: шифрование seed через user passcode + PBKDF2 (см. `07` F-6). ### E. Атака на VPN-сеть Montana через публичный endpoint **Капабилитности:** - Может поднять Montana VPN клиент (открытый VLESS URL) - Может слать heartbeat-ы с любого 40-hex адреса **Защита сейчас:** - Только проверка `request.remote_addr ∈ MONTANA_NODES` (helsinki/frankfurt/newyork). Атакующий должен сначала подключиться через VPN — это сделает любой. - Никакой подписи heartbeat **нет**. **Открыто (блокер):** - Атакующий с одним VPN-подключением шлёт 10⁶ heartbeat от 10⁶ fake-адресов → 10³ Ɉ/сек на fake-баланс - Экономика начисления рушится **Severity:** **блокер mainnet**. Closure: подпись Falcon-512 (см. `07` F-2, требует TimeChain integration M-VPN-2/3). ### F. Compromise CI/build pipeline **Капабилитности:** - Подмена `bip39-en.txt` в APK при сборке - Подмена UUID/Reality keys в Kotlin **Защита сейчас:** - BIP39 wordlist: **hardcoded SHA-256** в `MainActivity.kt` — если подменили, `bip39()` возвращает пустую строку, app не работает - APK signature: Genesis-keystore, fingerprint известен и публичен - Reproducible builds — частично (см. `08-Воспроизводимая-сборка.md`) **Открыто:** - Reality keys и UUID **захардкожены** в коде, не имеют integrity check — атакующий может подменить в скомпрометированной сборке без обнаружения - Closure: `[C-1]` SSOT — keys должны загружаться из одного authoritative источника с подписью (см. `07` CF-4). ### G. Mass surveillance government adversary **Капабилитности:** - Может координировать DPI с ML-классификатором - Может выпустить subpoena/court order на hosting provider узла Helsinki (Финляндия — нейтральная юрисдикция, но не безопасна абсолютно) - Может физически захватить узел (закон или операция) **Защита:** - Юрисдикция Finland — нейтральная, без mass surveillance законов аналогичных Five Eyes - Каскад через два exit-узла (Frankfurt DE / NewYork US) — добавляет дополнительный hop - Reality маскировка — повышает порог obfuscation **Открыто:** - Frankfurt (Germany) и NewYork (USA) — оба под юрисдикциями с MLAT-соглашениями - Если атакующий контролирует Helsinki + один из exit — может deanonymize пользователя - Compromise двух узлов из трёх → каскад теряет силу **Severity:** государственный actor — out of MVP scope. Дополнительные меры (Tor onion routing, additional jurisdictions) — future work. ### H. Sybil-атаки **Капабилитности:** - Создание миллиона BIP39-кошельков (бесплатно) - Отправка heartbeat с каждого через VPN **Защита:** - См. атакующий **E** выше. Сейчас не защищено никак. **Severity:** **блокер mainnet**. Closure: TimeChain validator state + Falcon signature per heartbeat (M-VPN-2/3). --- ## Что приложение защищает | Свойство | Защищено? | Механизм | Ограничения | |----------|-----------|----------|--------------| | Identity (seed) от других apps | **да** (если не root) | Android sandbox 0700 | Не защищено от root, forensic | | Identity от network adversary | **да** | Seed никогда не покидает устройство | n/a | | Identity от подмены в APK | **частично** | BIP39 wordlist SHA-256 check | Reality keys не verified | | Traffic content от пассивного DPI | **да** | Reality TLS-1.3 inside | Timing analysis возможен | | Traffic content от active probing | **да** | SNI Echo decoy | Full state inspection — открыто | | Целостность баланса | **нет** | n/a | Sybil-атака открыта (E,H блокеры) | | Authentication heartbeat | **нет** | n/a | Любой может слать heartbeat (E блокер) | | Persistence баланса при отказе сервера | **нет** | Single Moscow file | TimeChain integration отложена | --- ## Предположения (assumptions) 1. **Android FBE работает корректно** — данные приложения зашифрованы при выключенном устройстве. 2. **WebView SubtleCrypto детерминирован** — `crypto.subtle.digest('SHA-256', ...)` и `deriveBits('PBKDF2', ...)` дают идентичный результат на разных Chromium-версиях Android. (См. `06-Восстановление.md` — для верификации требуются tests on multiple Android versions.) 3. **xray-core реализует Reality корректно** — внешний аудит xray не входит в наш scope. Версия v26.2.6 актуальна на 2026-05. 4. **haproxy stick-table персистентна 24h** — verified empirically (см. `04-Сетевой-слой.md`). 5. **Genesis keystore хранится у автора в безопасном месте** — компрометация = возможность подписать malicious APK. --- ## Запреты в коде (что архитектурно невозможно) 1. **Heartbeat не идёт мимо VPN** — `MontanaVpnService.sendHeartbeat()` всегда через `socksConnect(127.0.0.1:10808)` (SOCKS5 локального xray). 2. **App не использует свой VPN для своего трафика** — `addDisallowedApplication(packageName)` исключает quest.montana.vpn из своего же TUN. 3. **Версия не дублируется** — `versionCode` и `versionName` только в `build.gradle.kts`, нигде в коде явно. 4. **xray access logs отключены** — `"access": "none"` в конфиге → logcat не спамит. --- ## Outside scope этого аудита - Уязвимости в Android OS (CVE на WebView, kernel etc.) — обязанность пользователя обновляться - Уязвимости в Linux kernel exit-нод — обязанность hosting provider - DDoS на публичный Helsinki:443 — на уровне hosting provider (THE.Hosting) + cloudflare если включено - Юридический аудит соответствия GDPR / законам о связи — отдельная экспертиза