О недавней уязвимости в банкоматах Diebold Nixdorf

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Дисклеймер: данная статья публикуется исключительно для ознакомления и ни в коем случае не является руководством к действию. Описанные в материале уязвимости были обнаружены автором статьи в рамках проекта, согласованного с производителем банкоматов. На данный момент они исправлены компанией Diebold Nixdorf, которая была уведомлена Positive Technologies в соответствии с принципами ответственного разглашения (responsible disclosure). В качестве дополнительного фактора защиты вендору рекомендовалось включить физическую аутентификацию для оператора во время установки встроенного ПО. Это позволяет убедиться, что изменения в банкомат вносит сотрудник, а не злоумышленники.

Приветствую! На днях Positive Technologies опубликовала новость о том, что банкоматы производителя Diebold Nixdorf (ранее Wincor), а точнее модели диспенсеров RM3 и CMDv5, содержат уязвимость, благодаря которой можно производить выдачу наличных и заливать модифицированную (уязвимую) прошивку. И поскольку я и мой бывший коллега Алексей Стенников имеем непосредственное отношение к нахождению этой уязвимости, я хотел бы поделиться некоторыми ее деталями.

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

Введение

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

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

Safe zone (она же сейф, диспенсер) — безопасная и заведомо защищённая часть банкомата. Закрывается она на ключ, который есть только у сервисных инженеров и инкассаторов, сделана не из пластика (в отличие от верхней части) и часто укреплена бетоном либо вмонтирована в стену. Именно в сейфе находится то, ради чего и взламываются банкоматы, — банкноты. Они разложены по кассетам с нужными номиналами, каждая из которых также закрыта на ключ. Из кассет деньги достаются присосками, едут по конвейеру к «шторке» (shutter), после чего извлекаются пользователем.

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

Зачем взламывают диспенсер вместо ПК и при чём тут blackbox? 

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

Кроме того, на диспенсеры в своё время часто совершались атаки типа blackbox, при которой, единожды захватив USB/COM-трафик выдачи наличных на одном устройстве, неизвестный мог подойти с ним же к другому, повторить и получить деньги. Сейчас же такое провернуть кому-либо вряд ли удастся, потому что повсеместно применяются анти-blackbox техники: например, сессионные rolling-ключи для шифрования USB-трафика и использование криптографии практически на каждом этапе. Теперь лишь компьютер банкомата может работать с этим шифрованием, поэтому вклиниваться в трафик злоумышленник чаще всего уже не может.

Но тогда и не было бы данной статьи, как и упомянутой новости. В нашем проекте была одна небольшая брешь (к счастью, её уже нет). И о ней ниже.

В чём уязвимость, брат?

Прежде чем мы начнём, я вкратце расскажу, в чём именно заключается уязвимость, а потом перейду к деталям.

Прежде всего стоит сказать, что прошивки зашифрованы ключами, которые известны только разработчику. Описанные Positive Technologies уязвимости (по одной на устройство) заключаются в том, что злоумышленник может загрузить на диспенсер прошивку, не зная этих самых ключей шифрования (они появятся дальше в статье в виде KEY0 и KEY1). То есть, имея чистый код, он может его модифицировать как хочется, зашифровать обратно и загрузить в банкомат, после чего произвести выдачу в обход имеющихся алгоритмов шифрования USB-трафика. Ну, а теперь к деталям...

Конец 2017-го, начало проекта

В рамках проекта в одном банке мне и Алексею достались два файлика: у одного было расширение BTR (bootloader), у второго — FRM (firmware). У файлов имелись понятные заголовки, но при этом совершенно непонятное содержимое. Мы и так, и этак пытались подойти к расшифровке содержимого (становилось очевидно, что оно зашифровано), но безуспешно. На этом проект мог бы и закончиться, и файлы действительно пролежали несколько месяцев на жестком диске, пока мудрый Алексей не решил поискать плату диспенсера на eBay. Плата там, как вы уже могли догадаться, нашлась, и спустя какое-то время оказалась у Алексея на столе.

Без контроллера плохо, с контроллером — хорошо

После некоторых манипуляций с прозвонкой был успешно найден разъём JTAG, который находился прямо рядом с главным процессором. Кроме главного, на плате имелись ещё два процессора, назначение которых нам было не очень понятно: CollectorBooter и DispenseBooter. Тем не менее память всех трёх процессоров была сдамплена для дальнейшего анализа.

Ну, сдампили и сдампили, чо бубнить-то, но что дальше? Мы решили, что подходить стоит со стороны заливаемой прошивки, зашифрованные файлы которой у нас, напоминаю, были. А дампы хоть и имелись, всё же приятнее работать с прошивкой в чистом виде.

ПО от вендора

Часто либо в целях диагностики, либо для работы с банкоматом производители пишут специализированные программы, с помощью которых можно выполнять как обычные для банкомата задачи, так и некоторые недокументированные, используемые редко. Например, обновление прошивки диспенсера. Такое ПО имелось и в нашем случае. И написано оно было не на каких-нибудь бейсиках или плюсах, а на нормальном (уважаемом любым реверс-инженером) языке Java. Хочешь — декомпилируй, хочешь — пересобирай.

Спустя непродолжительное время копания в JAR-файлах была обнаружена функция, загружающая на контроллер файлы прошивок. Файлы она не расшифровывала, к сожалению, но давала нам удобную возможность произвести отладку этого процесса. Подключившись отладчиком по JTAG и запустив заливку прошивки, кое-как мы всё же смогли найти место, отвечающее за расшифровку. О ней и поговорим.

Шифрование файлов прошивки

Алгоритм шифрования представлял из себя обычный XTEA, но с необычной для него дельтой: 0xF27716BA. Как она была сгенерирована, безопасна ли — мы не знаем. Но можно точно сказать одно: она не гуглится.

В качестве ключа шифрования XTEA использовались следующие входные данные:

  • пять первых двордов, идущих сразу же после имени прошивки, указанного в заголовке. Мы назвали их Header-Dwords

  • внешний ключ KEY0 длиной 8 байт, который пока неизвестно откуда брался

  • внешний ключ KEY1 длиной 16 байт, который мы также не знали, где брать

Спустя время мы всё же нашли участок кода, вычитывающий и KEY0, и KEY1. Оказалось, что находятся они в специальной области по смещению 0x64000000, смещение в которой по умолчанию было жёстко задано. Далее мы сделали дамп данной области и извлекли оттуда оба внешних ключа. Применив эти ключи в заранее написанном на коленке расшифровщике, мы получили... Нет, не прошивку.

AP32-архивы

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

Архивов оказалось много, и все они шли друг за другом. Если распакованные из них данные объединить, получится полноценная прошивка. Вроде можно радоваться. Но, погодите, пока рано. При попытках изменить что-либо в прошивке (например, строку), последующих запаковке и зашифровке устройство отказывалось принимать нашу прошивку. Значит, где-то имелась проверка целостности.

Самоподписывание

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

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

Так мы и сделали. Вместо оригинальных 2048 (кажется) был успешно вставлен ключ на 512 бит.

Заливаем модифицированную прошивку

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

А так список выглядит, когда устройство обновляется:

Вот этот последний девайс и принимает файлики. А работает он по протоколу DFU (Device Firmware Update), о чём можно было догадаться, даже не имея самой платы на руках. Дело в том, что в конце каждого файла прошивки есть определённая структура, которая содержит тег «UFD».

Сначала устройству отправляется команда DFU_DETACH протокола, после чего выполняется команда USB — UsbCyclePort, которая делает доступным интерфейс, принимающий прошивку. Кто работал с данным протоколом, скажет, что в нём ещё есть команда DFU_UPLOAD (в данном случае выгрузка), но в нашем случае она не была реализована.

Запуск прошивки

После загрузки прошивки в диспенсер она расшифровывается, распаковывается, в ней проверяется подпись, после чего происходит запись прошивки во флеш-память.

Выдача?

Пока нет. Прежде чем произвести выдачу, требовалось разобраться с тем, как же всё-таки отправлять диспенсеру команды. Покопавшись в Java-коде, нам удалось найти специальные JAR-файлы, отвечающие за self-test, то есть за тестирование компонентов диспенсера. Из этого кода удалось выяснить следующее:

  1. Во взаимодействии компьютера банкомата и диспенсера участвует смарт-карта (она давно уже виднелась на плате)

  2. Используется TPM (Trusted Platform Module)

  3. Используется Keystorage, в котором хранятся счётчики сессий (об этом ниже), сертификаты и базовый ключ (Basekey)

  4. Есть четыре направления, для каждого из которых используется свой сессионный ключ и счётчик: PC → Firmware IN/OUT, Firmware → PC IN/OUT

Смарт-карта

Смарт-карта оказалась интересным объектом для исследования. Мне никогда не доводилось иметь дел с APDU (протокол, используемый при общении со смарт-картами), поэтому пришлось изучать. После этого в Java-софте был найден класс, отвечающий за работу со смарт-картой, где я и смог вычленить большинство APDU-команд. К тому же их можно было найти и в коде прошивки, а затем по референсам найти и некоторые другие команды.

Вооружившись картридером для смарт-карт, я подбирал различные команды и их параметры. К сожалению, ничего особо секретного мне обнаружить не удалось. Тем не менее были найдены команды, позволяющие устанавливать свои значения счётчиков сессий (правда, их нельзя было установить на значения, которые использовались ранее).

Сессионные ключи (нет, спасибо)

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

В рамках проекта мы изменили прошивку таким образом, чтобы она перестала обращаться к смарт-карте за сессионными ключами, используя вместо них массив из нулей.

Осталось сделать то же самое в Java-софте, чтобы не заморачиваться с написанием кода с нуля. К слову, здесь же по коду стало понятно, что используется алгоритм шифрования Aes-EAX.

Выдача!

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

В ходе этих испытаний выяснилось, что для выполнения выдачи требовалось ещё указать, сколько у нас наличности и в каких кассетах (произвести конфигурацию), и пропустить настройку устройств, которые не были подключены к ноутбуку (ну, так-то в компьютере много USB-портов, а в ноуте только два).

Лишь после этого в диспенсер отправилась команда с номерами кассет и количеством банкнот для извлечения. Банкомат начал радостно жужжать, предвкушая, как делится наличностью с товарищами исследователями, но денег мы так и не увидели. Мы просто не знали забыли, что нужно ещё открыть шторку. Дубль два — и свежие «фантики» (специальные вендорские купюры) были у нас в руках. Ура!

Выводы

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

  • BDU:2021-04967

  • BDU:2021-04968

На этом, пожалуй, всё. Отдельно я хотел бы отметить работу Алексея над «железячной» частью проекта и приобретённую им плату диспенсера, которая по-прежнему лежит у меня на столе.

Источник: https://habr.com/ru/company/pt/blog/586126/


Интересные статьи

Интересные статьи

Привет, Хабр!Меня зовут Дмитрий Матлах. Я тимлид в AGIMA. Мы с коллегами обратили внимание, что в сообществе часто возникает вопрос о том, как совместить на одном проекте Bitrix-компоненты и реактивны...
Цифровизация стремительно охватывает важнейшие сферы общественной жизни – от получения социальных услуг, оформления кредита до обмена квартиры или покупки автомобиля. Сейчас уже трудно пр...
Данной статьей я начну публикацию решений отправленных на дорешивание машин с площадки HackTheBox. Надеюсь, что это поможет хоть кому-то развиваться в области ИБ. Мы рассмотрим, как можно проэк...
За неделю подобралось сразу несколько новостей на тему «что еще не так с IoT» (предыдущие выпуски: 1,2,3). Уязвимости были обнаружены в веб-интерфейсе для GPS-трекеров, в сетевых видеокамерах D-L...
Тема статьи навеяна результатами наблюдений за методикой создания шаблонов различными разработчиками, чьи проекты попадали мне на поддержку. Порой разобраться в, казалось бы, такой простой сущности ка...