- •От издательства
- •О техническом обозревателе
- •О соавторах
- •Об авторах
- •Вступительное слово
- •Благодарности
- •Предисловие
- •Почему важна защита интернета вещей?
- •Чем защита интернета вещей отличается от традиционной ИТ-защиты?
- •Законы хакинга интернета вещей
- •Заключение
- •Моделирование угроз для интернета вещей
- •Схема моделирования угроз
- •Определение архитектуры
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Использование деревьев атак для обнаружения угроз
- •Распространенные угрозы интернета вещей
- •Атаки с подавлением сигнала
- •Атаки с воспроизведением
- •Атаки со взломом настроек
- •Клонирование узла
- •Заключение
- •Пассивная разведка
- •Физический или аппаратный уровень
- •Периферийные интерфейсы
- •Среда загрузки
- •Блокировки
- •Предотвращение и обнаружение несанкционированного доступа
- •Прошивка
- •Интерфейсы отладки
- •Физическая устойчивость
- •Разведка
- •Атаки на сетевой протокол и службы
- •Тестирование беспроводного протокола
- •Оценка веб-приложений
- •Картирование приложений
- •Элементы управления на стороне клиента
- •Аутентификация
- •Управление сеансом
- •Проверка ввода
- •Логические ошибки
- •Сервер приложений
- •Исследование конфигурации хоста
- •Учетные записи пользователей
- •Привилегии учетной записи
- •Уровни патчей
- •Удаленное обслуживание
- •Управление доступом к файловой системе
- •Шифрование данных
- •Неверная конфигурация сервера
- •Мобильное приложение и облачное тестирование
- •Заключение
- •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 |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
та, нажав Tools > Serial Monitor (Инструменты > Монитор последо- |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
вательного порта). Serial Monitor – это всплывающее окно, которое может отправлять и получать данные UART в модуль Black Pill и из него.По функциям оно аналогично инструменту screen,который ис- пользовался ранее,но встроено в IDE Arduino для удобства.Нажмите Tools > Port (Инструменты > Порт), чтобы убедиться, что вы выбра- ли порт USB, к которому подключен ваш последовательный адаптер USB.Убедитесь,что скорость передачи в настройках окна Serial Mon- itor составляет 9600, как мы указали в коде. После этого вы должны увидеть приглашение Login: нашей программы Arduino. Введите образец текста для тестирования программы. На рис. 7.17 показан пример сеанса.
Если вы введете какой-либо другой текст, кроме sock-raw.org, вы должны получить сообщение Access Denied (доступ отклонен). В про- тивном случае – сообщение ACCESS GRANTED (доступ разрешен).
Рис.7.17.Всплывающее окно Serial Monitor в среде Arduino IDE
Отладка целевого устройства
Теперь пришло время для основного упражнения: отладки и взлома Black Pill. Если вы выполнили все предыдущие шаги, у вас должна быть полностью рабочая среда отладки, а Black Pill должен содержать написанную нами программу Arduino.
Мы будем использовать OpenOCD для связи с Black Pill с помощью SWD через программатор ST-Link. Сделаем это, чтобы открыть сеанс удаленной отладки с GDB. Затем, используя GDB, пройдемся по ин- струкциям программы и обойдем ее проверку аутентификации.
Запуск сервера OpenOCD
Запустим OpenOCD как сервер. Он нужен нам для связи с Black Pill через SWD.Чтобы запустить его с ядром STM32F103 Black Pill с помо- щью ST-Link,мы должны указатьдва соответствующих файла конфи- гурации с помощью переключателя -f:
218 Глава 7
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
|||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
|
r |
|||
P |
|
|
|
|
|
NOW! |
|
o |
|
P |
|
|
|
|
|
NOW! |
o |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
to |
|
|
|
|
|
|
||
w Click |
|
|
|
|
|
|
$m |
|
|
|
|
|
|
|
|
|
|
|
m |
|||||
|
|
|
|
|
|
|
sudo openocd -f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/w Click |
|
|
|
|
|
|
|||||||||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
|||||||
|
|
p |
|
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||
|
|
|
df |
-xcha |
|
e |
openocd/scripts/targets/stm32f1x.cfg |
|
|
|
df |
-x cha |
|
e |
|
|||||||||
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
[sudo] password for ithilgore:
Open On-Chip Debugger 0.10.0+dev-00936-g0a13ca1a (2019-10-06-12:35) Licensed under GNU GPL v2
For bug reports, read http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport
select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : clock speed 1000 kHz
Info : STLINK V2J31S7 (API v2) VID:PID 0483:3748 Info : Target voltage: 3.218073
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints Info : Listening on port 3333 for gdb connections
Эти файлы конфигурации помогают OpenOCD понять, как взаи- модействовать с устройствами, использующими JTAG и SWD. Если вы установили OpenOCD из источника, как было показано выше, эти файлы конфигурации должны находиться в каталоге /usr/local/share/ openocd.ПослезапускакомандыOpenOCDначнетприниматьлокаль- ные подключения Telnet на TCP-порт 4444 и GDB-подключения на
TCP-порт 3333.
На этом этапе мы откроем сеанс OpenOCD через Telnet и начнем отправлять команды Black Pill через SWD. В другом терминале вве- дите:
$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost. Escape character is '^]'. Open On-Chip Debugger
> reset init
target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000538 msp: 0x20005000
>halt
>flash banks
#0 : stm32f1x.flash (stm32f1x) at 0x08000000, size 0x00000000, buswidth 0, chipwidth 0 > mdw 0x08000000 0x20
0x08000000: 20005000 08000539 080009b1 080009b5 080009b9 080009bd 080009c1 08000e15 0x08000020: 08000e15 08000e15 08000e15 08000e15 08000e15 08000e15 08000e15 08000e35 0x08000040: 08000e15 08000e15 08000e15 08000e15 08000e15 08000e15 08000a11 08000a35 0x08000060: 08000a59 08000a7d 08000aa1 080008f1 08000909 08000921 0800093d 08000959 > dump_image firmware-serial.bin 0x08000000 17812
dumped 17812 bytes in 0.283650s (61.971 KiB/s)
Уязвимости портов UART,JTAG и SWD 219
|
|
|
|
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 |
|
|
|||
Команда reset init останавливает целевое устройство и вы- |
|
|
|
to |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
полняет полный сброс, выполняя скрипт reset-init. Этот скрипт |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
представляет собой обработчик событий, который выполняет та- кие задачи, как натройка тактовых импульсов и тактовой частоты JTAG. Вы можете найти примеры этих обработчиков, если посмо-
трите файлы .cfg каталога openocd/scripts/target/. Команда halt
отправляет запрос на останов, чтобы устройство остановилось и перешло в режим отладки. Команда flash banks выводит од- нострочную сводку каждой области флеш-памяти, которая была указана в файле OpenOCD .cfg (в данном случае stm32f1x.cfg). Она выводитна печатьосновную флеш-памятьBlack Pill,которая начи- нается с адреса 0x08000000. Этот шаг важен, поскольку он поможет вам определить, из какого сегмента памяти нужно сделать дамп микропрограммы. Обратите внимание, что иногда значение раз- мера указывается неправильно. Лучшим ресурсом для этого шага остается просмотр таблиц данных. Затем мы отправляем 32-бит- ную команду доступа к памяти mdw , начиная с найденного ранее адреса, чтобы прочитать и отобразить первые 32 байта флеш-па- мяти. Наконец выгружаем целевую память с этого адреса (всего 17 812 байт) и сохраняем ее в файле firmware-serial.bin в локаль- ном каталоге нашего компьютера . Мы получили число 17 812, запросив размер программного файла Arduino, загруженного во флеш-память. Для этого введите следующую команду из времен- ного каталога компилятора Arduino:
/tmp/arduino_build_336697 $ stat -c '%s' serial-simple.ino.bin
17812
Затем вы можете использовать такие инструменты сравнения, как colordiff и xxd, чтобы узнать, есть ли какие-либо различия между файлом firmware-serial.bin, который мы выгружали из флеш-памя- ти, и файлом serial-simple.ino.bin, который мы загрузили через IDE Arduino. Если вы сохранили ровно столько байтов, сколько содержит программа Arduino, в выводе colordiff не должно быть различий:
$ sudo apt install colordiff xxd
$ colordiff -y <(xxd serial-simple.ino.bin) <(xxd firmware-serial.bin) | less
Рекомендуем вам поэкспериментировать с другими командами OpenOCD; все они задокументированы на веб-сайте инструмента. Вот полезная команда, которую стоит попробовать:
> flash write_image erase custom_firmware.bin 0x08000000
Вы можете использовать ее для записи новой прошивки.
220 Глава 7
|
|
|
|
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 |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
t |
|
||
|
P |
D |
|
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
NOW! |
r |
||||||
|
|
|
|
|
|
BUY |
|
|
||||
Отладка с помощью GDB |
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
|||||
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
|
.c |
|
||
|
|
|
p |
df |
|
|
|
|
e |
|
||
|
|
|
|
|
|
g |
|
|
|
|||
|
|
|
|
|
|
n |
|
|
|
|
||
|
|
|
|
|
-x cha |
|
|
|
|
|
||
Давайте отладим и изменим поток выполнения программы Arduino |
|
|
|
|
|
|
|
с помощью GDB. С уже запущенным сервером OpenOCD мы можем начатьудаленный сеанс GDB.Чтобы облегчитьсвою задачу,мы будем использовать файл в формате исполняемых и связываемых файлов (ELF), созданный во время компиляции программы Arduino. ELF – стандартный формат файла для исполняемых файлов, объектного кода, разделяемых библиотек и дампов ядра в Unix-подобных систе- мах. В этом случае он действует как промежуточный файл во время компиляции.
Перейдите во временный каталог, созданный во время компиля- ции. Убедитесь, что вы изменили случайную часть имени каталога на значение, полученное в результате вашей собственной компиля- ции Arduino. Затем, предполагая, что ваша программа Arduino была названа serial-simple, запустите удаленный сеанс GDB, используя команду gdb-multiarch с аргументами, приведенными ниже:
$ cd /tmp/arduino_build_336697/
$ gdb-multiarch -q --eval-command="target remote localhost:3333" serial-simple.ino.elf
Reading symbols from serial-simple.ino.elf...done. Remote debugging using localhost:3333
0x08000232 in loop () at /home/ithilgore/Arduino/serial-simple/serial-simple.ino:15 15 if (start == true) {
(gdb)
Эта команда откроет сеанс GDB и используетлокальный двоичный файл ELF (называемый serial-simple.ino.elf), созданный Arduino во время компиляции для отладочных символов. Отладочные симво- лы–это примитивные типы данных,которые позволяют отладчикам получатьдоступктакойинформации,какпеременныеиименафунк- ций, из исходного кода двоичного файла.
Теперь вы можете использовать этот терминал, чтобы отправлять команды GDB. Начните с ввода команды info functions, чтобы убе- диться, что символы действительно были загружены:
(gdb) info functions
All defined functions:
File /home/ithilgore/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/HardwareSerial. cpp:
HardwareSerial *HardwareSerial::HardwareSerial(usart_dev*, unsigned char, unsigned char); int HardwareSerial::available();
…
File /home/ithilgore/Arduino/serial-simple/serial-simple.ino: void loop();
void recv_data(); void setup(); void validate();
…
Уязвимости портов UART,JTAG и SWD 221
|
|
|
|
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 |
|
|
|||
Теперь поместим точку останова на функцию validate(), потому |
|
|
|
to |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
что имя подразумевает, что она выполняет какую-то проверку, кото- |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
рая может быть связана с аутентификацией.
(gdb) break validate
Breakpoint 1 at 0x800015c: file /home/ithilgore/Arduino/serial-simple/serial-simple.ino, line 55.
Поскольку отладочная информация,записанная в двоичном файле ELF, сообщает GDB о том, какие исходные файлы использовались для его сборки, мы можем использовать команду list для печати частей исходного кода программы. Такая удобная возможность редко пре- доставляется в реальных сценариях обратного проектирования, где вам придется полагаться на команду дизассемблирования, которая вместо исходного кода показывает код ассемблера. Вот результат вы- полнения обеих команд:
(gdb) list validate,
55void validate() {
56Serial1.println(buf);
57new_data = false;
58
59if (strcmp(buf, "sock-raw.org") == 0)
60Serial1.println("ACCESS GRANTED");
61else {
62Serial1.println("Access Denied.");
63Serial1.print("Login: ");
64}
(gdb) disassemble validate
Dump of assembler code for function validate():
0x0800015c <+0>: push |
{r3, |
lr} |
|
0x0800015e <+2>: ldr |
r1, [pc, #56] ; (0x8000198 <validate()+60>) |
||
0x08000160 |
<+4>: ldr |
r0, [pc, #56] ; (0x800019c <validate()+64>) |
|
0x08000162 |
<+6>: bl |
0x80006e4 <Print::println(char const*)> |
|
0x08000166 |
<+10>: ldr |
r3, [pc, #56] ; (0x80001a0 <validate()+68>) |
|
0x08000168 |
<+12>: movs |
r2, #0 |
|
0x0800016a <+14>: ldr |
r0, [pc, #44] ; (0x8000198 <validate()+60>) |
||
0x0800016c <+16>: ldr |
r1, [pc, #52] ; (0x80001a4 <validate()+72>) |
||
0x0800016e <+18>: strb |
r2, [r3, #0] |
||
0x08000170 |
<+20>: bl |
0x8002de8 <strcmp> |
|
0x08000174 |
<+24>: cbnz |
r0, 0x8000182 <validate()+38> |
|
0x08000176 |
<+26>: ldr |
r0, [pc, #36] ; (0x800019c <validate()+64>) |
…
ПРИМЕЧАНИЕ Вы можете использовать более короткие версии мно- гих команд GDB, такие как l вместо list, disas вместо disassemble и b вместо break.Если вы долго пользуетесь GDB,такие сокращения за- метно облегчают работу
222 Глава 7
|
|
|
|
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 |
|
(в данном случае serialsimple.ino.elf) в декомпилятор наподобие техdf,-x chan |
.c |
|
||||||||
|
. |
|
|
|
|
|
|
|||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
e |
|
что предоставляет Ghidra или IDA Pro. Это очень поможет вам, пото- му что он переведет ассемблерный код в C, который намного легче читать (рис. 7.18).
Рис.7.18.Использование декомпилятора в Ghidra для быстрого чтения кода C вместо кода сборки
Если у вас есть только шестнадцатеричный файл (например, firm- ware-serial.bin) как результат сброса микропрограммы из флеш-па- мяти, вам сначала придется дизассемблировать его, используя ин- струментарий ARM следующим образом:
$ arm-none-eabi-objdump -D -b binary -marm -Mforce-thumb firmware-serial.bin > output.s
Файл output.s будет содержать ассемблерный код.
Теперьдавайте посмотрим,как мы можем обойти процесс простой аутентификации нашей цели.Чтобы продолжить нормальное выпол- нение программы, введите команду continue (или,для краткости, c):
(gdb) continue
Continuing.
Теперь программа ожидает последовательного ввода. Откройте монитор последовательного порта в средеArduino IDE,как мы этоде- лали раньше, введите образец пароля, например test123, и нажмите Enter. На терминале GDB вы должны увидеть, что срабатывает точка останова для функции проверки. С этого момента мы заставим GDB автоматически отображать следующую инструкцию, которая будет
Уязвимости портов UART,JTAG и SWD 223
|
|
|
|
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 |
|
|||||
выполнениякомандыdisplay / i $ pc.Затеммыпостепенноперейдем |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
к одной машинной инструкции, используя команду stepi, пока не дойдем до вызова strcmp. Дойдя до вызова Print :: println, обойдем его, потому что это не касается нас в данном контексте (листинг 7.2):
Листинг 7.2. Пошаговое выполнение функции проверки нашей программы в GDB
Breakpoint 1, validate () at /home/ithilgore/Arduino/serial-simple/serial-simple.ino:55
55 |
void validate() { |
|
|
|
|
|
(gdb) display/i $pc |
|
|
|
|
||
1: x/i $pc |
|
|
|
|
|
|
=> 0x800015c <validate()>: push |
{r3, lr} |
|
||||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x0800015e |
|
|
|
|
||
56 |
|
Serial1.println(buf); |
|
|
|
|
3: x/i $pc |
|
|
|
|
|
|
=> 0x800015e <validate()+2>: |
ldr |
r1, [pc, #56] |
; (0x8000198 <validate()+60>) |
|||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x08000160 |
|
|
|
|
||
0x08000160 |
56 |
Serial1.println(buf); |
|
|||
1: x/i $pc |
|
|
|
|
|
|
=> 0x8000160 <validate()+4>: |
ldr |
r0, [pc, #56] |
; (0x800019c <validate()+64>) |
|||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x08000162 |
|
|
|
|
||
0x08000162 |
56 |
Serial1.println(buf); |
|
|||
1: x/i $pc |
|
|
|
|
|
|
=> 0x8000162 <validate()+6>: |
bl |
0x80006e4 <Print::println(char const*)> |
||||
(gdb) next |
|
|
|
|
|
|
halted: PC: 0x080006e4 |
|
|
|
|
||
57 |
|
new_data = false; |
|
|
|
|
1: x/i $pc |
|
|
|
|
|
|
=> 0x8000166 <validate()+10>: |
ldr |
r3, [pc, #56] |
; (0x80001a0 <validate()+68>) |
|||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x08000168 |
|
|
|
|
||
0x08000168 |
57 |
new_data = false; |
|
|||
1: x/i $pc |
|
|
|
|
|
|
=> 0x8000168 <validate()+12>: |
movs r2, #0 |
|
||||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x0800016a |
|
|
|
|
||
59 |
|
if (strcmp(buf, "sock-raw.org") == 0) |
|
|||
1: x/i $pc |
|
|
|
|
|
|
=> 0x800016a <validate()+14>:ldr |
r0, [pc, #44] ; (0x8000198 <validate()+60>) |
|||||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x0800016c |
|
|
|
|
||
0x0800016c |
59 |
if (strcmp(buf, "sock-raw.org") == 0) |
||||
1: x/i $pc |
|
|
|
|
|
|
=> 0x800016c <validate()+16>: |
ldr |
r1, [pc, #52] |
; (0x80001a4 <validate()+72>) |
|||
(gdb) stepi |
|
|
|
|
|
|
halted: PC: 0x0800016e |
|
|
|
|
||
57 |
|
new_data = false; |
|
|
|
|
1: x/i $pc |
|
|
|
|
|
|
=> 0x800016e <validate()+18>: |
strb |
r2, [r3, #0] |
|
|||
224 |
Глава 7 |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
|
|
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|||
P |
|
|
|
|
|
NOW! |
o |
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
||||
|
|
|
|
to |
|
|
|
|
|
(gdb) stepi |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
w Click |
|
|
|
|
|
|
o |
m |
|
|
|
|
||||
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
e halted: PC: 0x08000170 |
|
|
|||||||
|
|
p |
df |
|
|
|
g |
.c |
|
|
|
|
|
|
||
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
59 |
if (strcmp(buf, "sock-raw.org") == 0) |
||||||
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
1: x/i $pc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=> 0x8000170 <validate()+20>: |
bl |
0x8002de8 <strcmp> |
|||
|
|
|
|
|
|
|
|
|
|
|
(gdb) x/s $r0 |
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
0x200008ae <buf>: |
"test123" |
|
|
||
|
|
|
|
|
|
|
|
|
|
|
(gdb) x/s $r1 |
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
0x8003a48: |
"sock-raw.org" |
|
|
|
|
|
|
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 |
|
|
|
|
Последниедве команды GDB (x/s $r0 иx/s $r1 ) отображаютсо- держимоерегистровr0 иr1 ввидестрок.Этирегистрыдолжнысодер- жать два аргумента, переданных функции strcmp() Arduino, потому что, согласно стандарту вызова процедур ARM (APCS), первые четы- ре аргумента любой функции передаются в первые четыре регистра ARM r0, r1, r2, r3. Это означает, что регистры r0 и r1 содержат адреса строки test123 (которую мы указали как пароль) и строку действи- тельного пароля sock-raw.org, для которой выполняется сравнение. Вы можете отобразить все регистры в GDB в любое время, выполнив команду info registers (или,для краткости, i r).
Теперь мы можем обойти аутентификацию несколькими способа- ми. Самый простой способ – установить значение r0 для sock-raw.org прямо перед тем, как выполнение достигнет вызова strcmp(). Вы мо- жете легко сделать это, введя следующую команду GDB:
set $r0="sock-raw.org"
В качестве альтернативы, если бы нам не было известно правиль- ное строковое значение ключевой фразы,мы могли бы обойти аутен- тификацию, обманув программу – заставив ее думать, что strcmp() завершилась успешно. Для этого мы изменим возвращаемое значе- ние strcmp() сразу после его возврата. Обратите внимание, что strcmp() возвращает 0 в случае успеха.
Мы можем изменить возвращаемое значение с помощью команды cbnz, которая предназначена для сравнения и перехода на ненулевое значение. Она проверяет регистр в левом операнде и, если он не ра- вен нулю, выполняет переход (ветвление) к месту назначения, ука- занномувправомоперанде.Вэтомслучаерегистр–r0,ионсодержит возвращаемое значение strcmp():
0x08000170 |
<+20>: |
bl |
0x8002de8 <strcmp> |
0x08000174 |
<+24>: |
cbnz |
r0, 0x8000182 <validate()+38> |
|
|
|
|
Теперь мы перейдем к функции strcmp(), выполнив еще одну команду stepi, когда достигнем ее. Затем мы можем выйти из нее, выполнив команду завершения. Непосредственно перед выполнени- ем команды cbnz изменим значение r0 на 0, что указывает на успеш- ное выполнение strcmp():
Уязвимости портов UART,JTAG и SWD 225