- •От издательства
- •О техническом обозревателе
- •О соавторах
- •Об авторах
- •Вступительное слово
- •Благодарности
- •Предисловие
- •Почему важна защита интернета вещей?
- •Чем защита интернета вещей отличается от традиционной ИТ-защиты?
- •Законы хакинга интернета вещей
- •Заключение
- •Моделирование угроз для интернета вещей
- •Схема моделирования угроз
- •Определение архитектуры
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Использование деревьев атак для обнаружения угроз
- •Распространенные угрозы интернета вещей
- •Атаки с подавлением сигнала
- •Атаки с воспроизведением
- •Атаки со взломом настроек
- •Клонирование узла
- •Заключение
- •Пассивная разведка
- •Физический или аппаратный уровень
- •Периферийные интерфейсы
- •Среда загрузки
- •Блокировки
- •Предотвращение и обнаружение несанкционированного доступа
- •Прошивка
- •Интерфейсы отладки
- •Физическая устойчивость
- •Разведка
- •Атаки на сетевой протокол и службы
- •Тестирование беспроводного протокола
- •Оценка веб-приложений
- •Картирование приложений
- •Элементы управления на стороне клиента
- •Аутентификация
- •Управление сеансом
- •Проверка ввода
- •Логические ошибки
- •Сервер приложений
- •Исследование конфигурации хоста
- •Учетные записи пользователей
- •Привилегии учетной записи
- •Уровни патчей
- •Удаленное обслуживание
- •Управление доступом к файловой системе
- •Шифрование данных
- •Неверная конфигурация сервера
- •Мобильное приложение и облачное тестирование
- •Заключение
- •4. Оценка сети
- •Переход в сеть IoT
- •VLAN и сетевые коммутаторы
- •Спуфинг коммутатора
- •Двойное тегирование
- •Имитация устройств VoIP
- •Идентификация устройств IoT в сети
- •Обнаружение паролей службами снятия отпечатков
- •Атаки MQTT
- •Настройка тестовой среды
- •Написание модуля MQTT Authentication-Cracking в Ncrack
- •Тестирование модуля Ncrack на соответствие MQTT
- •Заключение
- •5. Анализ сетевых протоколов
- •Проверка сетевых протоколов
- •Сбор информации
- •Анализ
- •Создание прототипов и разработка инструментов
- •Работа с Lua
- •Общие сведения о протоколе DICOM
- •Генерация трафика DICOM
- •Включение Lua в Wireshark
- •Определение диссектора
- •Определение основной функции диссектора
- •Завершение диссектора
- •Создание диссектора C-ECHO
- •Начальная загрузка данных функции диссектора
- •Анализ полей переменной длины
- •Тестирование диссектора
- •Разработка сканера служб DICOM для механизма сценариев Nmap
- •Написание библиотеки сценариев Nmap для DICOM
- •Коды и константы DICOM
- •Написание функций создания и уничтожения сокетов
- •Создание заголовков пакетов DICOM
- •Написание запросов контекстов сообщений A-ASSOCIATE
- •Чтение аргументов скрипта в движке сценариев Nmap
- •Определение структуры запроса A-ASSOCIATE
- •Анализ ответов A-ASSOCIATE
- •Создание окончательного сценария
- •Заключение
- •6. Использование сети с нулевой конфигурацией
- •Использование UPnP
- •Стек UPnP
- •Распространенные уязвимости UPnP
- •Злоупотребление UPnP через интерфейсы WAN
- •Другие атаки UPnP
- •Использование mDNS и DNS-SD
- •Как работает mDNS
- •Как работает DNS-SD
- •Проведение разведки с помощью mDNS и DNS-SD
- •Злоупотребление на этапе проверки mDNS
- •Атаки «человек посередине» на mDNS и DNS-SD
- •Использование WS-Discovery
- •Как работает WS-Discovery
- •Подделка камер в вашей сети
- •Создание атак WS-Discovery
- •Заключение
- •UART
- •Аппаратные средства для связи с UART
- •Как найти порты UART
- •Определение скорости передачи UART
- •JTAG и SWD
- •JTAG
- •Как работает SWD
- •Аппаратные средства для взаимодействия с JTAG и SWD
- •Идентификация контактов JTAG
- •Взлом устройства с помощью UART и SWD
- •Целевое устройство STM32F103C8T6 (Black Pill)
- •Настройка среды отладки
- •Кодирование целевой программы на Arduino
- •Отладка целевого устройства
- •Заключение
- •Как работает SPI
- •Как работает I2C
- •Настройка архитектуры шины I2C типа «контроллер–периферия»
- •Заключение
- •9. Взлом прошивки
- •Прошивка и операционные системы
- •Получение доступа к микропрограмме
- •Взлом маршрутизатора Wi-Fi
- •Извлечение файловой системы
- •Статический анализ содержимого файловой системы
- •Эмуляция прошивки
- •Динамический анализ
- •Внедрение бэкдора в прошивку
- •Нацеливание на механизмы обновления микропрограмм
- •Компиляция и установка
- •Код клиента
- •Запуск службы обновления
- •Уязвимости служб обновления микропрограмм
- •Заключение
- •10. Радио ближнего действия: взлом rFID
- •Радиочастотные диапазоны
- •Пассивные и активные технологии RFID
- •Структура меток RFID
- •Низкочастотные метки RFID
- •Высокочастотные RFID-метки
- •Настройка Proxmark3
- •Обновление Proxmark3
- •Клонирование низкочастотных меток
- •Клонирование высокочастотных меток
- •Имитация RFID-метки
- •Изменение содержимого RFID-меток
- •Команды RAW для небрендированных или некоммерческих RFID-тегов
- •Подслушивание обмена данными между меткой и считывателем
- •Извлечение ключа сектора из перехваченного трафика
- •Атака путем подделки RFID
- •Автоматизация RFID-атак с помощью механизма скриптов Proxmark3
- •Пользовательские сценарии использования RFID-фаззинга
- •Заключение
- •11. Bluetooth Low Energy (BLE)
- •Как работает BLE
- •Необходимое оборудование BLE
- •BlueZ
- •Настройка интерфейсов BLE
- •Обнаружение устройств и перечисление характеристик
- •GATTTool
- •Bettercap
- •Взлом BLE
- •Настройка BLE CTF Infinity
- •Приступаем к работе
- •Заключение
- •12. Радиоканалы средней дальности: взлом Wi-Fi
- •Как работает Wi-Fi
- •Атаки Wi-Fi на беспроводные клиенты
- •Деаутентификация и атаки «отказ в обслуживании»
- •Атаки на Wi-Fi путем подключения
- •Wi-Fi Direct
- •Атаки на точки доступа Wi-Fi
- •Взлом WPA/WPA2
- •Взлом WPA/WPA2 Enterprise для сбора учетных данных
- •Методология тестирования
- •Заключение
- •13. Радио дальнего действия: LPWAN
- •Захват трафика LoRa
- •Настройка платы разработки Heltec LoRa 32
- •Настройка LoStik
- •Превращаем USB-устройство CatWAN в сниффер LoRa
- •Декодирование протокола LoRaWAN
- •Формат пакета LoRaWAN
- •Присоединение к сетям LoRaWAN
- •Атаки на LoRaWAN
- •Атаки с заменой битов
- •Генерация ключей и управление ими
- •Атаки воспроизведения
- •Подслушивание
- •Подмена ACK
- •Атаки, специфичные для приложений
- •Заключение
- •14. Взлом мобильных приложений
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Защита данных и зашифрованная файловая система
- •Подписи приложений
- •Аутентификация пользователя
- •Управление изолированными аппаратными компонентами и ключами
- •Проверенная и безопасная загрузка
- •Анализ приложений iOS
- •Подготовка среды тестирования
- •Статический анализ
- •Динамический анализ
- •Атаки путем инъекции
- •Хранилище связки ключей
- •Реверс-инжиниринг двоичного кода
- •Перехват и изучение сетевого трафика
- •Анализ приложений Android
- •Подготовка тестовой среды
- •Извлечение файла APK
- •Статический анализ
- •Обратная конвертация двоичных исполняемых файлов
- •Динамический анализ
- •Перехват и анализ сетевого трафика
- •Утечки по побочным каналам
- •Заключение
- •15. Взлом умного дома
- •Физический доступ в здание
- •Клонирование RFID-метки умного дверного замка
- •Глушение беспроводной сигнализации
- •Воспроизведение потока с IP-камеры
- •Общие сведения о протоколах потоковой передачи
- •Анализ сетевого трафика IP-камеры
- •Извлечение видеопотока
- •Атака на умную беговую дорожку
- •Перехват управления интеллектуальной беговой дорожкой на базе Android
- •Заключение
- •Инструменты для взлома интернета вещей
- •Предметный указатель
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Рис.4.11.Пакет MQTT CONNACK с кодом 0x00,указывающим,что учетные данные были верны
Написание модуля MQTT Authentication-Cracking в Ncrack
В этом разделе мы расширим Ncrackдля поддержки MQTT,что позво- литвзламыватьучетныеданные этого протокола.Ncrack (https://nmap. org/ncrack/) – это высокоскоростной сетевой инструмент для взлома аутентификации с модульной архитектурой. Он поддерживает мно- жество сетевых протоколов (для версии 0.7 это SSH, RDP, FTP, Telnet, HTTP и HTTPS, WordPress, POP3 и POP3S, IMAP, CVS, SMB, VNC, SIP, Redis,PostgreSQL,MQTT,MySQL,MSSQL,MongoDB,Cassandra,WinRM, OWA и DICOM) и входит в набор инструментов безопасности Nmap. Его модули выполняют словарные атаки против аутентификации протокола, и он поставляется с различными списками имен пользо- вателей и паролей.
Последняя рекомендуемая версия Ncrack находится на GitHub по адресу https://github.com/nmap/ncrack/, хотя предварительно скомпили- рованные пакеты существуют для таких дистрибутивов, как Kali Li- nux. Последняя версия уже включает модуль MQTT, поэтому, если вы хотите воспроизвести следующие шаги самостоятельно, найдите на git самую свежую версию непосредственно перед добавлением мо- дуля. Для этого используйте следующие команды:
root@kali:~# git clone https://github.com/nmap/ncrack.git root@kali:~# cd ncrack
root@kali:~/ncrack# git checkout 73c2a165394ca8a0d0d6eb7d30aaa862f22faf63
Краткое знакомство с архитектурой Ncrack
Как и Nmap, Ncrack написан на C/C++ и использует библиотеку Nmap Nsock для асинхронной обработки сокетов, управляемой событиями. Этоозначает,чтовместоиспользованиянесколькихпотоковилипро- цессов для достижения параллелизма Ncrack непрерывно опрашива- ет дескрипторы сокетов, зарегистрированные каждым вызванным
Оценка сети 109
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
X |
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
||
|
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|||
P |
|
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
BUY |
|
|
|||
модулем.Каждый раз,когда происходитновое сетевое событие,такое |
|
|
|
to |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
как чтение, запись или тайм-аут, он переходит к предварительно за- |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
регистрированному обработчику обратного вызова, который выпол- няетопределенноедействие,связанное с этим событием.Внутреннее устройство этого механизма выходит за рамки нашего обсуждения. ЕсливыхотитеглубжепонятьархитектуруNcrack,изучитеофициаль-
ное руководство разработчика (https://nmap.org/ncrack/devguide.html).
Мы ограничимся объяснением того, какое место парадигма управля- емых событиями сокетов занимает в разработке модуля MQTT.
Компиляция Ncrack
Дляначалаубедитесь,чтоувасестьработающаякомпилируемаявер- сия Ncrack в вашей тестовой среде. Если вы используете Kali Linux, убедитесь, что у вас есть все доступные инструменты сборки и зави- симости, выполнив команду:
root@kali:~# sudo apt install build-essential autoconf g++ git libssl-dev
Затем клонируйте последнюю версию Ncrack с GitHub, введя:
root@kali:~# git clone https://github.com/nmap/ncrack.git
Для компиляции достаточно ввести следующую строку во вновь созданном каталоге ncrack:
root@kali:~/ncrack# ./configure && make
Теперь у вас должен быть рабочий двоичный файл Ncrack внутри локального каталога. Чтобы проверить это, попробуйте запустить Ncrack без аргументов:
root@kali:~/ncrack# ./ncrack
Должно появиться меню справки.
Инициализация модуля
Вам необходимо выполнять некоторые стандартные шаги каждый раз,когда вы создаете новый модульв Ncrack.Сначала отредактируй- те файл ncrack-services, включив в него новый протокол и его порт поумолчанию.ПосколькуMQTTиспользуетTCP-порт1833,мыдобав- ляем следующую строку (можно в любом месте файла):
mqtt 1883/tcp
110 Глава 4
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Во-вторых,включите ссылку на основную функцию вашего модуля |
|
|
|
|
|
m |
||||
w Click |
|
|
|
|
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
(например,ncrack_mqtt в нашем случае) в функцию call_module внутdf-x chan |
.c |
|
||||||||
|
. |
|
|
|
|
|
|
|||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
рифайлаncrack.cc.Всеосновныефункциимодуляимеютсоглашение об именах ncrack_protocol, заменяющее опцию protocol на факти- ческое имя протокола. Добавьте следующие две строки в основной регистр else-if:
else if (!strcmp(name, "mqtt")) ncrack_mqtt(nsp, con);
В-третьих, мы создаем главный файл для нашего нового модуля в каталоге модулей и называем его ncrack_mqtt.cc.В файле modules.h должнобытьопределениеосновнойфункциимодуля,поэтомумыего добавляем. Все функции основного модуля имеют одинаковые аргу-
менты (nsock_pool, Connection *):
void ncrack_mqtt(nsock_pool nsp, Connection *con);
В-четвертых, мы редактируем configure.ac в основном катало- ге Ncrack, чтобы включить новые файлы модулей ncrack_mqtt.cc
и ncrack_mqtt.o в переменные MODULES_SRCS и MODULES_OBJS со-
ответственно:
MODULES_SRCS="$MODULES_SRCS ncrack_ftp.cc ncrack_telnet.cc ncrack_http.cc \ ncrack_pop3.cc ncrack_vnc.cc ncrack_redis.cc ncrack_owa.cc \ ncrack_imap.cc ncrack_cassandra.cc ncrack_mssql.cc ncrack_cvs.cc \ ncrack_wordpress.cc ncrack_joomla.cc ncrack_dicom.cc ncrack_mqtt.cc" MODULES_OBJS="$MODULES_OBJS ncrack_ftp.o ncrack_telnet.o ncrack_http.o \ ncrack_pop3.o ncrack_vnc.o ncrack_redis.o ncrack_owa.o \
ncrack_imap.o ncrack_cassandra.o ncrack_mssql.o ncrack_cvs.o \ ncrack_wordpress.o ncrack_joomla.o ncrack_dicom.o ncrack_mqtt.o"
Обратите внимание, что после внесения каких-либо изменений в configure.ac нам необходимо запустить инструмент autoconf внут ри основного каталога,чтобы создать новый скриптнастройки,кото- рый будет использоваться при компиляции:
root@kali:~/ncrack# autoconf
Основной код
Теперь давайте разработаем код модуля MQTT в файл ncrack_mqtt. cc.Этотмодуль проведетсловарную атаку на аутентификацию серве- ра MQTT. В листинге 4.1 показана первая часть нашего кода, которая включает заголовки и объявления функций.
Оценка сети 111
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
Листинг 4.1. Подключение заголовочных файлов и объявления функций
#include "ncrack.h" #include "nsock.h" #include "Service.h" #include "modules.h"
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
#define MQTT_TIMEOUT 20000
extern void ncrack_read_handler(nsock_pool nsp, nsock_event nse, void *mydata); extern void ncrack_write_handler(nsock_pool nsp, nsock_event nse, void *mydata); extern void ncrack_module_end(nsock_pool nsp, void *mydata);
static int mqtt_loop_read(nsock_pool nsp, Connection *con); enum states { MQTT_INIT, MQTT_FINI };
Файл начинается с включения локального заголовка, стандартно- го для каждого модуля. Затем в MQTT_TIMEOUT мы определяем как долго будем ждать, пока не получим ответ от брокера. Мы будем ис- пользовать это значение позже в коде. Затем объявляем три важных обработчика обратного вызова: ncrack_read_handler и ncrack_write_ handler для чтения и записи данных в сеть и ncrack_module_end, кото- рыйнеобходимовызыватькаждыйраз,когдамызавершаемвесьэтап аутентификации . Эти три функции определены в ncrack.cc, и их семантика здесь не важна.
Функция mqtt_loop_read – это вспомогательная функция с ло- кальной областью видимости (это означает, что она видна только в файле модуля из-за статического модификатора),которая анализи- руетвходящиеданныеMQTT.Наконец,унасбудетдвасостояниявна- шем модуле . Состояния на языке Ncrack относятся к конкретным этапам процесса аутентификации для конкретного протокола, кото- рый мы взламываем. Каждое состояние выполняет микродействие, которое почти всегда включает регистрацию определенного сетевого события Nsock.Например,в состоянии MQTT_INIT мы отправляем наш первый пакет MQTT CONNECT брокеру. Затем в состоянии MQTT_FINI мы получаем от него пакет CONNACK. Оба состояния включают запись или чтение данных в сеть.
Вторая часть файла определяет две структуры, которые помогут намуправлятьпакетамиCONNECT иCONNACK.Влистинге4.2показанкод для первого из них.
Листинг 4.2. Структура для управления пакетом CONNECT
struct connect_cmd { |
|
|
|
uint8_t message_type; |
/* 1 |
для |
пакета CONNECT */ |
uint8_t msg_len; |
/* длина |
оставшегося пакета */ |
|
uint16_t prot_name_len; /* |
должно быть 4 для "MQTT" */ |
||
u_char protocol[4]; |
/* здесь |
всегда "MQTT" */ |
|
uint8_t version; |
/* 4 |
для |
MQTT версии 3.1.1 */ |
uint8_t flags; |
/* 0xc2 для следующих флагов: username, password, clean session */ |
||
uint16_t keep_alive; |
/* 60 секунд */ |
||
uint16_t client_id_len; /* |
должно быть 6 для идентификатора "Ncrack" */ |
112 Глава 4
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
||||
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
|
||||
|
|
|
|
to |
|
|
|
|
|
|
u_char client_id[6]; /* соответствует Ncrack */ |
|
|
|
|
|
|
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
uint16_t username_len; /* длина строки имени пользователя */ |
||||
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
e |
|
||||
|
|
p |
df |
|
|
|
g |
.c |
|
|
||
|
|
|
|
|
n |
|
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
/* остаток пакета, динамически добавляемый из буфера: |
||
|
|
|
|
|
|
|
|
|
|
|
|
*username (dynamic length),
*password_length (uint16_t)
*password (dynamic length)
*/
connect_cmd() { /* конструктор – инициализация указанными значениями */ message_type = 0x10;
prot_name_len = htons(4); memcpy(protocol, "MQTT", 4); version = 0x04;
flags = 0xc2; keep_alive = htons(60);
client_id_len = htons(6); memcpy(client_id, "Ncrack", 6);
}
} __attribute__((__packed__)) connect_cmd;
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
МыопределяемструктуруСconnect_cmd,чтобыонасодержалаожи- даемые поля пакета MQTT CONNECT в качестве ее членов. Поскольку начальная часть этого типа пакета состоит из фиксированного заго- ловка, легко статически определить значения этих полей. Пакет CONNECT – это управляющий пакет MQTT, который имеет:
zzфиксированный заголовок, состоящий из типа пакета и длины полей;
zzпеременный заголовок, состоящий из имени протокола с префик-
сомProtocol Name Length (длинаименипротокола),Protocol Level
(уровень протокола), Connect Flags (флаги подключения) и Keep Alive (поддержание активного соединения);
zzполезную нагрузку с одним или несколькими полями с префик- сом длины. Наличие этих полей определяется флагами подклю- чения – в нашем случае идентификатором клиента, именем пользователя и паролем.
Чтобы точно определить структуру пакета MQTT CONNECT, обрати- тесь к официальной спецификации протокола по адресу https://docs. oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901033. Для удобства вы можете использовать созданную нами табл. 4.2. Мы также рекомен- дуем поискать ту же структуру пакета в дампе трафика Wireshark (на- пример,рис.4.9).Какправило,увасбудетнесколькоспособовсопостав- ления полей пакета в полях структуры C; наш способ–один из многих.
Message_type – это четырехбитное поле, которое определяет тип пакета. Значение 1 определяет пакет CONNECT. Обратите внимание, что мы выделяем восемь бит (uint8_t) для этого поля,чтобы покрыть четыре младших бита, зарезервированных для этого типа пакета (все 0). Msg_len – это количество байтов, оставшихся в текущем па- кете, не включая байты поля длины. Он соответствует полю длины пакета Length.
Оценка сети 113
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||
|
|
X |
|
|
|
|
|
|
||
|
- |
|
|
|
|
d |
|
|
||
|
F |
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
||
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
BUY |
|
|
|
||
|
|
|
|
to |
Таблица 4.2.Структура пакета MQTT CONNECT: фиксированный заголовок, |
|||||
|
|
|
|
|
||||||
w |
|
|
|
|
||||||
w Click |
|
|
|
|
o |
m |
заголовок и полезная нагрузка,разделенные жирной рамкой |
|||
|
w |
|
|
|
|
|
|
|
||
|
. |
df-xchaпеременныйn |
||||||||
|
|
|
|
|
.c |
|
|
|||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
e |
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Бит |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Тип пакета |
Тип пакета (1 для CONNECT) |
|
Зарезервировано (все 0) |
|
||||
Длина |
Оставшаяся длина пакета |
|
|
|
|
|
|
|
Длина имени |
MSB длины имени протокола (4 для «MQTT») |
|
|
|
|
|||
протокола |
LSB длины имени протокола |
|
|
|
|
|
||
|
«M» |
|
|
|
|
|
|
|
Имя протокола |
«Q» |
|
|
|
|
|
|
|
«T» |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
«T» |
|
|
|
|
|
|
|
Уровень |
Уровень протокола (4 для MQTT версии 3.1.1) |
|
|
|
|
|||
протокола |
|
|
|
|
|
|
|
|
Флаги |
Флаг имени |
Флаг |
Будет |
QoS |
|
Флаг |
Очистка |
Зарезер- |
соединения |
пользователя |
пароля |
сохранен |
|
|
|
сессии |
вировано |
Удержание |
Удержание MSB |
|
|
|
|
|
|
|
соединения |
Удержание LSB |
|
|
|
|
|
|
|
Длина |
MSB длины идентификатора клиента |
|
|
|
|
|
||
ID клиента |
LSB длины идентификатора клиента |
|
|
|
|
|
||
ID клиента |
(произвольный размер–зависит от длины поля имени пользователя) |
|
||||||
Длина имени |
MSB длины имени пользователя |
|
|
|
|
|
||
пользователя |
LSB длины имени пользователя |
|
|
|
|
|
||
Имя пользователя |
(произвольный размер–зависит от длины поля имени пользователя) |
|
||||||
Длина пароля |
MSB длины пароля |
|
|
|
|
|
|
|
LSB длины пароля |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
||
Пароль |
(произвольный размер–зависит от длины поля пароля) |
|
|
|
Фиксированный
заголовок
Произвольный
заголовок
Полезная
нагрузка
В заголовке переменной prot_name_len и protocol соответствуют полям Protocol Name Length и Protocol Name. Длина этого поля всегда должна быть равной 4, поскольку имя протокола всегда представле- но заглавной строкой в кодировке UTF-8 "MQTT". Поле version, пред- ставляющее поле уровня протокола, имеет значение 0x04 для MQTT версии 3.1.1, но в более поздних стандартах могут использоваться другие значения. Параметр flags, представленный в поле Connect Flags, определяет поведение MQTT-соединения и наличие или от- сутствие полей в полезной нагрузке.Мы инициализируем его значе- нием 0xC2, чтобы установить три флага: username, password и clean session. Параметр keep_alive, представляющий поле Keep Alive,
представляетсобой временной интервал в секундах,определяющий максимальное время, которое может пройти между отправкой по- следовательных пакетов управления. В нашем случае это не важно, но мы будем использовать то же значение, что и приложение Mos- quitto.
Наконец, полезная нагрузка пакета начинается с client_id_length и client_id. Идентификатор клиента всегда должен быть первым по- лем в полезной нагрузке пакета CONNECT. Он должен быть уникаль- нымдлякаждогоклиента,поэтомумыбудемиспользоватьNcrackдля нашего модуля. Остальные поля – это Username Length (username_len),
Username, Password Length и Password. Поскольку мы ожидаем исполь-
зовать разные имена пользователей и пароли для каждого соедине- ния(потомучтовыполняематакупословарю),позже вкодемыдина- мически выделяем место под последние три параметра.
114 Глава 4
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Затем мы используем конструктор структуры для инициализа- |
|
|
|
|
|
m |
||||
w Click |
|
|
|
|
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
ции этих полей значениями, которые, как мы знаем, останутся неизd-f-x chan |
.c |
|
||||||||
|
. |
|
|
|
|
|
|
|||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
менными.
Наш сервер отправитпакетCONNACK в ответна пакетCONNECT от кли- ента. Листинг 4.3 показывает структуру пакета CONNACK.
Листинг 4.3. Структура C для управления пакетом CONNACK
struct ack {
uint8_t message_type; uint8_t msg_len; uint8_t flags; uint8_t ret_code;
} __attribute__((__packed__)) ack;
Message_type и msg_len составляют стандартный фиксированный заголовок пакета управления MQTT, аналогичный заголовку пакета CONNECT. MQTT устанавливает значение message_type для пакета CONNACK равным 2. Для этого типа пакета флаги обычно равны 0. Вы мо- жете увидетьэтотакже на рис.4.10 и 4.11.Ret_code –наиболее важное поле, потому что в зависимости от его значения мы можем опреде- лить, были ли приняты наши учетные данные. Код возврата 0x00 оз- начает принятое соединение, а код возврата 0x05 указывает, что со- единение не авторизовано (как мы видели на рис. 4.10), поскольку учетные данные либо не были предоставлены, либо неверны. Хотя есть и другие возвращаемые значения, для упрощения кода модуля мы предположим, что любое значение, отличное от 0x00, означает, что мы должны попробовать другие учетные данные.
Атрибут packed – это директива компилятору C не добавлять ка- ких-либо отступов между полями (что обычно делается автомати- чески для оптимизации доступа к памяти), чтобы все оставалось не- тронутым. Мы сделали то же самое для структуры connect_cmd. Это хорошая практика для структур, используемых в сети.
Затем определяем функцию с именем mqtt_loop_read для анализа пакета CONNACK, как показано в листинге 4.4.
Листинг 4.4. Определение функции mqtt_loop_read, которая отвечает за синтаксический анализ пакетов CONNACK, и проверка кода возврата
static int
mqtt_loop_read(nsock_pool nsp, Connection *con)
{
struct ack *p;
if (con->inbuf == NULL || con->inbuf->get_len() < 4) { nsock_read(nsp, con->niod, ncrack_read_handler, MQTT_TIMEOUT, con); return -1;
}
p = (struct ack *)((char *)con->inbuf->get_dataptr());
if (p->message_type != 0x20) /* отвергнуть, если это не MQTT ACK */
Оценка сети 115
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
return -2;
if (p->ret_code == 0) /* вернуть 0 только если код возврата равен 0 */ return 0;
return -2;
}
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Сначала мы объявляем локальный указатель p на структуру типа ack. Затем проверяем, получили ли мы какие-либо данные в нашем входящем буфере (содержит ли указатель con->inbuf значение NULL), или длина полученных данных меньше 4, что составляет минималь- ный размер ожидаемого ответа сервера. Если любое из этих условий истинно, нам нужно продолжать ждать входящих данных, поэтому мы планируем событие чтения nsock, которое будет обрабатываться нашим стандартным ncrack_read_handler.
Как это происходит, мы здесь не будем обсуждать, но важно пони- матьасинхроннуюприродуэтогометода.Сутьвтом,чтоэтифункции будут выполнять свою работу после того, как модуль вернет управ- ление основному механизму Ncrack, что произойдет по завершении функции ncrack_mqtt. Чтобы знать, где модуль останавливался для каждого TCP-соединения при следующем вызове, Ncrack сохраняет текущее состояние в переменной con-> state. Дополнительная ин- формациятакжесохраняетсявдругихчленахклассаConnection,таких как буферы для входящих (inbuf) и исходящих (outbuf) данных.
Как только мы получим полный ответ CONNACK, мы можем пере- строить наш локальный указатель p на буфер , предназначенный для входящих сетевых данных. Мы приводим этот буфер к указателю struct ack.Проще говоря,это означает,чтотеперь мы можем исполь- зовать указатель p, чтобы легко просматривать элементы структуры. Затем первое, что мы проверяем в полученном пакете,– является ли онпакетомCONNACK;еслиэтонетак,намнеследуетбеспокоитьсяоего дальнейшем анализе.Если же это пакетCONNACK,мы проверяем,равен ли код возврата 0 , и в этом случае возвращаем 0, чтобы уведомить вызывающего абонента о правильности учетных данных. В против- ном случае произошла ошибка или учетные данные были неверны- ми, и мы возвращаем –2.
Последняя часть нашего кода – это основная функция ncrack_mqtt, которая обрабатывает всю логику для аутентификация на сервере MQTT. Он представлен двумя листингами: листинг 4.5 представляет логикусостоянияMQTT_INIT,алистинг4.6–логикусостоянияMQTT_FINI.
Листинг 4.5. Код состояния MQTT_INIT, который отправляет пакет
CONNECT
void
ncrack_mqtt(nsock_pool nsp, Connection *con)
{
nsock_iod nsi = con->niod;
116 Глава 4
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
|
X |
|
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
|||
|
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
||
|
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
BUY |
|
|
||||
struct connect_cmd cmd; |
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
|
|
|
m |
||
uint16_t pass_len; |
w Click |
|
|
|
|
|
|
o |
||||
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
e |
|
||||
|
|
|
p |
df |
|
|
|
g |
.c |
|
||
|
|
|
|
|
|
n |
|
|
|
|
||
|
|
|
|
|
-x cha |
|
|
|
|
|
switch (con->state)
{
case MQTT_INIT: con->state = MQTT_FINI;
delete con->inbuf; con->inbuf = NULL; if (con->outbuf)
delete con->outbuf; con->outbuf = new Buf();
/* длина сообщения равна длине структуры плюс длина имени пользователя
*и пароля минус 2 первых байта (тип сообщения и длина сообщения) которые
*не подсчитываются
*/
cmd.msg_len = sizeof(connect_cmd) + strlen(con->user) + strlen(con->pass) + sizeof(pass_len) - 2;
cmd.username_len = htons(strlen(con->user)); pass_len = htons(strlen(con->pass));
con->outbuf->append(&cmd, sizeof(cmd)); con->outbuf->snprintf(strlen(con->user), "%s", con->user); con->outbuf->append(&pass_len, sizeof(pass_len)); con->outbuf->snprintf(strlen(con->pass), "%s", con->pass);
nsock_write(nsp, nsi, ncrack_write_handler, MQTT_TIMEOUT, con,
(const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
break;
Первый блок кода в нашей основной функции объявляет три ло- кальныепеременные.Nsockиспользуетпеременнуюnsock_iod вся- кий раз, когда мы регистрируем сетевое чтение и записываем собы- тия через nsock_read и nsock_write соответственно. Структура struct cmd, которую мы определили в листинге 4.2, обрабатывает входящий пакет CONNECT. Обратите внимание, что его конструктор автомати- чески вызывается, когда мы объявляем его, поэтому он инициализи- руется значениями по умолчанию, которые мы дали каждому полю. Будем использовать pass_len для временного хранения двухбайтово- го значения длины пароля.
КаждыймодульNcrackимеетоператорswitch ,вкоторомкаждый случай представляет определенный этап аутентификации фазы для конкретного протокола,который мы взламываем.У аутентификации MQTT есть только два состояния: мы начинаем с MQTT_INIT, а затем устанавливаемследующеесостояние как MQTT_FINI.Этоозначает,что, когда мы завершаем выполнение этой фазы и возвращаем управле- ние основному механизму Ncrack, оператор switch продолжится со следующего состояния, MQTT_FINI (см.листинг 4.6), когда модуль сно- ва запускается для этого конкретного TCP-соединения.
Оценка сети 117
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
X |
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
||
|
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|||
P |
|
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
BUY |
|
|
|||
Затем проверяем, чтобы наши буферы для приема (con->inbuf) |
|
|
|
to |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
и отправки (con->outbuf) сетевых данных были пустыми .Далее об- |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
новляем оставшееся поле длины в нашей структуре cmd . Помните, что оно вычисляется как оставшаяся длина пакета CONNECT, не вклю- чая поле длины. Мы должны учитывать размер трех дополнительных полей(имяпользователя,длинапароляипароль),которыедобавляем в конце нашего пакета, потому что мы не включили их в структуру cmd. Также обновляем поле длины имени пользователя с учетом фак- тического размера текущего имени пользователя. Ncrack автомати- чески выполняет итерацию по словарю, обновляет имя пользователя и пароль в переменных user и pass класса Connection соответственно. Мы также вычисляем длину пароля и сохраняем ее в pass_len. Затем начинаем создавать наш исходящий пакет CONNECT, сначала добавляя обновленную структуру cmd в outbuf , а затем динамически добав- ляядополнительныетри поля.Класс Buffer (inbuf,outbuf) имеетсвои собственные удобные функции, такие как append и snprintf, с помо- щью которых вы можете легко и постепенно добавлять отформати- рованные данные для создания собственных полезных нагрузок TCP.
Кроме того, мы планируем отправить наш пакет из буфера outbuf в сеть, зарегистрировав событие сетевой записи через nsock_write, обрабатываемое ncrack_write_handler . Затем завершаем switch и ncrack_mqtt (на данный момент) и возвращаем управление выпол- нением основному механизму, который среди других задач будет перебирать все зарегистрированные сетевые события (например, то, что мы только что запланировали выше с использованием функции ncrack_mqtt) и обрабатывать их.
Следующее состояние, MQTT_FINI, принимает и анализирует входя- щий пакет CONNACK от брокера и проверяет, были ли предоставлены наши учетные данные правильно. В листинге 4.6 показан код, кото- рый входит в то же определение функции, что и листинг 4.5.
Листинг 4.6. Код состояния MQTT_FINI, который получает входящий пакет CONNACK и оценивает, верны ли отправленные нами имя пользователя и пароль
case MQTT_FINI:
if (mqtt_loop_read(nsp, con) == -1) break;
else if (mqtt_loop_read(nsp, con) == 0) con->auth_success = true;
con->state = MQTT_INIT; delete con->inbuf; con->inbuf = NULL;
return ncrack_module_end(nsp, con);
}
}
Мы начинаем с того, что спрашиваем mqtt_loop_read, получили ли мы ответсервера .Вспомните излистинга 4.4,что он вернет-1,если
118 Глава 4