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

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

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).

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

Популярное

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

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

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

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

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

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.
    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 в режиме множественных срабатываний, чтобы каждое попадание было записано в журнал:
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • Подтвердите готовность хоста:
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

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

  • QEMU с поддержкой SNP. Стандартный QEMU не поддерживает SNP, поэтому соберите форк AMD:
    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, оба значения контролируются гостем.

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 никогда не должен идти по этому пути, но ничто этого не предотвращает:

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() проверяет количество записей по константе протокола, а не по реально выделенному буферу:

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 и диску в соответствии с вашей конфигурацией:

Скачать инструмент