306 lines
22 KiB
Markdown
306 lines
22 KiB
Markdown
# Driver App Recon — Design Doc
|
||
|
||
- **Дата:** 2026-05-11
|
||
- **Статус:** Draft, ожидает review владельца
|
||
- **Владелец:** vladtechno@gmail.com (PremiumPark)
|
||
- **Родительский проект:** PremiumDriverApp
|
||
- **Экосистема:** Premium CRM (TaxiDashboard)
|
||
|
||
---
|
||
|
||
## 1. Контекст и проблема
|
||
|
||
У PremiumPark есть Android-приложение для водителей проката, поставляемое подрядчиком 1С на условиях абонентской платы. Текущее приложение умеет:
|
||
|
||
- авторизовать водителя (логин/пароль),
|
||
- показывать остаток баланса и список штрафов,
|
||
- принимать платежи через приложение (детали неизвестны, выяснит разведка).
|
||
|
||
Все оплаты от водителей принимает юр.лицо PremiumPark. Подрядчик прекратил доработки приложения, оставаясь при этом получателем абонентской платы. Никаких функций эксплуатации авто (ТО, ремонты, фото повреждений, заявки в техслужбу) в приложении нет.
|
||
|
||
Стратегическая цель — построить собственное приложение, интегрированное с Premium CRM, и постепенно вытащить интеллектуальную собственность из 1С, сняв зависимость от подрядчика.
|
||
|
||
**Настоящий документ описывает только подпроект «Разведка»** — фазу изучения существующего приложения, предшествующую любой разработке. Подпроект «Новое приложение» имеет отдельный дизайн-док, который пишется после завершения разведки.
|
||
|
||
## 2. Цели и не-цели
|
||
|
||
### Цели
|
||
|
||
1. Получить полную карту HTTP/HTTPS-эндпоинтов, к которым ходит существующее приложение.
|
||
2. Документировать поток аутентификации и lifecycle сессии/токенов.
|
||
3. Документировать платёжный поток end-to-end: провайдер, инициация, токенизация, фискализация (54-ФЗ), связь с балансом в 1С.
|
||
4. Документировать механизм обновлений (poll / push / FCM) — как водитель узнаёт о новом штрафе.
|
||
5. Идентифицировать защитные механизмы (TLS pinning, обфускация, root detection, request signing, Play Integrity).
|
||
6. Принять решение go/no-go по подпроекту «Новое приложение» на основе фактов.
|
||
|
||
### Не-цели
|
||
|
||
- Не разрабатываем код нового приложения, BFF или платёжного канала.
|
||
- Не модифицируем APK и не публикуем «свой клиент».
|
||
- Не подключаем mitmproxy к боевому трафику реальных водителей — работаем только на тестовом аккаунте, заведённом в 1С специально для разведки.
|
||
- Не передаём APK, дампы, decompiled-исходники или отчёты третьим лицам.
|
||
- Не реализуем платёжный канал в этом подпроекте.
|
||
|
||
## 3. Юридическая рамка
|
||
|
||
- Декомпиляция выполняется на собственном устройстве/эмуляторе пользователя, с собственным тестовым аккаунтом, для целей совместимости и переноса данных — попадает под ст. 1280 ГК РФ (декомпилирование программы для ЭВМ для interoperability).
|
||
- PremiumPark является плательщиком абонентской платы за продукт и владельцем данных (балансы, штрафы, платежи водителей).
|
||
- Артефакты разведки хранятся локально, в `recon/artifacts/`, не публикуются в git (см. `.gitignore`).
|
||
- В случае официального запроса от подрядчика — разведка приостанавливается, артефакты архивируются.
|
||
|
||
## 4. Технический стенд
|
||
|
||
### 4.1 Хост
|
||
|
||
- Windows 11 (рабочая машина владельца)
|
||
- Python 3.10+ (для mitmproxy и frida-tools)
|
||
- Android Studio с Emulator и Platform-tools (`adb`)
|
||
- Свободное место: ≥30 GB (эмулятор + APK + дампы + декомпил)
|
||
|
||
### 4.2 Эмулятор Android
|
||
|
||
- **AVD:** Pixel 6 или Pixel 4
|
||
- **System Image:** Google APIs (НЕ Google Play) — это критично, иначе `adb root` недоступен и не получится положить mitmproxy CA в системные сертификаты
|
||
- **API Level:** 33 или 34
|
||
- **Архитектура:** x86_64 (для совместимости с frida-server)
|
||
|
||
При обнаружении сильной анти-эмуляторной защиты допустимо переключение на физическое Android-устройство с Magisk; это указано как fallback в плане исполнения.
|
||
|
||
### 4.3 Инструменты
|
||
|
||
| Инструмент | Назначение | Установка |
|
||
|---|---|---|
|
||
| `jadx-gui` | Декомпиляция APK в Java | github.com/skylot/jadx/releases |
|
||
| `apktool` | Распаковка манифеста и ресурсов | scoop install apktool |
|
||
| `mitmproxy` | Перехват HTTPS-трафика | `pip install mitmproxy` |
|
||
| `frida-tools` | Динамические хуки | `pip install frida-tools` |
|
||
| `objection` | Frida-обёртка с готовыми bypass'ами | `pip install objection` |
|
||
| `adb` | Управление эмулятором | Android SDK Platform-tools |
|
||
|
||
Конкретные команды установки и шаги настройки идут в план исполнения (writing-plans), не в спеку.
|
||
|
||
### 4.4 Файловая структура проекта
|
||
|
||
```
|
||
PremiumDriverApp/
|
||
├── README.md
|
||
├── .gitignore # игнорирует recon/artifacts/
|
||
├── docs/superpowers/specs/
|
||
│ └── 2026-05-11-driver-app-recon-design.md # этот документ
|
||
└── recon/
|
||
├── artifacts/ # НЕ в git
|
||
│ ├── original.apk # вытащенный APK
|
||
│ ├── decompiled/ # вывод jadx
|
||
│ ├── unpacked/ # вывод apktool
|
||
│ └── flows/ # mitmproxy дампы (*.mitm)
|
||
├── scripts/
|
||
│ ├── frida-bypass-pinning.js # шаблон обхода TLS pinning
|
||
│ ├── mitm-filter.py # фильтр mitmproxy для шумовых хостов
|
||
│ └── setup-emulator.ps1 # подготовка AVD
|
||
└── findings/
|
||
├── 00-final-report.md # финальный отчёт + go/no-go
|
||
├── 01-static-analysis.md
|
||
├── 02-network-capture.md
|
||
├── 03-auth-flow.md
|
||
├── 04-payment-flow.md
|
||
├── 05-realtime.md
|
||
└── 06-defenses.md
|
||
```
|
||
|
||
## 5. Этапы разведки
|
||
|
||
### Этап 1. Статический анализ APK
|
||
|
||
**Цель:** понять, что в принципе делает приложение, найти константы (URL, ключи провайдеров, package id), оценить уровень защиты.
|
||
|
||
**Действия:**
|
||
|
||
1. Получить APK: `adb shell pm path <package>` → `adb pull <path> recon/artifacts/original.apk`
|
||
2. Декомпиляция: `jadx-gui recon/artifacts/original.apk` → `recon/artifacts/decompiled/`
|
||
3. Распаковка манифеста: `apktool d original.apk -o recon/artifacts/unpacked/`
|
||
4. Извлечь из manifest и кода:
|
||
- `package` name, version, target SDK, min SDK
|
||
- permissions (особенно `INTERNET`, `RECEIVE_SMS`, `ACCESS_FINE_LOCATION`, payment-related)
|
||
- `network_security_config.xml` (cleartext policy, pinning declarations)
|
||
- встроенные base-URL — grep по `https://`
|
||
- сторонние SDK — поиск пакетов `ru.yoomoney`, `ru.tinkoff`, `com.google.firebase`, `okhttp3`, `retrofit2`
|
||
5. Оценить обфускацию: имена классов читаемые → R8/ProGuard не агрессивный; одно-/двухбуквенные имена → агрессивный.
|
||
6. Найти root/emulator detection: grep по `RootBeer`, `isDebuggerConnected`, `build.fingerprint`, `Build.PRODUCT`.
|
||
|
||
**Deliverable:** `recon/findings/01-static-analysis.md` со следующими разделами:
|
||
- Package metadata
|
||
- Permissions
|
||
- Network config
|
||
- Встроенные URL-ы и хосты
|
||
- Сторонние SDK
|
||
- Уровень обфускации
|
||
- Защитные механизмы (предварительный список)
|
||
|
||
### Этап 2. Перехват сетевого трафика
|
||
|
||
**Цель:** получить полный лог HTTP/HTTPS-запросов в обычных пользовательских сценариях.
|
||
|
||
**Действия:**
|
||
|
||
1. Подготовить эмулятор:
|
||
- `emulator -avd Pixel_6_API_34 -writable-system -no-snapshot`
|
||
- `adb root` → доступ к /system
|
||
- Установить mitmproxy CA в `/system/etc/security/cacerts/` (имя файла — hash сертификата + `.0`)
|
||
2. Прописать прокси: `Settings → Network → WiFi → Modify → Proxy: manual → 10.0.2.2:8080`
|
||
3. Запустить mitmproxy на хосте: `mitmweb --listen-port 8080`
|
||
4. Установить приложение: `adb install recon/artifacts/original.apk`
|
||
5. Прогнать сценарии (каждый — отдельным mitmproxy save):
|
||
- **S1. Вход:** запуск приложения → ввод логина/пароля → попадание на главный экран
|
||
- **S2. Просмотр баланса:** открытие экрана баланса, ожидание 60 сек (захватить полл, если есть)
|
||
- **S3. Просмотр штрафов:** открытие списка штрафов, открытие одного штрафа
|
||
- **S4. Экран платежа (без оплаты):** перейти к оплате, выбрать позицию, дойти до выбора способа оплаты, остановиться
|
||
- **S5. Инициация платежа:** довести до момента подтверждения, **но не платить реальной картой**
|
||
- **S6. Выход:** logout
|
||
6. Сохранить flow'ы: `recon/artifacts/flows/S1-login.mitm`, `S2-balance.mitm`, …
|
||
|
||
**При TLS pinning:**
|
||
- Запустить frida-server в эмуляторе.
|
||
- `objection --gadget <package> explore` → `android sslpinning disable`
|
||
- Если не помогает — кастомный Frida-скрипт (шаблон в `recon/scripts/frida-bypass-pinning.js`)
|
||
|
||
**Deliverable:** `recon/findings/02-network-capture.md` с таблицей всех увиденных эндпоинтов:
|
||
|
||
| Endpoint | Method | Auth | Сценарий | Запрос (схема) | Ответ (схема) | Частота |
|
||
|---|---|---|---|---|---|---|
|
||
|
||
И ссылки на исходные mitm-файлы для воспроизведения.
|
||
|
||
### Этап 3. Глубокое погружение в auth
|
||
|
||
**Цель:** понять формат и lifecycle токена, наличие подписей.
|
||
|
||
**Действия:**
|
||
|
||
1. Распарсить токен (jwt.io если JWT) — header, payload, claims, alg, iss, exp.
|
||
2. Проверить, есть ли request signing (HMAC, подпись тела) — искать в декомпиле использование `Mac.getInstance` / `Signature`.
|
||
3. Сэмплировать сессии:
|
||
- повторный логин → тот же токен или новый?
|
||
- есть ли refresh-токен и отдельный refresh-эндпоинт?
|
||
- что происходит при 401?
|
||
4. Построить sequence diagram (Mermaid).
|
||
|
||
**Deliverable:** `recon/findings/03-auth-flow.md`
|
||
|
||
### Этап 4. Платёжная подсистема (центральный этап)
|
||
|
||
**Цель:** разобрать поток оплаты end-to-end, выявить провайдера и механизм фискализации.
|
||
|
||
**Гипотезы, которые проверяем:**
|
||
|
||
- H1. Приложение использует SDK провайдера (YooKassa / Tinkoff Acquiring / СберPay) и общается напрямую с провайдером после получения init-токена от 1С.
|
||
- H2. Приложение прокидывает данные в 1С, а 1С общается с провайдером (приложение видит только наши эндпоинты).
|
||
- H3. Гибрид: init через 1С → провайдер через SDK → колбэк в 1С.
|
||
|
||
**Действия:**
|
||
|
||
1. В декомпиле найти SDK провайдера (по package name).
|
||
2. В трафике (этап 2, сценарий S5) изолировать запросы к провайдерским доменам vs к 1С.
|
||
3. Проследить токенизацию: куда уходят данные карты — в провайдер напрямую или в 1С (если последнее — большой ред-флаг по PCI DSS).
|
||
4. Понять чек 54-ФЗ:
|
||
- кто формирует — 1С / провайдер / ОФД напрямую?
|
||
- где водитель видит чек (push, email, экран приложения)?
|
||
5. Корреляция платёж ↔ баланс:
|
||
- до платежа `GET /balance` → X
|
||
- инициация → колбэк → когда `GET /balance` возвращает X + delta? (сразу/асинхронно/после явного pull)
|
||
6. Sequence diagram (Mermaid) с участниками: App, 1С, Provider, ОФД.
|
||
|
||
**Безопасность разведки:** не доводить до фактического списания. Останавливаемся на моменте, когда приложение запрашивает у провайдера init-токен и формирует webview/redirect — этого достаточно для понимания флоу.
|
||
|
||
**Deliverable:** `recon/findings/04-payment-flow.md`
|
||
|
||
### Этап 5. Push / realtime
|
||
|
||
**Цель:** понять, как водитель узнаёт о новом штрафе/начислении.
|
||
|
||
**Действия:**
|
||
|
||
- Проверить наличие FCM в манифесте (`com.google.firebase.MESSAGING_EVENT`).
|
||
- Если FCM — посмотреть payload (требует регистрации в FCM или симуляции).
|
||
- Если нет FCM — проверить наличие long-polling эндпоинта в трафике.
|
||
- Если возможно — попросить ответственного администратора 1С создать тестовый штраф для тестового водителя и засечь, как именно эта инфа приходит.
|
||
|
||
**Deliverable:** `recon/findings/05-realtime.md`
|
||
|
||
### Этап 6. Защитные механизмы (фоном)
|
||
|
||
В течение всех этапов фиксировать в `recon/findings/06-defenses.md`:
|
||
|
||
- TLS pinning — есть / нет / способ обхода
|
||
- Root/emulator detection — есть / нет / срабатывает ли на нашем стенде
|
||
- Request signing / HMAC — есть / нет / откуда берётся ключ
|
||
- Play Integrity API — есть / нет
|
||
- Антидебаг и анти-Frida хуки
|
||
|
||
### Этап 7. Финальный отчёт
|
||
|
||
**Deliverable:** `recon/findings/00-final-report.md`. Структура:
|
||
|
||
1. **Executive Summary** (1 страница, для бизнес-обсуждения)
|
||
2. **Полная карта API** (агрегированная таблица из этапа 2)
|
||
3. **Auth-flow** (Mermaid + текст)
|
||
4. **Payment-flow** (Mermaid + текст, ключевая часть)
|
||
5. **Realtime** (Mermaid + текст)
|
||
6. **Защитные механизмы и их преодоление**
|
||
7. **Оценка трудозатрат на «Новое приложение»** (грубая, в неделях разработчика)
|
||
8. **Рекомендация go/no-go**
|
||
9. **Открытые риски и неизвестные**
|
||
|
||
## 6. Критерии go / no-go
|
||
|
||
### Go — двигаемся в подпроект «Новое приложение»
|
||
|
||
- API эндпоинты и аутентификация поняты, стабильны (нет признаков частой смены контракта).
|
||
- Платёжный поток разобран, и видна возможность построить параллельный канал (свой эквайринг → свой backend → свой чек).
|
||
- Защитные механизмы преодолимы статически (т.е. мы понимаем, как мимикрировать или обойти без runtime-вмешательства).
|
||
- В трафике нет признаков hardware-bound криптографии, доступной только подрядчику.
|
||
|
||
### No-go — пересмотр стратегии
|
||
|
||
- API использует interactive challenge, который нельзя автоматизировать (CAPTCHA, манипуляция UI и пр.).
|
||
- Платёжный поток жёстко зависит от 1С на стороне сервера, и параллельный канал требует доступа к серверным обработкам.
|
||
- Используется криптография, привязанная к серверному секрету подрядчика (например, server-issued tokens с проверкой подписи приложения).
|
||
- Уровень защиты несоразмерен ценности — реверс займёт больше, чем оригинальная разработка с нуля.
|
||
|
||
### В случае no-go — альтернативы
|
||
|
||
1. **Прямые переговоры с подрядчиком** о публикации API (на руках уже будет отчёт разведки — рычаг в диалоге).
|
||
2. **Companion App** — приложение **только с новыми функциями** (блок B: эксплуатация авто), старое приложение остаётся для балансов/платежей. Реверс не нужен.
|
||
3. **Полная замена 1С** — крупный проект, не на этом цикле.
|
||
|
||
## 7. Open questions (на разведку)
|
||
|
||
Заполняются по ходу. Начальный список:
|
||
|
||
- Package name приложения — будет известно из APK на этапе 1.
|
||
- Платёжный провайдер — выясняется на этапе 4.
|
||
- Частота поллинга баланса — выясняется на этапе 2.
|
||
- Используется ли FCM — выясняется на этапе 5.
|
||
- Уровень обфускации — выясняется на этапе 1.
|
||
|
||
## 8. Следующий шаг
|
||
|
||
После утверждения этой спеки владельцем:
|
||
|
||
1. Создаём подробный план исполнения через `writing-plans` skill — пошагово, с чёткими DoD по каждому этапу.
|
||
2. Скрипты-заготовки в `recon/scripts/`: `setup-emulator.ps1`, `frida-bypass-pinning.js`, `mitm-filter.py`.
|
||
3. README с инструкцией «как развернуть стенд на пустой машине».
|
||
4. Запускаем этап 1 (статический анализ).
|
||
|
||
---
|
||
|
||
## Приложение A. Контактные точки с экосистемой Premium CRM
|
||
|
||
Этот подпроект ничего не пишет в боевую инфраструктуру (PremiumCRM, PostgreSQL, n8n, ASR-стек) и ничего не читает оттуда. Разведка изолирована — все артефакты локальны.
|
||
|
||
Контактные точки появятся **только** в подпроекте «Новое приложение»:
|
||
|
||
- FastAPI backend PremiumCRM получит новые роуты `/api/v1/driver/*`.
|
||
- PostgreSQL получит новые таблицы (maintenance, repairs, tickets, photos, driver_external_ids).
|
||
- Дейв (user_id=26) может стать author'ом авто-комментариев в новых сущностях.
|
||
- Telegram-бот @p_park_bot — потенциальный канал доставки OTP при логине нового приложения (TBD на этапе дизайна нового приложения).
|