Низкоуровневый взлом банкоматов NCR

akok

Команда форума
Администратор
Сообщения
15,469
Симпатии
12,573
Баллы
2,203
#1
Существуют системы, доступа к которым у простых смертных нет по умолчанию. И разработчики таких систем наивно полагают, что они защищены от проникновения и зорких глаз исследователей.

Взять хотя бы банкоматы (АТМ). Нередки случаи, когда к АТМ подходят неизвестные, подключают ноутбук, забирают деньги и уходят, не оставляя каких-либо логов в системе. А недавние истории с «котлетами» (вредоносное ПО под названием Cutlet Maker) и подавно подтверждают, что неуязвимых систем нет — есть недоисследованные.
Начало исследования

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

После непродолжительных поисков на Ebay у меня на столе оказалась платка диспенсера NCR USB S1 Dispenser с прошивкой. Цели были такие:

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

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fnk%2Fqw%2Fri%2Fnkqwri4xymfedse_tdd_mfqkwc8.png&hash=673666b5b0403aa1fd53be5fbc448c7b


Прошивка

Прошивка представляет из себя ELF-файл под процессор NXP ColdFire (Motorola 68040, мой любимый процессор), работающий на VxWorks v5.5.1.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fzy%2Fn2%2F01%2Fzyn201rwrhyrwet6lawdgkcjmpm.png&hash=8d589e8eb6d330f88e45be394afa4da4



В ELF-файле интерес представляют две основные секции — .text и .data:

  • В одной из них содержится код, который крутится все основное время (назовем его основной прошивкой), когда диспенсер подключен к системнику в верхней части АТМ.
  • Во второй лежит упакованный с помощью zlib код загрузчика (его местное название USB Secure Bootloader), который отвечает за заливку прошивки и запуск основного кода.

И самое приятное то, что в файлике остались невырезанными символы — бери да ищи что-нибудь интересное.

Внутреннее устройство основной прошивки

Если разделять код на основные составляющие, то получится такая схема (в порядке подчинения):

  1. Поток, который занимается получением USB-пакетов и распределением их по сервисам.
  2. Сервисы — основные исполняющие единицы, каждому из них отведена своя роль и у каждого есть свои задачи (классы).
  3. Классы — здесь это задачи, которые может выполнять тот или иной сервис с помощью контроллеров.
  4. Контроллеры — собственно «воркеры» (workers), которые занимаются валидацией присланных им задач, их выполнением, а также формированием ответных пакетов.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fbb%2Fx9%2Fds%2Fbbx9dsyvocknltgx3sr8kubghv0.png&hash=e577f153d6ba523c1b7da0f5b011250c


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

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

1) DispTranService (Dispenser Transaction Service): работа с шифрованными командами, формирование пачек банкнот, аутентификация. Можно сказать, самое интересное — здесь.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fz4%2Fj9%2F48%2Fz4j948foksgqipdtpkpd4txwe2m.png&hash=571ba6b0c9ca446fbc8835eee791648b


2) securityService: после аутентификации на стороне диспенсера генерируется сессионный ключ, который по запросу компьютера отправляется на него в зашифрованном виде. Этим ключом будут шифроваться все важные команды — выдача, формирование пачки банкнот.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fak%2Fwi%2Fq2%2Fakwiq2yyefxr1l_3d2iepme-qdo.png&hash=0980af78ff4c82e44ddb8813e0c769bf


Впоследствии на глаза попался еще один сервис: UsbDownloadService. Его задача – при подключении диспенсера к компьютеру и несоответствии версии прошивки диспенсера той, что хранится на компьютере банкомата, переходить в bootloader с целью заливки прошивки, с которой должна работать ОС (лежит в папке с ПО вендора на компьютере). Этот сервис также умеет отдавать информацию о версии прошивки.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2F26%2Fkc%2Fyc%2F26kcycxcpiehexunrdlmpq4gjus.png&hash=9e487a63f4258bd975feaa04262ba03e


Физическая аутентификация

Физическая аутентификация реализована на высочайшем уровне и защищает АТМ от простой отправки по USB команд на выдачу без авторизации. В данном случае она заключается в том, что только при открытом сейфе с деньгами нужно выполнить одно из следующих действий:

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

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fwr%2Fvg%2Fjn%2Fwrvgjn2ondfz-ar9eqratwm8fuy.png&hash=dbf9aca8eb48be27b8e8a1bdb6969b54


Но все это требуется только если уровень доступа установлен на максимальный, то есть физический. Всего их три: USB (0), логический (1) и физический (2). Остальные два используются сервисниками и разработчиками для отладки и тестирования прошивки. Ну а физический — крайне рекомендуется вендором к использованию по умолчанию.

Уязвимость

Далее описана критическая уязвимость (уже исправленная вендором на момент публикации статьи), которая позволяла при наличии доступа в сервисную зону, но без доступа в сейф (например, через проделанное в лицевой панели ATM отверстие) выполнять любые команды диспенсера, включая выдачу наличных.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fyj%2Fyp%2Fn4%2Fyjypn4wot4lpkggp6xunjrgr2va.png&hash=617de494a4f7ee7d13f5eeed502371cc



Как выяснилось, UsbDownloadService принимает команды, не требующие шифрования. Звучит заманчиво. Но вдруг дальше все защищено, и название Secure Bootloader оправдает себя?

(Спойлер: не оправдает!)

We need to go deeper

Как уже было сказано, в секции .data лежит упакованный код загрузчика, который долгое время не вызывал у меня интереса, да и коллеги, когда исследовали прошивку, не обратили на него внимание.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Frd%2Fbf%2Fzt%2Frdbfztrajma7yrnq6kmrr7o5jcc.png&hash=0d47a00db1796e513fe7407ad321159a


Пока наличие загрузчика было тайной, оставался открытым вопрос: как же все-таки ПО на компьютере заливает прошивку? Ведь в основной прошивке ничего такого обнаружить не удалось.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Ftb%2Fb0%2Fuy%2Ftbb0uy2d1bzgxpfbf1ies02kapg.png&hash=b4f6bd124bf1ba4c29b7da068ac8b154



Итак, bootloader распакован, загружен в IDA по смещению 0x100000 — теперь можно исследовать… Только символов нет!

Не беда: сравнение основной прошивки с кодом загрузчика, чтение datasheet контроллера — и начинает вырисовываться определенная картина.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fe-%2Fxd%2Fvv%2Fe-xdvvhfkqldjbfbjrqybgdwua4.png&hash=4c04f8856284f79330b725f2e8adc52a


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

На полное понимание этого процесса было потрачено довольно много усилий и времени (подробнее об этом можно узнать из доклада «Blackbox is dead—Long live Blackbox!» на конференции Black Hat 2018 в Лас-Вегасе). Чего только стоит перепайка памяти NVRAM, заливка в нее бэкапа с целью «раскирпичивания» всего контроллера… Спасибо коллеге Алексею за терпение!

В итоге получился следующий алгоритм заливки прошивки в диспенсер:

1) Сгенерировать пару RSA-ключей и залить публичный ключ в контроллер.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2F6g%2Fy4%2F1h%2F6gy41hu5hu_ivzg6lazlc5qbaaw.png&hash=7fa3da8941f91c3306c60cad296f186a


2) Записать последовательно секции .data и .text из ELF по их физическим адресам из заголовков секций.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fjj%2Fyj%2F3t%2Fjjyj3t71ptne_l7r4cpouwbi6iq.png&hash=ab779b5befe094e7621d62737fd94734



3) Подсчитать SHA-1 от записанных данных, зашифровать хеш приватным ключом, отправить в контроллер.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fkr%2F9o%2Fld%2Fkr9oldlexmlcav4iyl9hnxrs844.png&hash=ac36d76dbbc524ece0258934c7f18ef4


4) Подсчитать и отправить сумму всех записанных word-ов прошивки.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2F54%2Fe8%2Fdl%2F54e8dl0gwyv3i0pxaqw-udgbmbu.png&hash=c161e6ae63eab3926cae0dd219375b8c


После чего, если все подсчитано и записано успешно, загрузится основная прошивка.

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

В итоге моя особая прошивка с antisecurity-фиксами была залита и успешно запущена!

К этому моменту код основной прошивки был хорошо изучен, найдены команды на выдачу банкнот. Теперь их можно посылать незашифрованными, и диспенсер их с радостью выполнит.

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fgu%2Fbk%2Fm1%2Fgubkm1l2g0mdd_dfepxjy2n50sa.png&hash=23c8711d3a768b052af726d8da2a7089


Выдача

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

proxy.php?image=https%3A%2F%2Fhabrastorage.org%2Fwebt%2Fyt%2Fk1%2Fwx%2Fytk1wxlqy9dotiuoqvwlvsc2g0o.png&hash=e3d876fae341f424f12c37e8cd28f687


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

Выводы

Мы в очередной раз убедились, что, руководствуясь принципом security through obscurity, обеспечить надлежащую защиту невозможно. Проприетарность кода или прошивки совершенно не означает, что к ней в один прекрасный момент не получит доступ злоумышленник и не воспользуется найденными уязвимостями. Всем необходимым для реализации корыстных целей можно обзавестись при наличии определенной суммы денег.

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

P.S. Вендор подтвердил уязвимость (брешь также обнаружена и в другой модели — S2), которая была заявлена как исправленная в февральском фиксе 2018-го года.

Список CVE:


Благодарности

До меня над прошивкой (правда без платы диспенсера) уже работали мои коллеги — Дима Скляров и Миша Цветков. Их наработки мне очень помогли в исследовании, за что им огромное спасибо! По части «железа» мне очень помог Алексей Стенников.

habr.com
 
Сверху Снизу