
VirtualBox 7.2.20 — высокий уровень — локальная — чтение файла — OVF NAT TFTP пустой префикс
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-ovf-nat-tftp-prefix
Класс: чтение файлов Достижимость: локально (гость) после импорта с UI:R
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) — Oracle
Импорт vbox:Machine OVF очищает ExtraData, общие папки, путь NVRAM и serial RawFile. Он никогда не трогает NAT enable-tftp или TFTP @prefix. libslirp отключает TFTP только когда tftp_prefix равен NULL. DrvNAT g_strdup("") остаётся не-NULL. Гостевой RRQ etc/passwd с префиксом / или пустым становится /etc/passwd. ../ в гостевом имени по-прежнему отклоняется.
Импортированный NAT TFTP с пустым префиксом или префиксом / позволяет гостю выполнять RRQ к файлам хоста от имени UID VBox. Не запись. Не ядро хоста. Не остаток закрытой проверки ../.
| ID | CVE пока нет |
| Класс | Чтение файлов (гостевой TFTP RRQ к путям хоста) |
| Достижимость | Локально (гость) после импорта vbox:Machine OVF с UI:R, затем запуск VM |
| CWE | CWE-22 — остаток класса префиксов CVE-2022-21394 |
| CVSS | High: 7.7 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N |
| Продукт | Oracle VM VirtualBox OSS |
| Затронуто | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| Аутентификация | отсутствует в госте; пользователь хоста должен выполнить Import, затем Start |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | исходный harness; loopback compose; VirtualBox не загружается |
Поставить vbox:Machine OVF/OVA, в NAT-блобе которого заданы enable-tftp и TFTP-префикс / или пустой, вместе с гостевым диском, который выполняет TFTP RRQ к NAT-шлюзу (10.0.2.2:69). Пользователь хоста импортирует (File / Import или VBoxManage import) и запускает VM. Импорт очищает ExtraData, общие папки, serial RawFile и путь NVRAM. Поля TFTP сохраняются. При запуске ConsoleImplConfigCommon вставляет EnableTFTP. Пустой префикс опускается в CFGM; DrvNAT затем по умолчанию задаёт TFTPPrefix как "" и выполняет g_strdup. libslirp считает это включённым.
Это весь набор привилегий. Здесь нет ни записи на хост, ни примитива кучи процесса VM, ни побега из ядра.
| Метод | Точка сброса | Привилегия |
|---|---|---|
TFTP RRQ oracle/VBOX-OVF-NAT-TFTP-PREFIX-WITNESS с импортированным префиксом "" | libslirp tftp_handle_rrq, затем RTFileOpen для префикса + / + гостевого имени | Доказано в лаборатории. Пустой префикс остаётся не-NULL. Построенный путь — /oracle/VBOX-OVF-NAT-TFTP-PREFIX-WITNESS. Открытие только для чтения вернуло байты свидетеля. |
TFTP RRQ того же имени с импортированным префиксом / | то же | Доказано в лаборатории. Построенный путь — //oracle/..., POSIX-эквивалентный /oracle/.... Байты свидетеля возвращены. |
Путевой аналог гостевого RRQ etc/passwd с пустым префиксом | "" + "/" + "etc/passwd" | Построение пути доказано в лаборатории. Результат — /etc/passwd. Лаборатория не открывает хостовый /etc. |
TFTP RRQ любого относительного имени, которое может открыть UID VBox (ключи в home, VirtualBox.xml, хостовый /etc, корень текущего диска Windows) | тот же RTFileOpen | Предположено. Та же конкатенация. Файлы, которые процесс не может открыть, остаются закрытыми (File not found). |
| Метод | Привилегия |
|---|---|
| TFTP WRQ | Закрыто. Этот TFTP-сервер поддерживает только RRQ. Обработчика записи нет. |
| Перезапись / создание файла хоста | Закрыто. Только чтение RTFILE_O_READ. |
| Куча процесса VM, VBoxSVC, другие VM, ядро хоста | Закрыто. Этот остаток — открытие файла по построенному пути. |
| TFTP DoS | Вне рамок. |
fEnableTFTP false (конструктор NATEngine в Settings.cpp).VBoxNetSlirpNAT всегда устанавливает tftp_path в <VirtualBox home>/TFTP, если home существует. RRQ остаются под этим префиксом.../ и завершающий / по-прежнему вызывают "Access violation". Это закрытый обход CVE-2022-21394./work/tftp/boot.pxe в лаборатории).Реальный хост, который импортирует этот appliance и запускает ВМ, даёт гостю чтение любого пути, который может открыть UID VBox. Лаборатория — это исходный стенд для такого обхода. VirtualBox не загружается.
Я зафиксировал VirtualBox/virtualbox v7.2.20 (f2792cf44). Поиск по NAT и OVF. В 7.2 NAT переключён на встроенный libslirp 4.9.3. Поддержка общих папок из .ova уже считается опасностью и вырезается. TFTP в этом списке не было.
Settings.cpp по-прежнему читает NAT enable-tftp и TFTP/@prefix при импорте vbox:Machine:
elmMode.getAttributeValue("enable-tftp", nic.nat.fEnableTFTP);
// ...
pelmTFTP->getAttributeValue("prefix", nic.nat.strTFTPPrefix);
ApplianceImplImport.cpp:6147 очищает всё, что они вспомнили:
config.sanitizeImportedSerialPorts();
config.sanitizeSharedFolderSettings();
config.sanitizeImportedNvramSettings();
if (!m->optListImport.contains(ImportOptions_KeepExtraData))
config.sanitizeImportedExtraData();
Эти четыре тела никогда не упоминают strTFTPPrefix или fEnableTFTP.
При запуске ConsoleImplConfigCommon.cpp:2286-2292 вставляет TFTPPrefix только если он не пуст, и всегда вставляет EnableTFTP. DrvNAT.cpp:1656-1665 по умолчанию устанавливает EnableTFTP в true для старых ВМ, в которых отсутствует этот ключ, затем:
rc = pDrvIns->pHlpR3->pfnCFGMQueryStringAllocDef(pCfg, "TFTPPrefix", &pszTmp, "");
slirpCfg.tftp_path = pszTmp;
slirp.c:698 — это g_strdup. Пустая строка остаётся не-NULL. tftp.c:353-357 отключает только при NULL. 364-370 добавляет префикс, /, имя гостя. 398-407 отклоняет ../. Затем RTFileOpen для построенного пути.
Уже зафиксированные неверные пути: трактовка гостевого ../ как остаточного (CVE-2022-21394, по-прежнему отклоняется); трактовка новых ВМ по умолчанию как уязвимых; трактовка домашнего каталога/TFTP NAT Network как этого остатка; утверждение о записях WRQ; утверждение о ядре хоста. Театр: открытие /etc/passwd хоста. Оракул — файл-свидетель в /oracle.
python3 vbox-ovf-nat-tftp-prefix-Abraxas-Labs.py
или
cd lab
./run.sh
Исходная обвязка пин-санитайзеров, значение по умолчанию DrvNAT в виде пустой строки, g_strdup и tftp_handle_rrq из libslirp. Проект Docker compose vbox-ovf-nat-tftp-prefix. Только loopback. VirtualBox не загружается. Свидетель VBOX-OVF-NAT-TFTP-PREFIX-WITNESS размещён в /oracle/.... Контрольный PXE-файл — /work/tftp/boot.pxe. Последняя строка: