Обратная инженерия сетевого трафика


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

Кроме знакомства с базовыми примерами анализа сетевого трафика (с помощью программы Wireshark) мы научимся делать отправку «сырых» данных в UDP и TCP. То есть не используя протоколы HTTP, HTTPS или какие-то другие прикладные протоколы, а задействуя только протоколы транспортного уровня. А также рассмотрим довольно простую, но при этом вполне эффективную «обфускацию» трафика для защиты от анализа в Wireshark.

В качестве объектов изучения меня заинтересовала программа CMS и IP камера. Программа CMS (насколько я понимаю) популярна у владельцев IP камер. Причём, опять же насколько я понял, для управления IP камерами с телефонов используется не так много клиентов, например, Yoosee, CamHi, CiSee, XMeye.

А для компьютера используется эта самая программа CMS, которая поддерживает множество камер самых разных производителей. Например, у меня на опытах камера R80X20-PQ, которая, судя по MAC-адресу, произведена HangZhou KuoHeng Technology. Это довольно занимательно, учитывая зоопарк производителей IP камер — получается, все эти камеры объединяет какой-то один протокол.

Программа CMS является официальным клиентом камер Polyvision. В самой программе при добавлении камеры можно выбрать из четырёх вариантов:

  • Polyvision
  • Hikvision
  • Dahua
  • Onvif

Сначала я добавил камеру как «Onvif», а затем и как Polyvision. С протоколом ONVIF мы уже знакомы из статьи «Аудит безопасности IP камер»: этот протокол позволяет управлять IP камерой, получать адрес медиа потока, иногда управление этим протоколом возможно без ввода пароля. Но протокол ONVIF плох тем, что не позволяет получить доступ к хранилищу видео файлов.

Подключившись как Polyvision можно управлять камерой и плюс появляется доступ к хранилищу видео на карте памяти IP камеры.

Вот этот «протокол» Polyvision меня и заинтересовал — получается, что камеры разных производителей используют его. При обмене данных этот протокол использует порт 34567, который напомнил мне статью «IP Camera Security Horror» («Ужас безопасности IP-камер»).

Как CMS ищет камеры

Рассмотренная в предыдущей статье программа ONVIF Device Manager и CMS быстро обнаруживают IP камеры при этом даже не спрашивая настройки сети. Поверхностный анализ показал, что они не сканируют IP и порты в локальной подсети, тогда как они это делают?

Запустим Wireshark и запустим в CMS поиск новых устройств. Когда поиск завершится, остановим захват трафика Wireshark.

Запросов оказалось мало и почти все они были однокипными. Первый тип запросов выполнялся несколько раз подряд на UDP порт 34569 IP адреса 255.255.255.255 передавалась шестнадцатеричная строка «ff00000000000000000000000000fa0500000000». Хотя, пожалуй, правильнее её записать так: «\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x05\x00\x00\x00\x00».

Адрес 255.255.255.255 является ограниченным широковещательным адресом. Такой пакет доставляется всем хостам в данной локальной сети, но за пределы локальной сети не маршрутизируется.

Второй тип запросов выполнялся только один раз на UDP порт 3702 IP адреса 239.255.255.250.

Адрес 239.255.255.250 - это multicast адрес, то есть используется для многоадресного вещания.

Передаются следующие данные:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:dn="http://www.onvif.org/ver10/network/wsdl" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"><SOAP-ENV:Header><wsa:MessageID>urn:uuid:00000029-5566-7788-99aa-2a3f00125c87</wsa:MessageID><wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></SOAP-ENV:Header><SOAP-ENV:Body><d:Probe><d:Types>dn:NetworkVideoTransmitter</d:Types><d:Scopes></d:Scopes></d:Probe></SOAP-ENV:Body></SOAP-ENV:Envelope>

Как можно догадаться, это знакомый нам протокол ONVIF. Не будем в этой статье останавливаться на этом протоколе, просто запомним, что для поиска ONVIF необязательно делать сканирование подсети — можно использовать широковещательный адрес и протокол SSDP.

Посмотрим на ответы, которые прислала камера. Для Polyvision это:


Для ONVIF:

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

Как отправить и получать сырые TCP и UDP данные с помощью Ncat / Netcat / nc

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

Как мы уже выяснили, чтобы камеры откликнулись, нам нужно на UDP порт 34569 IP адреса 255.255.255.255 передать следующие шестнадцатеричные данные: «ff00000000000000000000000000fa0500000000». Причём нам это нужно сделать без использования протоколов прикладного уровня (без HTTP, FTP, SMTP, RDP, SNMP, DHCP, RTSP, DNS и прочих).

Передавать сырые данные TCP и UDP умеют программы Ncat, Netcat, nc.

Связанная статья: Как пользоваться netcat (nc), ncat

Чтобы не просто выполнить подключение, когда данные вводятся вручную (вводить шестнадцатеричные данные вручную затруднительно для нас), а чтобы подключиться и сразу передать данные, можно использовать команду вида:

cat ФАЙЛ | ncat -u -C IP-АДРЕС ПОРТ

Опция -u означает использовать UDP протокол (по умолчанию используется TCP).

Начнём с того, что сохраним нужные нам данные в файл hello-camera.bin. Для этого мы воспользуемся шестнадцатеричным редактором Bless:

bless

Связанная статья: Руководство по Bless (шестнадцатеричный редактор)

В открывшейся программе в шестнадцатеричную область введите:

ff00000000000000000000000000fa0500000000

Затем сохраните файл с именем hello-camera.bin.

Теперь мы можем отправить данные на широковещательный адрес командой:


cat hello-camera.bin | ncat -u -C 255.255.255.255 34569

И… не сработало? На самом деле невозможно ответить, сработало или нет - мы отправили данные, но UDP протокол не дожидается ответа, он завершает соединение. Для отправки ответа удалённых хост запускает новое UDP соединение, но дело в том, что для его подключения мы должны прослушивать порт. Ответ придёт на UDP порт 34569. Прослушивать порт можно также командой ncat. Для этого используется команда вида:

ncat -u -l IP-АДРЕС ПОРТ

В этой команде опция -u означает использовать UDP протокол (по умолчанию используется TCP). Опция -l означает прослушивать входящие соединения. IP-АДРЕС - это IP сетевого интерфейса на локальной машине, где запущена утилита ncat. ПОРТ - это порт для прослушивания.

IP адрес компьютера, где будет запущена ncat, 192.168.0.88, нужно прослушивать на 34569 порту, тогда команда следующая:


ncat -u -l 192.168.0.88 34569

Кажется, что ничего не происходит, но программа и не завершает работу - она просто ожидает входящее соединение.

Не закрывая это окно терминала, откроем другую консоль и вновь отправим запрос на широковещательный адрес:

cat hello-camera.bin | ncat -u -C 255.255.255.255 34569

После этого в первой консоли будет показан полученный ответ:

Чтобы сохранить присланный ответ (вместо того, чтобы выводить его на экран), можно использовать следующую команду для прослушивания входящих подключений:

ncat -u -l 192.168.0.88 34569 > response.bin

В результате присланный ответ будет сохранён в файле response.bin, откроем его в редакторе Bless:

Большая часть данных - это обычный текст, но из-за того, что перед ними идут бинарные данные, Wireshark не смогла распарсить информацию.

Посмотрим на них:

{ "NetWork.NetCommon" : { "BuildDate" : "2020-07-13 18:49:41", "ChannelNum" : 1, "DeviceType" : 24, "GateWay" : "0x0100A8C0", "HostIP" : "0xA700A8C0", "HostName" : "robot_7338", "HttpPort" : 80, "MAC" : "30:ff:f6:81:73:38", "MonMode" : "TCP", "NetConnectState" : 0, "OtherFunction" : "D=2021-02-13 13:09:57 V=a28c32f737ea760", "SN" : "5091138861ce4338", "SSLPort" : 8443, "Submask" : "0x00FFFFFF", "TCPMaxConn" : 10, "TCPPort" : 34567, "UDPPort" : 34568, "UseHSDownLoad" : false, "Version" : "V5.00.R02.00030695.10010.343106.0000000" }, "Ret" : 100, "SessionID" : "0x00000000" }

Обратим внимание на строки:


"HostIP" : "0xA700A8C0"
"TCPPort" : 34567

В них содержится IP адрес, порт и транспортный протокол. Если вас смущает форма записи IP адреса, то смотрите:

То есть программа CMS отправляет данные на широковещательный адрес, а все камеры откликаются, присылая информацию о себе. Эта информация используется для дальнейшего подключения к камере.

Выполним в программе CMS вход в камеру, перед этим вновь запустив Wireshark. Проанализируем захваченный трафик.

Поскольку захват происходил дольше чем в первый раз, то среди захваченного трафика присутствует не имеющий отношение к камере. Отфильтруем его, используя фильтр Wireshark:

ip.addr == 192.168.0.167

Связанная статья: Фильтры Wireshark

Обратим внимание, что Wireshark вновь не узнала ни какой протокол и показывает переданные данные как сырой TCP трафик.

Кликнем правой кнопкой мыши по первому пакету в контекстном меню выберем «Следовать» -> «Поток TCP».

Открывается полный диалог:

Данные в обычном текстовом виде, но перед ними бинарный мусор, поэтому Wireshark вновь не смогла распарсить их.

Мы можем видеть хеш пароля. Благодаря строке DVRIP-Web я нашёл статью «Вытаскиваем видео с камеры по DVRIP с помощью PHP». В этой статье сказано, что «протокол, предположительно придуманный китайцами, который используется для общения ПО c камерами наблюдения», он называется или DVRIP, или Sofia, или NetSurveillance. В той же статье вы можете найти алгоритм, по которому вычисляется хеш пароля. Если я правильно помню, то пароль может содержать не более 8 (или ровно 8) символов.

Теперь в поле «Показать данные как» я выбираю вариант «Необработанный».

Логин и пароль отправляются шестнадцатеричной строкой:

ff00000000000000000000000000e803640000007b2022456e63727970745479706522203a20224d4435222c20224c6f67696e5479706522203a202244565249502d576562222c202250617373576f726422203a20224a556b684d466750222c2022557365724e616d6522203a202261646d696e22207d0a

В Bless создаю файл hex и записываю в него эту строку.

Теперь данные отправляются протоколом TCP. Чтобы просто отправить сырые данные протоколом TCP в ncat, достаточно убрать опцию -u. Но в этом случае вы не получите ответа. Для того чтобы отправить данные и получить ответ нужно использовать конструкцию:

{ cat ФАЙЛ; cat; } | ncat -C IP-АДРЕС ПОРТ

В этой команде:

  • ФАЙЛ - это файл, содержащий данные для отправки
  • IP-АДРЕС - IP удалённого хоста, куда мы хотим отправить данные
  • ПОРТ - порт удалённого хоста, на который мы хотим отправить данные

Пример команды:

{ cat hex; cat; } | ncat -C 192.168.0.167 34567

Как можно увидеть, мы получили ответ.

Я записал все бинарные строки, которые отправляла программа CMS на камеру, в отдельные файлы с именами hex1, hex2 и так далее до hex12. Для воспроизведения полного диалога с камерой можно использовать команду вида:

{ cat hex{1..12}; cat; } | ncat -C 192.168.0.167 34567

Как можно увидеть на скриншоте - воспроизведён полный «диалог» общения CMS с камерой, который мы видили до этого в Wireshark. Точнее говоря, показаны только ответы, но они такие же.

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

Заключение

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

tcp contains Admin

На самом деле, узнав название используемого протокола, удалось найти готовые реализации и даже документацию. Готовая реализация написана на Python 3, называется python-dvr.

Документация там же: https://github.com/NeiroNx/python-dvr/tree/master/doc

Утилита (или библиотека) python-dvr позволяет записывать видео с камер, делать снимки, создавать пользователей, изменять пароли и делать многие другие вещи. В плане аудита безопасности IP камер наблюдения, с помощью python-dvr можно брут-форсить учётные данные камер. Этому будет посвящена следующая статья «Как брут-форсить протокол DVR-IP, NetSurveillance, Sofia».

Статья, посвящённая python-dvr: «Как управлять камерами по протоколу DVR-IP, NetSurveillance, Sofia (NETsurveillance ActiveX плагин XMeye SDK)». В этой статье кратко говорится об использовании DeviceManager.py. Это мощная программа по обнаружению IP камер наблюдения в локальной сети. Если посмотреть исходный код, то можно увидеть все используемые техники, среди них есть и та, которую мы «раскрыли» в данной статье.

Другие статьи, посвящённые камерам наблюдения, вы найдёте по соответствующему тегу «камеры наблюдения».


Рекомендуется Вам:

2 комментария to Обратная инженерия сетевого трафика

  1. Виктор:

    Большое спасибо за интересное исследование! Качество подачи информации, как всегда, на высоте.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *