DaMAgeCard: как возрождение DMA-атак связано с индустрией SD-карт памяти

Did I ever tell you what the definition of insanity is? Insanity is doing the exact… same ******* thing… over and over again expecting… **** to change… That. Is. Crazy.

(c) FarCry 3

Индустрия периферийных устройств снова гонится за СКОРОСТЬЮ и снова забывает про безопасность.

DaMAgeCard: как возрождение DMA-атак связано с индустрией SD-карт памяти

Размеры медиа-файлов кардинально растут, а вместе с ними растут и требования к скорости носителей. Копировать сотни гигабайт RAW-изображений с обычной, даже высокоскоростной SD-карты стандарта UHS-II стало слишком долго. И вот жалобы фотографов на то, что кофе успевает остыть, пока все данные будут скопированы с карты, дошли до председателей SD Association и CompactFlash Association, и те приняли решительные меры: выпустили стандарт SD ExpressCFexpress).

Наша команда (Positive Labs) занимается исследованием безопасности программно-аппаратных систем и системного ПО. Поэтому мы внимательно наблюдали за развитием событий еще с 2018 года — с момента публикации стандарта, который обещал огромный прирост скорости за счет подключения карты к шине PCIe. Но мы следили не только за бенчмарками скорости, хотя она, конечно, внушительная. Наличие PCIe потенциально опасно из-за возможности доступа к памяти устройства, а это очень интересный вектор атак.Вот только до недавнего времени производители контроллеров и пользовательских устройств не спешили с поддержкой стандарта SD Express. Мы уже даже было обрадовались, что они научились на своих ошибках, и теперь не хотят давать внешним устройствам доступ к памяти (спойлер: нет). А пока расскажем, почему уделяем столько внимания почтенной шине PCI.

Для быстрой навигации по статье

Прелюдия: DMA и особенности перевода с немецкого

У программируемых электронных устройств множество применений. Но делать под каждое назначение отдельное устройство с нуля — со специализированными микросхемами — не оправдано экономически. Вместо этого производители комплектующих выпускают чипы или целые блоки электроники как можно более (но не более, чем нужно!) общего применения. Неважно, идет ли речь о создании умной колонки группой суперпрофессиональных инженеров или о сборке любительского ПК. На плечи создателя возлагается обязанность разобраться в номенклатуре и выбрать лучшие компоненты из доступных: процессор общего назначения, самые подходящие сенсоры и датчики и, возможно, даже самую дешевую микросхему памяти. Затем соединить это все, скрестить пальцы, запустить и вдохнуть волшебный дым обрадоваться.

Но любой, кто когда-либо собирал ПК, не соврет, если скажет, что ему важна СКОРОСТЬ. Есть много факторов, которые влияют на общую скорость работы собранного электронного устройства. Например, скорость центрального процессора — то есть того компонента, который исполняет основную программу. Другой  фактор — скорость периферийного устройства: количество байтов, которые может в секунду прочесть диск или отправить сетевая карта. Помимо того, важна также скорость обмена между центром и периферией, и она зачастую становится «бутылочным горлышком».

Проблема скорости работы с периферийными устройствами не сводится только к количеству прокачиваемых по проводнику битов. Кроме неё важны также задержки (latency) и простаивание (I/O wait). Простаивание случается, если процессор не делает ничего полезного во время ожидания данных. Это архитектурная проблема модели доступа к периферии.

Кстати о моделях: рассмотрим две из них, PIO и DMA (наконец-то, вот он, акроним из заголовка!). Не будем спешить. Сначала — коротко про (исторически) первую модель, Programmable Input/Output. В ней процессор всегда выступает инициатором обмена. Он запрашивает данные, он их получает, он их переносит в свою память. При этом с точки зрения разработчика это может выглядеть по-разному. Возможно, запрос данных идет какой-то отдельной инструкцией (inb 0x8,0xFF у x86). Или периферия может быть отражена (замаплена, MMIO) в его адресном пространстве, и остается просто сделать mov. В обоих случаях (железная) логика на стороне ЦПУ — обратиться к периферии, дождаться ответа и положить что-то в основную память. Ожидая ответ, процессор, конечно, может что-то считать, но вот класть в память все равно придется ему. На это уйдет много тактов, особенно если нужно скачать много данных, и одно ядро будет занято только этим [1] [2].

Модель Direct Memory Access (DMA) переносит ответственность за последний шаг — положить результат в память — на другое устройство. Это меняет дело: теперь ЦПУ получит уведомление о готовности, когда все уже лежит в памяти. А это значит, что даже во время передачи огромного массива данных ЦПУ может исполнять какие-то полезные инструкции. Но встает вопрос: какое другое устройство, кроме ЦПУ, достойно полного контроля над памятью?

В индустрии приняли решение выделить для этого специальный блок — DMA-контроллер [3]. Все, что требуется от ЦПУ, — это настроить один из них: указать, по какому адресу ожидается увидеть данные [B]. Подчеркнем: инициатором все еще выступает ЦПУ. А контроллер DMA выступает в роли аппаратного ускорителя memcpy (). И это не совсем шутка — на микроконтроллерах этот принцип иногда используется для копирования внутри оперативки. В качестве менее экзотического примера можно привести серверные платформы Intel Xeon.

Bus mastering in action
Bus mastering in action

Проблемы начинаются с идеи «а не поставить ли нам контроллер DMA прямо на периферийное устройство?», или bus mastering DMA.

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

🚌 В электронику название «шина» проникло из электротехники. Туда оно попало из немецкого: у них «шина» означает и «резина на колесе», и «рельс». А нечто подобное рельсу — длинный закрепленный кусок металла — и используется электротехниками для параллельного подключения. Англоязычный термин для этого «рельса» — «bus», или «busbar» («bus» уходит в латынь: «omnibus» — «для всех»). И получается, что «busbar» — это «брусок, к которому все подключено».

Шина — это подключение, которое позволяет соединить более двух устройств, гарантируя возможность того, что хотя бы одно из них может передать информацию нескольким другим, используя при этом один и тот же способ передачи. Существует небольшая сложность в терминологии: на территории СНГ, говоря «шина», чаще имеют в виду «параллельная шина». А это вещь более конкретная: пространство передачи, разделяемое несколькими устройствами, которое в один момент контролирует только одно из устройств. Параллельной шине требуется наличие арбитража в том или ином виде — способа решать, кто сейчас на нее пишет, то есть контролирует ее. Это отличное от bus mastering понятие, хотя и смежное с ним.

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

Итого: в мире электроники существуют Стандартизированные Шины Передачи Данных. И обычно обсуждение DMA идет в контексте системы, где используется одна из них.

Вернемся к bus mastering DMA. Установка контроллера DMA [4] прямо на устройство дает ему возможность самому инициировать обращения к памяти. Это может быть полезно, например, для сокращения задержек при обработке сетевых пакетов или при работе с изохронными потоками данных. Но так как сам по себе метод не подразумевает участия или хотя бы уведомления [5] ЦПУ о факте обмена, синхронизация с остальными компонентами системы, в особенности с управляющей программой, ложится на плечи разработчиков.

Что, естественно, создает вектор атак (и просто источник ошибок) на систему в случае, когда об этом не задумались.

Примером шины с поддержкой bus mastering DMA является PCI. Эта шина в силу набора исторических причин (привет отделу аналитики рынка IBM 😉 ) стала довольно популярна во времена IBM PC/AT. Классическая шина PCI при этом является параллельной шиной, что только подливает масло в огонь терминологических проблем.

Прежде чем осуждать дизайн этой шины с точки зрения безопасности, нужно понимать контекст принятых ее разработчиками решений. Она разрабатывалась для персональных компьютеров: устройств, мобильность которых сильно ограничена. Важнейшими критериями были доступная СКОРОСТЬ, стоимость, простота разработки и использования (plug-and-play). Да и что касается безопасности: не предполагалось, что физические порты будут доступны без открытия крышки устройства — действия, за которым следит физическая безопасность [C]. Действия, которое доступно только квалифицированным кадрам IT. Возможность DMA-атак если и рассматривалась, то была out of scope — в нашем обзоре мы увидим это еще не раз.

Если не сказано обратное, далее мы будем обсуждать DMA именно на примере шины PCI, стараясь, однако, сохранить общность рассуждений там, где это возможно.

Свечи были дорогие…

А что, если кто-то попробует эксплуатировать этот вектор? Потенциальный нарушитель должен будет либо создать периферийное устройство, либо взломать какое-нибудь существующее.

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

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

  • умеет все, что нужно атакующим,

  • имеет помимо PCI какой-то управляющий интерфейс [6],

  • самим фактом подключения не будет нарушать работу системы.

Получив подобную «злую» периферию, как уже было сказано ранее, нужно будет ее как-то подключить к цели… И что далее? У атакующего появляется доступ к памяти, когда он хочет, и теперь, чтобы добиться реализации  

Источник

Читайте также