Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2

в 12:48, , рубрики: ida pro, stm32, Блог компании ИНФОРИОН, информационная безопасность, реверс-инжиниринг, скрытые возможности

Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 1
Представляем вашему вниманию вторую часть статьи о реверс-инжиниринге прошивки устройства «Мигающий носорог» по мотивам мастер-класса на конференции SMARTRHINO-2018.

В первой части статьи прошивка устройства была загружена в дизассемблер IDA и выполнен первичный анализ команд протокола устройства. Отдельные команды были проверены на работающем устройстве.

Во второй части будет выполнен анализ оставшихся тасков прошивки.

Напомню, после анализа Bluetooth-таска в части управления светодиодами, было решено переключиться на LED-таск, так как исходная задача – создать приложение для управления светодиодами, а для этого необходимо детальное понимание работы прошивки.

Файл прошивки доступен для самостоятельного изучения.

Вся информация проводится исключительно в образовательных целях.

Под катом много мигающего носорога.

LED-таск

Кратко: полный разбор таска, отвечающего за переключение светодиодов. Анализ типов данных и глобальных переменных.

LED-таск представлен функцией x_leds_task, расположенной по адресу 0x08005A08.

Помимо странных строк «I've got a super power… » в основной функции LED-таска можно обратить внимание на строку «hue > max: change shinern».
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 2

При этом видим знакомую ситуацию – (WORD *)(v26 + 4). В контекстном меню переменной v26 выбираем пункт «Convert to struct *», затем указываем созданную ранее структуру:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 3

С учётом, что v5 = v26, повторяем операцию «Convert to struct *» для переменной v5.

Продолжаем структурировать код и данные. Устанавливаем везде hex-представление. Переименовываем:

  • v5 — led;
  • v6 — idx;
  • v8 — hue_1;
  • v9 — hue_2;
  • v26 — _led;

Код улучшается. Но некоторые переменные всё ещё режут глаз, например, переменная v23:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 4

Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 5

По всей видимости, v23 - это массив из 4 байт.

idx – это индекс светодиода; этот индекс добавляется к базовому адресу; таким образом обращение ведется к элементам по одинаковым смещениям – так ведут себя массивы.

Назначаем тип char v23[4] и переименовываем в leds_smth, код становится симпатичнее:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 6

Можно также обратить внимание, что результат работы функции x_queue_recv возвращается в переменную v25:

x_queue_recv(&v25, leds_queue, 1000);

Но может быть непонятно, как нужные данные оказываются в структуре _led. Дело в том, что переменные v25 и _led расположены рядом в стеке — это можно понять по тому, что в декомпиле они написаны на соседних строках. Расположение переменных на стеке можно увидеть в отдельном окне, если дважды кликнуть на переменной:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 7

Вероятно, они представляют собой структуру или же компилятор провёл оптимизацию. Таким образом, можно утверждать, что данные из Bluetooth-таска передаются в LED-таск. Чтобы узнать точнее, я выполню проверку на устройстве – для нулевого светодиода по Bluetooth отправлю значения 0x208, 0x2D0, 0x398, 0x3E9, которые можно было заметить в коде:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 8

Результаты проверки значения hue (оттенок) на устройстве:

  • 0x208 – светодиоды перестали плавно переключаться и установились в цвета: красный, зеленый, синий, фиолетовый;
  • 0x2D0 – светодиоды стали снова переключаться;
  • 0x398 – ничего не изменилось;
  • 0x3E9 – ничего не изменилось.

Если снова посмотреть на код, то можно увидеть, что значение 0x398 может быть логически связано со значением меньше, чем 0x167 (устанавливаются разные значения для элемента массива leds_smth). Поэтому выполню такую проверку: сначала установлю первый светодиод в зелёный цвет (hue=0x78, команда LED 010078FF20), при этом три других светодиода продолжают переключать свои цвета.
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 9
Теперь выполню команду Bluetooth-протокола LED 010398FFFF – после этого первый светодиод перешёл в общий режим переключения цвета.

Таким образом, значение hue 0x398 сбрасывает статическое значение цвета, а это означает, что массив leds_smth содержит флаги (0 или 1) занятости светодиодов:

  • 0 – светодиод не занят, участвует в плавном переключении цветов (hue = 0x398);
  • 1 – светодиод занят, пользователь установил статический цвет (hue <= 0x167).

Переименуем leds_smth в leds_busy.

Теперь должно стать понятно назначение следующего блока кода:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 10

Цикл в строках 83-101 осуществляет плавную цветную мозаику с шагом переключения цвета, равным 5: v12 += 5. В случае, если на светодиоде включен статический цвет, то этот светодиод не участвует в мозаике. После цикла идут строки кратковременного включения всех светодиодов.

Переименуем:

  • sub_800678A — x_led_set_hsv;
  • v12 — hue_step;
  • v13, v17, v18, v19 — led0_busy, led1_busy, led2_busy, led3_busy;
  • v11, v20, v21, v22 — hue0, hue1, hue2, hue3;
  • dword_200004C4 — led_control.

Функция sub_80039FE предположительно выполняет таймаут (иначе светодиоды переключались не плавно, а моментально), назовём её x_sleep, а переменную v16 – led_timeout.

Назначение функции sub_8006934 пока неочевидно, но она используется везде после установки цвета на светодиодах – можно назвать ее x_led_fix_color.

После этих переименований легко понять функцию sub_8006944 (вызывается в ветке «hue <= 0x167»):
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 11
Здесь просто выполняется дополнительная проверка для установления цвета светодиода. Переименуем функцию sub_8006944 в x_led_set_hsv_wrap (суффикс _wrap — пояснение, что это «обёртка» над другой функцией) и установим для неё следующий прототип:

signed int __fastcall x_led_set_hsv_wrap(int led_control, signed int idx, int hue, char sat, char val)

Вернёмся на уровень выше к функции x_leds_task. Ещё раз посмотрев на код, можно обнаружить, что ветка «hue > 0x3E8» стала выглядеть так:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 12

То есть значение hue больше 0x3E8 должно менять таймаут цветной мозаики. Проверю, отправив на устройство некоторые значения:

  • hue = 0x3E9 – светодиоды стали переключаться быстро:
    Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 13
  • hue = 0xFFFF – светодиоды стали переключаться очень медленно:
    Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 14

При выходе из основного цикла LED-таска используется функция sub_8003C44, которая также используется в функции sub_8005070:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 15

Переименуем:

  • sub_8005070 — x_freeMsg;
  • sub_8003C44 — x_free_queue.

Далее в LED-таске не может не обратить на себя внимание следующая ветка:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 16
Можно попробовать выполнить команду LED B816D8D90000FFFF. Но если вспомнить, что в качестве индекса светодиода берется всего 2 символа, попытка достичь данного кода будет заведомо неудачной. Оставим эту ветку «на потом». Функцию sub_8004AE8 переименую в x_mad_blinking, а также пришло время исправить сигнатуру функции x_printf (в прошлый раз записал неправильную сигнатуру):

void x_printf(const char *format, ...)

Основной цикл LED-таска разобран, но есть еще код в самом начале таска.

Посмотрим на код:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 17
В строке 49, по всей видимости, проверяется доступность светодиодов и, в случае ошибки, происходит обращение к функции sub_8004BBС, которая выключает прерывания и запускает бесконечный цикл, в котором используется строка «../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c». Скорее всего, это assert или аналогичная функция.

Переименуем:

  • sub_8004BBC — x_gpio_assert;
  • sub_800698C — x_check_gpio.

Назначение функции sub_8006968 станет понятно, если внимательно посмотреть на устройство при включении:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 18
Все четыре светодиода вместе включаются сначала красным, потом зелёным, потом синим. После этого устанавливаются по цветам: 0-красный, 1-зеленый, 2-синий, 3-фиолетовый. И только потом начинают переключаться мозаикой.

Поскольку мозаика запускается в основном цикле таска, то логично, что строки 58-61 перед главным циклом отвечают за кратковременное включение разных цветов на светодиодах, а строки 52-56 – за установку красного-зелёного-синего на всех светодиодах сразу. Переименуем функцию sub_8006968 в x_led_all_set_rgb (RGB – чисто по наитию, по передаваемым аргументам).

Странности в LED-таске

Кратко: определение функциональности кода, содержащего странные строки. Формирование пароля для устройства.

Теперь перейдём к самому началу функции x_leds_task:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 19

«eraze», «gen», «flash», «reset» – зачем это всё???

Попробуем разобраться.

Пусть sub_80066BC будет x_leds_task_init.

Посмотрим на sub_8006B38:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 20

Чистой воды memset, согласны?
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 21

Вернёмся к x_leds_task. Что-то не так с типом переменной v24:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 22
IDA немного ошиблась с типом, но комментарий с отметкой стека нам помогает. Между переменными v24 и v25 целых 12 байт (0x44 – 0x38). Поэтому v24 переименовываем в buf и назначаем тип unsigned __int8 buf[12] (Ида предупредит, что новый тип данных больше старого – соглашаемся).

Далее. Функция sub_8004CE4:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 23
Переименовываем а1 в buf, v1 в _buf.

Функция sub_8006B26:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 24
Узнали её?

А если без грима?

Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 25
Конечно, memcpy. Переименовываем.

Тогда назначение функции sub_8004CE4 состоит в получении каких-то данных по адресу 0x08007C00. Между прочим, этот адрес лежит в диапазоне адресов флэш-памяти микроконтроллера (и прошивки, в частности). Переименуем sub_8004CE4 в x_read_data_0x08007C00.

Функция x_leds_task, строка 36:

if ( (unsigned int)buf[0] - 65 > 0x19 )

Изменим отображение данных (клавиша R на числе 65, клавиша H на числе 0x19):

if ( (unsigned int)buf[0] - 'A' > 25 )

Немного поразмыслив, можно понять, что это такая проверка диапазона латиницы A-Z.

Далее, пользуясь подсказками в виде форматных строк, переименовываем:

  • sub_8004C10 — x_erase;
  • sub_80059C8 — x_gen;
  • sub_8004C84 — x_flash.

Функция sub_8003C66 не делает ничего примечательного – только увеличивает некоторую глобальную переменную – переименуем sub_8003C66 в x_smth_inc.

Функция x_erase на самом деле не принимает никаких аргументов – в этом можно убедиться в дизассемблере:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 26

Внутри x_erase используется знакомый нам адрес 0x08007C00 и происходит обращение к трём неизвестным функциям:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 27

Бегло просмотрев эти три функции, увидим, что в них происходит обращение к адресам в диапазоне 0x40022000 — 0x400223FF. Документация на микроконтроллер совершенно четко говорит, что это диапазон «FLASH Interface». То есть функция x_erase стирает кусочек флэш-памяти — прекрасно!

По всей видимости, функция x_flash выполняет запись во флэш-память, предварительно проверив длину строки для записи (кстати, аргументы a2 и a3 тут лишние – поможем Иде):
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 28

И это всё происходит в «осветительном приборе»???

Хорошо, а что там с функцией x_gen? После беглого взора и переименования переменных она будет иметь такой вид:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 29

При этом функция sub_8006CB4 выглядит вот так:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 30

А sub_8006D10 – вот так:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 31
Не сдерживайте желание выполнить поиск в интернете этих неприлично-красивых констант: 0xABCD, 0x1234, 0xE66D, 0xDEEC, 0x4C957F2D и 0x5851F42D. Если интернет еще не полностью запрещён, наверняка Вы найдёте эти константы в исходниках на random-функции. Не зря родительская функция называется x_gen.

Тут тоже весьма типичная ситуация: перед циклом вызвать srand(), а в цикле вызывать random(), поэтому переименуем:

  • sub_8006D10 — x_rand;
  • sub_8006CB4 — x_srand.

Пытливый читатель, заглянув в функцию sub_8005098, сможет узнать, откуда берется seed для функции srand.

Таким образом, функция x_gen формирует случайную строку, указанного размера.

После того, как сгенерированная строка записывается во флэш-память, происходит перезагрузка устройства:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 32
Кажется, какая-то странная перезагрузка. Но если мы посмотрим на список тасков данного устройства, то обнаружим среди них «watchdogTask». Очевидно, при наличии «зависшего таска» watchdog выполняет перезагрузку.

LED-таск кроме режима MadBlinking можно считать проанализированным.

Посмотрим через строки, какие еще таски есть в системе:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 33

Восстановив в коде ссылки на строки, можно увидеть вот такую картину:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 34

Сначала идёт ссылка на строку с именем таска, потом ссылка на основную функцию таска. А используются они в функции main, где и происходит запуск этих тасков:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 35

Выполним недостающие переименования:

  • sub_80050FC — x_sensor_task;
  • sub_8004AAC — x_watchdogTask;
  • sub_8005440 — x_uartRxTask.

Watchdog-таск

Таск watchdog’а не делает ничего особенно интересного:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 36
Переименуем:

  • dword_200003F8 — wd_variable;
  • sub_8001050 — x_update_wd_var.

UART-таск

Кратко: поиск данных и функций, имеющих ссылки из разных функций. Определение их назначения.

Беглый просмотр UART-таска позволяет обнаружить отправку данных в неизвестную пока очередь, определяемую переменной unk_200003EC:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 37

Восстановив ссылки на эту переменную через бинарный поиск, увидим, что помимо x_uartRxTask она используется в main’е (там очередь создаётся, по всей видимости) и в неизвестной пока функции sub_80051EC:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 38

Переименуем:

  • sub_80051EC — x_recvMsg_uart_queue;
  • unk_200003EC — uart_queue.

Смотрим кросс-ссылки на x_recvMsg_uart_queue:

  • sub_8005250;
  • x_bluetooth_task.

Посмотрим сначала функцию sub_8005250:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 39

Подумав, переименуем:

  • unk_2000034C — cmd_count;
  • a1 — cmd;
  • v4 — _cmd;
  • v6 — rsp;
  • sub_8005250 — x_bluetooth_cmd.

Посмотрим теперь, где ещё используется x_bluetooth_cmd. Все дополнительные ссылки только из Bluetooth-таска, самое время к нему вернуться.

Вернёмся к Bluetooth-таску

Кратко: окончательный разбор Bluetooth-таска. Поиск возможности авторизации без пароля.

Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 40

Если посмотреть места, в которых используется функция sub_8006A84, а еще не полениться и заглянуть в её недра, то не останется сомнений – это calloc. Оно и логично – чтобы получать данные в буфер, надо этот буфер сначала создать.

Теперь sub_8006DBC. Посмотрим на неё (переменные уже переименованы):
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 41
Припомнив функции стандартной библиотеки С для работы со строками, увидим здесь strstr (поиск подстроки) и смело переименуем её.

Пройдемся по коду функции x_bluetooth_task – возможно с последнего посещения здесь что-то изменилось. По ходу именуем переменные:

  • v2 — _state;
  • v3 — data_len.

Тут же рядом есть функция sub_80052E2. По аналогии с функциями, вытаскивающими числа из Bluetooth-команды, она вытаскивает строку указанной длины — назовём ее x_get_str.

Продолжаем:

  • v26 — isEcho;
  • v6 — meow_str;
  • v10 — uart_cmd_byte;
  • v11 — uart_cmd_str;
  • v12 — str_0;
  • v13 — str_1;
  • v14 — format_str;
  • sub_8000F5C — x_blink_small_led.

Закончим с беглым переименованием:

  • v19 — password; (так как рядом строки про авторизацию и пароль)
  • sub_8004CC0 — x_check_password;
  • sub_8006AF4 — x_free (так как password, cmd и bt_args являются указателями на динамические объекты (проверьте это!), то память должна освобождаться после их использования);
  • sub_8006DAC — x_strcpy (проверьте это!).

Теперь исследуем ветки READ, WRIT, AUTP, SETP.

Как показала проверка на работающем устройстве, для команд READ, WRIT, SETP необходима авторизация. Попытка авторизации командой AUTP приводит нас в функцию x_check_password для проверки пароля:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 42
Получается, что длина пароля должна быть 8 символов и пароль сравнивается (в функции sub_8006B08) с байтами по адресу 0x08007C00 – где хранится сгенерированная строка случайных символов A-Z.

Получается, не зная пароля, мы не можем авторизоваться на устройстве. Ну или почти не можем…

Обратим внимание на то, где используется переменная auth_flag:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 43

Оказывается, она используется не только в Bluetooth-таске. А вот в Sensor-таск мы как раз еще не заглядывали. Идём туда.

Sensor-task

Кратко: что делает сенсорная кнопка?

В соответствии с лучшими практиками программирования вся функция Sensor-таска умещается в один IDA-экран. И это не может не радовать:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 44

Строки-строки…

  • «TSC %drn» — эта строка должна заставить задуматься про Touch sensing controller для микроконтроллеров STM32;
  • «AUTH BTNrn» — кнопка авторизации???
  • «SET AUTH %drn» — установка флага авторизации?

Посмотрим, как будет вести себя устройство, если нажимать сенсорную кнопку (все же поняли, что у носорога на ноге сенсорная кнопка?):
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 45

При кратковременном нажатии загорается красный небольшой светодиод. При длительном нажатии этот светодиод включается на продолжительное время.

Если соотнести это с кодом, то можно сделать предположение, что функция sub_8000708 – это функция получения текущего времени. Тогда, если разница между текущим временем и началом касания сенсора больше, чем 1000 (1 секунда), то светодиод включается на 0xEA60 милисекунд (1 минута). Но больший интерес представляет переменная auth_flag, которая устанавливается в 1 при длительном нажатии на сенсорную кнопку, открывая доступ злоумышленнику администратору «осветительного прибора» к привилегированным функциям.

Таким образом, проведя авторизацию «по кнопке» можно прочитать пароль, хранящийся в устройстве (команда READ), выполнить запись в ОЗУ (функция WRIT) или установить новый пароль (SETP).

Mad Blinking

Кратко: может ли быть выполнена странная ветка кода «Mad Blinking»?

Вернёмся к Bluetooth-таску и выполним еще несколько переименований.

  • v21 — vip_smth (пока непонятно, что там);
  • v22 — vip_str (строка неизвестного размера, извлекаемая из аргументов);
  • v23 — mad_led — назначаем «Convert to struct *» и указываем struct_LED.

И тут видим число 0xB816D8D9 (оно встречалось в первой части статьи в Bluetooth-таске) в качестве индекса светодиода. Этот код будет выполнен, если выполнится проверка:

if ( sub_8005520(vip_str, vip_smth) == 0x46F70674 )

Переименуем sub_8005520 в x_vip_check и заглянем в неё:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 46

Учитывая, что первый аргумент – это строка (по крайней мере, строка передается в эту функцию), то по данному коду получается, что второй аргумент – длина этой строки (или длина, которая должна быть обработана). Переименуем:

  • a1 — str;
  • a2 — len.

Посмотрим на функцию sub_8000254:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 47

А теперь заглянем в sub_8000148. Вот её начало:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 48

Это только треть функции… Мммм… Вкусняшка! Опытный копатель без труда увидит здесь...

Что?

операцию целочисленного деления.

Как это можно раскопать?

Если приложить усилия, то от функции sub_8000254 можно добраться до x_printf (через несколько других функций). В этом месте стоит сделать важное замечание – обычно все стандартные функции достаточно стандартны. Это значит, что можно попробовать найти в открытом доступе хоть какой-нибудь исходный код исследуемой функции, чтобы исследование было более продуктивным.

Итак, берём исходник printf, далее смотрим vfprintf, сопоставляя её с кодом исследуемой прошивки. По исходному коду выходим на функцию itoa и делаем вывод, что функция sub_8000254 – это оператор оператор % (взятие остатка от деления), а эта страшная длинная функция ни что иное, как взятие целой части от деления (операция div).

Может возникнуть вполне законный вопрос – почему так? Дело в том, что операций DIV, MOD может не быть в конкретном микроконтроллере, поэтому компилятор вместо этих операторов подставляет вызов отдельных функций. Кстати, вот ещё какие бывают математические функции.

Не забываем выполнять переименования по ходу копания.

Таким образом, функция x_vip_check, вычисляет… А это и будет вашим домашним заданием.

Кстати, если выполнить правильную команду VIP , получим «носорога на дискотеке»:
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 2 - 49

Краткий отчет по прошивке

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

  1. Bluetooth-таск. Обрабатывает команды, приходящие в текстовом виде по Bluetooth.
  2. LED-таск. Управляет цветными светодиодами в соответствии с Bluetooth-командами.
  3. Sensor-таск. Включает красный светодиод, позволяет выполнить кратковременную авторизацию без пароля на устройстве.
  4. UART-таск. Позволяет взаимодействовать с Bluetooth-модулем по внутреннему UART-порту (используется для инициализации Bluetooth).
  5. Watchdog-таск. Отслеживает зависание тасков.

При исследовании не учитывалась возможность читать данные из UART-порта (контакты Tx/GND).

Итоги

В ходе мастер-класса на конференции была разобрана только основная функциональность управления светодиодами. Самым активным участникам были подарены их подопытные «носороги».

На мой взгляд, из «носорога» получился достойный макет для учебного курса по обратной разработке и поиску уязвимостей. Особенностью макета может быть возможность менять прошивку сколько угодно раз, для каждого курса – своя прошивка. В отличие от разбора исполняемого файла, реверс прошивки позволяет лучше понять:

  • как работать с IDA;
  • принципы взаимодействия прошивки с устройством;
  • принципы работы RTOS.

Большое спасибо всем дочитавшим до конца!

Автор: prusanov

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js