В 2019 году мы обнаружили в интернете магазин, распространяющий программное обеспечение для тяжёлых промышленных машин. Мы скачали некоторые из этих приложений и провели их реверс-инжиниринг, чтобы понять, как они работают. Их код был написан на одном из проприетарных языков программирования, использовавшихся для автоматизации промышленных роботов, которые собирают автомобили и упаковывают пищевые продукты на конвейерах. В одном из этих приложений обнаружилась уязвимость, с которой и началось наше исследование Rogue Automation: Vulnerable and Malicious Code in Industrial Programming.
Изучив технические детали и слабые места восьми наиболее популярных сред промышленного программирования (ABB, Comau, Denso, Fanuc, Kawasaki, Kuka, Mitsubishi и Universal Robots), мы выяснили, что эти языки можно использовать для создания вредоносов-червей, которые будут перемещаться с одного уязвимого робота на другой, подчиняясь дистанционным командам своих операторов.
Обнаруженные недостатки — результат выбора дизайна, созданного несколько десятилетий назад. Эти решения определили технологию, методы и инструменты, которые до сих пор используются для программирования промышленного оборудования. Рассмотрим последствия такого выбора в контексте современных киберугроз.
Кража данных у робота
Мы обнаружили реальный случай уязвимого веб-сервера, реализованного в виде приложения для запуска на промышленном роботе. Веб-сервер, написанный на языке ABB Rapid, содержал уязвимость обхода путей, которая позволяла злоумышленнику подключиться к роботу по сети и копировать любые файлы с контроллера робота, включая журналы работы. Такие файлы с большой вероятностью содержат различные конфиденциальные данные и ноу-хау, поэтому их можно выгодно реализовать на подпольных рынках.
Если злоумышленнику удастся взломать компьютер в той же сети, что и робот, он сможет подключиться к веб-серверу контроллера под видом агента, запросить интересующий его файл и получить его без авторизации, поскольку программа выполняет любые запросы от агента.
Фрагмент кода уязвимого приложения. Источник (здесь и далее, если не указано иное): Trend Micro
В строке 493 вызывается функция sendFile для отправки запрошенного файла клиенту. Строка pageString никак не фильтруется, поэтому может содержать «.../» или другой путь. Это позволяет выполнить обход файловой системы и скачать практически любой файл.
Схема эксплуатации уязвимости
Примечательным в этом случае оказался комментарий, оставленный разработчиком уязвимого веб-сервера в коде. Он знал о том, что написанный им код уязвим, но не сделал ничего для устранения проблемы, потому что предполагал, что все запросы будут поступать от «правильного» браузера, который будет проверять вводимые данные и не допустит передачи в обработчик строки типа «...\\...\\»:
Фрагмент кода с комментарием разработчика о том, что санитизацию данных должен выполнять браузер
Подмена команд роботу по сети
Эксплуатация некоторых уязвимостей может привести к последствиям в физическом мире, например, причинить вред готовым изделиям или даже окружающим людям.
В open-source проекте для промышленных роботов Kuka мы обнаружили уязвимость, которая позволяет изменить траекторию движения подвижной части. Программа получает поток координат по сети и передаёт их исполнительному механизму, который выполняет заданные перемещения. Для этого используется специальный класс процедур — серверы автоматизации движения. Это стандартный интерфейс, который позволяет OEM-производителям промышленных роботов обеспечить единый способ управления перемещением их изделий.
Уязвимый код сервера автоматизации движения не содержит никаких проверок на легитимность переданных ему данных
Код сервера никак не проверяет, откуда поступила очередная порция координат для перемещения робота, в нём не предусмотрена внутренняя аутентификация. Единственной защитой является проверка MAC-адреса и IP-адреса отправителя, любой из которых может быть с лёгкостью подделан проникшим в сеть злоумышленником.
На нашем лабораторном стенде мы убедились, что, используя спуфинг, можно фальсифицировать трафик между роботом и инженерной рабочей станцией. Злоумышленник мог посылать произвольные координаты, а робот просто выполнял их, что на реальном производстве привело бы к несчастному случаю.
Внедряя в трафик сетевые пакеты с неверными координатами, мы смогли несколько раз вытолкнуть манипулятор за пределы зоны безопасности и ударить «рукой» робота по физическому объекту. В результате «рука», с помощью которой робот подбирает объекты, отвалилась:
Отвалившаяся рука робота — результат внедрения небезопасных координат в трафик
Динамические вредоносы
Эта разновидность атаки предполагает, что робот работает под управлением программы, написанной системным интегратором, которая считается доверенной. В реальности любая созданная интегратором программа считается доверенной и разворачивается без проверок кода на безопасность.
Скомпрометировав интегратора или заменив программу в уязвимом сетевом хранилище, можно незаметно внедрить в сеть предприятия вредоносный код: добавить загрузчик, который скачивает нужный злоумышленнику модуль и запускает его на выполнение как часть стандартного производственного цикла.
Загрузчик вредоноса, написанный на языке программирования для промышленных роботов
Для проверки этой концепции мы написали дроппер на языке программирования для промышленных роботов и убедились, что для загрузки кода в контроллер робота и его выполнения может быть использована внешняя программа. Получив управление, такая программа может выполнять дальнейшие вредоносные действия, собирая информацию о сетевой инфраструктуре, похищая файлы и учётные данные.
Необычная RCE-уязвимость
Одной из наших находок стала вполне допропорядочная программа, которая запускает на исполнение функции, имена которых получает по сети. Для их исполнения она использует динамическую загрузку кода, но при этом не интересуется, что именно она запускает: в программе не предусмотрена проверка целостности загружаемых библиотек.
Уязвимая логика работы «добропорядочного» приложения
Фрагмент кода, реализующий уязвимую логику.
Хотя сама по себе программа не содержит вредоносных функций, злоумышленник может воспользоваться ей, чтобы отдавать команды роботу в нужный ему момент, оказывая влияние на физический мир.
Венец творения — червь-вредонос
Для демонстрации серьёзности обнаруженных проблем мы разработали программу с функцией саморазмножения и автоматического обновления, динамической загрузкой кода с управляющего сервера и возможностью удалённого управления. Проверочная программа также может выполнять сетевое сканирование, передавать на управляющий сервер произвольные файлы, вести список заражённых устройств и выполнять функции бота.
Логика работы PoC-программы, имитирующей работу реального вредоноса
Формирование списка найденных файлов и его отправка на управляющий сервер
Источник проблем
Проанализировав восемь популярных языков программирования для промышленной автоматизации, разработанных в прошлые десятилетия, мы пришли к выводу, что основная причина выявленных и потенциальных уязвимостей состоит в том, что эти языки содержат низкоуровневые средства для доступа к системным ресурсам. И хотя эти средства сами по себе не являются чем-то опасным, злоумышленники могут использовать их не по прямому назначению, критически повлияв на безопасность робота, его оператора и подключённых систем. Например, с их помощью можно перемещать манипулятор вверх, поднимать заготовку, опускать манипулятор вниз и освобождать заготовку.
Этот богатый набор сложных функций даёт инженерам-технологам свободу при разработке прикладных программ, в которых они могут получать данные из сети читать и записывать файлы. Однако, поскольку платформы не реализуют защищённый доступ к этим расширенным возможностям, злоумышленники могут использовать их для написания вредоносных модулей.
Другая проблема устаревших языков для промышленной автоматизации (Industrial Robots Programming Language, IRPL), доставшихся в наследство вместе с оборудованием, состоит в том, что для них не существует средств проверки кода на небезопасные паттерны, подобных инструментарию для C, C++, C#, Java, PHP и Python.
Каждый OEM-производитель создаёт свои собственные языки и среду, в которой будут выполняться целевые программы. Некоторые из них основаны на операционных системах реального времени (RTOS), но в целом стандартизации не существует. Семантика каждого IRPL также уникальна и может существенно отличаться от семантики языков программирования общего назначения. Некоторые возможности, например, для манипулирования строками или криптографических операций, в IRPL либо отсутствуют, либо не настолько развиты, как в традиционных языках.
Главные источники уязвимостей в программах, написанных на IRPL, —три основные функции:
- работа с файлами и каталогами,
- динамическая загрузка модулей и вызов функций по имени,
- сетевые функции — приём и передача данных внешним системам.
Доступные в IRPL «опасные» функции
Как защититься
Как и любое программное приложение, работающее с недоверенными данными, системы промышленной автоматизации должны разрабатываться, внедряться, конфигурироваться и развёртываться с соответствующими механизмами безопасности.
Сводные рекомендации по обеспечению безопасности программ для промышленной автоматизации
Следовательно, при написании таких программ необходимо руководствоваться следующими принципами:
- воспринимайте промышленных роботов как компьютеры, а прикладные программы для них — как чрезвычайно ответственный код;
- аутентифицируйте все коммуникации;
- реализуйте политики контроля доступа;
- внедряйте проверку входных данных везде, где это применимо;
- обеспечьте постоянную санитизацию выходных данных;
- при обработке ошибок не раскрывайте ненужные технические детали;
- создавайте правильные конфигурации и процедуры развёртывания;
- внедрите процессы управления изменениями для кода промышленной автоматизации.
Старые или умные?
В то время, как разработчики традиционного ПО десятки лет сражаются с последствиями небезопасного программирования и вырабатывают различные методики, обеспечивающие победу, мир промышленной автоматизации оказался неподготовленным к обнаружению и предотвращению эксплуатации уязвимостей.
Учитывая темпы конвергенции IT/OT, необходимо в приоритетном порядке внедрять в индустрию промышленной автоматизации методы разработки безопасного кода. В противном случае ближайшие несколько лет могут принести нам множество сообщений об инцидентах в сфере промышленности, причём последствия этих инцидентов будут проявляться не только в киберпространстве, но и в физическом мире.
tumaso
Вспомним протокол Modbus, активно использующийся в автоматизации где только можно, и у которого защиты нет от слова «вообще»
Dotarev
Если Modbus TCP доступен со внешнего окружения — проблема не в нем. а в разработчике системы. Использоваться он должен только в сети технологического управления, не имеющей моста с внешним миром.
tumaso
Проблема в том, что Modbus уязвим от несанкционированного доступа и внутри. Притащил какой нибудь инженер флешку, а там зловред. А так как нет абсолютно никакой авторизации в модбасе, то пиши в любые порты что хочешь, с соответствующими возможными последствиями
LEKAPb
Если инженер притащил флешку, зачем лезть в модбас если можно сразу в базу залезть. Есть варианты когда и в modbus реализовывают «авторизацию», но обычно это не нужно.Это не вредоносный код, а возможность управления в предусмотренных случаях.
tumaso
Вот яркий пример из реального мира: Stuxnet: война 2.0:
Читаем дальше:Думаю не нужно объяснять, каким образом шел обмен между контроллером и вирусом на компах — через вышеупомянутый modbus.
Поэтому проблема не только в разработчике системы, но и в используемых элементах системы. Прописную истину, что надежность любой системы равна её надежности слабейшего элемента, еще никто не отменял. У modbus защиты от несанкционированного доступа нет от слова вообще.
А самый мой первый пост видимо минусуют те, кто прячет голову в песок ))))
Dotarev
Откуда Вы знаете, что использован был Modbus, а не ProfiNet, к примеру? А Вы можете перечислить все протоколы, которые поддерживают контроллеры семейства Simatic S7? И какие из них поддерживают ограничение доступа и шифрование? Мне вот, например, кроме OPC UA ничего в голову не приходит.
В промышленности используются сотни протоколов, и подавляющее большинство не решает вопросы ограничения доступа и шифрования. И это не потому, что протоколы старые, а разработчики ленивые. У промышленной сети предназначение — работать внутри периметра доверия. И основные приоритеты — надежность, скорость, экономичность.
Вот где была точка отказа. Дальше уже не важно было -по защищенному или нет протоколу ОС АРМ оператора связывается с контроллером, будет шифрование или нет — поскольку доверие к командам вирусной программы = доверию командам оператора.
tumaso
Ммм, зачем мне вам что то перечислять? )))) Достаточно того факта, что симатик поддерживает модбас
Вот в этом то и проблема, что практически все протоколы, используемые в автоматизации, небезопасные
Вот именно, должна обеспечиваться надежность. И под надежностью понимается не только бесперебойная работа оборудования, его резервирование и т.д., но и защита от человеческого фактора, от случайных или преднамеренных ошибок. Современные протоколы, используемые в автоматизации, этого практически не обеспечивают.