Сим-сим откройся или реверс инжиниринг умного домофона

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

Настройка прокси

Для анализа трафика часто применяется подход называемый человек посередине (man in the middle). Он состоит в том, что при подключении к локальной сети трафик с анализируемого устройства сначала идет на компьютер, на котором он расшифровывается и анализируется, а затем зашифровывается обратно и отправляется на сервер. Для расшифровки трафика наиболее популярной является программа mitmproxy. Установка mitmproxy не составила больших проблем.

Для просмотра трафика с мобильного устройства нужно подключиться к домашнему wifi с телефона и компьютера. На комп установить mitmproxy и запустить. На телефоне в настройках wifi установить локальный адрес и порт компа как прокси сервер. Далее зайти с телефона на mitm.it и установить сертификат дающий возможность расшифровки https запросов. После этих шагов запросы из браузера стали видны. Ура! Однако следующим шагом меня ждало разочарование:

Поиск в гугле привел к открытому issue на гитхабе. Оказалось, что, начиная с API Level 24, приложения больше не доверяют пользовательским сертификатам. К счастью это можно обойти если разархивировать apk и добавить в AndroidManifest.xml следующий конфиг:

<network-security-config>  
     <debug-overrides>  
          <trust-anchors>  
               <!-- Trust preinstalled CAs -->  
               <certificates src="system" />  
               <!-- Additionally trust user added CAs -->  
               <certificates src="user" />  
          </trust-anchors>  
     </debug-overrides>  
</network-security-config>

Более того, на гитхабе есть готовый скрипт который делает это автоматом. Итак, скачиваем apk, патчим скриптом, ставим командой adb install и вуаля все работает.

Анализ трафика

Видим, что запросы выполняются на адреса вида:

https://{intercom-company-url}/api/

В заголовке передаются два параметра:

'api-version': '2',
'authorization':  'Bearer your.jwt.token’

Первый параметр — это версия api, а второй — токен авторизации. Для авторизации используется json web token состоящий из трех частей: заголовок, полезная нагрузка (payload) и подпись.
Декодировав его с помощью команды:

pyjwt decode --no-verify your.jwt.token

увидим, что в payload содержатся account_id и exp. Поле exp соответствует времени создания токена, что позволяет генерить токены для разных девайсов с одного аккаунта.

Наиболее интересными для нас являются запросы на получение списка доступных домофонов и открытие дверей. При отправке запроса (я использовал python и библиотеку requests) к

https://{intercom-company-url}/api/customers/properties/{account_id}/intercoms 

Получаем json содержащий список домофонов c полями:

[
    {
        'id': ID,
        'mode': MODE, 
        'sip_account': {'ex_user': USER_ID, 'proxy': PROXY,  'password': PSWD}, 
        'video': [{'quality': 'low', 'source': 'rtsp://LINK }]
    }
]

В json id — идентификатор домофона, mode — какую дверь можно открыть (возможные значения one_door, left_door, right_door), sip аккаунт и ссылка на видео трансляцию. Ого!

С помощью протокола установления сеанса (session initiation protocol, sip) осуществляются видео звонки через домофон. В поле sip_account нам пришли id’шники и пароли домофонов к которым есть доступ у нашего аккаунта. Позвонить на них всё же не получится так как они находятся во внутренней сети. А вот поле видео — это интересно. В нем содержится внешняя ссылка на трансляцию видео с камеры. Достаточно открыть vlc, скопировать ссылку и можно круглосуточно смотреть в камеру домофона. Не хорошо такими ссылками разбрасываться!

Далее разберёмся как открыть дверь. При нажатии на кнопку открытия дверей приложение посылает get-запрос:

https://{intercom-company-url}/api/customers/intercoms/{intercom_id}/unlock?door=left_door&id={intercom_id}

Оказалось, что наличие или отсутствие параметра id ни на что не влияет, а вот door позволяет в случае домофона с двумя дверьми открывать не только свою, но и соседнюю дверь по выбору.

Сим-сим откройся!

Разобравшись с api, я решил сделать что-то полезное. В результате получилось приложение под Андроид, которое распознает голосовые команды, и при распознавании заранее заданных команд вроде «сим-сим откройся» отправляет запрос на открытие соответствующей двери.

Выводы

Умный домофон — это хорошо, но безопасный и умный домофон ещё лучше.

Специально для сайта ITWORLD.UZ. Новость взята с сайта Хабр