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

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

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

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

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

Категории

Все категории
Loading categories
virtualbox_e1000_0day — VirtualBox E1000: побег из гостевой системы в хост-систему | Kitploit
Инструменты/GitHubGitHub/mortenoir1/virtualbox_e1000_0day
Анализ уязвимостейЭксплуатацияТестирование на ПроникновениеАппаратная БезопасностьЭксплуатация Бинарных Файлов
GitHubmortenoir1/virtualbox_e1000_0day

virtualbox_e1000_0day

VirtualBox E1000: побег из гостевой системы в хост-систему

Репозиторий
1.4k196227 лет назадПроверено Kitploit

Популярное

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

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

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

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

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

Why

Я люблю VirtualBox, и это не связано с тем, почему я публикую 0day-уязвимость. Причина — моё несогласие с современным состоянием инфосека, особенно в области исследования безопасности и bug bounty:

  1. Ждать полгода, пока уязвимость будет пропатчена, считается нормальным.
  2. В сфере bug bounty нормой считается:
    1. Ждать больше месяца, пока подтвердят присланную уязвимость и примут решение, покупать её или нет.
    2. Менять решение на лету. Сегодня ты выяснил, что программа bug bounty будет покупать баги в каком-то ПО, через неделю приходишь с багами и эксплоитами и получаешь «не интересует».
    3. Не иметь точного списка ПО, баги в котором программа bug bounty готова покупать. Удобно для bug bounty, неудобно для исследователей.
    4. Не иметь точных нижних и верхних границ цен на уязвимости. На цену влияет много факторов, но исследователям нужно знать, над чем стоит работать, а над чем — нет.
  3. Мания величия и маркетинговая чушь: называние уязвимостей и создание для них сайтов; тысяча конференций в год; преувеличение важности собственной работы как исследователя безопасности; считать себя «спасителем мира». Спуститесь на землю, Ваше Высочество.

Я устал от первых двух пунктов, поэтому мой шаг — полное раскрытие. Инфосек, пожалуйста, двигайся вперёд.

Общая информация

Уязвимое ПО: VirtualBox 5.2.20 и более ранние версии.

Хост-ОС: любая, ошибка находится в общей кодовой базе.

Гостевая ОС: любая.

Конфигурация ВМ: по умолчанию (единственное требование — сетевая карта Intel PRO/1000 MT Desktop (82540EM) и режим NAT).

Как защититься

Пока не вышла пропатченная сборка VirtualBox, вы можете сменить сетевую карту ваших виртуальных машин на PCnet (любую из двух) или на Paravirtualized Network. Если не можете, смените режим с NAT на другой. Первый способ безопаснее.

Введение

Сетевое устройство VirtualBox по умолчанию — Intel PRO/1000 MT Desktop (82540EM), а сетевой режим по умолчанию — NAT. Далее будем называть его E1000.

В E1000 есть уязвимость, позволяющая атакующему с правами root/administrator в гостевой системе выйти за её пределы (escape) в ring3 хоста. Затем атакующий может использовать существующие техники для повышения привилегий до ring 0 через /dev/vboxdrv.

Детали уязвимости

E1000 101

Чтобы отправлять сетевые пакеты, гостевая система делает то же, что и обычный ПК: настраивает сетевую карту и передаёт ей сетевые пакеты. Пакеты представляют собой кадры канального уровня и другие заголовки более высокого уровня. Пакеты, передаваемые адаптеру, оборачиваются в Tx-дескрипторы (Tx означает transmit — передача). Tx-дескриптор — это структура данных, описанная в документации 82540EM (317453006EN.PDF, Revision 4.0). Она хранит такую метаинформацию, как размер пакета, VLAN-тег, флаги включения сегментации TCP/IP и так далее.

В документации 82540EM предусмотрено три типа Tx-дескрипторов: legacy, context, data. Legacy, насколько я понимаю, устарел. Два других используются вместе. Нас интересует только то, что контекстные дескрипторы задают максимальный размер пакета и включают/выключают сегментацию TCP/IP, а data-дескрипторы хранят физические адреса сетевых пакетов и их размеры. Размер пакета в data-дескрипторе должен быть меньше максимального размера пакета, заданного контекстным дескриптором. Обычно контекстные дескрипторы передаются сетевой карте перед data-дескрипторами.

Чтобы передать Tx-дескрипторы сетевой карте, гостевая система записывает их в Tx Ring. Это кольцевой буфер, расположенный в физической памяти по заранее заданному адресу. Когда все дескрипторы записаны в Tx Ring, гостевая система обновляет MMIO-регистр TDT (Transmit Descriptor Tail) сетевой карты E1000, чтобы сообщить хосту о наличии новых дескрипторов для обработки.

Входные данные

Рассмотрим следующий массив Tx-дескрипторов:``` [context_1, data_2, data_3, context_4, data_5]

Давайте назначим их поля структуры следующим образом (имена полей гипотетические, чтобы быть читаемыми для человека, но напрямую соответствуют спецификации 82540EM):```
context_1.header_length = 0
context_1.maximum_segment_size = 0x3010
context_1.tcp_segmentation_enabled = true

data_2.data_length = 0x10
data_2.end_of_packet = false
data_2.tcp_segmentation_enabled = true

data_3.data_length = 0
data_3.end_of_packet = true
data_3.tcp_segmentation_enabled = true

context_4.header_length = 0
context_4.maximum_segment_size = 0xF
context_4.tcp_segmentation_enabled = true

data_5.data_length = 0x4188
data_5.end_of_packet = true
data_5.tcp_segmentation_enabled = true

Мы узнаем, почему они должны быть именно такими, в нашем пошаговом анализе.

Анализ первопричины

[context_1, data_2, data_3] Обработка

Предположим, что описанные выше дескрипторы записываются в Tx Ring в указанном порядке, и регистр TDT обновляется гостем. Теперь хост выполнит функцию e1kXmitPending в файле src/VBox/Devices/Network/DevE1000.cpp (большинство комментариев удалено и будет удалено для удобочитаемости):```c static int e1kXmitPending(PE1KSTATE pThis, bool fOnWorkerThread) { ... while (!pThis->fLocked && e1kTxDLazyLoad(pThis)) { while (e1kLocateTxPacket(pThis)) { fIncomplete = false; rc = e1kXmitAllocBuf(pThis, pThis->fGSO); if (RT_FAILURE(rc)) goto out; rc = e1kXmitPacket(pThis, fOnWorkerThread); if (RT_FAILURE(rc)) goto out; }

e1kTxDLazyLoad прочитает все 5 Tx-дескрипторов из Tx Ring. Затем e1kLocateTxPacket вызывается в первый раз. Эта функция проходит по всем дескрипторам, чтобы установить начальное состояние, но фактически не обрабатывает их. В нашем случае первый вызов e1kLocateTxPacket обработает дескрипторы context_1, data_2 и data_3. Оставшиеся два дескриптора, context_4 и data_5, будут обработаны на второй итерации цикла while (вторую итерацию мы рассмотрим в следующем разделе). Это разделение массива на две части является ключевым для срабатывания уязвимости, поэтому давайте разберёмся, почему.

e1kLocateTxPacket выглядит так:```c
static bool e1kLocateTxPacket(PE1KSTATE pThis)
{
...
    for (int i = pThis->iTxDCurrent; i < pThis->nTxDFetched; ++i)
    {
        E1KTXDESC *pDesc = &pThis->aTxDescriptors[i];
        switch (e1kGetDescType(pDesc))
        {
            case E1K_DTYP_CONTEXT:
                e1kUpdateTxContext(pThis, pDesc);
                continue;
            case E1K_DTYP_LEGACY:
                ...
                break;
            case E1K_DTYP_DATA:
                if (!pDesc->data.u64BufAddr || !pDesc->data.cmd.u20DTALEN)
                    break;
                ...
                break;
            default:
                AssertMsgFailed(("Impossible descriptor type!"));
        }

Первый дескриптор (context_1) относится к типу E1K_DTYP_CONTEXT, поэтому вызывается функция e1kUpdateTxContext. Эта функция обновляет контекст сегментации TCP, если для дескриптора включена сегментация TCP. Для context_1 это верно, поэтому контекст сегментации TCP будет обновлён. (Что именно представляет собой обновление контекста сегментации TCP, не важно — мы используем это лишь для ссылки на код ниже).

Второй дескриптор (data_2) относится к типу E1K_DTYP_DATA, поэтому будет выполнено несколько действий, несущественных для обсуждения.

Третий дескриптор (data_3) также относится к типу E1K_DTYP_DATA, но поскольку data_3.data_length == 0, никаких действий не выполняется.

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