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

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

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

CFD0C5CECEC5D4_1736148820.jpg

При помощи отладчика 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 Error\r");
            shell_login_state = 0;
        }
    } else {
        // actually run the command
    }
}

Дальнейшее изучение прошивки показало, что команды обрабатываются в пакетах, всегда начинающихся с одних и тех же 8 байт данных и заканчивающихся кодом 0xf7. Так как внешнее взаимодействие с синтезатором осуществляется только через MIDI, а в спецификации MIDI предусмотрен специальный служебный тип сообщений SysEx, было предположено, что именно он может использоваться для передачи команд. Догадку также подкрепляло то, что сообщения SysEx и пакеты, разбираемые оболочкой, начинались с одного кода 0xf0, за которым следовал идентификатор производителя 0×43 (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-файла, который достаточно было передать на устройство.

CFD0C5CECEC5D4_1736151295.jpg

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

CFD0C5CECEC5D4_1736151618.jpg





Источник: http://www.opennet.ru/opennews/art.shtml? num=62516

©  OpenNet