Как исследовать динозавра

  • #Промышленная_экспертиза

О чем материал

Исследуем контроллер Honeywell Experion C300 вместе с Центром промышленной экспертизы Позитива

Центр промышленной экспертизы Позитива занимается защитой производственных объектов от всех видов информационных угроз. Мы разрабатываем комплексные ИБ-продукты, учим наших клиентов ими пользоваться и правильно настраивать инфраструктуру.

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

Бизнесу нужно, чтобы производство не встало и не взлетело на воздух. Исследователю хочется открывать что-то новое и нести эти знания миру. На заводе у них случается идеальный мэтч. Там ИБ-специалист будто попадает на археологические раскопки — только успевай заносить в справочники неизвестные ранее виды рептилий :)

Сегодня мы поделимся опытом исследования промышленного оборудования на примере контроллера Honeywell Experion C300 (см. рис. 1).

Рисунок 1. Honeywell Experion C300

Небольшая справка:

  • Программируемый логический контроллер (ПЛК, он же просто «контроллер») — мозг современного промышленного производства. С одной стороны, собирает с датчиков информацию о технологических процессах. С другой — управляет различными приводами, вентилями и прочими исполнительными устройствами.
  • Honeywell — крупный американский вендор промышленного оборудования.
  • Experion PKS — распределенная система управления (РСУ или DCS).
  • C300 — распространенное и достаточно самобытное семейство контроллеров.

Аппаратный анализ

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

  • процессоры, на которых исполняется прошивка устройства;
  • микросхемы памяти, хранящие данные и прошивку;
  • отладочные интерфейсы, позволяющие делать с устройством гораздо больше, чем внешние разъемы.
Рисунок 2. Контроллер изнутри

Снимаем корпус и видим «бургер» из двух плат, соединенных несколькими технологическими разъемами. Также имеется отдельная платка с текстовым экраном и диодами, которые выводятся на корпус контроллера. Основные аппаратные компоненты отмечены на рис. 3–4.

Рисунок 3. Верхняя плата: 1 — процессор Freescale MPC8270 на архитектуре PowerPC; 2 — программируемая логическая интегральная схема (ПЛИС) Xilinx
Рисунок 4. Нижняя плата: 1 — память NOR с загрузчиком и прошивкой; 2 — память EEPROM с конфигурацией

Анализ прошивки

Мы выпаяли микросхемы памяти и считали ее образ с помощью программатора. Теперь нужно определить, где хранится прошивка и за что отвечают ее части.

В считанном образе находим сразу две прошивки: основную и recovery. На рис. 5 представлены компоненты основной. В recovery же есть только приложение SYS — CDA, CEE и IOL отсутствуют.

Рисунок 5. Компоненты основной прошивки Honeywell C300

Первая и самая очевидная точка интереса — обработчики сетевых протоколов. Если мы поймем их функции и структуры, то узнаем, как устройство «разговаривает». А значит, сможем извлечь полезную информацию из сетевого трафика на заводе. 

Проводим сетевое сканирование и обнаруживаем четыре открытых порта (см. рис. 6).

Рисунок 6. Открытые порты

Мы определили, что на них обрабатываются следующие протоколы:

Порты 55553 и 55554 — CDA. Основной протокол для чтения и записи различных производственных параметров (температура, давление, скорость вращения двигателя и др.). Также используется для обновления конфигурации устройства (то есть того самого алгоритма, который управляет технологическим процессом).

Порт 55565 — EpicMo. Сервисный протокол, служит для обмена диагностической информацией и обновления прошивки контроллера. 

Порт 55555 — FtebCipMsg. Понять точное назначение этого протокола сложно, потому что в текущей реализации он не выполняет существенных функций. По сути, это «протокол-обвертка», инкапсулирующий данные других протоколов (например, того же CDA).

Отладка: часть первая

Следующий шаг — изучение обработчиков каждого протокола. Сначала можно применить статический анализ псевдокода, полученного на выходе декомпилятора. Однако, если алгоритм обработки протокола слишком запутан (как в нашем случае), процесс может затянуться на долгие месяцы. Для ускорения процесса попробуем научиться получать отладочную информацию динамически. 

Это можно сделать разными способами, но, поскольку нас интересует возможность в произвольный момент времени останавливать отлаживаемый процессор и считывать его состояние (регистры, оперативную память и т. д.), попробуем воспользоваться отладочными интерфейсами. На нашем устройстве нашелся один из самых распространенных — JTAG. Доступ к нему можно получить при помощи специального разъема, расположенного на верхней плате.

JTAG — это хардкорный интерфейс, созданный для нужд инженеров, которые производят устройства и микросхемы. Одно из его основных исходных предназначений — тестирование связности различных компонентов, но это гораздо шире необходимой нам отладки. Чтобы не копаться в интерфейсе сверх меры, можно раздобыть ответное устройство-отладчик, поддерживающее целевой процессор. Немного покопавшись в закромах, мы нашли Freescale CodeWarrior TAP. Оно работает в связке с интегрированной средой разработки CodeWarrior IDE, которая предоставляет удобный интерфейс для управления процессом отладки. 

Подключаем отладчик к исследуемой плате и к ноутбуку с установленной IDE (см. рис. 7).

Рисунок 7. Отладочный стенд

Наступает кульминация настройки стенда. Включаем устройство, нажимаем на кнопочку в IDE в надежде увидеть успешный статус и получить возможность отлаживаться. С первого раза не вышло...

Расследование показало: вендор поставляет две версии IDE — 10.5.1 (последняя) и 8.8. Кроме того, есть несколько вариантов отладчика: актуальный CodeWarrior TAP (наш вариант), а также устаревшие CodeWarrior USB TAP и CodeWarrior Ethernet TAP. Старая версия IDE поддерживает нужное семейство процессоров, но не поддерживает отладчик. И наоборот: в новой версии отладчик поддерживается, а процессор — нет.

Погружаемся глубже в устройство IDE и выясняем, что для взаимодействия с отладчиком применяется отдельное приложение CodeWarrior Connection Server (сокращенно — CCS). Причем его можно использовать отдельно от остальной части IDE. 

Рисунок 8. CodeWarrior Connection Server

Для управления отладчиком используется терминал со встроенным интерпретатором языка TCL, который поддерживает набор проприетарных команд. В составе IDE мы нашли примеры таких команд в виде скриптов, соответствующих разным семействам процессоров. Однако документации на сами команды мы не обнаружили, поэтому, помимо прошивки контроллера, пришлось исследовать еще и DLL протокола отладки.

После пары экспериментов мы разработали первичный скрипт для подключения к процессору. Получилось достаточно лаконично (см. рис. 9).

Рисунок 9. Первичный скрипт для подключения к процессору

Отметим, что в дальнейшем мы итеративно расширяли этот скрипт и добавляли в него новые инструкции (например, для остановки процессора или выполнения операций с памятью).

Запуск первичного скрипта мы сочли успешным, но, когда попытались остановить исполнение процессора, контроллер впал в странное состояние: дисплей потух, светодиод замигал красным цветом, сеть перестала работать. Разбираемся дальше…

Отладка: часть вторая

Дальнейшие опыты показали, что после остановки процессор очень малое время остается доступен для отладки и только потом уходит в неактивное состояние. В качестве примера возьмем последовательность команд, которая выполняет остановку исполнения процессора и считывает часть памяти прошивки (см. рис. 10).

Рисунок 10. Последовательность команд эксперимента

При попытке считать участок оперативной памяти с их помощью, получаем следующий результат (см. рис. 11.)

Рисунок 11. Полученный дамп памяти

Видим, что отладчик успел считать некоторую часть памяти (примерно 0xC0 байт), но потом процессор отключился и перестал передавать данные, поэтому конец образа заполнен нулями. Теперь попробуем остановить исполнение процессора и сразу же запустить его с помощью следующих команд (см. рис. 12):

Рисунок 12. Команды для остановки и запуска процессора

В этот раз мы получили совершенно другой результат: контроллер перезагрузился в recovery-образ прошивки и вывел на экран надпись FAIL. Становится все интереснее!

Рисунок 13. Очередной FAIL

Мы предположили, что на устройстве включена функция Watchdog (или Watchdog Timer). Это механизм, который отлавливает зависания процессора и при необходимости перезагружает его, чтобы дать программе еще один шанс корректно исполниться от начала до конца. Отладочная остановка процессора как раз может трактоваться как такое зависание.

Один из способов реализации Watchdog — отдельный аппаратный модуль, встроенный прямо в процессор. Как правило, такой модуль можно включить или выключить с помощью специального регистра. В документации на наш процессор он есть (см. рис. 14).

Рисунок 14. Регистр для включения и отключения Watchdog

Мы считали этот регистр за доступное нам время между остановкой процессора и его отключением. Оказалось, в нашем устройстве данный аппаратный механизм не используется...

Поиски причин необычного поведения устройства мы решили продолжить… в официальной документации на контроллер. Иногда помогает :) Там мы обнаружили следующие строки, которые буквально описывают странное состояние нашего устройства после попытки прочитать память (см. рис. 15.1–15.2). 

Рисунок 15.1. Описание странного состояния контроллера
Рисунок 15.2. Что мы узнали о Watchdog

Итак, что нам известно на данный момент: 

  • У контроллера есть два Watchdog — программный и аппаратный. Оба взаимодействуют с некой отдельной «аппаратной схемой».
  • Программный Watchdog срабатывает, когда тайм-аут на сброс таймера превышает предустановленное значение на относительно небольшую величину. В этом случае ПЛК перезагружается в recovery-образ прошивки и выводит на экран строку FAIL. От пользователя требуется заново перезагрузить контроллер в основной образ.
  • Аппаратный Watchdog срабатывает, когда тайм-аут на сброс таймера значительно превышает предустановленное значение либо таймер вовсе не сброшен. В результате получаем потухший дисплей. 

Симптомы ясны — теперь нужно точно определить причины и попытаться их устранить. Раз при «мягком» срабатывании таймера устройство перезагружается в recovery-образ, попробуем найти в коде ссылки на места, которые точно исполняются при такой загрузке. Практически для любого процессора в составе любого устройства любая загрузка — это повод передать управление обработчику RESET-прерывания. Причем неважно, в какой момент она происходит: когда достали устройство с чердака и подключили к батарейке или после того, как дернули специальную ножку на микросхеме. 

Практика вызывать обработчик RESET-прерывания чисто программными средствами, при помощи инструкций передачи управления, тоже существует. В нашей прошивке обработчик вызывается в функции, в которой, судя по строке, проверяется тайм-аут Watchdog-таймера (см. рис. 16).

Рисунок 16. Функция, в которой проверяется тайм-аут Watchdog-таймера

Попробуем пропатчить эту функцию так, чтобы она всегда считала таймер сброшенным вовремя. Сделаем это при помощи еще одного TCL-скрипта. Действовать будем в момент загрузки устройства, когда прошивка скопирована в оперативную память и ее целостность проверена, но Watchdog еще не включен.

Рисунок 17. TCL-скрипт с патчем

С программным Watchdog’ом разобрались! А что насчет аппаратного? В документации упоминается некая «аппаратная схема» — пора вернуться к печатной плате и найти ее. При первоначальном анализе мы отметили микросхему ПЛИС Xilinx: а что, если это она перезагружает процессор снаружи при превышении тайм-аута? Мы сняли слой лака с тестовых площадок выводов процессора и стали прозванивать их мультиметром попарно с ножками ПЛИС. 

Рисунок 18. Прозвон

Мы подключили к выводам логический анализатор, воспроизвели эксперимент с остановкой процессора при помощи отладчика и… увидели, как ПЛИС (которую теперь правильнее будет называть «Hardware Watchdog») подтягивает выводы HRESET и SRESET к земле! В результате процессор оказывается в состоянии сброса и не может выполнять никаких инструкций — соответственно, не может быть отлажен.

Значит, нужно всеми силами помешать микросхеме ПЛИС выключать процессор. Дешевый и сердитый способ — отпаять соответствующие ножки и приподнять их над контактными площадками (см. рис. 19).

Рисунок 19. Подняли ножки ПЛИС

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

Дело в том, что мы не знаем назначения всех ножек микросхемы ПЛИС. В силу плотной компоновки платы прозванивать их все попросту нецелесообразно. Вероятно, упомянутые ножки сброса — не единственный интерфейс между ПЛИС и процессором, но обработка других способов коммуникации должна быть уже программной, а не аппаратной. 

Выходит, ранее сделанного патча недостаточно, но мы можем развить эту методику. Кандидатов на патч будем искать по ссылкам на строки, в которых упоминается слово «Watchdog» или что-то похожее. К счастью, нам хватило буквально одного патча (см. рис. 20).

Рисунок 20. Что еще пришлось пропатчить

Точки останова

Итак, теперь мы можем свободно останавливать процессор, считывать его состояние и возвращать к выполнению кода. Однако для полноценной отладки нужно уметь останавливать его в момент исполнения конкретной инструкции по определенному адресу. Точно угадать момент и сделать это по нажатию клавиши на клавиатуре невозможно. Эта задача решается с помощью точек останова — брейк-пойнтов.

Они бывают двух типов — аппаратные и программные (прямо как наши Watchdog’и). Для использования первых нужно записать адрес остановки в специальный регистр. Во втором случае — заменить инструкцию в памяти по интересующему адресу на специальную инструкцию остановки. Оба механизма реализуются с помощью прерываний: в момент, когда исполнение дойдет до нужного адреса, оно будет прервано и управление перехватит соответствующий обработчик. Обработчика прерываний на аппаратные брейк-пойнты у нас нет, поэтому воспользуемся программными. 

В архитектуре PowerPC специальная инструкция остановки называется trap. Мы поставили ее в интересующее нас место обработчика сетевого пакета, отправили пакет — и контроллер снова перезагрузился в recovery-образ. Опять идем расследовать, что пошло не так… 

Оказывается, обработчик прерывания Program Exception, который отвечает за программные брейк-пойнты, также обрабатывает ряд других ситуаций. Например, невалидные и привилегированные инструкции. Далее мы обнаружили, что на механизме обработки невалидных инструкций построен еще один интересный механизм — так называемые программные инструкции. Суть в следующем: когда процессор натыкается на инструкцию, которую не может декодировать, он передает управление в обработчик Program Exception. Внутри него на основании числового кода инструкции выбирается соответствующее действие. Например, в нашем случае при попытке выполнить инструкцию с числовым кодом 3 управление передается по адресу, указанному сразу после инструкции (см. рис. 21).

Рисунок 21. Та самая инструкция с числовым кодом 3

Проанализировав код обработчика, мы обнаружили, что в прошивке Honeywell Experion C300 роль trap выполняет инструкция с кодом 0xFFFF. 

Наконец, после всех мытарств, у нас есть отладка! 

***

Мы рассказали, как взяли американский промышленный контроллер, притащили его в лабу и рассмотрели со всех возможных ракурсов. Теперь мы знаем, как он устроен, какие там есть протоколы, умеем его отлаживать, а еще собрали ряд забавных и, на первый взгляд, бесполезных фактов :) И что в итоге? 

  • Теперь ИБ-продукты Позитива умеют неплохо понимать это оборудование, а иногда даже самостоятельно с ним общаться.
  • Мы обнаружили уязвимости и оказали вендору посильную помощь в их исправлении, а значит, сделали мир чуточку лучше :). Подробнее об этой грани нашей работы смотрите здесь.

Мы дěлаем Positive Research → для ИБ-экспертов, бизнеса и всех, кто интересуется ✽ {кибербезопасностью}