# Как провести аудит приватности приложений на Android через ADB: права, трекеры и сетевые эндпоинты

> AI Release · @ai_release1 · https://ai-release.org/guides/kak-provesti-audit-privatnosti-prilozheniy-na-android-c.html

## TL;DR
- Время выполнения: 40–60 минут на одно приложение
- Уровень сложности: Intermediate
- Понадобится: ПК (Windows/macOS/Linux), Android platform-tools (`adb`), тестовое Android-устройство с включённой отладкой по USB, прокси-перехватчик mitmproxy, USB-кабель, ~1 ГБ свободного места под выгрузку APK и логи. Версии platform-tools и mitmproxy сверьте с документацией — здесь они не фиксируются.

## Требования и подготовка
![Иллюстрация к разделу «Требования и подготовка»](https://ai-release.org/guides/img/kak-provesti-audit-privatnosti-prilozheniy-na-android-c-ru-1.jpg?v=1794041334)


- **ADB (Android Debug Bridge)** — утилита, которая даёт ПК доступ к служебным командам телефона. Установите platform-tools и проверьте, что `adb` есть в PATH.
- **Режим разработчика на телефоне.** Настройки → О телефоне → 7 тапов по «Номер сборки» → Настройки → Система → Для разработчиков → включить «Отладка по USB».
- **Тестовое устройство или тестовый профиль.** Аудит ставит HTTP-прокси глобально — на рабочем телефоне это ломает часть приложений.
- **mitmproxy на ПК** — прокси, который показывает HTTPS-запросы приложения в открытом виде. Нужен для шага 2.
- **Свободное место ~1 ГБ** — для выгруженного APK и файлов логов.
- **Пакет-цель.** Узнайте package id приложения заранее: он понадобится во всех командах. Пример: `com.example.app`.

Если `adb` ещё не связан с телефоном, сначала пройдите подключение по инструкции [Как подключить Android к Windows через ADB: команды, список устройств и ошибки](https://ai-release.org/guides/kak-podklyuchit-android-k-windows-cherez-adb-komandy-sp.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide) — в этом гайде предполагается, что `adb devices` уже показывает устройство в статусе `device`.

**Проверка готовности:**
```bash
adb devices
adb shell getprop ro.build.version.release
```
Ожидаемый вывод: строка `<серийный-номер>	device` (именно `device`, не `unauthorized`) и номер версии Android, например `14`.

## Шаг 1. Инвентаризация: пакет, версия, разрешения

**Что сделать:** собрать базовый паспорт приложения — версию, targetSdk и полный список запрошенных разрешений.

**Зачем:** без базовой линии вы не отличите «приложение просит доступ к контактам» от «приложение уже получило его и пользуется». `dumpsys package` — это дамп внутренней базы пакетного менеджера, он показывает и запрошенные, и фактически выданные разрешения.

```bash
adb shell pm list packages -3 -f | grep -i example
```
Ожидаемый вывод — строка вида `package:/data/app/~~xxxx==/com.example.app-yyyy==/base.apk=com.example.app`. Флаг `-3` оставляет только сторонние (не системные) приложения, `-f` показывает путь к APK.

```bash
adb shell dumpsys package com.example.app | grep -A 100 "requested permissions"
```
На Windows без Git Bash то же самое делается через `findstr`:
```powershell
adb shell dumpsys package com.example.app | findstr /C:"requested permissions" /C:"install permissions" /C:"targetSdk"
```
Ожидаемый вывод: блок `requested permissions:` со строками вида `android.permission.CAMERA`, `android.permission.ACCESS_FINE_LOCATION`, `android.permission.READ_CONTACTS` и блок `install permissions:`, где у части строк стоит `granted=true`.

**Пример:** приложение-фонарик с `targetSdk=33`, у которого в `requested permissions` есть `ACCESS_FINE_LOCATION` и `READ_CONTACTS`, — уже повод для вопросов: фонарику эти данные не нужны.

Дальше снимите «операционные разрешения» (appops) — отдельную подсистему Android, которая решает, разрешён ли конкретный тип доступа прямо сейчас:
```bash
adb shell cmd appops get com.example.app
```
Ожидаемый вывод — список вида `CAMERA: allow`, `LOCATION: ignore`, `READ_CONTACTS: deny`. Значение `ignore`/`deny` при `granted=true` в `dumpsys` — нормальная ситуация: разрешение выдано, но операционно заблокировано.

**Как проверить:** сохраните оба вывода в файлы и убедитесь, что список пакетов содержит именно ваш package id, а не похожий (`com.example.app` vs `com.example.app.lite`).
```bash
mkdir -p audit && adb shell dumpsys package com.example.app > audit/package.txt && adb shell cmd appops get com.example.app > audit/appops.txt && wc -l audit/*.txt
```

## Шаг 2. Трекеры и сетевые эндпоинты
![Иллюстрация к разделу «Шаг 2. Трекеры и сетевые эндпоинты»](https://ai-release.org/guides/img/kak-provesti-audit-privatnosti-prilozheniy-na-android-c-ru-2.jpg?v=1794041344)


**Что сделать:** найти в приложении сторонние SDK-трекеры (аналитика, реклама, краш-репортинг) и зафиксировать домены, к которым оно обращается.

**Зачем:** разрешения показывают потенциал, а трекеры и трафик — фактическое поведение. Трекер — это встроенная библиотека разработчика, которая собирает события и отправляет их на свой сервер.

**2.1. Выгрузите APK и посмотрите, какие SDK внутри.**
```bash
adb shell pm path com.example.app
adb pull /data/app/~~xxxx==/com.example.app-yyyy==/base.apk audit/base.apk
unzip -l audit/base.apk | grep -iE "com/facebook|com/google/android/gms/analytics|com/appsflyer|com/adjust/sdk|com/onesignal"
```
Ожидаемый вывод — пути классов, например `classes2.dex` внутри не покажет имена, поэтому надёжнее искать по строкам:
```bash
unzip -p audit/base.apk classes.dex | strings | grep -iE "appsflyer|adjust|onesignal|firebase-analytics"
```
Если строки нашлись — соответствующий SDK в приложении есть. Если вывод пустой, проверьте остальные dex-файлы: `unzip -l audit/base.apk | grep "classes.*dex"`.

**2.2. Включите HTTP-прокси и перехват.**

Запустите mitmproxy на ПК (порт по умолчанию 8080) и направьте на него трафик телефона:
```bash
adb shell settings put global http_proxy <ip-ПК>:8080
```
`<ip-ПК>` — локальный адрес компьютера в той же Wi-Fi-сети, например `192.168.1.10`. Почему это работает: Android применяет системный прокси ко всем приложениям, которые используют стандартный сетевой стек.

Затем откройте приложение и пройдите типовой сценарий: запуск, регистрация, переход по 3–4 экранам, сворачивание. В окне mitmproxy появятся запросы вида `GET https://api.example.com/v1/config`.

**2.3. Продублируйте проверку через logcat.**
```bash
adb logcat -c
adb logcat | grep -iE "http://|https://|SSLHandshake|UnknownHost"
```
`adb logcat -c` очищает буфер, чтобы в отчёт попали только события после запуска приложения. Ожидаемый вывод — строки с доменами или сетевыми ошибками; отсутствие строк тоже результат: приложение может не логировать сеть.

**Пример:** в перехвате видно `POST https://api.example.com/collect` сразу после старта, до нажатия любых кнопок, — это телеметрия запуска. В отчёте фиксируйте: домен, метод, время относительно запуска, отправляемые поля (без значений).

**Как проверить:** в mitmproxy в списке потоков есть хотя бы один запрос от приложения, а `adb shell settings get global http_proxy` возвращает заданный адрес.

## Шаг 3. Проверка результата и отчёт
![Иллюстрация к разделу «Шаг 3. Проверка результата и отчёт»](https://ai-release.org/guides/img/kak-provesti-audit-privatnosti-prilozheniy-na-android-c-ru-3.jpg?v=1794041353)


**Что сделать:** свести данные в таблицу, отключить прокси и убедиться, что настройки устройства вернулись в исходное состояние.

**Зачем:** аудит без отчёта и без отката изменений бесполезен: следующий запуск приложения будет вести себя иначе, а коллега не сможет повторить замер.

Сведите результаты в таблицу:

| Что проверяли | Команда | Что нашли у `com.example.app` |
|---|---|---|
| Запрошенные разрешения | `dumpsys package` | CAMERA, ACCESS_FINE_LOCATION |
| Операционные разрешения | `cmd appops get` | LOCATION: ignore |
| Сторонние SDK | `strings` по APK | найден рекламный SDK |
| Сетевые эндпоинты | mitmproxy | `api.example.com`, `cdn.example.com` |

**Как проверить:** выполните откат и убедитесь, что прокси снят.
```bash
adb shell settings put global http_proxy :0
adb shell settings get global http_proxy
```
Ожидаемый вывод: `null` — прокси отключён. Если остался адрес, повторите команду: пока прокси активен, приложения без интернета будут вести себя некорректно.

Чек-лист приёмки аудита:
- [ ] Вывод `dumpsys package` сохранён в файл и содержит `requested permissions`
- [ ] Вывод `cmd appops get` сохранён и сопоставлен с разрешениями
- [ ] Список сторонних SDK зафиксирован с указанием, в каком dex найден
- [ ] Для каждого домена указан метод и триггер (запуск, экран, кнопка)
- [ ] Прокси отключён, `http_proxy` равен `null`
- [ ] Отчёт не содержит персональных данных из перехваченных запросов

**Пример готовой строки отчёта:** `api.example.com — POST /collect — сразу после cold start — поля: app_version, device_model, event.`

## Возможные проблемы и решения

**Проблема. Устройство видно, но команды не выполняются.**
- Ошибка: `error: device unauthorized. Please check the confirmation dialog on your device.`
- Причина: на телефоне не подтверждён RSA-ключ отладки, либо подтверждение было отозвано.
- Решение: разблокируйте телефон, нажмите «Разрешить» в диалоге (включите «Всегда разрешать с этого компьютера»), затем перезапустите сервер:
```bash
adb kill-server && adb start-server && adb devices
```

**Проблема. mitmproxy не видит HTTPS-запросы приложения.**
- Ошибка в mitmproxy или в логах приложения: `SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.`
- Причина: certificate pinning — приложение доверяет только своему вшитому сертификату и отвергает подмену от прокси.
- Решение: проверьте остальной трафик (часто часть доменов не запинена) и зафиксируйте в отчёте сам факт пиннинга как положительную практику:
```bash
adb logcat | grep -i "Trust anchor"
```
Обход пиннинга требует модификации APK или тестовой сборки — это отдельная задача и для продакшен-сборки не выполняется.

**Проблема. Команда с `grep` не работает.**
- Ошибка: `'grep' is not recognized as an internal or external command, operable program or batch file.`
- Причина: команда запущена в `cmd.exe`, где `grep` отсутствует.
- Решение: используйте `findstr` или запустите Git Bash:
```powershell
adb shell dumpsys package com.example.app | findstr /C:"requested permissions"
```

## Резюме и следующие шаги

Вы получили три срезa по приложению: запрошенные и операционные разрешения, список встроенных SDK и домены, куда уходит трафик, — и оформили их таблицей с откатом настроек. Дальше повторите ту же процедуру на 2–3 приложениях из одной категории и сравните, кто из них отправляет данные до первого действия пользователя; если приложение ставится не из Google Play, начните с инструкции [Как скачивать и устанавливать ИИ-приложения на Android через RuStore](https://ai-release.org/guides/kak-skachivat-i-ustanavlivat-ii-prilozheniya-na-android.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

## FAQ

**Можно ли провести такой аудит без root?**
Да, все команды шагов 1–3 выполняются через `adb shell` на обычном устройстве. Ограничение — перехват HTTPS: часть приложений блокирует прокси через certificate pinning, и это фиксируется как результат, а не как ошибка методики.

**Почему в настройках разрешение выглядит выключенным, а `dumpsys` пишет `granted=true`?**
Потому что это разные слои: `granted=true` — разрешение выдано на уровне пакетного менеджера, а `cmd appops get` показывает операционное состояние (`allow`/`ignore`/`deny`), которое может быть изменено отдельно, в том числе системой.

**Что делать, если logcat пустой, а трафик в mitmproxy есть?**
Это нормально: приложение просто не пишет сетевые события в лог. Основным источником данных остаётся прокси, а `logcat` используйте для ошибок вида `SSLHandshakeException` и `UnknownHostException`.

**Законно ли перехватывать трафик приложения?**
Аудит корректен на своём устройстве и на своём приложении либо с разрешения владельца. Перехват чужого трафика без согласия и обход защиты — вне рамок этой инструкции; тексты ошибок и результаты замеров публикуйте без персональных данных.
