ADB vs Spy Cam & Mic

    Как проверить, ведет ли какое-нибудь приложение на Android-смартфоне фото- или видеорепортаж, хотя ему это ни разу ни к чему? Нижепредлагаемый вариант совсем не идеален, но не требует «рута» или кастомной прошивки.

    P.S. Я добавил в статью описание мониторинга доступа приложений к микрофону.

    Что требуется установить:
    • ADB (Android Debug Bridge) (например, в составе Android SDK Platform Tools — загрузить можно здесь);
    • драйвер для телефона (при необходимости, например, Google USB Driver можно загрузить здесь).

    Включаем на телефоне режим отладки через USB и подключаем смартфон к USB-порту компьютера, причем следует выбрать режим USB-подключения, отличный от «Только зарядка».
    Скрытый текст
    В «Диспетчере устройств» смартфон отображается, например, так:
    в режиме «Фото» или «Файлы»

    в режиме «USB-диск»

    А вот так — в выводе команды lsusb:


    Открываем командную строку в каталоге, в который установились «тулзы».
    Проверяем, что подключение успешно (отображается серийный номер подключенного смартфона):
    adb devices
    (для Windows)

    Для Linux команда бы выглядела так:
    ./adb devices

    Если компьютер не авторизован для использования с этим смартфоном (под Android 4.2.2 и новее), то рядом с серийным номером появится предупредительное сообщение "unauthorized".
    Для авторизации необходимо подтвердить на смартфоне разрешение отладки через USB.
    Скрытый текст
    Под Linux может появляться сообщение "no permissions" — в моем случае удалось решить проблему переключением смартфона в режим «Медиаустройство (MTP)».

    Запускаем оболочку на устройстве (получаем приглашение "$"):
    adb shell



    Затем вводим следующие «магические» символы:
    while true; do ps `while ! (dumpsys media.camera | grep -E "PID") do  done | grep -o "[^PID: ][0-9]*$"` | grep -o "[^S ]*$" ; date; sleep 1; done



    Улучшенный вариант, убирающий вывод «NAME» и пустые строки:
    while true; do ps `while ! (dumpsys media.camera | grep -E "PID") do  done | grep -o "[^PID: ][0-9]*$"` | grep -o "[^S ]*$" | grep -v "NAME" | grep .; date; sleep 1; done
    


    И ничего не происходит :-) Пока что-то не решит немного поснимать :-)

    Означенный «магический» набор символов запускает с максимально возможной скоростью мониторинг доступа к сервису камеры — media.camera (этот сервис реализуется библиотекой libcameraservice.so). Если камера не активна, dumpsys выдает примерно такое:

    А если камера понадобилась, то появляется такое:


    grep-ы проверяют наличие "PID" и, если таки эта цепочка есть, то вырезают из строки номер процесса и скармливают его команде ps, которая выводит данные об этом процессе, а еще один grep вырезает его имя. После обнаружения активности камеры делаем паузу на секунду, чтобы сообщения не сыпались слишком часто. Для прерывания работы команды служит комбинация клавиш CTRL-C, а для выхода из оболочки — CTRL-D.

    Простейший пример — после запуска штатного приложения смартфона для фото/видеосъемки начинают с интервалом в 1 секунду сыпаться сообщения с именем процесса и датой/временем:

    "

    Но есть и более хитрые приложения, их можно найти по ключевому слову «spy cam» (использующие трюк, например, с однопиксельным превью (http://www.ez.ai/2014/05/exploring-limits-of-covert-data.html)). Подобное творение при запуске съемки сворачивается и ведет репортаж, но сообщения сыпятся исправно:



    Также я проверил работоспособность предложенного метода на приложении, делающем однократный снимок при нажатии на плавающую кнопку без всякого видимого окна предпросмотра.
    Скрипт успешно отлавливал обращение к камере и выдавал два сообщения при каждом снимке:


    Но ведь ничто не мешает реализовать подобную функциональность и в приложении с более безобидным названием (https://www.zdnet.com/article/this-scary-android-malware-can-record-audio-video-and-steal-your-data/), а разрешения — ну так случаи всякие бывают. Да и «легальное» приложение может вести репортаж, когда ему заблагорассудится (я встречал упоминание об одном таком случае). И не зря в Android P приняли меры по предотвращению доступа к камере фоновых приложений.

    Способ проверен на смартфонах Huawei SCL-L01 (Android 5.1.1) и Huawei G700-U20 (Android 4.2.1), на других моделях смартфонов формат вывода dumpsys может отличаться (для сервиса media.camera он не стандартизован), что потребует коррекции кода.
    Формат сообщений жестко «зашит» в библиотеке /system/lib/libcameraservice.so — например, для смартфона Huawei SCL-L01:

    В комментарии — подсказка, как изменить код для работы со смартфоном под Android 9.
    В этом комментарии приводится лог обращений к камере, который ведет HTC U11.
    Но, например, на «древнем» Huawei U8650 (Android 2.3.4) dumpsys отрабатывает нормально:

    А прав не хватает для… grep :-)


    Мониторинг доступа к микрофону

    Аналогичный метод можно применить и для мониторинга за доступом приложений к микрофону. В этом случае необходимо следить за сервисом media.audio_flinger.
    Вводим в «шелле» команду (приведенный код работает смартфоне Huawei SCL-L01 (Android 5.1.1)):
    while true; do ps `while ! (dumpsys media.audio_flinger | grep -A20 Input| grep -A1 Client | grep yes | grep -o "[^yes ].*" | grep -o [0-9]*) do  done` | grep -o "[^S ]*$" | grep -v "NAME" | grep .; date; sleep 1; done
    

    Если какое-то приложение записывает звук посредством микрофона, то в выводе dumpsys media.audio_flinger присутствует подобный фрагмент:

    (Input thread — входной поток, 22467PID записывающего звук процесса).
    При записи звука через стандартное приложение «Диктофон» и включенном мониторинге (посредством вышеприведенного кода) появляются соответствующие сообщения:

    А вот какие сообщения сыпятся при активированном голосовом вводе Google переводчика:

    На других моделях смартфонов формат вывода dumpsys может отличаться, что потребует коррекции кода.
    Например, на смартфоне Huawei G700-U20 (Android 4.2.1):

    В этом случае код для мониторинга будет иметь вид:
    while true; do ps `while ! (dumpsys media.audio_flinger | grep -A3 Input| grep -A1 Clien | grep -o "[^   ].*" | grep -o [0-9]*) do  done` | grep -o "[^S ]*$" | grep -v "NAME" | grep .; date; sleep 1; done

    Вот как в этом случае проявляет себя «ожившая» Алиса:
    Поделиться публикацией

    Комментарии 34

      +2
      Спасибо. Полезно. Хорошо, что в последней версии Android этот вопрос решили.
      Foreground Services Requirement — When does your app interact with the camera? On Android 9 (API level 28) and later, apps running in the background cannot access the camera. Therefore, you should use the camera either when your app is in the foreground or as part of a foreground service.
      Правда не понятно, когда Pie доберется до всех. Да и в этом случае вендоры могут оставить для себя бэкдор и тогда даже ADB не спасет.
        +3

        Вообще меня удивляет почему только уже в поздних версиях начали думать о безопасности в этом ключе, еще не так давно можно было легально в фоне следить за активными приложениями (или всё еще можно?), забить на пермишны ибо не было системных диалогов (т.е. читай смс-ки, лазь по фоткам, снимая втихаря) и еще пяток примеров точно наберется...

          +4
          Безопасность и возможности- две стороны одной медали. Предполагаю, что в начале сделали ставку на второе по принципу «не нравятся пермишены- не устанавливай». По идее большое количество доступов к личным данным должно было опускать приложение в списках из-за отказов.

          Только крупные сервисы не оставляли пользователям альтернатив. А потом понемногу пошли скандалы о сливах.

          Да и сейчас с приходом runtime permissions ничего сильно не поменялось. Приложения некоторых крупных сервисов отказываются работать, пока пользователь на старте не даст им доступы к смс, звонкам, контактам и т.д.

          или всё еще можно?
          Можно. Начиная с 5.0 можно получить у пользователя разрешение на доступ к статистике использования, либо на то, чтобы сделать приложение администратором устройства. И то и другое явно для пользователя и тот может отказаться.

          Есть варианты как получить эту инфу без разрешений на свежих версиях. Но все они требуют нестандартных подходов и имеют кучу оговорок, из-за чего рабочими их назвать нельзя.
            +2
            Есть варианты как получить эту инфу без разрешений на свежих версиях

            Вот бы и выложили статью на эту тему, как продолжение к нынешней… Глядишь, кто-нибудь бы и эти дыры позакрывал.
              +1
              Справедливо. Я думал об этом раньше, но в итоге решил отказаться по двум причинам:
              1. Все эти способы давно есть на stackoveflow и в остальном интернете
              2. Процент отказов и получения ложных или неверных данных настолько велик, что подобное не годится для широкомасштабного применения. Потому это не интересно ни компаниям ни отдельным лицам. И потому подобное мало реально встретить в приложениях (скорее всего, такие даже не пройдут постмодерацию). И потому статья об этом получится бесполезной. У меня есть более интересный материал)
              +2
              Приложения некоторых крупных сервисов отказываются работать, пока пользователь на старте не даст им доступы к смс

              А еще не написали патч, который позволяет эмулировать выданный доступ? То есть приложению вызов функции перечисляющей разрешения отдает желаемое, а при попытке воспользоваться этим разрешением возвращает OK, но без данных или с шумом вместо данных.
                +1
                Для старых приложений примерно так и должно работать, для новых при доступе- exception. Возможно, решение есть у отдельных вендоров. Но нельзя такое расценивать как патч. В самой системе пермишенов, с точки зрения реализации и логики, проблем нет. Есть проблема в наглости сервисов. Даже если и станет подобная подмена повсеместной- сервисы начнут вкладывать человекочасы в способы определения реальности получаемых данных.
                  +2

                  Давно написали, для старых андроидов это XPrivacy, для новых XPrivacyLua, но для его работы нужен рут и Xposed Framework.

                    +1

                    Рут то ладно, а вот xposed жёстко ломает SafetyNet, из-за чего куча приложений вообще отказываются работать...

                    +3
                    А еще не написали патч, который позволяет эмулировать выданный доступ?

                    Есть вполне законный способ это делать для большинства разрешений без рута (но только для Android 6.0 и выше).

                    Можно поставить Shizuku Manager, дать ему доступ с помощью adb (инструкция прямо в приложении), потом поставить App Ops — и рулить как угодно.

                    Если доступ к чему-то закрыт в App Ops, то приложению (если оно его запрашивает) можно сказать Allow — оно всё равно ничего не получит (пустой список контактов, SMS etc), хотя будет уверено что разрешение получило.

                    Закрыть таким образом доступ в сеть нельзя, но контакты, микрофон, камера, GPS и ещё куча всего (включая возможность работать в фоне) — вполне можно.

                    Используются стандартные возможности Android, никакой магии (отбирать доступ можно просто с помощью adb — до переустановки приложения), эти два приложения просто удобный UI.
                    +1
                    В Lineage OS есть Trust, я так сберу «выдавал» разрешения на доступ к смс, телефону и местоположению
                      0
                      Почему нельзя дать разрешения в настройках приложения? Понял, ступил)
                    +2
                    Приложения некоторых крупных сервисов отказываются работать, пока пользователь на старте не даст им доступы к смс, звонкам, контактам и т.д.

                    Когда уже появятся решения с fake permissions? Приложение думает, что разрешщение ему дали, а по факту — скармливают мусор.
                      +1
                      Написал комментом выше. По факту оно и не нужно, если бы GDPR и его аналоги распостранялись на всех.
                      Появится fake permissions повсеместно- сервисы начнут с этим бороться анализом фейковых данных.
                      С другой стороны, так можно и такси в другую страну вызвать случайно, и записать на диктофон шум вместо голоса)
                        +1
                        Написал комментом выше. По факту оно и не нужно, если бы GDPR и его аналоги распостранялись на всех.

                        Слежка и так не законна. Но всем плевать.

                        Появится fake permissions повсеместно- сервисы начнут с этим бороться анализом фейковых данных.

                        Ну и будет более толковые обманки. Врядли у тех, кто делает скам приложения достаточно ресурсов чтобы победить в этой войне. Это все таки не гугл против адблока.

                        С другой стороны, так можно и такси в другую страну вызвать случайно, и записать на диктофон шум вместо голоса)

                        А это уже детали использования. Если диктофону дал фейк пермишен вместо настоящего на запись звука — сам себе злобный буратино. А вот зачем сервис погоды хочет доступ к звонкам и не работает без него — вопрос открытый.
                          +1
                          Сервис погоды хочет доступ к телефонии — индентификация пользователя.
                          В Андроиде те ещё велосипеды.
                            +2
                            Ну и идет он нафиг с такими хотелками.
                              +2
                              Тем не менее, вопрос «почему сервис погоды не может работать без идентификации пользователя» остается открытым
                              +2
                              Слежка и так не законна. Но всем плевать.
                              Потому большинство этим и не занимается. Зато большинство собирает данные о аккаунтах и прочих идентификаторах пользователя и устройства, установленных приложениях и так далее. Что с такой bigdata можно делать- уже давно известно.

                              Но тем не менее, под определение негласного наблюдения (слежки) это не попадает. И потому такое делают незаконным только акты вроде GDPR.

                              Врядли у тех, кто делает скам приложения достаточно ресурсов чтобы победить в этой войне. Это все таки не гугл против адблока.
                              Это битва именно такого класса. Речь идет о вендорах, финансовых организациях и компаниях вроде Facebook- у них ресурсов более чем достаточно. А даже если и не победят, и Android защитит инфу своих пользователей- начнут вкладывать деньги в вендоров или ОС, которые более «сговорчивы», тем самым выводя такие продукты в топы рынка.

                              В итоге получается, что полная приватность не выгодна никому. Компании не заработают на данных, а пользователи не получат годных продуктов (я никого не защищаю, мне самому от этого печально).
                              0
                              По факту оно и не нужно, если бы GDPR и его аналоги распостранялись на всех.

                              Увы, GDPR не запрещает сбор данных, он просто выставляет к нему определенные требования, в частности, явное согласие пользователя на их сбор, его право на opt-out и удаление уже собранных данных. Но после первого согласия до opt-out данные уже могут быть собраны, а удаление проверить невозможно — есть где разгуляться для нечестных разработчиков, особенно если они из Китая или Индии, а пользователи где-то в других странах.

                              Единственным действенным методом воздействия может быть только жёсткая политика платформы — если бы приложения, которые безусловно запрашивают неадекватные разрешения (т.е. те которые не необходимы для выполнения основной функции приложения) явно помечались красным флажком с пометкой «потенциально небезопасно» и понижались в рейтинге поиска, тогда бы лёд тронулся (мало кто захотел бы такой флажок).

                              По хорошему, «правильный» магазин приложений должен требовать от разработчика обосновать наличие того или иного разрешения, и отказывать в публикации если обоснование слабое (к примеру, доступ к контактам в приложении для фотографий, или доступ к GPS в календаре — и то и другое могут выполнять свои функции без контактов и GPS).

                              Но маловероятно что такой магазин появится, или выживет (если таки появится) — разве что подобные требования введут на уровне закона, что, в свою очередь, приведет к другим проблемам.
                                0
                                Увы, GDPR не запрещает сбор данных, он просто выставляет к нему определенные требования, в частности, явное согласие пользователя на их сбор, его право на opt-out и удаление уже собранных данных
                                Верно, не запрещает. Как WhasApp пользоваться без указания номера телефона?..

                                Поправьте, если ошибаюсь- в одной из тем по GDPR говорилось о запрете необоснованного ограничения функционала сервиса в случае отказа предоставить данные. То есть нельзя не пустить пользователя в приложение, если тот не хочет давать доступ к контактам или, например, телефонии. Это как раз то, чего сейчас не хватает многим сервисам.

                                действенным методом воздействия может быть только жёсткая политика платформы
                                Есть такая политика у Apple на бумаге. Например, приложение должно объяснять пользователю, зачем ему те или иные права, и что делать в случае отказа их предоставления. Но по факту это работает странным образом- применяется избирательно. Плюс, несмотря а всю жесткость, в AppStore тоже есть мошенники (русская версия).

                                В итоге Модерация с жесткой политикой тоже не особо помогают- человеческий фактор + коммерция. Если что и может помочь с вопросом- так это холодный, бездушный, не делающий исключений и хорошо протестированный софт платфомы. Только никому такой делать не выгодно- об этом писал выше.
                          +1
                          Народ начинал массово отключать рекламу и модули проверки легальности установки программ.
                          Было уже, и не раз.
                        +1
                        На моем 9 андроиде не работает, так как формат изменился, там надо ориентироваться на 'Client PID:'
                        Ну и немножко:
                        * синтаксис
                        ps `<длинная-длинная команда>`
                        читается хуже, чем
                        <длинная-длинная команда> | xargs ps

                        * грепать по захардкоженному типу процесса не очень хорошо, можно просто передать -o NAME для ps

                        Рабочий вариант для моего Honor 10:
                        while true; do while ! (dumpsys media.camera | grep 'Client PID:') do done | grep -o '[0-9]*$' | xargs ps -o NAME; date; sleep 1; done


                        Результат
                        NAME
                        com.huawei.camera
                        Fri Jan 4 11:45:15 MSK 2019
                        NAME
                        com.huawei.camera
                        Fri Jan 4 11:45:17 MSK 2019
                        NAME
                        com.huawei.camera
                        Fri Jan 4 11:45:18 MSK 2019
                        NAME
                        com.huawei.camera
                        Fri Jan 4 11:45:19 MSK 2019
                          +1
                          На Android 8.1 (Honor 8X JSN-L21) тоже только Ваш вариант заработал.
                            0
                            Не зря Google озаботился стандартизацией вывода dumpsys (https://www.xda-developers.com/android-oreo-dumpsys-commands/), но не для всех сервисов :-) media.camera не вошел в список.
                              0
                              Добавил в статью описание мониторинга доступа приложений к микрофону.
                            +1
                            как выключается камера, в консоль выпадает ошибка
                            Error dumping service info: (Unknown error -32) media.camera
                            ps: {})
                            Fri Jan 4 14:54:06 +05 2019
                            и сама камера выключается с ошибкой андрод 9
                            +1
                            HTC U11 ведёт логи камеры (и изменения разрешений доступа), без необходимости снимать dumpsys каждую секунду:

                            $ dumpsys media.camera
                            == Service global info: ==

                            Number of camera devices: 2
                            Number of normal camera devices: 2
                            Active Camera Clients:
                            [
                            (Camera ID: 0, Cost: 100, PID: 26107, Score: 0, State: 2User Id: 0, Client Package Name: com.htc.camera2, Conflicting Client Devices: {})
                            ]
                            Allowed user IDs: 0

                            == Camera service events log (most recent at top): ==
                            01-05 13:24:12 : CONNECT device 0 client for package com.htc.camera2 (PID 26107)
                            12-31 12:24:34 : DISCONNECT device 0 client for package com.htc.camera2 (PID 26107)
                            12-31 12:24:11 : CONNECT device 0 client for package com.htc.camera2 (PID 26107)
                            12-31 12:24:04 : DISCONNECT device 0 client for package com.htc.camera2 (PID 25652)
                            12-31 12:24:04 : DIED client(s) with PID 1132, reason: (Binder died unexpectedly)
                            12-31 12:22:52 : CONNECT device 0 client for package com.htc.camera2 (PID 25652)
                            12-31 12:22:50 : DISCONNECT device 0 client for package com.htc.camera2 (PID 2733)
                            12-31 12:22:50 : DIED client(s) with PID 1132, reason: (Binder died unexpectedly)
                            12-31 12:22:36 : CONNECT device 0 client for package com.htc.camera2 (PID 2733)
                            12-31 12:22:32 : DISCONNECT device 0 client for package com.htc.camera2 (PID 2733)
                            ...
                            12-15 14:59:54 : USER_SWITCH previous allowed user IDs: , current allowed user IDs: 0
                            ...
                              0
                              Добавил улучшенный вариант кода, убирающий NAME и пустые строки
                                0
                                Я добавил в статью описание мониторинга доступа приложений к микрофону.

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое