Содержание статьи
- Исследуем модем
- Общаемся с модемом удаленно
- Переполнение кучи
- Что делать с black box окружением?
- Поиск примитива записи
- Реализация записи в память на практике
- Особенности обработки каждого WAP-сообщения
- Собираем все вместе
- Исполнение кода
- Разблокируем память
- Запускаем свое приложение, без регистрации, но через SMS
- Возможные риски
Найденная уязвимость впоследствии получила идентификатор CVE-2023-47610 и высокую оценку критичности.
Pentest Award
Этот текст получил первое место на премии Pentest Award 2024 в категории «Девайс». Это соревнование ежегодно проводится компанией Awilix.
Модемы Cinterion стоят в огромном числе самых разных устройств. Даже примерный список девайсов составить сложно, поскольку модель модема не всегда указана в документации. Мы изучали сайты производителей и таможенные декларации импортеров разных изделий и установили, что такие модемы можно встретить в умных устройствах, банкоматах, индустриальных шлюзах, автомобилях и даже медицинском оборудовании.
Результатами исследования мы уже делились на конференциях OffensiveCon и Hardware.io.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Исследуем модем
Итак, наш модем — это модуль в форм‑факторе LGA (Land Grid Array), предназначенный для встраивания в печатные платы. Сам модуль состоит из baseband-процессора Intel X-Gold 625 (XMM 6260), микросхемы NAND-флеш‑памяти (совмещенной с 512 Мбит памяти LPDDR), микросхемы RF-усилителя и трансивера. Модем поддерживает стандарты GSM, GPRS, EDGE, UMTS и HSPA+.
Чтобы получить прошивку, мы сняли защитный экран и выпаяли микросхему флеш‑памяти, после чего считали данные с нее на программаторе и восстановили логические блоки из сырого образа.
Общаемся с модемом удаленно
Cinterion EHS5 поддерживает геопозиционирование с помощью подсистемы SUPL. Она отвечает за обмен специальными сообщениями между H-SLP (Home SUPL Location Platform) и SET (SUPL Enabled Terminal). Сам модем при этом — это объект типа SET.
Для коммуникации используется бинарный протокол ULP. Его данные в сети GSM передаются при помощи push-сообщений через стек протоколов WAP (Wireless Application Protocol).
На уровне push-сообщений WSP (Wireless Session Protocol) в протокол ULP заложена возможность фрагментации передаваемого сообщения. Это сделано для того, чтобы можно было передавать большие бинарные сообщения через ограниченный канал передачи SMS. Чтобы фрагментированные послания можно было собрать на стороне SET, они индексируются. При этом в самом начале SUPL-сообщения указывается еще и размер всего сообщения.
С помощью статического анализа мы изучили части кода ОС модема, а именно, участки, отвечающие за реализацию этого протокола. Прежде всего мы выяснили, что в модеме используется операционная система ThreadX, затем — нашли функции создания процессов и в одном из них обнаружили код обработки тех самых «магических» значений из SMS-сообщений со скриншотов выше.
После этого мы углубились в изучение алгоритма работы.
Переполнение кучи
Изучая драйвер, отвечающий за обработку фрагментации ULP-сообщений, мы нашли уязвимость переполнения кучи.
На скриншоте выше переменная ULPSizeFromPacket
отвечает за размер всего пакета ULP, а за размер принятого WAP-сообщения — переменная wapTpduLen
. Обработка WAP-сообщений заключается в последовательном копировании фрагментов ULP-сообщения в буфер, размер которого равен ULPSizeFromPacket
.
В соответствии с протоколом передачи переменные ULPSizeFromPacket
и wapTpduLen
вычисляются независимо. Эти переменные имеют отношение к разным уровням представления данных и косвенно связаны только в части алгоритма приема WAP-сообщений: сумма размеров всех принятых WAP-сообщений одного UPL-сообщения не должна превышать ULPSizeFromPacket
. Но в алгоритме приема WAP-сообщений отсутствует такая проверка. Соответственно, принятое WAP-сообщение размера wapTpduLen
будет безусловно копироваться в буфер размера ULPSizeFromPacket
. Это классическая уязвимость типа Heap-based Buffer Overflow.
Мы сформировали соответствующее SMS-сообщение и с первой же попытки вызвали переполнение буфера на стороне модема, что привело к его полной перезагрузке.
Что делать с black box окружением?
Мы нашли переполнение буфера, и это хорошо. Но нам неизвестен его контекст, и это плохо. У нас нет никакой возможности хотя бы прочитать память модема (RAM), чтобы разобраться в происходящем... или есть?
При переполнении буфера мы получали стабильный Hardware Fault и перезагрузку модема, а в качестве обратной связи смогли извлечь только адрес места падения и состояние регистров процессора с помощью AT-команды AT+XLOG
.
Чтобы продвинуться в эксплуатации, нужно было проанализировать место падения, получить контекст исполнения (состояние оперативной памяти на момент падения) и разобраться в устройстве менеджера кучи операционной системы ThreadX. Мы не могли читать память или отлаживать прошивку, однако мы обнаружили, что при падении в регистр R0 попадают контролируемые нами данные.
Дальнейший анализ кода прошивки показал, что падение происходит внутри функции malloc
, когда программа пытается разыменовать указатель, содержащий контролируемый нами адрес в регистре R0.
Значение 0xFFFFEEEE
— «магическое» и означает начало свободного блока памяти в куче. В случае если блок занят, в Curr_Chunk[
вместо магического значения будет указатель на структуру, описывающую глобальное состояние менеджера кучи (HeapBase
).
Если вызвать переполнение таким образом, чтобы в регистре R0 оказался корректный адрес памяти модема, то падения в этом месте не произойдет и в R0 сохранится значение из памяти по этому адресу. Однако если значение не окажется корректным адресом, то программа упадет и значение, записанное ранее в R0, можно будет прочитать после перезагрузки командой AT+XLOG
. Модем загружается всегда по одному сценарию, поэтому между перезагрузками его оперативная память будет иметь приблизительно одинаковый вид.
Эта находка позволила нам очень медленно, со скоростью 4 байта в минуту, считывать память модема путем отправки SMS-сообщений, вызывающих переполнение кучи. Для автоматизации процесса мы собрали стенд, и в итоге считывание интересующих областей памяти таким изощренным способом заняло несколько недель.
Поиск примитива записи
Пока память считывалась, мы занялись детальным изучением устройства кучи в ОС ThreadX с целью найти примитив записи. Мы полностью проанализировали код функций malloc
и free
и определили, что единственное подходящее место, в котором происходит запись в память через двойное разыменование, находится в коде free
, и связано это с особенностями ее реализации.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее