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

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

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

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

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

Категории

Все категории
Loading categories
cve-2024-21978-poc — Эксплойт для уязвимости прошивки AMD SEV-SNP CVE-2024-21978, позволяющий расшифровать произвольную память гостевой системы путем повреждения памяти контекстных страниц. | Kitploit
Инструменты/GitHubGitHub/freax13/cve-2024-21978-poc
Инструменты шифрования/дешифрованияКриминалистика памятиАнализ уязвимостейЭксплуатацияТестирование на ПроникновениеАппаратная БезопасностьЭксплуатация Бинарных Файлов
GitHubfreax13/cve-2024-21978-poc

cve-2024-21978-poc

Эксплойт для уязвимости прошивки AMD SEV-SNP CVE-2024-21978, позволяющий расшифровать произвольную память гостевой системы путем повреждения памяти контекстных страниц.

Репозиторий
91 год назадЕщё не проверено

Популярное

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

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

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

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

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

Уязвимость в прошивке SEV

Этот репозиторий содержит эксплойт для уязвимости в прошивке SEV. Эксплойт позволяет расшифровывать произвольную память работающего гостя SEV-SNP.

Протестировано на версии 1.55.16 (последней на момент написания).

Коренная причина

Поле nv_paddr команды SEV_INIT_EX можно использовать для передачи фрагмента памяти прошивке, чтобы она могла использовать его вместо постоянной flash. Если SEV-SNP включен, эта память должна находиться в состоянии FIRMWARE. Прошивка проверяет это один раз во время выполнения команды SEV_INIT_EX. После этого прошивка предполагает, что данная память находится в состоянии FIRMWARE, и записывает в неё без каких-либо дополнительных проверок. Предположение о том, что память всё ещё находится в состоянии FIRMWARE, не всегда верно — ничто не мешает хосту изменить состояние обратно на HYPERVISOR с помощью команды SNP_PAGE_RECLAIM. Как только страницы оказываются в состоянии HYPERVISOR, их можно перевести в другие состояния, например, CONTEXT. Даже если страницы больше не находятся в состоянии FIRMWARE, прошивка будет в них записывать, нарушая целостность, требуемую некоторыми состояниями страниц.

Эксплойт

Мы можем использовать это повреждение памяти, нацелившись на страницы CONTEXT. Страницы CONTEXT — мощная цель, но есть некоторые проблемы:

  1. Страницы CONTEXT шифруются другим ключом, чем остальная память. В результате сложно управлять открытым текстом, даже если мы можем управлять шифротекстом.
  2. У нас не так много контроля над памятью, записываемой прошивкой.

Повреждение памяти фактически заполняет страницу CONTEXT случайными данными, поэтому нелегко повредить страницы CONTEXT таким образом, чтобы это было полезно для атакующего. Чтобы обойти это, мы можем многократно вызывать ошибку, вызывая повреждение, и использовать команду SNP_GUEST_STATUS для чтения соответствующих полей повреждённой страницы CONTEXT, пока не увидим полезные значения.

Команда SNP_DBG_DECRYPT может использоваться для расшифровки памяти гостя SEV-SNP с включённой политикой DEBUG. Если мы сможем сформировать CONTEXT так, чтобы в нём был установлен флаг DEBUG и содержался ASID другого гостя, мы сможем использовать его для расшифровки памяти другого гостя, даже если у него не установлена политика DEBUG.

Оказывается, SNP_DBG_DECRYPT игнорирует большинство полей на странице CONTEXT; она проверяет только gctx->guest.asid, gctx->guest.policy_snp и gctx->guest.guest_flags. Вероятность того, что эти поля окажутся корректными после повреждения памяти, невысока, но не за пределами возможного. Хорошая новость также в том, что мы можем прочитать все эти поля с помощью команды GUEST_STATUS.

Итак, мы можем использовать ошибку, выполнив следующие шаги:

  1. Перевести nv_paddr в состояние FIRMWARE с помощью инструкции rmpupdate.
  2. Выполнить команду SEV_INIT_EX.
  3. Перевести nv_paddr обратно в состояние HYPERVISOR с помощью команды SNP_RECLAIM_PAGE.
  4. Создать одну или несколько страниц CONTEXT по адресу nv_paddr.
  5. Заставить прошивку записать в nv_paddr с помощью команды SEV_PDH_GEN. Это повреждает страницы CONTEXT.
  6. Использовать команду GUEST_STATUS для проверки, будет ли SNP_DBG_DECRYPT успешным; если нет, вернуться к шагу 5. Основное узкое место здесь в том, что ASID хранятся в 32-битном int, но допустимых ASID гораздо меньше (509 или 1006 в зависимости от CPU), поэтому потребуется довольно много попыток, чтобы добиться правильного результата.

Эксплойт проводит большую часть времени на шагах 5 и 6. Шансы на выполнение всех правильных условий составляют примерно 1/20 000 000 на EPYC Milan, и мы можем делать около 100 попыток в секунду, поэтому ожидаем, что правильные условия будут достигнуты примерно раз в два дня (предупреждение: расчёты приблизительны, и я мог что-то напутать, но анекдотически оценка «раз в два дня» кажется верной). Мы можем ускорить это, атакуя не одну страницу CONTEXT за раз, а три страницы CONTEXT по адресам nv_paddr, nv_paddr+4096 и nv_paddr+8192 (SEV_PDG_GEN повредит три страницы). Удобно, что эти шаги можно выполнить до запуска гостя-жертвы, и их нужно выполнить успешно только один раз, чтобы атаковать произвольное количество гостей (однако обратите внимание, что PoC в настоящее время атакует только одного гостя).

Воздействие

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

Смягчение

Несколько команд (например, SNP_RECLAIM_PAGE, SNP_GCTX_CREATE, RING_BUFFER, возможно, ещё, а может быть, для безопасности все?), которые принимают страницу FIRMWARE, должны проверять, перекрывается ли она с nv_paddr, и завершаться ошибкой в случае перекрытия.

Смягчение при обновлении

Есть ещё одна проблема, которая меня беспокоит, и я не уверен, обоснована ли она; буду рад услышать ваше мнение: если я правильно понимаю, прошивку SEV можно обновлять без прерывания работы запущенных гостей. Это означает, что можно перенести повреждённую страницу CONTEXT из старой уязвимой версии прошивки в новую исправленную версию. Можно ли начать на старой уязвимой версии, выполнить описанный эксплойт, обновить и зафиксировать новую исправленную прошивку, запустить гостя на новой прошивке (чтобы старая версия прошивки не отображалась в аттестационном отчёте), а затем использовать повреждённую страницу CONTEXT, созданную с помощью старой прошивки, для атаки на гостя, созданного с помощью новой версии? Сможет ли потребитель аттестационных отчётов, созданных новым гостем, определить, что старая версия прошивки работала в какой-то момент до запуска нового гостя? Если нет, требуются ли дополнительные меры смягчения для предотвращения этого?

Использование PoC

  1. Примените патчи из папки linux-patches к вершине https://github.com/AMDESE/linux/commits/snp-host-v10. Соберите, установите и загрузите ядро.
  2. Запустите PoC.
    root@kitploit:~
    root@server:~/sev-exploit# cargo run --release
        Finished release [optimized] target(s) in 0.12s
        Running `target/release/sev-exploit`
    Corrupt guest context page so that ASID is in range 1..510
    Smallest ASID: 0x0000001f iterations: 14052175 zeros: 10539628 unique asids: 31500727 elapsed time: 1d 19h 20m 31s
    Creating VM with same ASID
    [03, 00, 00, 00, 00, 00, 00, 00, 11, 0f, a0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, f0, 51, a5, 03, 3f, 69, 6b, 93, e8, d8, 61, 0d, 2e, 5a, 45, f1, ea, 6d, bf, 49, fe, e4, a9, 2d, 8d, af, 76, 5e, 2e, 56, e0, fa, a9, b3, a7, e0, bc, 09, d9, 4f, 28, 5c, 9f, 84, d2, 7e, 34, eb, ea, 3f, 29, 88, 30, 01, 28, 65, 8b, 73, 3c, 84, 00, ae, 4a, 74, a2, 7a, d1, c7, 4f, 63, 7f, 72, 7b, 3b, 2f, 08, b3, 1a, 8c, 99, 1b, ad, b5, 1d, 42, 0b, 4d, 98, d4, 7d, c1, 0b, d6, 2f, b4, 6c, 6b, 51, a2, 92, 17, 3b, 01, e8, 82, 11, 1e, cb, cb, a2, 8f, c9, b0, 52, 1d, 1d, b7, d2, 25, 8d, 32, a9, 7a, 6f, 86, e4, 40, 44, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 80, 00, 88, 00, 00, 00, 00, ee, ff, 00, 00, f0, ff, ff, ff, ff, ff, ff, ff, ff, 3f, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, <cut off zeros>]
    thread 'main' panicked at src/main.rs:170:13:
    not yet implemented: use the leaked secrets to send guest messages
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

Обратите внимание, что эксплойт может работать значительное время (от нескольких часов, если повезёт, до нескольких дней, если не повезёт). На EPYC Genoa, вероятно, будет быстрее, так как допустимых ASID почти в два раза больше.

Во время шагов 5 и 6 PoC отображает некоторые метрики:

  • «Наименьший ASID»: наименьший встреченный ASID. Это просто метрика для проверки корректности, чтобы убедиться, что со временем мы встречаем всё меньшие ASID.
  • «итераций»: эта метрика увеличивается каждый раз при активации ошибки.
  • «нулей»: примерно в 1/4 случаев страница CONTEXT находится в состоянии, когда прошивка считает, что ей ещё не назначен ASID. В таких случаях SNP_GUEST_STATUS возвращает 0 в поле ASID.
  • «уникальных asid»: ещё одна вспомогательная метрика, чтобы убедиться, что ASID случайны и не повторяются через некоторое время.
  • «прошедшее время»: время с момента запуска PoC.

В большинстве случаев вывод из эксплуатации повреждённых страниц CONTEXT вызывает сбой прошивки (скорее всего, здесь). Насколько я понимаю, сбои прошивки приводят к перезагрузке всей системы. Чтобы избежать таких сбоев, патчи ядра предотвращают вывод страниц CONTEXT из эксплуатации. Один из недостатков этого заключается в том, что модуль ядра ccp не может быть выгружен. После запуска PoC всю систему необходимо перезагрузить, прежде чем его можно будет запустить снова (независимо от того, успешно ли выполнен PoC или прерван).

Скачать инструмент
  • Запустить (и, при желании, выполнить) гостя-жертву, используя повреждённый ASID в повреждённой странице CONTEXT. Отслеживать страницу секретов. Это возможно, потому что прошивка SEV отслеживает активные ASID внутренне и не проверяет активные страницы CONTEXT на наличие дубликатов.
  • Использовать повреждённую страницу CONTEXT для выполнения SNP_DBG_DECRYPT на странице секретов гостя-жертвы.