| «Механик» | `com.naughtysoft.ttc` | 1.8.13 (build 165) | Приложение для механиков парка: фото машин в 1С |
Оба от одного вендора (`com.naughtysoft.*`), технологический стек **разный** (см. §3) — признак того, что вендор находится в процессе технологической миграции и не унифицирует разработку.
---
## 2. Метаданные APK
### Водитель (`com.naughtysoft.TtcDriver`)
| Параметр | Значение |
|---|---|
| Version | 1.2.313 (build 323) |
| Target SDK | 36 (Android 16) |
| Min SDK | 24 (Android 7) |
| Main Activity | `com.naughtysoft.TtcDriver.MainActivity` |
- Бизнес-логика приложения — **в Dart, скомпилированном AOT в `libapp.so`**. jadx-декомпиляция Java/Kotlin даёт только тонкие plugin wrappers, не бизнес-код.
- Все строковые константы (URL, paths, ключи) хранятся в `libapp.so` как plain ASCII → извлекаемы через `grep -a`/`strings` (см. §4).
- HTTP-запросы Flutter делает через стандартный Dart `HttpClient` → видимы в mitmproxy как обычный HTTPS (без custom низкоуровневых трюков).
- Дальнейший реверс Dart-кода (поведение, проверки) — через **reFlutter** (требует пересборки snapshot) или динамический анализ через mitmproxy. На статическом этапе ограничиваемся извлечёнными строками.
- jadx даёт ноль информации о логике Механика (всё в C# DLL).
- Для распаковки нужен **pyxamstore** (распаковать blob → отдельные DLL) + **dnSpy/ILSpy** для C# декомпиляции.
- Это **отдельный поток работы**, отложен. Приоритет — водитель.
**Вывод о стеке вендора:** Xamarin (Mechanic) сейчас deprecated Microsoft'ом в пользу .NET MAUI. Driver переписан на Flutter — современный стек. Вендор находится в процессе технологической миграции, что согласуется с фактом «прекратил доработки» — ресурсы ушли на перенос/переход, а не на обновление наших фич.
---
## 4. Сетевая инфраструктура
Все извлечены из `libapp.so` водительского приложения через `grep -aoE 'https?://...'`.
### Бэкенды
| Endpoint | Назначение |
|---|---|
| **`https://api.ttcontrol.naughtysoft.ru/api`** | Главный API вендора NaughtySoft. Основной канал общения приложения с сервером. |
| **`https://taksi.0nalog.com:1703/`** | Нестандартный порт **1703** — классический паттерн **HTTP-сервиса 1С Предприятие**. С большой вероятностью это сам сервер 1С PremiumPark, на котором работает конфигурация вендора. Имя `0nalog` (вместо `nalog`) — возможный obscurity-приём. |
| **`https://ttcdriver.firebaseio.com`** | Firebase Realtime Database. Помимо FCM-пушей, часть данных может синхронизироваться через Realtime DB. Project ID: `ttcdriver`. |
### Архитектурная гипотеза
```
Driver App (Flutter)
│
├──► api.ttcontrol.naughtysoft.ru (HTTPS, основное взаимодействие)
│ │
│ └──► (на бэке вендора, вероятно) ──► taksi.0nalog.com:1703 (1С)
│
├──► taksi.0nalog.com:1703 (возможно, прямые запросы — нужно подтвердить на этапе 2)
│
├──► ttcdriver.firebaseio.com (Realtime DB + FCM регистрация)
│
└──► FCM (Firebase Cloud Messaging — push-уведомления о штрафах и пр.)
```
Подтвердить факт прямых обращений на `0nalog:1703` (или это идёт только через прокси `api.ttcontrol`) — задача этапа 2 (mitmproxy).
### Карта API endpoints
Извлечены пути `/v1/...` и `/v3/...` из `libapp.so`. Префикс домена — `api.ttcontrol.naughtysoft.ru/api`.
| `/v1/GetStatus/` | Статус (требует расшифровки на этапе 2) |
| `/v1/Sell` | Продать что-то (требует расшифровки) |
| `/v1/GetListOfQuestions` | Список вопросов (FAQ / скрининг) |
### Аутентификация
Найдены характерные строки в `libapp.so`:
-`Authorization` — заголовок HTTP
-`Bearer` — Bearer-токен
-`apiKey` — упоминание (вероятно Firebase API key)
-`authorization` (lowercase) — тоже встречается
**Гипотеза:** стандартная Bearer-token аутентификация. Логин → получение access_token → дальше во всех запросах `Authorization: Bearer <token>`. Подтвердить и понять lifecycle (refresh? expiry?) — задача этапа 3.
---
## 5. Защитные механизмы
### TLS pinning
- **На уровне Android system (network_security_config.xml):** отсутствует — конфиг не найден в декомпиле.
- **Cleartext traffic разрешён** — приложение умеет HTTP без TLS (вероятно для `taksi.0nalog.com:1703`).
- **Программный TLS pinning в Dart-коде:** возможен, но в `libapp.so` явных маркеров pinning'а (типа `setTrustedRoots`, custom SecurityContext с pinned certs) поверхностный grep не выявил. Проверится на этапе 2: если mitmproxy сразу читает трафик — pinning'а нет; если нет — нужен reFlutter/Frida.
**Прогноз:** на этапе 2 mitmproxy будет работать **без обхода TLS pinning**. Это сильно упрощает разведку.
### Root/Emulator detection
Не сканировалось специально (требует анализа Dart-кода в `libapp.so`). На этапе 2 проверим эмпирически — запустится ли приложение на эмуляторе. Учитывая что:
- Приложение Flutter (без agressive anti-debug по умолчанию)
- Нет premium-фич, ориентированных на security (банковский класс, антифрод)
— вероятность блокирующего detection'а низкая.
### Request signing / HMAC
Маркеров явного HMAC (типа `Mac.getInstance("HmacSHA256")`) в Kotlin-стороне не найдено (большая часть Java-кода — Flutter engine + plugins, без бизнес-логики). В Dart возможна реализация, но это нестандартный паттерн для Flutter приложений — обычно полагаются на Bearer + TLS.
### Прочее
- **Play Integrity API** — не используется (нет соответствующих библиотек в декомпиле).
-`com.squareup.okhttp3` / `retrofit2` — нет (HTTP идёт через Dart)
-`dagger`, `hilt` — нет DI-фреймворков (Flutter сам по себе их не требует)
**Вывод по платежам:** на Kotlin-стороне платёжных SDK провайдеров нет. Платёж через `/v1/CreatePayment` скорее всего возвращает **deep link** (типа `https://qr.nspk.ru/<id>` для СБП или URL веб-страницы провайдера), и Flutter открывает его через стандартный intent. Это **отличный сценарий для миграции** — точно повторяемо в нашем приложении без необходимости лицензировать чьи-то SDK.
---
## 7. Промежуточные гипотезы
1.**Архитектура двухслойная**: NaughtySoft API (`api.ttcontrol`) — фасад, под капотом стоит 1С (`taksi.0nalog:1703`). Подтвердить на этапе 2: смотреть, идут ли с приложения **прямые** запросы на `0nalog:1703` (тогда оба слоя независимы), или только на `api.ttcontrol` (тогда `0nalog` — публично доступный backend 1С только в декомпиле, а реально приложение его не дёргает).
2.**Платежи через СБП + deep links**, без нативных SDK провайдеров → **легко повторимо** в нашем будущем приложении.
3.**Фото-функция (`/v1/AddInspection`, `/v1/FOTO/`) уже есть на бэке** — она просто не выдана водителям в UI текущего приложения. Если на этапе 2 удастся снять трафик этих endpoints (через Механика или через намеренный вызов в Driver если кнопка где-то есть), мы получим готовый протокол для нашего блока B без дизайна с нуля.
4.**QIWI код мёртв** — индикатор того, что подрядчик не зачищает мёртвый функционал. Подтверждает «прекратили доработки».
5.**TLS pinning слабый или отсутствует** → mitmproxy будет работать в этап 2 «из коробки».
---
## 8. Open questions для следующих этапов
- Какой формат запроса/ответа на `/v1/CreatePayment`? (этап 2)
- Использует ли приложение `/api/...` префикс или `/v1/...` идут напрямую от корня? (этап 2)
- Использует ли водитель `taksi.0nalog.com:1703` напрямую или только через прокси `api.ttcontrol`? (этап 2)
- Что приходит в FCM-сообщении при штрафе? Полный объект или только триггер «обнови данные»? (этап 5)
- Что лежит в `assemblies.blob` Механика? Те же endpoints или другие? (отдельный поток)
---
## 9. Блокеры и риски
| # | Риск | Митигация |
|---|---|---|
| R1 | **ARM-only ABI** в обоих APK — на x86_64 эмуляторе `adb install` падает с`INSTALL_FAILED_NO_MATCHING_ABIS` | Для этапа 2 либо: (a) создать AVD x86_64 API 33+ с включённой ARM-translation, (b) использовать физическое Android-устройство, (c) использовать ARM-эмулятор (медленный) |
| R2 | Программный TLS pinning в Dart-коде возможен, но не подтверждён на статике | Проверить эмпирически на этапе 2; если есть — обойти через **reFlutter** |
| R3 | Механик на Xamarin требует отдельного тулинга (pyxamstore + dnSpy) для разбора C# логики | Отдельный поток работы; приоритет — водитель |
| R4 | Часть Dart-логики (валидация, формат запросов) невидима без динамики | Перенесено на этап 2 (mitmproxy) |
---
## 10. Артефакты
| Файл | Что |
|---|---|
| `recon/artifacts/original-driver.xapk` | Исходный XAPK водителя из APKPure |
| `recon/artifacts/decompiled/mechanic/` | jadx-декомпиляция Механика (даёт только Xamarin glue, не C# логику) |
| `recon/artifacts/native/driver/lib/arm64-v8a/libapp.so` | Извлечённый Dart AOT snapshot водителя — главный источник URL и endpoints |
---
## 11. Следующий шаг (этап 2)
Все необходимые данные для разворачивания этапа 2 готовы:
- Список endpoints для отслеживания — есть
- Базовые URL'ы — есть
- Подтверждено отсутствие XML-pinning'а — mitmproxy будет работать
- Топология FCM известна — этап 5 пойдёт от Firebase project `ttcdriver`
**Перед этапом 2 нужно решить ARM-блокер** (R1): выбрать ARM-эмулятор / x86_64 с ARM translation / физическое устройство. Это **открытый пункт для пользователя**.
После этого по плану: установка приложения на стенд → mitmproxy + системный CA → проигрыш сценариев S1-S6 (см. §5 design-doc'а) → каталог реальных запросов/ответов.
print(f"\nExtracted {extracted} assemblies into {out_dir}")
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.