К чему приводят уязвимости протокола DICOM

15 ИЮНЯ 2022

------------------------------------------------------------------------

Наш телеграм-канал: t.me/@mailsgun_online

Youtube: youtube.com/@mailsgun_online

------------------------------------------------------------------------

Автор: Мария Недяк

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

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

Протокол DICOM и его слабые места

Коротко о самом протоколе

DICOM (Digital Imaging and Communication in Medicine) — протокол представления медицинских обследований и передачи их между различными компонентами. Этими компонентами могут быть:

  • медицинское оборудование, которое непосредственно делает сканирование;
  • DICOM-сервер — база данных для DICOM-файлов;
  • DICOM-клиент — обычно это приложение для просмотра результатов медицинских обследований.

Протокол DICOM имеет две части:

  • описание формата файла;
  • описание сетевого взаимодействия.

Теперь к делу

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

Мы также изучили безопасность PACS (Picture Archiving and Communication System). Это такие системы, в которых результаты обследований хранятся в электронном виде. Они позволяют передавать снимки между врачами по сети. Да-да, благодаря PACS больше не нужно таскать с собой рентгеновские снимки в конверте, как мы привыкли.

DICOM-файл

DICOM-файл — изображение медицинского характера, сохраненное в формате DICOM. Этот формат — отраслевой стандарт для хранения и распространения медицинских снимков.

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

На рисунке показана структура DICOM-файла:

DICOM Network

Стандарт протокола довольно сложно и нудно описывает сетевое взаимодействие — мне до сих пор не удалось изучить его целиком. Но если говорить в общем, вот какие команды сетевого взаимодействия есть у DICOM-протокола:

Действие Описание
C-ECHO Тест соединения между двумя устройствами
C-FIND Поиск исследований на удаленном сервере
C-GET, C-MOVE Скачивание исследований с удаленного сервера
C-STORE Сохранение исследования на удаленном сервере


Вот как выглядит процесс передачи результатов медицинских обследований по DICOM-протоколу

Немного статистики по DICOM-серверам в интернете.


Такие картинки-отчеты о сканировании генерирует Grinder Framework

Интересный факт: когда мои коллеги из AISec проводили сканирование в 2019 году, то доступных серверов было меньше тысячи. В 2020 году же их оказалось около 2700.

Большинство хостов в сети настроены таким образом, что любой может установить с ними соединение. Давайте разберем пример, как просто получить исследование с удаленного сервера из сети. Для этого воспользуемся утилитами findscu и getscu из DCMTK — набора библиотек и приложений, реализующих большую часть стандарта DICOM.

Первой командой получаем список всех доступных исследований на сервере.

$ findscu -aet <AE Title> -P -k PatientName="*" <host> <port>

С ключом -aet в запросе передаем название Application Entity Title. Обычно этот тайтл требуется, когда нужно разграничить доступ к изображениям при использовании одного DICOM-сервера разными PACS. Это, своего рода, идентификация клиента. Но проблема в том, что тайтлы на многих серверах настроены по умолчанию. Это значит, подобрать его можно, перебирая дефолтные значения от разных разработчиков PACS и DICOM-серверов.

С ключом -k передаем фильтр "PatientName=*", который позволит показать любое доступное исследование на сервере.


Пример вывода команды findscu

Следующей командой скачиваем нужное нам исследование или все исследования сразу.

$ getscu -aet <AE Title> -P -k PatientName="John Doe" <host> <port>

Значения ключей в команде аналогичны предыдущей.


Пример исследования, скачанного с удаленного сервера DICOM

Вот так с помощью двух команд можно скачать данные с удаленного DICOM-сервера при наличии одного из условий:

  • Application Entity Title не задан,
  • Application Entity Title установлен по умолчанию, поэтому его удалось подобрать.

Далее рассмотрим популярные инструменты и реализации протокола и найденные в них недостатки.

Реализации протокола DICOM

SimpleITK

SimpleITK — реализация протокола, которая используется в одном из крупных проектов в области medical imaging NVIDIA CLARA.

Для поиска уязвимостей в ней использовался фаззинг AFL со словарем. В результате мы наткнулись на переполнение кучи. Попытки эксплуатации привели к обнаружению более простой уязвимости — переполнению буфера через поле PatientName. Причем для переполнения буфера было достаточно создать файл с длиной имени пациента свыше 512 байт.

В ответ на репорт о переполнении кучи разработчик просто поправил файл, демонстрирующий уязвимость, чтобы он корректно обрабатывался библиотекой 🙂

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

DCMTK

DCMTK (DICOM Toolkit) — самая старая реализация DICOM-протокола. Она включает набор инструментов для работы с протоколом: парсеры DICOM-файлов в разных форматах и из разных форматов, а также утилиты для взаимодействия с DICOM-сервером по сети.

XXE в xml2dcm

Парсер xml2dcm конвертирует результаты медицинского обследования из формата XML в DICOM.
В xml2dcm мы нашли уязвимость к самой простой XXE-атаке: создаем XML-файл с внешней сущностью в имени пациента и на выходе получаем DICOM-файл с содержимым /etc/passwd.

<?xml version="1.0" encoding="ISO-8859-1"?>
   <!DOCTYPE foo [
   <!ELEMENT foo ANY >
 <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
…
<element tag="0010,0010" vr="PN" vm="1" len="32" name="PatientName">&xxe;</element>
…

Чем кончилось: данную уязвимость вендор устранил.

Небезопасные функции xml2dcm

По аналогии с external entities в XML, cама по себе утилита xml2dcm позволяет создавать DICOM-файлы c содержимым других файлов внутри. Это удобно, потому что не нужно писать данные в XML-файл — достаточно указать в теге PixelData путь к файлу, из которого нужно подгрузить данные при конвертировании.

<element tag="7fe0,0010" vr="OW" vm="1"  name="PixelData" loaded="no" binary="file">/etc/passwd</element>

Если в теге PixelDatа указать путь к любому файлу в системе, то после обработки утилитой xml2dcm мы получим DICOM-файл с его содержимым.

Чем кончилось: эту функцию невозможно отключить никаким флагом, а на доработку парсера xml2dcm вендор не согласился 🙁

DoS в парсерах DICOM-файлов

Мы тестировали парсеры из DCMTK при помощи фаззинга AFL и libFuzzer. Результат — DoS-утилиты xml2dcm и dcm2xml.

Чем кончилось: вендор исправил найденные ошибки.

DoS в dcmqrscp-сервере

DCMTK также предоставляет реализацию DICOM-сервера dcmqrscp. Тестирование безопасности DICOM-сервера dcmqrscp было проведено с помощью фаззинга, в результате которого был обнаружен DoS.
Фаззинг проводился при помощи AFLNet. Поддержку протокола DICOM я добавила в официальный репозиторий AFLNet, если кому-то захочется пофаззить другие DICOM-серверы.

Чем кончилось: вендор исправил ошибку реализации.

Приложения medical imaging

ORTHANC

В ходе исследования мы затронули приложение ORTHANC. Этот продукт очень прост в настройке и использовании: он предоставляет веб-обертку для просмотра DICOM-файлов, и для работы с DICOM-протоколом требуется только браузер.
ORTHANC используют в здравоохранении, в различных университетах и госпиталях, с его помощью проводятся исследования в области машинного обучения medical imaging (раз и два).


Открытые серверы ORTHANC в сети

Небезопасное API

Сервер ORTHANC открыт к сообществу разработчиков и предоставляет REST API для написания различных плагинов. Если взглянуть на список доступных методов, можно заметить интересные методы для перезагрузки и выключения сервера, а также метод с названием execute-script.

Он принимает на вход скрипты на lua и без какой-либо валидации выполняет их на сервере. Чтобы убедиться в этом самостоятельно, посмотрите исходный код ORTHANC.

Чем кончилось: раньше этот метод был включен по умолчанию в конфиге Orthanc, но, к счастью, недавно вендор догадался его отключить. Однако в сети до сих пор можно наткнуться на Orthanc-серверы с работающим методом execute-script.

Уязвимость аутентификации к CSRF-атаке

Метод execute-script является небезопасным. Разработчик ORTHANC решил эту проблему при помощи аутентификации, чтобы выполнять такие запросы могли только зарегистрированные пользователи. Но по умолчанию аутентификация отключена при работе с ORTHANC-сервером с официального сайта.

В докере от разработчика уже включена аутентификация по умолчанию. Это здорово, если бы не следующая проблема: данная система аутентификации уязвима к CSRF-атаке. Достаточно создать страничку со следующим содержанием и отправить ее пользователю:

<html>
  <body>
    <form action="http://<host>:8042/tools/execute-script" method="POST" enctype="text/plain">
      <input type="hidden" name="cmd" value="'mkdir /tmp/testCSRF';os.execute(cmd)"/>
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

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

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


Ответ вендора

BTW: кеш гугла показал, что приписку в документации о CSRF вендор сделал после моего репорта об уязвимости. И, конечно же, вряд ли он известил тех клиентов, которые уже пользуются их «микросервисом» и верят в его надежность.


Страница документации после ответа вендора на репорт об уязвимости


Страница документации из кеша гугл за пару дней до репорта не содержит каких-либо упоминаний CSRF

Чем кончилось: вендор так ничего и не предпринял для устранения данной уязвимости, только дополнил документацию.

Заключение

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

Напоследок оставлю табличку со всеми описанными в статье багами.

Vendor Product Weakness
SimpleITK ImageSeriesReader Heap-buffer-overflow
SimpleITK ImageSeriesReader Buffer-overflow
Orthanc Orthanc CSRF with remote code execution
DCMTK xml2dcm File read functionality

Также подробная информация лежит на github.

Source: habr1

Ну и напоследок напоминаю вам о нашем новом проекте vkserfing bot.