Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-53360-POC — PoC для CVE-2026-53360: вызванный гостем выход за границы кучи при чтении/записи в обработке KVM SEV-SNP Page State Change (PSC). | Kitploit
Инструменты/GitHubGitHub/0xcyberstan/cve-2026-53360-poc
Криминалистика памятиАнализ уязвимостейЭксплуатацияАппаратная БезопасностьЭксплуатация Бинарных Файлов
GitHub0xcyberstan/cve-2026-53360-poc

CVE-2026-53360-POC

PoC для CVE-2026-53360: вызванный гостем выход за границы кучи при чтении/записи в обработке KVM SEV-SNP Page State Change (PSC).

Репозиторий
11 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-53360: Переполнение кучи PSC KVM SEV-SNP

Доказательство концепции для чтения и записи за пределами кучи в обработчике Page State Change (PSC) SEV-SNP KVM. Злоумышленный гость SEV-SNP заставляет ядро хоста обходить массив записей PSC за пределами его slab-выделения. Это раскрывает расположение соседних объектов kmalloc-cg-32 и записывает в них контролируемое небольшое значение, и гость может повторять это сколько угодно.

Полное описание: https://cyberstan.co.uk/sev-snp-oob/

CVECVE-2026-53360
КомпонентПоддержка SNP хоста KVM, arch/x86/kvm/svm/sev.c
Введён9b54e248d264 (первая обработка PSC KVM SNP, май 2024, ~v6.10)
Исправленdb3f219 (основная ветка, май 2026, Cc: stable), помечено Fixes: 4af663c
Сообщён[email protected], 8 апреля 2026
ЗатронутыТолько путь хоста SEV-SNP. KVM не включает PSC для обычных гостей SEV-ES.

Влияние

Любой гость SEV-SNP может повредить кучу ядра хоста и прочитать информацию о её расположении, отправив некорректный запрос PSC. Это направление от гостя к хосту: SEV-SNP создан для защиты гостя от недоверенного хоста, но хост всё ещё должен защищаться от злонамеренного гостя, и этот обработчик этого не делает.

Требования

Для этого требуется реальное оборудование SEV-SNP. Его нельзя воспроизвести на Intel, и вложенная виртуализация не даст вам гостя SNP.

Оборудование:

  • Серверный чип AMD EPYC с SEV-SNP: Milan (7003) или новее, то есть Genoa (9004), Bergamo, Siena или Turin. SEV-SNP — это кремний только для EPYC. Его нет на Ryzen или Threadripper, и здесь нет аналога от Intel (Intel использует TDX).
  • "Голое" железо. Экземпляр "голого" облака также подойдёт (Vultr, AWS *.metal, Hetzner AX и аналогичные).
  • В BIOS включите SEV, SEV-ES, SEV-SNP, SME, IOMMU и SVM. Управляемые "голые" облачные провайдеры обычно уже включают их.

Ядро хоста:

  • Соберите его с KASAN, чтобы выход за границы был зафиксирован. Без KASAN ошибка всё равно повреждает память хоста, просто не выводится. Протестировано на 6.11.11.
    root@kitploit:~
    CONFIG_KASAN=y
    CONFIG_KASAN_GENERIC=y
    CONFIG_KVM=y
    CONFIG_KVM_AMD=y
    CONFIG_KVM_AMD_SEV=y
    CONFIG_CRYPTO_DEV_SP_PSP=y
    
  • Загрузитесь с включённым SNP и KASAN в режиме множественных срабатываний, чтобы каждое попадание было записано в журнал:
    root@kitploit:~
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • Подтвердите готовность хоста:
    root@kitploit:~
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

Пользовательское пространство хоста:

  • QEMU с поддержкой SNP. Стандартный QEMU не поддерживает SNP, поэтому соберите форк AMD:
    root@kitploit:~
    git clone https://github.com/AMDESE/qemu.git
    cd qemu && git checkout snp-latest
    mkdir build && cd build
    ../configure --target-list=x86_64-softmmu && make -j$(nproc)
    
  • Прошивка SNP OVMF с https://github.com/AMDESE/AMDSEV/releases.

Гость:

  • Любой гость Linux, загружаемый под SNP, с установленными build-essential и linux-headers-$(uname -r), чтобы можно было собрать модуль в нём.

Ошибка

Гости SEV-SNP общаются с хостом через GHCB — общую страницу размером 4 КБ. Запрос PSC устанавливает SW_EXITCODE в SVM_VMGEXIT_PSC (0x80000010), указывает SW_SCRATCH на дескриптор и помещает длину дескриптора в SW_EXITINFO2.

Дескриптор — это struct psc_buffer: заголовок из 8 байт, за которым следует массив записей по 8 байт. Явного поля счётчика нет. Хост обрабатывает записи от hdr->cur_entry до hdr->end_entry, оба значения контролируются гостем.

root@kitploit:~
struct psc_hdr {
        u16 cur_entry;
        u16 end_entry;
        u32 reserved;
} __packed;                     /* 8 bytes */

struct psc_entry {
        u64 cur_page    : 12;
        u64 gfn         : 40;
        u64 operation   :  4;
        u64 pagesize    :  1;
        u64 reserved    :  7;
} __packed;                     /* 8 bytes */

Гость GHCB v2+ должен хранить свою scratch-область внутри Shared Buffer GHCB размером 2032 байта, чтобы хост мог использовать существующее отображение. (2032 - 8) / 8 = 253 записи туда помещается, откуда и берётся максимум протокола VMGEXIT_PSC_MAX_COUNT (253). Это число имеет смысл только когда буфер действительно является Shared Buffer.

Если гость указывает scratch-область вне GHCB, хост не может использовать своё отображение, поэтому setup_vmgexit_scratch() выделяет отдельный буфер запрошенного гостем размера. SNP никогда не должен идти по этому пути, но ничто этого не предотвращает:

root@kitploit:~
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);   /* len == exit_info_2, guest-controlled */

len поступает напрямую от гостя, а GFP_KERNEL_ACCOUNT помещает выделение в кэши kmalloc-cg-N с учётом cgroup. Запросите exit_info_2 = 24 и получите выделение в 24 байта в слоте kmalloc-cg-32 размером 32 байта: место для заголовка и двух записей. Всё, что после entries[1], — это память другого объекта.

Затем snp_begin_psc() проверяет количество записей по константе протокола, а не по реально выделенному буферу:

root@kitploit:~
idx_end = hdr->end_entry;

if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {   /* проверяет 253, а НЕ размер буфера */
        snp_complete_psc(svm, ...);
        return 1;
}

for (idx = idx_start; idx <= idx_end; idx++) {
        entry_start = entries[idx];       /* OOB после idx >= 2 */
        ...
}

При буфере в 24 байта существует только две записи, но проверка допускает end_entry до 252. Установите его в 252, и цикл пройдёт примерно на 2 КБ за пределы выделения, через соседние slab-объекты.

Примитивы

Каждый шаг за границу интерпретирует следующие 8 байт slab-памяти как psc_entry и пропускает их через код PSC. Это даёт три вещи:

  1. Оракул чтения. Хост считывает соседнее qword просто для декодирования, извлекая entry.gfn и entry.operation из памяти, которой буфер никогда не владел. Это выход за границы slab при чтении, который регистрирует KASAN.
  2. Ограниченная запись. Если декодированная запись выглядит корректной и отправляется как KVM_HC_MAP_GPA_RANGE, код завершения записывает обратно в тот же OOB-слот: entries[idx].cur_page = entry.pagesize ? 512 : 1. Одно из двух маленьких значений в младшие 12 бит слова, выбранного гостем, повторяемо.
  3. Оракул ошибок. Если запись не прошла проверку, ответ в SW_EXITINFO2 сообщает индекс, на котором остановилась обработка. Увеличивая end_entry по одному, можно выяснить, слот за слотом, была ли соседняя память декодирована как недействующая или как нечто, вызвавшее ошибку. Этого достаточно, чтобы найти границы объектов и отличить ноль от ненулевого значения.

Каждый VMGEXIT перераспределяет scratch-буфер, поэтому повторные запросы попадают в разные слоты freelist и позволяют гостю сканировать соседей, а не зацикливаться на одном. Вместе это даёт раскрытие структуры кучи, описанную ограниченную запись и использование после освобождения между запросами.

Что делает PoC

trigger.c — это гостевой модуль ядра. Загрузите его внутри гостя SEV-SNP, и он выполнит четыре этапа против хоста из одного insmod:

  • Этап 1 зондирует 48 записей за границами по одной и строит карту кучи хоста (нулевая vs. ненулевая соседняя память).
  • Этап 2 доказывает, что OOB-запись сохраняется между VMGEXIT, записывая cur_page в нулевого соседа и подтверждая, что последующий запрос его пропускает.
  • Этап 3 отправляет один запрос с end_entry=200 и измеряет, насколько далеко достигает OOB-чтение до попадания в ненулевые данные.
  • Этап 4 отправляет 200 запросов с entries[3..10] за границами, каждый из которых вызывает сообщение KASAN на хосте.

Модуль выделяет страницу, помечает её как расшифрованную с помощью set_memory_decrypted(), использует её как scratch-область и вручную формирует запрос PSC через GHCB. Он завершается с кодом -EAGAIN, чтобы не оставаться загруженным.

Сборка и запуск

1. Запуск гостя SNP

Настройте пути к OVMF и диску в соответствии с вашей конфигурацией:

root@kitploit:~
qemu-system-x86_64 \
    -enable-kvm -cpu EPYC-v4 \
    -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
    -object memory-backend-memfd,id=ram1,size=4G \
    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=0x30000 \
    -smp 4 -m 4G \
    -bios OVMF_SNP.fd \
    -drive file=guest.qcow2,format=qcow2,if=virtio \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

2. Сборка и загрузка внутри гостя

Скопируйте trigger.c и Makefile в гостя, затем:

root@kitploit:~
make
insmod trigger.ko

Модуль сначала проверяет SEV-SNP через CPUID и отказывается работать где-либо ещё. Он выполняет свои четыре этапа и выгружает себя (init возвращает -EAGAIN, поэтому он никогда не остаётся резидентным).

3. Наблюдение за хостом

На хосте:

root@kitploit:~
dmesg | grep -E "KASAN|BUG|snp_begin_psc"

Ожидаемый вывод:

root@kitploit:~
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199

BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199

The buggy address belongs to the object at ffff888XXXXXXXXX
 which belongs to the cache kmalloc-cg-32 of size 32

Один insmod породил 73 сообщения KASAN на тестовом хосте (62 выхода за границы slab, 7 slab-use-after-free, 4 use-after-free), все против kmalloc-cg-32. Тестовый хост: AMD EPYC 7443P, Ubuntu 24.04.4, ядро 6.11.11 с KASAN, гость под AMDESE QEMU (snp-latest).

Исправление

Исправление в основной ветке отвергает любую scratch-область вне GHCB для GHCB v2 и новее в setup_vmgexit_scratch(), что фиксирует буфер фиксированного известного размера, так что цикл никогда не сможет выйти за конец:

root@kitploit:~
  } else {
+         /* GHCB v2 requires the scratch area to be within the GHCB. */
+         if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
+                 goto e_scratch;
+
          /*
           * The guest memory must be read into a kernel buffer, so
           * limit the size

Эти четыре строки — db3f219. Они были включены в более крупную серию, которая также ограничивает количество записей реальным размером буфера и перечитывает дескриптор через READ_ONCE(), что закрывает вариант со смещением внутрь буфера и состояние гонки "проверка-использование" в том же обработчике.

Файлы

ФайлОписание
trigger.cГостевой модуль ядра, выполняющий четыре этапа PoC
MakefileСобирает trigger.ko под текущее гостевой ядро

Устранение неполадок

  • not an SEV-SNP guest: QEMU не был запущен с sev-snp-guest, или SNP на хосте выключен.
  • QEMU SEV-SNP not supported: проверьте /sys/module/kvm_amd/parameters/sev_snp, настройки BIOS и параметры загрузки.
  • QEMU LAUNCH_START failed: PSP не инициализирован. Проверьте dmesg | grep psp и CONFIG_CRYPTO_DEV_SP_PSP=y.
  • Нет вывода KASAN: убедитесь, что CONFIG_KASAN=y и kasan_multi_shot указаны в командной строке хоста.

Предупреждение

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

Ссылки

  • Статья: https://cyberstan.co.uk/sev-snp-oob/
  • CVE-2026-53360 (следите за коммитом db3f219 в linux-cve-announce)
  • Исправление: db3f219, автор Mike Roth, рецензент Tom Lendacky, закоммитил Paolo Bonzini
  • Введено: 9b54e248d264; исправление помечено Fixes: 4af663c
  • Спецификация GHCB, раздел 2.1 (SW_SCRATCH должен находиться в shared buffer GHCB)

Лицензия

trigger.c распространяется под лицензией GPL-2.0, что соответствует его MODULE_LICENSE. См. LICENSE.

Скачать инструмент
LICENSEGPL-2.0, соответствует MODULE_LICENSE модуля