Скрытая командная оболочка в синтезаторе Yamaha, позволившая выполнить код через MIDI

Анна Антоненко, занимающаяся разработкой встраиваемых систем и в свободное время развивающая операционную систему BOSS (BEAM-based Operating System with Security), опубликовала результаты обратного инжиниринга музыкального синтезатора Yamaha PSR-E433. В ходе проведённой работы в синтезаторе был выявлен обфусцированный shell-интерфейс, позволивший организовать выполнение своего кода на уровне прошивки. Доступ к shell-интерфейсу осуществляется посредством отправки MIDI-пакетов с сообщениями SysEx, которые можно передать при подключении синтезатора через порт USB. Полученные в ходе обратного инжиниринга сведения о чипе и прошивках, а также примеры кода и отладочные дампы размещены на GitHub.

Интерес к обратному инжинирингу возник несколько лет назад, после того как Анна решила почистить внутренности синтезатора от пыли и заодно удовлетворить своё любопытство, связанное с желанием посмотреть начинку устройства. На плате присутствовал чип YAMAHA SWL01U, про который в интернете не удалось найти подробную информацию. Пару месяцев назад Анна натолкнулась на руководство по похожей модели синтезатора, в котором была приведена распиновка этого чипа. Анна вновь разобрала устройство и начала эксперименты, воспользовавшись имевшимися на плате выводами для отладочного интерфейса JTAG и порта UART.

При помощи отладчика OpenOCD, подключения к JTAG и экспериментов было выяснено, что на плате используется чип с процессорным ядром ARM7TDMI. Изучив раскладку памяти в отладчике, удалось выгрузить содержимое прошивок, размещённых в ПЗУ и Flash-памяти. После этого образы прошивок были проанализированы в пакете для обратного инжиниринга Ghidra.

В процессе просмотра выделенных из прошивки строковых данных был замечен набор строк (“help, “info”, “ver”, “logout” и т.п.), напоминающих команды программной оболочки. Изучение указателей на эти строки позволило найти код, вызывающий функции для обработки команд, напоминающий интерфейс входа и командную оболочку. Так же было выявлено, что для активации оболочки предусмотрена команда “login”, в которую необходимо передать пароль “#0000”.

void shell_run_command(char* command_input) { if (shell_login_state == 0) { if (shell_compare_command(command_input, “login”) == 0) { shell_ask_passwd(); // prints “passwd? ” shell_login_state = 1; } } else if (shell_login_state == 1) { if (shell_compare_command(command_input, “#0000”) == 0) { shell_login_ok(); // prints “login OK” shell_login_state = 2; } else { shell_print(“Passwd Errorr”); shell_login_state = 0; } } else { // actually run the command }
}

Дальнейшее изучение прошивки показало, что команды обрабатываются в пакетах, всегда начинающихся с одних и тех же 8 байт данных и заканчивающихся кодом 0xf7. Так как внешнее взаимодействие с синтезатором осуществляется только через MIDI, а в спецификации MIDI предусмотрен специальный служебный тип сообщений SysEx, было предположено, что именно он может использоваться для передачи команд.
Догадку также подкрепляло то, что сообщения SysEx и пакеты, разбираемые оболочкой, начинались с одного кода 0xf0, за которым следовал идентификатор производителя 0x43 (Yamaha).

Для проверки гипотезы был написан Python-скрипт, который транслировал вводимые данные в пакеты протокола MIDI. И метод сработал:

login passwd? #0000 login OK > help logout help ? info ver stack perf-on perf-off perf-disp d dp d xxxxx d/s xxxxx m ADDRESS DATA m/b ADDRESS DATA m/w ADDRESS DATA m/l ADDRESS DATA > info DevelopName PSR-E433 DevelopNumber #3341 Main DevelopNumber #3341 Make data & time MAY 16 2012 19:00:57 J/E Select English >

В подсказке, показанной при отправке команды “help”, среди прочего присутствовали команды для изменения содержимого памяти. При помощи данных команд можно было загрузить произвольный код в память и передать на него управление, подменив указатель в стеке, используемый для возврата после завершения обработки команды. В качестве эксперимента в неиспользуемой области памяти было размещено написанное на ассемблере простейшее приложение, выводящее строку “HeloWrld” в 8-символьный индикатор ЖК-дисплея. Программа была оформлена в виде обычного MIDI-файла, который достаточно было передать на устройство.

После этого началась работа по изучению особенностей вывода графики на ЖК-дисплей, кульминацией которой стала подготовка кода, выводящего произвольное пиксельное содержимое в символьную область, синхронно с воспроизведением видео Bad Apple на внешнем устройстве (видео с демонстрацией).




Release. Ссылка here.