- •От издательства
- •О техническом обозревателе
- •О соавторах
- •Об авторах
- •Вступительное слово
- •Благодарности
- •Предисловие
- •Почему важна защита интернета вещей?
- •Чем защита интернета вещей отличается от традиционной ИТ-защиты?
- •Законы хакинга интернета вещей
- •Заключение
- •Моделирование угроз для интернета вещей
- •Схема моделирования угроз
- •Определение архитектуры
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Использование деревьев атак для обнаружения угроз
- •Распространенные угрозы интернета вещей
- •Атаки с подавлением сигнала
- •Атаки с воспроизведением
- •Атаки со взломом настроек
- •Клонирование узла
- •Заключение
- •Пассивная разведка
- •Физический или аппаратный уровень
- •Периферийные интерфейсы
- •Среда загрузки
- •Блокировки
- •Предотвращение и обнаружение несанкционированного доступа
- •Прошивка
- •Интерфейсы отладки
- •Физическая устойчивость
- •Разведка
- •Атаки на сетевой протокол и службы
- •Тестирование беспроводного протокола
- •Оценка веб-приложений
- •Картирование приложений
- •Элементы управления на стороне клиента
- •Аутентификация
- •Управление сеансом
- •Проверка ввода
- •Логические ошибки
- •Сервер приложений
- •Исследование конфигурации хоста
- •Учетные записи пользователей
- •Привилегии учетной записи
- •Уровни патчей
- •Удаленное обслуживание
- •Управление доступом к файловой системе
- •Шифрование данных
- •Неверная конфигурация сервера
- •Мобильное приложение и облачное тестирование
- •Заключение
- •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 |
|
|
|
|
udp |
0 |
0 |
0.0.0.0:53 |
0.0.0.0:* |
udp |
0 |
0 |
0.0.0.0:67 |
0.0.0.0:* |
udp |
0 |
0 |
:::53 |
:::* |
udp |
0 |
0 |
:::69 |
:::* |
|
|
|
|
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 |
|
|
|
|
Вместо того чтобы заменять двоичный файл, можно изменить его, чтобысохранитьисходнуюфункциональностьиоболочку.Этоснизит вероятностьтого,что пользователи обнаружатбэкдор.Завершитьэто упражнение предоставляем вам самостоятельно.
Нацеливание на механизмы обновления микропрограмм
Механизм обновления микропрограмм является важным вектором атаки и одной из уязвимостей в IoT-устройствах,вошедших в десятку основныхрисковповерсииOWASP.Механизмобновлениямикропро- граммы – это процесс, который загружает новую версию микропро- граммы через веб-сайт поставщика или внешнее устройство, напри- мер USB-накопитель, и устанавливает ее путем замены более ранней версии. Эти механизмы могут создать ряд проблем безопасности . Они часто не могут проверить микропрограммное обеспечение или используют незашифрованные сетевые протоколы; в некоторых от- сутствуют механизмы предотвращения отката или уведомления ко- нечного пользователя олюбых изменениях безопасности ,вызванных обновлением. Процесс обновления может также усугубить другие проблемы в устройстве, такие как использование жестко заданных учетных данных, небезопасная аутентификация в облачном ком- поненте, на котором размещено микропрограммное обеспечение, и даже излишне подробное и небезопасное ведение журнала.
Чтобы наглядно представить все эти проблемы,мы создали специ- альную уязвимую службу обновления прошивки. Эта служба состоит из эмулированного устройства IoT, которое загружает прошивку из эмулируемой облачной службы обновления. Вы можете загрузить файлы для этого упражнения с веб-сайта книги по адресу https://no- starch.com/practical-iot-hacking/. Эта служба обновления может быть включенавбудущемкакчастьIoTGoat,намереннонебезопаснойпро- шивки на основе OpenWrt, цель которой – показать пользователям распространенные уязвимости в устройствах IoT. Авторы этой книги вносят свой вклад в проект.
Чтобыдоставитьновыйфайлпрошивки,сервербудетпрослушивать TCP-порт 31337.Клиент будет подключаться к серверу через этот порт и аутентифицироваться с помощью заранее заданного жестко запро- граммированного ключа. Затем сервер отправит клиенту следующие данные по порядку: длину встроенного ПО, хеш-код файла встроен- ного ПО MD5 и файл встроенного ПО. Клиент проверяет целостность файла микропрограммы, сравнивая полученный хеш MD5 с хешем файла микропрограммы, который он вычисляет с использованием
Взлом прошивки 269
|
|
|
|
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 |
|
граммы записывается в текущий каталог как received_firmware.gz.
Компиляция и установка
Хотя вы можете запускать клиент и сервер на одном хосте, в идеале выдолжны запускатьих на разных хостах,чтобы имитироватьреаль- ный процесс обновления.Поэтому мы рекомендуем скомпилировать и настроить два компонента в разных системах Linux. В нашем при- мере используются Kali Linux для сервера обновлений и Ubuntu для клиентаIoT,новысможетевзятьлюбойдистрибутивLinux,еслиуста- новили правильные зависимости.
Установите следующие пакеты на обе машины:
# apt-get install build-essential libssl-dev
Перейдите в каталог клиента и используйте включенный в него make-файл, чтобы скомпилировать клиентскую программу, введя следующее:
$ make client
Эта команда должна создать исполняемый клиентский файл в те- кущем каталоге.Затем скомпилируйте сервер на второй машине.Пе- рейдите в каталог, где находятся make-файл и server.c, и скомпили- руйте их, введя эту команду:
$ make server
Мы не будем анализировать код сервера, потому что при реальной оценке безопасности у вас, скорее всего, будет доступ только к двоич- номуфайлуклиента(даженекисходномукоду!)изфайловойсистемы микропрограммы.Но в образовательных целях рассмотрим исходный код клиента,чтобы исследовать лежащие в его основе уязвимости.
Код клиента
Теперь посмотрим на клиентский код.Эта программа,написанная на
C,доступна по адресу https://nostarch.com/practical-iot-hacking/.Здесь мы выделим только важные части:
#define PORT 31337
#define FIRMWARE_NAME "./received_firmware.gz"
#define KEY "jUiq1nzpIOaqrWa8R21"
270 Глава 9
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Директивы #define определяют постоянные значения. Сначалаwмы |
|
|
|
|
|
m |
|||||
|
w Click |
|
|
|
|
|
o |
||||
|
|
w |
|
|
|
|
|
|
|
|
|
определяем порт сервера, который будет прослушивать служба обd-f-x chan |
.c |
|
|||||||||
|
|
. |
|
|
|
|
|
|
|||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
|
новления. Далее указываем имя для полученного файла прошивки. |
|
|
|
|
|
|
|||||
Затем жестко кодируем ключ аутентификации, который уже был пе- |
|
|
|
|
|
|
|||||
редан серверу.Использование жестко запрограммированных ключей |
|
|
|
|
|
|
|||||
создает угрозу безопасности |
, как мы объясним позже. |
|
|
|
|
|
|
|
|
|
|
Мы разделили код клиентской функции main() на два отдельных списка для большей ясности. Первая часть представлена в листин-
ге 9.2.
Листинг 9.2. Первая половина функции main() незащищенного клиента обновления прошивки
int main(int argc, char **argv) { struct sockaddr_in servaddr;
int sockfd, filelen, remaining_bytes; ssize_t bytes_received;
size_t offset;
unsigned char received_hash[16], calculated_hash[16]; unsigned char *hash_p, *fw_p;
unsigned int hash_len; uint32_t hdr_fwlen;
char server_ip[16] = "127.0.0.1"; FILE *file;
if (argc > 1)
strncpy((char *)server_ip, argv[1], sizeof(server_ip) - 1);
openlog("firmware_update", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); syslog(LOG_NOTICE, "firmware update process started with PID: %d", getpid());
memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET;
inet_pton(AF_INET, server_ip, &(servaddr.sin_addr)); servaddr.sin_port = htons(PORT);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) fatal("Could not open socket %s\n", strerror(errno));
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -1) fatal("Could not connect to server %s: %s\n", server_ip, strerror(errno));
/* отправляем ключ для аутентификации */ write(sockfd, &KEY, sizeof(KEY));
syslog(LOG_NOTICE, "Authenticating with %s using key %s", server_ip, KEY);
/* получаем размер прошивки */
recv(sockfd, &hdr_fwlen, sizeof(hdr_fwlen), 0); filelen = ntohl(hdr_fwlen);
printf("filelen: %d\n", filelen);
Функция main начинается с определения переменных для нужд ра- боты с сетью и хранения значений,используемых во всей программе.
Взлом прошивки 271
|
|
|
|
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 |
|
го уровня. Обратите внимание на переменную server_ip , которая хранит IP-адрес сервера как строку C с завершающим нулем. Если пользователь не указывает аргумент в командной строке при запуске клиента, IP-адресом по умолчанию будет localhost (127.0.0.1). В про- тивном случае мы копируем первый аргумент argv[1] (поскольку argv[0] всегда является именем файла программы) в server_ip . За- тем открываем соединение с системой logger и инструктируем ее,что все сообщения, которые она получит в будущем, будут добавляться к ключевому слову firmware_update,за которым следует идентифика- тор процесса вызывающего абонента (PID). С этого момента каждый раз, когда программа вызывает функцию системного журнала, она отправляет сообщения в файл /var/log/messages – общий журнал ак- тивностисистемы,которыйобычноиспользуетсядлянекритических, неотладочных сообщений.
Следующий блок кода подготавливаетсокетTCP (черездескриптор сокета sockfd) и инициирует TCP-соединение с сервером.Если сер- вер прослушивает на другом конце, клиент успешно выполнит трех- стороннее квитирование TCP. Затем он может начать отправку или получение данных через сокет.
Затем клиент аутентифицируется на сервере, отправляя значение KEY, определенное ранее . Он отправляет в системный журнал дру- гое сообщение, указывающее, что он пытается аутентифицироваться с использованием этого ключа. Это действие демонстрирует две не- безопасные практики: запись избыточных данных в журнал и вклю- чение конфиденциальной информации в файлы журнала. Предвари- тельный секретный ключ теперь записывается в журнал, к которому могут иметь доступ непривилегированные пользователи. Вы можете узнать больше об этих проблемах на https://cwe.mitre.org/data/definitions/779.html и https://cwe.mitre.org/data/definitions/532.html.
После успешной аутентификации клиент ожидает получения дли- ны микропрограммного обеспечения от сервера, сохраняя это значе- ние в hdr_fwlen, а затем преобразует сетевой порядок байтов в поря- док размещения байтов на хосте путем вызова ntohl .
В листинге 9.3 показана вторая часть функции main.
Листинг 9.3. Вторая половина функции main() незащищенного клиента обновления прошивки
/* получение хеша */
recv(sockfd, received_hash, sizeof(received_hash), 0);
/* получение файла */
if (!(fw_p = malloc(filelen)))
fatal("недостаточно памяти для получения прошивки\n");
remaining_bytes = filelen; offset = 0;
272 Глава 9
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
||||
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
|
||||
|
|
|
|
to |
|
|
|
|
|
|
while (remaining_bytes > 0) { |
|
|
|
|
|
|
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
bytes_received = recv(sockfd, fw_p + offset, remaining_bytes, 0); |
||||
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
e |
|
||||
|
|
p |
df |
|
|
|
g |
.c |
|
|
||
|
|
|
|
|
n |
|
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
offset += bytes_received; |
||
|
|
|
|
|
|
|
|
|
|
|
|
remaining_bytes -= bytes_received; #ifdef DEBUG
printf("Получено байтов %ld\n", bytes_received);
#endif
}
|
|
|
|
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 |
|
|
|
|
/* проверка прошивки путем сравнения полученного и вычисленного хеша */ hash_p = calculated_hash;
hash_p = HMAC(EVP_md5(), &KEY, sizeof(KEY) - 1, fw_p, filelen, hash_p, &hash_len);
printf("вычисленный хеш: ");
for (int i = 0; i < hash_len; i++) printf("%x", hash_p[i]);
printf("\nполученный хеш: ");
for (int i = 0; i < sizeof(received_hash); i++) printf("%x", received_hash[i]);
printf("\n");
if (!memcmp(calculated_hash, received_hash, sizeof(calculated_hash))) printf("хеши совпадают\n");
else
fatal("хеши не совпадают\n");
/* запись прошивки на диск */
if (!(file = fopen(FIRMWARE_NAME, "w")))
fatal("Не удалось открыть файл для записи %s\n", strerror(errno)); fwrite(fw_p, filelen, 1, file);
syslog(LOG_NOTICE, "Прошивка успешно скачана"); /*очистка */
free(fw_p); fclose(file); close(sockfd); closelog(); return 0;
Послеполучениядлинымикропрограммы(хранящейсявперемен- ной filelen) клиент получает хеш MD5 файла микропрограммы (хра- нится в переменной received_hash) .Затем,в зависимости отдлины микропрограммы, он выделяет необходимую память в куче для по- лучения файла микропрограммы . Цикл while постепенно получа- ет файл микропрограммы с сервера и записывает его в выделенную память.
Затем клиент вычисляет MD5-хеш файла микропрограммы (calculated_hash), используя предварительный ключ . В целях отладки мы также печатаем вычисленные и полученные хеши. Если два хеша соответствуют , клиент создает файл в текущем каталоге, исполь- зуя имя файла,взятое из значения FIRMWARE_NAME.Затем он выгружает микропрограммное обеспечение , которое было сохранено в памя-
Взлом прошивки 273