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

Итак, последняя версия приложения — 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). Пока лицо не будет найдено, фотографию отправить не получится.

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

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

Присоединяйся к сообществу «Xakep.ru»!

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

Подписаться
Уведомить о
24 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии