Статья [POC] Tiandy DVR

Admin

Администратор
Недавно встретился с этими ужасными камерами, которые в ценовом диапазоне даже выше Hikvision, которые массово ломают, но при этом Tiandy до сих пор позволяет посмотреть пароль от камеры особо не заморачиваясь, ведь нужен только айпи адрес, веб интерфейс висит на 80 порту, а сами камеры на 3000. Решил перевести PoC из гитхаба. https://github.com/zb3/tiandy-research


Трудно точно сказать, какие версии затронуты, так как мы можем скачать только последние. Все эти загружаемые версии затронуты:

DVRS_V9.12.7.20200422
DVRS_V11.7.4.20200721
NVSS_V13.6.1.20200723
NVSS_V22.1.0.20200722

Восстановление пароля​

Вам понадобится Python 3 с PyCrypto.

Во-первых, попробуйте recover.py. Это требует, чтобы порт 3001был доступен:

python3 recover.py [HOST]
если все пойдет хорошо, учетные данные администратора должны быть напечатаны.

Если этот порт недоступен, веб-порт может работать. Для этого требуется URL:

python3 cgi_recover.py http://123.45.67.89
python3 cgi_recover.py https://123.45.67.89
Если ничего из вышеперечисленного не работает, проверьте, включен ли telnet. Если это так, вы можете получить root права на устройство напрямую, просто взломав этот хэш:

support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(не забудьте открыть PR на случай, если вы действительно взломаете его :D)

Уязвимости​

Жестко заданные учетные данные telnet для старой прошивки​

В старых версиях telnet включен по умолчанию и вот что мы можем найти в /etc/passwdфайле:

support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(пароль root обновляется динамически, также я не взламывал этот хэш, так что пул-реквесты более чем приветствуются :D)

Пользователь support(фактически присутствующий во всех версиях прошивки) может показаться непривилегированным, но, конечно, у этого пользователя достаточно привилегий, чтобы прочитать пароль Adminи перезаписать общедоступные сценарии инициализации /etc/init.dили даже создать новые :)

Учетная запись по умолчанию + повышение привилегий с проверкой подлинности​

Концептуально метод действительно прост. Мы просто отправляем логин-пакет и читаем ответ. Вот и все, потому что ответ «логин успешен» содержит учетные данные всех пользователей, независимо от наших привилегий. Хотя и так было V7, но практически этот метод стал полезен только тогда, когда в прошивке видеорегистратора была введена учетная запись по умолчанию. Неудаляемый «По умолчанию» не имеет удаленных привилегий, поэтому с ним ничего не сделаешь. Ну, может быть, кроме чтения пароля администратора...

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

См. recover_with_defaultфункцию в recover.py файле для реализации.

Небезопасное восстановление пароля - метод PSW​

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

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

Я могу предположить, что поток должен был быть таким:

  1. Вы вводите свой адрес электронной почты или телефон при настройке устройства
  2. Вы просите Тианди восстановить ваш пароль
  3. Tiandy отправляет «волшебный пакет» на ваше устройство и получает адрес электронной почты/телефон и зашифрованные данные для получения кода безопасности.
  4. Tiandy расшифровывает и получает защитный код и отправляет его по этому каналу связи.
  5. Вы вводите этот защитный код в свою клиентскую программу, которая отправляет второй пакет.
  6. Вуаля. Клиент расшифровывает ответ и показывает вам учетные данные.
Это все хорошо, но не хватает одного... где охрана? Нигде, оказывается. Ничто не мешает нам отправить этот пакет, получить защитный код и восстановить пароль любого доступного устройства.

Я нахожу это удивительным, потому что дело не в том, что в механизме есть какая-то ошибка, которая побеждает безопасность. Его просто вообще нет. Здесь нечего исправлять, но мне это тоже не кажется очевидным бэкдором. Это оставляет следы в логах и имеет 3 разные схемы деривации, каждая из которых сложнее предыдущей. На самом деле потребовалось время, чтобы реализовать...

С технической стороны этот механизм на самом деле довольно сложен, и его было труднее всего отменить и реализовать заново. Существует 3 версии этого механизма, каждая из которых использует свой алгоритм получения защитного кода. Помимо DES с перевернутыми битами, используется пользовательский шифр замены с жестко запрограммированным ключом. Но все это напрасно, потому что Tiandy не может сделать симметричное шифрование с жестко закодированным ключом безопасным, как бы они ни старались.

Одна вещь, которую я заметил, заключается в том, что, поскольку код безопасности меняется каждую минуту, существует вероятность того, что исходный процесс может завершиться ошибкой только потому, что код изменился между пакетом на шаге 3 и пакетом на шаге 5, независимо от того, как мало времени прошло между отправкой. те. Я принял это во внимание, поэтому мой скрипт повторяет процесс, если код оказывается недействительным.

Весь процесс, включая настройку электронной почты (владеть которой нам не обязательно) реализован в recover.py файле.

Обход аутентификации веб-API​

Этот работает с более новыми версиями прошивки (2019 и выше), которые имеют «современный» веб-интерфейс (та, что с «картой». Мне нравится эта карта, хотя Австралия кажется немного искаженной).

Этот обход прост. Хотя большинство конечных точек API аутентифицируются, есть некоторые исключения. Однако проверка того, следует ли пропускать аутентификацию, и сопоставление конечной точки для активации реализованы в разных местах. В большинстве случаев аутентификация пропускается, если путь URL-адреса равен заданной строке, что является безопасным.

Но последние версии вводят другое исключение, которое активируется, когда строки Record/DownLoad и ID=просто существуют где-то в пути URL.

Теперь для конечных точек, где совпадает полный путь, это по-прежнему безопасно. Поскольку Security/users это одна из этих конечных точек, мы не можем восстановить пароль напрямую. К счастью для нас, конечная точка экспорта конфигурации выбирается путем проверки того, начинается ли путь URL с заданной строки (используя strncmp), поэтому мы можем просто добавить эти строки к пути и экспортировать файл конфигурации.

Восстановление пароля с помощью этой уязвимости реализовано в cgi_recover.py.