Хакер - Потрошим «Социальный мониторинг». Что внутри у приложения для изоляции на дому
hacker_frei![](/file/dd0de004e560f2d50558c.png)
Mazay
Содержание статьи
- Смотрим трафик
- Декомпилируем приложение
- Выводы
Приложение «Социальный мониторинг», которое позволяет следить за тем, чтобы заразившиеся коронавирусом оставались дома, уже успело собрать массу негативных отзывов. Оно, мол, и глюкавое, и вообще «цифровой ошейник». Однако именно технической информации о нем (и, в частности, о его последней версии) немного. Чтобы восполнить этот пробел, я предпринял собственное исследование.
Итак, последняя версия приложения — 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 года, и почему-то указан город Самара. Интересно, при чем тут Самара?
![](https://st768.s3.eu-central-1.amazonaws.com/e3052a9022907abe00b451007654f121/12779/ris01.png#26183894)
Первым делом смотрим, что в манифесте.
![](https://st768.s3.eu-central-1.amazonaws.com/e3052a9022907abe00b451007654f121/12778/ris02.png#26183894)
Версия программы — 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.
Первый компонент особого интереса не представляет, он используется для проверки ввода телефонного номера при регистрации приложения. Последний компонент проверяет «рутованность» используемого устройства: ищет определенные приложения, бинарный файл 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). Пока лицо не будет найдено, фотографию отправить не получится.
В интернете попадалась информация, что у пользователя есть один час с прихода уведомления, чтобы сделать фото. В коде я никаких подтверждений этому не нашел. Если отсчет времени ведется, то это, надо думать, происходит на сервере.
Посмотрим подробнее, какие именно данные приложение отправляет на сервер.
![](https://st768.s3.eu-central-1.amazonaws.com/e3052a9022907abe00b451007654f121/12777/ris03.png#26183894)
Класс Location, как оказалось, содержит не только координаты (а именно долготу, широту, высоту, скорость, точность, азимут), но и кучу интересной информации: версию ОС, уровень заряда батареи, заряжается ли устройство в настоящий момент, дата и время, номер телефона, модель телефона, дату и время установки программы, название провайдера, находится ли телефон в руках в момент сбора данных, количество пройденных шагов.
INFO
Геолокация в телефоне сама по себе — это крайне ненадежный способ отслеживания. Если переключить телефон в режим разработчика, то в появившихся настройках будет пункт «Выбрать приложение для фиктивных местоположений». Есть масса бесплатных приложений, которые при запросе будут выдавать ложные координаты, и ОС передаст их приложениям вместо реальных.
Помимо этого, приложение собирает информацию об окружающих телефон сетях Wi-Fi и подключенных по Bluetooth устройствах.
public final class IndoorNavigation { public final Set bluetoothDevices; public final Set wifiDevices; public IndoorNavigation(Set arg2, Set arg3) { if(arg2 != null) { if(arg3 != null) { super(); this.bluetoothDevices = arg2; this.wifiDevices = arg3; return; } j.a("wifiDevices"); throw null; } j.a("bluetoothDevices"); throw null; }
Также программа ведет лог, в который пишет собранную информацию и ошибки, но посмотреть содержимое лога без рута не получается. Надеюсь, когда надобность в программе у меня отпадет, я рутану телефон и смогу изучить лог.
За неделю использования приложение отправило 8,54 Мбайт трафика, из них в активном режиме 6,34 Мбайт, в фоновом 2,2 Мбайт.
Выводы
Честно говоря, по итогам исследования я несколько разочарован. Была надежда найти какие-нибудь шокирующие факты и грубые попирания приватности, но вынужден признать, что в целом функции соответствуют заявленным. Конечно, отправляется не только геолокация и фото, но и много других данных сверх описанных (шагомер, Bluetooth, Wi-Fi и прочее), но это явно сбор косвенных улик, а не что-то постороннее. Впрочем, было бы неплохо уведомлять пользователя о собираемых данных и не умалчивать эти подробности.
На этом все. Будьте здоровы!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei