Мониторим мониторинг. Что внутри у приложения для изоляции на дому

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

Итак, последняя версия приложения — 1.4.1. Разработчик приложения — Департамент информационных технологий города Москвы. Существуют версии для Android и iOS. По данным из Google Play, на текущий момент приложение установлено более чем у 50 тысяч пользователей. Обещано, что если ваш телефон не поддерживает его, то в теории вам должен быть предоставлен аппарат с уже установленным приложением. На практике, конечно, такое случается далеко не всегда и не сразу.

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

Конечно, ставить что-либо на свой телефон по чьему-то требованию мне не хотелось, но раз уж я был к этому принужден весьма незамысловатым способом, то надо хотя бы проверить, действительно ли приложение выполняет только заявленные функции, или там есть что-то еще.

Итак, поехали. Сразу скажу — я не гуру реверса, так что мог чего-то не заметить. Если обнаружишь что-то новое, обязательно поделись находкой в комментариях.

Смотрим трафик

Первым делом я решил проверить трафик с помощью приложения Fiddler, однако тут меня ждало разочарование. «Социальный мониторинг» устанавливает шифрованное соединение (HTTPS) с сервером mos.ru, а что там происходит дальше — так просто не понять, нужно или рутовать телефон, или пересобирать приложение. Но на рутованном аппарате приложение не работает, а пересобирать его я не рискнул, слишком высока цена ошибки — 4000 рублей за каждый пропущенный запрос на фотографию. А вдруг этот запрос придет как раз в тот момент, когда я буду с трафиком разбираться...

С помощью Fiddler и logcat удалось выяснить только то, что приложение раз в пять минут что-то отправляет на mos.ru. Что ж, придется декомпилировать и ковыряться в коде.

Декомпилируем приложение

Для декомпиляции я использовал программу JEB версии 3.17.1 производства PNF Software. На мой взгляд, это одно из лучших приложений для исследования APK, единственный его недостаток — высокая стоимость.

Приложение подписано сертификатом, сгенерированным 17 апреля 2020 года, и почему-то указан город Самара. Интересно, при чем тут Самара?

Первым делом смотрим, что в манифесте.

Версия программы — 1.4.1, имя пакета — ru.mos.socmon.

Приложение запрашивает следующие разрешения: доступ к координатам, в том числе и фоновый, доступ к камере, к интернету, состоянию сети, состоянию и изменению Wi-Fi, возможность запускать неубиваемые сервисы и добавление в список исключений оптимизации батареи (чтобы ОС не заставляла приложение экономить энергию), а также чтение и запись данных на карте памяти. Ну что же, уже неплохо — намеков на недекларированные функции пока не видно. Контакты, журнал звонков, SMS и прочее вроде не просят. Будем смотреть дальше.

Дальше видим, что приложение весьма обфусцировано. Конечно, это осложняет анализ, но попробуем.

Обычно при анализе всякой обфусцированной вирусни я поступаю так: сначала переименовываю все объявленные переменные в соответствии с их типом, то есть вместо a, b, c, d пишу intIn, intOut, int1, str1 и так далее. Затем заново смотрю на код, уже становится видно, что некоторые переменные можно переименовать в counter, i, k, resString. Ну и третьим проходом после беглого анализа алгоритма переименовываю во всякие там name, password, hashMD5 и так далее.

То же самое и с классами. Сначала переименовываю созвучно тому, от чего класс наследуется, например activity1 или serviceHZ, а дальше уже, изучив содержимое, даю осмысленное имя. Да, это кропотливый труд, но я не знаю, как по-другому эффективно бороться с обфускацией. В данном случае объем кода не позволяет выполнить такие переименования за разумное время, да и нет в этом особой необходимости.

Прежде чем погружаться в дебри кода, окинем взглядом используемые приложением нативные библиотеки, а именно:

  • libconscrypt_jni.so — гугловская библиотека Conscrypt, поставщик безопасности Java (JSP), который реализует расширения криптографии Java (JCE) и расширения безопасных сокетов Java (JSSE). Он использует BoringSSL для предоставления криптографических примитивов и безопасности транспортного уровня (TLS) для приложений Java на Android и OpenJDK;
  • libface_detector_v2_jni.so — опенсорсная библиотека libfacedetection для распознавания лиц на фото;
  • libtool_checker_jni.so — библиотека из состава опенсорсного пакета rootbeer, предназначенного для проверки наличия прав root на устройстве. Чуть подробнее расскажу о ней дальше.

Беглый анализ показал, что, помимо обфусцированного кода и почти стандартных OkHttp 3, Retrofit 2 и Crashlytics, приложение использует компоненты com.redmadrobot.inputmask.helper и com.scottyab.rootbeer.

Первый компонент особого интереса не представляет, он используется для проверки ввода телефонного номера при регистрации приложения. Rootbeer же как раз проверяет «рутованность» используемого устройства: ищет определенные приложения, бинарный файл su или компоненты BusyBox.

Все, дальше вроде тянуть уже некуда, надо смотреть код. Я не буду утомлять читателя скрупулезным и занудным описанием алгоритма, тем более что из-за обфускации кода пришлось бы часто использовать слова «вероятно», «похоже» и «судя по всему», и просто расскажу своими словами.

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

if(!((activity)this).j()) {
            StringBuilder v1 = k.b.a.a.a.a("package:");
            v1.append(this.getPackageName());
            this.startActivityForResult(new Intent("android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS", Uri.parse(v1.toString())), 3);
            return;
        }

Также проверяется (с помощью акселерометра), держит ли пользователь устройство в руках.

В приложении есть три основных сервиса:

  • LocationService — периодически собирает координаты;
  • MessagingService — отслеживает сообщения с сервера, в сообщениях могут быть новые настройки или запрос на фото пользователя;
  • PeriodicJobService — собирает и отправляет телеметрию.

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

В интернете попадалась информация, что у пользователя есть один час с прихода уведомления, чтобы сделать фото. В коде я никаких подтверждений этому не нашел. Если отсчет времени ведется, то это, надо думать, происходит на сервере.

Посмотрим подробнее, какие именно данные приложение отправляет на сервер.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Комментарии (20)

  • Жаль, что статья неполная. Я, конечно, понимаю, что монетизация это святое. Но ведь общественно важная тема же. Эх...

    > Ну что же, уже неплохо — намеков на недекларированные функции пока не видно. Контакты, журнал звонков, SMS и прочее вроде не просят.
    Есть ещё READ/WRITE_EXTERNAL_STORAGE. Хотя, увы, нынче принято считать доступ к внешнему хранилищу само собой разумеющимся. Тем не менее, пользователи могут хранить там свои данные (это вполне рационально, учитывая, что купить карту памяти может быть дешевле, чем более дорогой смартфон).

    • Они должны предоставлять бесплатный смартфон, если пользователь не может/не хочет устанавливать на свой. Но в реальности бесплатного я от них не дождался, хотя некоторые знакомые говорили, что им предоставляли смартфон. Я для себя нашел старый, сделал хард-ресет ему и установил, так спокойнее.

    • Поддерживаю. Был бы рад, если б открыли. Или хотя бы цену снизили за материал. 50 рублёв, мне кажется, адекватная цена. Причём объём "продаж" покрыл бы выпадающие доходы...

      • Не берусь обсуждать цены, но лично мне показалось выгодным купить подписку годовую. Был период, когда 50% необходимых по работе ссылок вели на хакер, я решил, что проще один раз заплатить и потом не париться целый год. Но это ни в коем случае не реклама. Если по статье вопросы - задавайте, что знаю - расскажу. Как карантин отменят - попробую телефон рутануть и посмотреть, чего там еще в логах у приложения накопилось.

    • Прежде чем писать о фашизме вы бы для начала изучили его определение.

  • А почему не с помощью ssl пининга не проверить, что за данные он передаёт?

    • Я в сетевых технологиях не очень силен, поэтому решил не рисковать. Неохота штраф платить, если что-то заглючит в самый неподходящий момент.

  • Странно, что социалочки не просят подключить или добавить в друзья какой нибудь дит Москвы

  • Тема не раскрыта. Очень похоже на заказную статью.

    • Соглашусь, ожидал большего. С другой стороны, для обывателя этого точно достаточно. Даже чисто вывода, что "ничего очевидно опасного в коде не найдено", было бы достаточно. Тут сидят технически подкованные люди, инструменты описаны, если что-то не устраивает - можно поковырять самостоятельно.
      Единственное, автору минус, потому что в 2020 году жить без рута и чему-то учить про Android - звучит несерьезно.

      • А я где-то чему-то учил? Повторюсь, я всего лишь рассказал о своем личном, приватном исследовании. Задачи чему то научить не ставилось. Более того, серьезно или несерьезно - это личное дело каждого. Поясните, для чего нужно "жить с рутом"? Раскрою страшную тайну - на моем личном телефоне, которым я ежедневно пользуюсь, стоит чистый андроид с минимумом программ, отключена отладка по USB и нет рута. Мне так спокойнее, с точки зрения безопасности. Рут нужен на рабочих аппаратах, "подопытных кроликах".
        И еще, не забывайте, программа не будет работать просто так, ее нельзя поставить на телефон, зарегистрироваться и начать пользоваться. Она заработает только у тех, кто есть в списках больных короной или контактировал. И моя первоочередная задача была не обмануть ее, а избежать штрафов, поэтому я бегло проанализировал код, а затем взял совершенно левый телефон, сделал ему хард-ресет и поставил на него прогу, и все. Убедился, что все работает, штрафы на госуслугах не приходят, а потом уже начал спокойно ковыряться. Да, естественно, я нашел рутованный телефон с Magisk, поколдовал немножко и таки у меня получилось скрыть рут от СоцМона, он запустился, а дальше затык - запрос на регистрацию с левой симки висит уже несколько суток, и я полагаю, что регистрация не пройдет, ведь левого номера нету в собянинских списках.
        Единственное, что я еще попробую сделать - после того, как надобность в этой программе отпадет, я рутану тот телефон, на котором она установлена, и посмотрю, что в логах. Ну чтобы окончательно поставить точку.

    • Почему же не раскрыта? Я рассказал о том, что сделал, а делал я то, что мне было интересно. А интересно мне было - что приложение шлет на сервер, какие данные собирает. Тупо увеличивать объем, рассказывая о том, как например шифруются данные, как шагомер считает шаги и прочее - можно, но зачем? Если будет много комментариев с какими то пожеланиями - можно попробовать еще статейку забабахать, но на момент проведения исследования такой задачи я перед собой не ставил.
      А насчет заказухи - чем вызваны подобные подозрения? Я старался максимально убрать эмоции из своего рассказа, описывать только техническую сторону. Если я упустил что-то важное, или где-то ошибся, то ткните меня носом в это, обсудим. А так обвинения беспочвенны.

  • Шагомер, интересно, а можно понять откуда он тянет шагаюи. Вот есть у меня самсунг, у него есть родной samsung health, что считает шаги. И есть на мне браслет от хонора, к которому хоноровское же приложение на телефоне. И данными приложения не обмениваются, показания различаются в 2-3 раза.
    Этот от кого тянуть будет..?

  • Добрый день! Благодарю Вас за анализ! Меня заинтересовало: есть ли сама фотография в результате проверки, отправляемом на сервер?

    Могли бы Вы выложить архив с результатами декомпиляции? Либо, если нельзя публично, то хотя бы прислать на почту vladislav собачка vm-0.com

  • Друзья. Подскажите. Если установить социальный мониторинг, на левый телефон и поставить переадресацию с засвеченного номера на новую сим. Можно будет находиться вне "зоны изоляции" не замеченным. При приёме звонка?

    • Я пробовал этот вариант, штрафов не было. Главное, чтобы если позвонят из Роспотребнадзора спросить температуру, в фоне не было посторонних звуков :-)))

    • Помогите пожалуйста, я не поняла, чайник. На свой номер кот у Роспотребнадзора я устанавливаю приложение мониторинга и делаю переадресацию например на телефон дочки. Так?

Похожие материалы