Как я «случайно» получил root-доступ к платёжному терминалу

в 13:01, , рубрики: ruvds_перевод, wordline, информационная безопасность, платежные терминалы, реверс-инжиниринг

Как я «случайно» получил root-доступ к платёжному терминалу - 1


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

▍ Первый взгляд

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

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

Как я «случайно» получил root-доступ к платёжному терминалу - 2

На вид корпус и печатные платы выполнены добротно. Всего устройство включает несколько плат: небольшую интерфейсную плату для внешних разъёмов, основную плату и вертикальную, на которой расположено гнездо для карт. Похоже, что основная SoC представляет кастомную ASIC, которая содержит двухъядерный процессор Arm под кодовым именем «Samoa II». Но я забегаю вперёд… Согласно документации Wordline, это действительно кастомная ASIC, а не просто серийный чип с другой маркировкой. Рядом с ней находится небольшая микросхема флэш-памяти и RAM.

▍ Защита от проникновения

В процессе разборки я всё высматривал контрольный переключатель, который должен подавать сигнал о вскрытии корпуса устройства. Такие переключатели я встречал в ноутбуках и прочих девайсах. Однако найти мне его не удалось. Вместо этого для обнаружения вскрытия здесь применены чувствительные к давлению межплатные коннекторы Zebra. Такое решение требует надёжной фиксации плат друг к другу, и откручивания даже одного винта достаточно, чтобы нарушить контакт и активировать событие «взлом». Естественно, обнаружение взлома должно работать и при отключённом питании, для чего здесь и установлена «таблетка».

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

Как я «случайно» получил root-доступ к платёжному терминалу - 3
Изогнутый рисунок дорожек на плате дисплея, позволяющий обнаруживать вскрытие

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

Как я «случайно» получил root-доступ к платёжному терминалу - 4
Блок считывания карт, обогнутый гибкой печатной платой для обнаружения вскрытия

Собрав терминал обратно, я понял, что моё вмешательство не прошло незамеченным. Теперь дисплей устройства показывал лишь красный экран с надписью «OUT OF ORDER. TAMPERED STATE». В этом режиме терминал абсолютно невосприимчив к какому-либо внешнему вводу. Значит, всё?

Как я «случайно» получил root-доступ к платёжному терминалу - 5

▍ Снятие микросхемы и чтение прошивки

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

Как я «случайно» получил root-доступ к платёжному терминалу - 6

Флэш-память в BGA-корпусе, выпаянная с платы и подключённая к устройству чтения

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

Обратившись за подсказкой к своим друзьям, я смог-таки разобраться в этой схеме. Дело в том, что вместо использования стандартной схемы — 2048 байт полезная нагрузка + 64 байта ECC/резервной области — здесь используется 3 блока данных по 694 байта, каждый из которых сопровождается 10 байтами ECC. Причём байты ECC используются не полностью. Вместо этого последние 16 байт резервной области, похоже, выступают в качестве метаданных для файловой системы YAFFS2.

Обычно на страницу приходится меньше байтов ECC, в связи с чем доступная под метаданные область получается больше 16 байт. По этой причине YAFFS2 пришлось пропатчить для работы с меньшими структурами метаданных.

Я написал подходящую под эту файловую систему программу считывания, с помощью которой успешно прочёл её содержимое.

yomani-unpacker на Github

Теперь стало ясно, на какой ОС работает этот девайс. Я обнаружил файловую систему Linux со множеством интересных файлов. В основе системы лежит ядро 3.6, собранное с помощью Buildroot 2010.02 (!) в феврале 2023 года. Похоже, что в ней используется кастомный загрузчик, «Booter v1.7». И хотя я не знаю, насколько свежей является считанная мной прошивка, вышла она явно после февраля 2023. Честно сказать, встреча столь престарелого ядра вызывает беспокойство. В рамках пространства пользователя здесь используются элегантные скрипты инициализации, busybox и uClibc (последний релиз 13 лет назад). А также libcrypt версии 0.9.26 — ай-ай.

▍ Случайное получение root-доступа

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

Как я «случайно» получил root-доступ к платёжному терминалу - 7

Флэш-память снова подключена к плате — почти как новая

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

Как я «случайно» получил root-доступ к платёжному терминалу - 8

Прощупывание отладочного разъёма

Почти сразу же я нащупал некую активность на одной из линий отладочного разъёма. Бинго!

------------------------------------------------------------------------
Booter: 1.7b+00002:gbe6b338 Jun  3 2014 08:51:58 owi
Reset reason: Tamper
Start USB boot ...
Got address 0x00000015
Enumerated.
Dfu timeout
yaffs: checkpoint restore ... KO!
yaffs: clean up the mess caused by an aborted checkpoint
file "hwinfo-l0" found
file "hwinfo-l1" found
file "hwinfo-l2" found
file "loadercode" found
file "mp1.img" found
file "linux" found
Uncompressing Linux... done, booting the kernel.
Linux version 3.6.0-samoa-01844-g1f05798 (ppd@debian) (gcc version 4.3.4 (Buildroot 2010.02) ) #0 Fri, 10 Feb 2023 16:26:07 +0100
cpufreq: initial frequency: 264000 kHz
MAC-1G DMA: 430ab000 - 430ab9ff
MAC addr = 00:08:19:4e:56:2c
eth0: ioaddr: d00d0000, dev: c30ac000
probing samoafb: rc = 0
  DMA = 4F500000->c3a00000, IO =   (null)
UART 1 probing
UART 1 probing OK
UART 2 probing
UART 2 probing OK
UART 3 probing
UART 3 probing OK
pca953x 0-0049: failed reading register
ba315 ba315.0: NAND ID: id[0-3]=’EF A1 00 95’, manu=’Winbond’, dev=’NAND 128MiB 1,8V 8-bit’
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
yaffs: Attempting MTD mount of 31.0,"mtdblock0"
yaffs: yaffs_read_super: is_checkpointed 0
starting pid 398, tty ’’: ’/etc/init.d/rcS’
/etc/init.d/rcS started
Mounting local file systems: ok
rootfs on / type rootfs (rw)
/dev/root on / type yaffs2 (rw,relatime)
proc on /proc type proc (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
tmpfs on /tmp type tmpfs (rw,relatime)
none on /sys type sysfs (rw,relatime)
Mounting usbfs: failed
Terminal is initializingnPlease wait
...
dropbear is not present
emv-engine-4.3e-with-trace is not present
tim-server-nexo-config_3.1.6.0-1140_arm is not present
mp1-samoa2-eft-sr-prod is not present
Checking for FW updatesnPlease wait

FW is up to date.

Starting Application Monitoring Daemons
Mounting USB stick: failed
starting pid 600, tty ’/dev/ttyCU’: ’/sbin/getty 115200 ttyCU’

samoa login: 

Показано даже приглашение к авторизации. Неплохо! Значит, это определённо журнал загрузки Linux. Во многих встраиваемых системах Linux есть подобная консоль, но чаще всего авторизация отключена полностью или какой-нибудь случайный, жёстко прописанный пароль подставляется либо генерируется при загрузке. Без особых ожиданий я просто из любопытства ввёл в качестве логина «root», и…

samoa login: root
~ #

Подождите-ка! Это что, всё? Я в системе?

Как бы, да. Такова скучная история моего обнаружения root-оболочки. Голой, неприкрытой, root-оболочки. Не потребовалось ни запутанной цепочки эксплойтов, ни подбора паролей… К тому же, несмотря на красный экран с оповещением системы о вскрытии, всё вроде как работает.

Тут вы можете сказать: «Хорошо, но для получения доступа к этой голой root-оболочке нужно вскрыть устройство, что вызовет срабатывание защиты и, по сути, сделает его бесполезным». Но суть в том, что последовательный порт доступен снаружи. К отладочному разъёму можно подключиться без вскрытия устройства через небольшое отверстие на задней панели. Всё, что нужно атакующему — это 30 секунд наедине с устройством, чтобы подключиться к порту, авторизоваться, развернуть вредонос и скрыться. Звучит очень серьёзно.

Как я «случайно» получил root-доступ к платёжному терминалу - 9

Доступ к отладочному разъёму и root-оболочке можно получить извне устройства

▍ Так ли всё плохо на самом деле?

Как я «случайно» получил root-доступ к платёжному терминалу - 10

Столько навороченных аппаратных решений защиты и всё впустую из-за лени программных инженеров?

Собственно, нет. Поясню: В ходе анализа устройства стало ясно, что его система не ограничивается одной только Linux. Например, похоже, здесь нет графического драйвера для дисплея, и единственный фреймбуфер ничего не делает. Вместо этого в двоичный файл (display_tool), который отправляет межпроцессорные сообщения, передаются только текстовые строки. То же касается блока клавиш и самого кардридера. Я не нашёл никаких свидетельств того, что к этим периферийным устройствам можно обратиться напрямую из Linux.

Зато здесь есть полностью отдельный процессор, называемый mp1, который отвечает за все нюансы «безопасности» — обрабатывает вставленную карту, получает пин-код и показывает информацию на экране. То есть «небезопасная» Linux, работающая на втором процессоре, mp2, обрабатывает только сеть, обновления и бизнес-логику.

По всей видимости, ядро Linux загружается всегда, вне зависимости от состояния защиты. И из него уже загружается безопасное ядро. Для этого Linux загружает в память защищённый загрузчик (loadercode), который, в свою очередь, проверяет, срабатывали ли защиты от вскрытия, и исходя из результата либо показывает красный экран, либо продолжает загружать фактический «защищённый» образ (mp1.img в файловой системе Linux). Этот образ уже как следует зашифрован и подписан двумя сущностями.

Как я «случайно» получил root-доступ к платёжному терминалу - 11
Как я на данный момент вижу процесс загрузки Yomani на базе Samoa II ASIC. Первое ядро (небезопасное, прикладное) всегда загружает Linux, которая, в свою очередь, загружает на втором ядре защищённый загрузчик и безопасный образ. Сообщение о вскрытии устройства на экран выводит loadercode. Защищённый образ, который обрабатывает карточку, дисплей и панель клавиш, подобающим образом зашифрован и подписан.

▍ Хронология проекта

  • 14/11/2024 Обнаружил доступ к root-оболочке.
  • 15/11/2024 Уведомил производителя, объявив о том, что опубликую статью через 90 дней.
  • 18/11/2024 Производитель подтвердил получение отчёта.
  • — забыл об этом проекте ---
  • 01/06/2025 Опубликовал статью.

▍ Заключение

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

Предполагаю, что эта отладочная фича просто в один момент каким-то образом проникла в релизную версию прошивки. Есть вероятность, что её обнаружили и исправили ещё до того, как я сообщил об этом производителю (поскольку у меня не было возможности обновить прошивку или убедиться в том, что я использую её последнюю версию).

Это был очень интересный проект, и жаль, что у меня не было больше времени для углублённого анализа прошивки и изучения других возможностей. Если вы желаете перенять эстафету, напишите мне (mail@stefan-gloor.ch). Благодарю всех причастных к этому эксперименту людей за их ценный вклад.

Автор: Bright_Translate

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js