Эксплуатация индустриальных кооперативных роботов

Эксплуатация индустриальных кооперативных роботов

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

Автор: Lucas Apa (@lucasapa)
Традиционные индустриальные роботы довольно скучны, поскольку являются автономными или работают в рамках ограниченных возможностей и выполняют повторяющиеся, запрограммированные задачи на производстве ([1] см. раздел Ссылки). Обычно эти роботы выполняют обязанности, сопряженные с опасностью, и решают задачи, непосильные для рабочих. То есть, этот тип роботов функционирует изолированно от людей и другой более продвинутой техники.

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


Рисунок 1: Робот UR5 от компании Universal Robots [2]


Рисунок 2: Робот Baxter от компании Robotics [3]

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


Рисунок 3: Робот Moley Robotic Kitchen орудует на кухне (две руки UR10) [4]


Рисунок 4: Робот ALIAS от компании DARPA принимает участие в управлении самолетом (рука UR3) [5]

В феврале текущего года я и Сезар Серрудо (Cesar Cerrudo; @cesarcer) опубликовали нетехническую статью под названием «Hacking Robots Before Skynet», которая предшествовала нашим исследованиям роботов, используемых в различных областях (в домашних условиях, в бизнесе и на производстве) от нескольких хорошо известных производителей. В итоге мы обнаружили около 50 критических проблем, связанных с безопасностью. Что касается коботов, то мы проводили аудит моделей Baxter/Sawyer, выпускаемых компанией Rethink Robotics, и UR от компании Universal Robots.

  • В моделях Baxter/Sawyer мы обнаружили проблемы, связанные с аутентификацией, небезопасной доставкой в протоколах, типичные проблемы размещения, уязвимость к физическим атакам и использование фреймворка ROS, который также имеет несколько брешей. Наиболее критичные проблемы, о которых мы сообщили, кажется, были исправлены производителем в феврале 2017 года.
  • В моделях UR мы нашли несколько проблем, связанных с аутентификацией во многих управляющих протоколах, уязвимость к физическими атакам, бреши на базе нарушения целостности памяти и небезопасные коммуникации. Все эти проблемы пока не решены (версия 3.4.2.65 от мая 2017 года).

В соответствии с политикой раскрытия информации об уязвимостях компании IOActive мы связывались производителем в январе. Было достаточно времени для устранения брешей и оповещения клиентов. Наша цель – сделать коботов более безопасными и защищенными от эксплуатации злоумышленниками, чтобы предотвратить серьезные последствия от подобного рода деяний (например, порча окружающего имущества или нанесение вреда рабочим). Я очень надеюсь, что эта статья поможет индустрии кооперативных роботов сделать шаг вперед в направлении выпуска более безопасного поколения роботов.

В этой заметке мы обсудим, как злоумышленник может объединить несколько уязвимостей, присутствующих в коботах UR3, UR5, UR10 от компании Universal Robots, с целью удаленной модификации настроек и нарушения стандартов безопасности, что, как следствие, приводит к порче окружающего имущества посредством перемещения робота в хаотичном режиме.

Этот пример является показательным в плане того, насколько опасны могут быть подобные системы в случае взлома. Манипуляция правилами безопасности и отключение аварийных кнопок может напрямую угрожать человеческой жизни. Представьте, что бы могло произойти, если бы атаке подверглись 64 коботов, как в случае с китайской промышленной корпорацией [7].

Финальный эксплоит использует 6 уязвимостей для изменения ограничений по безопасности, отключения безопасных поверхностей и аварийных кнопок/сенсоров через сеть. В итоге, рука кобота начинает непредсказуемо перемещаться, наводя хаос в окружающем пространстве. На видео демонстрируется пример этой атаки:

Вопрос: Могут ли эти роботы нанести вред человеку?

Ответ: Исследование Лаборатории Роботизации и Управления университета École de technologie supérieure (ÉTS) в Монреале (Канала) наглядно показывает, что даже небольшая по размерам модель UR5 вполне может нанести серьезный вред человеку [8]. Даже на небольших скоростях силы этих коботов вполне достаточно для появления трещин в черепе [9].

Вопрос: Подождите… Разве у этих роботов нет специальных функций, которые предотвращают нанесение вреда находящимся рядом людям?

Ответ: Есть, но, как будет продемонстрировано далее, эти функции могут быть взломаны удаленно.

Вопрос: Где используются подобные роботы?

Ответ: По всему миру в серийных производствах и каждый день [10].

Интеграторы определяют все настройки безопасности

Компания Universal Robots – производитель роботов UR. Компания, которая устанавливает роботов по месту, называется интегратором. Только интегрированные и установленные роботы рассматриваются как решение, готовое к использованию. Интеграторы роботов UR отвечают за то, чтобы любой потенциальный вред от всей роботизированной системы был исключен. Этот комплекс мер включает (но не ограничивается) следующее [11]:

  • Анализ рисков всей системы. Во многих странах эта стадия закреплена на законодательном уровне.
  • Взаимодействие с другим оборудованием и устройствами безопасности, если того требуют результаты оценки рисков.
  • Установка настроек безопасности в приложении Polyscope (управляющая панель).
  • Принятие мер к тому, чтобы пользователь не смог изменить настройки безопасности при помощи «безопасного пароля».
  • Проверка того, что вся система спроектирована и установлена корректно.

В компании Universal Robots признали потенциально опасные и важные факторы риска, которые должны учитываться интеграторами. Например:

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

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

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


Рисунок 5: Использование виртуальных плоскостей [12]

Безопасность ввода/вывода: когда активируется функция безопасности ввода (через аварийные кнопки, сенсоры и т. д.), посылается слабый сигнал на входные выводы, и система безопасности переключается в «дежурный» режим.


Рисунок 6: Сканер безопасности [13]

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

Рисунок 7: Выдержка из руководства пользователя для робота UR

Удаленное изменение настроек безопасности

«Настройки безопасности следует менять только по результатам анализа рисков, который выполняется интегратором [14]. Если любой параметр безопасности изменен, всю роботизированную систему следует рассматривать как новую, и, соответственно, весь процесс проверки безопасности, включая оценку рисков, должен быть обновлен».

Процесс удаленного изменения настроек безопасности состоит из следующих шагов:

Шаг 1. Подтверждение версии удаленной системы посредством эксплуатации проблемы в механизме аутентификации на сервере UR Dashboard Server.
Шаг 2. Эксплуатация переполнения буфера стека в службе UR Modbus TCP и выполнение команд от имени суперпользователя.
Шаг 3. Модификация файла safety.conf, что отменяет все общие ограничения безопасности, ограничения соединений, границ и безопасные значения ввода/вывода.
Шаг 4. Осуществление коллизии при подсчете контрольной суммы и загрузка нового файла. Мы должны подделать этот номер, поскольку интеграторы, скорее всего, сделали запись текущей контрольной суммы на аппаратных средствах (например, жестком диске), так как это наиболее распространенная практика.
Шаг 5. Перезагрузка робота и обновление настроек безопасности из нового файла. Этот процесс должен пройти незаметно.
Шаг 6. Перемещение робота в хаотичной и опасной манере посредством эксплуатации проблемы аутентификации в службе управления роботом UR.

Во время анализа образа прошивки ursys-CB3.1-3.3.4-310.img мне удалось найти входные точки и службы, позволяющие другим машинам в сети взаимодействовать с операционной системой. В этом демо-примере я использовал симулятор URSim, предоставляемый производителем, с настоящим бинарным файлом из образа прошивки робота. Мне удалось создать измененные версии этого бинарного файла для частичного запуска на стандартной Linux-машине даже при том, что этот файл был пригоден для использования в симуляторе вместе с экспериментальной версией эксплоита.

В главном бинарном файле URControl используются различные сетевые службы, и в большинстве собственных протоколов не реализованы сколь-нибудь серьезные механизмы аутентификации. Например, любой пользователь сети может отправить команду к одной из этих служб и получить удаленную версию запущенного процесса (Шаг 1):


Рисунок 8: Получение версии удаленного процесса

Теперь, когда я знаю, что в удаленной системе используется уязвимое ядро ursys-CB3.1-3.3.4-310 (модели роботов UR3, UR5 или UR10), то могу эксплуатировать удаленную службу для компрометирования робота (Шаг 2).
Служба UR Modbus TCP (порт 502) не предоставляет механизмов аутентификации для исходной команды. Таким образом, злоумышленник может переключить робота в такое состояние, которое негативно скажется на контролируемом процессе. Злоумышленник, подсоединившись к роботу через IP-адрес, может выполнять запросы чтения/записи к службе Modbus, чтобы частично изменить состояние робота или отсылать запросы устройствам, управляющим перемещениям для изменения состояния сочленений.

Метод изменения безопасных настроек, связанный с отсылкой запросов на запись к Modbus, не сработал. Однако была найдена уязвимость, связанная с переполнением буфера в стеке получателя службы UR Modbus TCP (внутри основного бинарного файла URControl).

Переполнение буфера в стеке было основано на использовании функции recv, которая использует размер буфера, определяемый пользователем, а конкретно, сколько байтов из сокета будет скопировано. Довольно распространенная проблема.


Рисунок 9: Схема переполнение стека на базе параметра функции recv

Перед переходом к рассмотрению эксплоита, рассмотрим используемые методы защиты. Linux-ядро робота настроено на рандомизацию (randomize_va_space=1 => ASLR) позиций в стеке, странице виртуальных разделяемых динамических объектов и областях разделяемой памяти. Более того, в основном бинарном файле используется бит NX (No eXecute), который не позволяет записывать и выполнять никакие сегменты.

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


Рисунок 10: Указатель edx+0x2c должен быть корректным

На рисунке выше указатель edx+0x2c разыменован и используется в качестве аргумента в вызове 0x82e0c90. Проблема возникает после того, как EBX (вычисленный на базе предыдущего, контролируемого нами, указателя в регистре EDX) должен указывать на структуру, где находится файловый дескриптор, который последствии закрывается.


Рисунок 11: ebx+01014 должен содержать значение 0

Чтобы выбрать статический адрес, удовлетворяющий этим двум требованиям, я выбрал следующую статическую область, поскольку все другие изменяются из-за использования ASLR.


Рисунок 12: Синим цветом подсвечена выбранная статическая область

Я написал несколько скриптов для поиска и нашел подходящий адрес 0x83aa1fc, который удовлетворяет обоим вышеуказанным условиям:

  • 0x83aa1fc+0x2c указывает на корректную область памяти -> 0x831c00a ("INT32").
  • 0x83aa1fc+0x1014 содержит 0 (практически вся эта область содержит нулевые значения).

Теперь, когда удовлетворены оба этих условия, выполнение сможет продолжиться до окончания этой функции, и я получу управление над регистром EIP, поскольку сохраненный регистр в стеке был переполнен:

Рисунок 13: Состояние регистров и указателей при переполнении буфера

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

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

В этом бинарном файле я нашел лишь одну подходящую инструкцию int 0x80, которая используется для запуска системных вызовов. Поскольку гаджет только один, соответственно, я смогу выполнить только один системный вызов. Я выбрал функцию execve. Инструкция int 0x80 требует настройки регистра с номером системного вызова (в нашем случае – EAX со значением 0xb) и регистра (EBX), который будет указывать на специальную структуру). Эта структура содержит массив указателей, указывающих на аргументы выполняемой команды.

Из-за специфики уязвимости я не могу использовать пустые байты (0x00) в запрашиваемом буфере, что представляет собой проблему, поскольку нам нужно отсылать команды и аргументы, а также создать массив указателей, заканчивающийся пустым байтом. Чтобы решить этот вопрос, я временно использовал группы байтов 0xFF, которые затем, во время выполнения ROP, заменил на 0x00.

В псевдокоде этот вызов будет выглядеть так: (вызов обратного TCP-шелла):


Рисунок 14: Аргументы системного вызова execve

Вся контролируемая информация находится в стеке, и вначале я попытался выровнять указатель стека (ESP) относительно наибольшей управляемой секции (STAGE 1). Я разделил самые большие управляемые секции на два участка, поскольку оба могут потенциально содержать множество ROP-гаджетов.


Рисунок 15: Схема стека с разделением на два участка

Как было сказано выше, на данный момент я контролирую регистры EBX и EIP. Далее нужно выровнять ESP относительно любого из управляемых сегментов, и я начал конструировать ROP-цепь.

Следующий гаджет (ROP1 0x8220efa) используется для выравнивания ESP:


Рисунок 16: Добавление первого гаджета для выравнивания ESP

Таким образом, ESP = ESP + EBX – 1 (адрес секции STAGE 1 в стеке). Теперь ESP выровнен относительно секции STAGE 1. Регистр EBX должен уменьшить ESP на 0x137 байт, и я использовал число 0xfffffec9 (4294966985), после добавления которого в ESP устанавливается нужное значение.

Когда у гаджета выполняется инструкция retn, ROP-гаджеты в секции STAGE 1 начинают выполнять свою работу. Участок STAGE 1 работает по следующему алгоритму:

    • Обнуляет окончание структуры с аргументами, чтобы процессор понимал, что на аргументы системного вызова EXECVE ссылаются только три указателя.
    • Сохраняет указатель на первую команду из cmd[] в структуре с аргументами.
    • Переходит к секции STAGE 2, поскольку в первом участке не особо много свободного места.


Рисунок 17: Алгоритм работы секции STAGE 1

Участок STAGE 2 работает по следующему алгоритму:

    • Обнуляет \xff\xff\xff\xff в конце каждого аргумента из массива cmd[].
    • Сохраняет указатель на 2 и 3 аргумент из cmd[] в структуре с аргументами.
    • Подготавливает регистры для выполнение системного вызова EXECVE. Как было сказано ранее, нам нужно, что в регистрах были следующие значения:
  • EBX=*args[]
  • EDX = 0
  • EAX=0xb
    • Вызывает гаджет int 0x80 и выполняет команду с обратным шеллом.


Рисунок 18: Алгоритм работы секции STAGE 2

Как только полезная нагрузка с обратным TCP-шеллом выполнилась, появляется обратное соединение к моему компьютеру. Теперь я могу использовать sudo для запуска команд в системе управления роботом от имени суперпользователя.
Настройки безопасности сохраняются в файле safety.conf (Шаг 3). Компания Universal Robots использует алгоритм CRC (STM-32) для поддержки целостности файла и сохраняет вычисленную контрольную сумму на диске. На самом деле, этот алгоритм не предоставляет никакой целостности настроек, поскольку можно спровоцировать коллизии или вычислить новые контрольные суммы для новых настроек, перезаписав специальные файлы в файловой системе. Я исследовал алгоритм вычисления для каждой настройки и создал альтернативный вариант. На видео я не подменял новое CRC-значение (находится в правом верхнем углу экрана), хотя подобную замену легко можно сделать (Шаг 4).
Перед модификацией настроек безопасности робота я настроил процесс, который по истечении 25 секунд автоматически инициирует новый экземпляр контроллера робота с новыми настройками. Этого времени достаточно для получения, модификации и обратной загрузки файла с настойками безопасности. Команда, показанная на рисунке ниже, инициирует новый процесс URControl. Я использовал Python, поскольку здесь при ответвлении я могу закрыть все текущие дескрипторы файлов запускаемого процесса. Не следует забывать, что я провожу ответвление из объекта обратного шелла, и мне нужно создать новый процесс, который не наследует файловые дескрипторы, поскольку эти дескрипторы закрываются, когда родительский процесс URControl прекращает свое существование (во время перезагрузки и внедрении новых настроек безопасности).


Рисунок 19: Инициация подчиненного процесса с закрытием файловых дескрипторов

Теперь у меня есть 25 секунд для загрузки текущего файла, модификации, вычислении нового CRC, загрузки обратно и прекращение работы процесса URControl (который работает со старой конфигурацией). Для остановки текущего процесса URControl я использую команду kill (Шаг 5).


Рисунок 20: Остановка текущего экземпляра процесса URControl при помощи команды kill

Далее я отсылаю эту команду службе URControl для активации новой загруженной инсталляции, и отключаю все всплывающие окна, которые могут появиться в пользовательском интерфейсе.


Рисунок 21: Команда для загрузки инсталляции с обновленными настройками

Кроме того, злоумышленник может воспользоваться функцией movej, предусмотренной в службе URControl, для удаленного перемещения соединений с нужной скоростью и ускорением (Шаг 6), что показано в конце видео.
В этой статье было продемонстрировано, что новая и дорогая технология имеет много технических уязвимостей, наподобие переполнения буфера, в одном из протоколов, которые позволяют осуществлять удаленные атаки, нарушающих целость всей роботизированной системы. Мы сообщили обо всех брешах производителям еще в январе, но проблемы до сих пор не решены.

Так чего же мы ждем?

Ссылки

  • https://www.robots.com/faq/show/what-is-an-industrial-robot
  • https://www.roboticsbusinessreview.com/manufacturing/cobot-market-boom-lifts-universal-robots-fortunes-2016/
  • http://www.rethinkrobotics.com/blog/humans-and-collaborative-robots-working-together-in-grand-rapids-mi/ 
  • https://www.wired.com/2016/11/darpa-alias-autonomous-aircraft-aurora-sikorsky/
  • https://www.universal-robots.com/how-tos-and-faqs/faq/ur-faq/release-note-software-version-34xx/
  • https://www.youtube.com/watch?v=PtncirKiBXQ&t=1s
  • http://coro.etsmtl.ca/blog/?p=299
  • http://www.forensicmed.co.uk/pathology/head-injury/skull-fracture/
  • https://www.universal-robots.com/case-stories/
  • https://www.universal-robots.com/download/?option=22045#section22032 (UR5 User Manual)
  • https://academy.universal-robots.com
  • https://academy.universal-robots.com
  • Software_Manual_en_US.pdf - Universal Robots
  • https://www.youtube.com/watch?v=G6_LCwu7dOg

Мир сходит с ума, но еще не поздно все исправить. Подпишись на канал SecLabnews и внеси свой вклад в предотвращение киберапокалипсиса!