
VirtualBox 7.2.20 - Alta - Local - Escritura de archivos - Escape de destino href en OVF
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-ovf-href-dest-escape
Clase: Escritura de archivos Alcance: Local (host) UI:R
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
Un usuario del host que importa un OVF/OVA hostil escribe bytes de imagen de disco fuera de la carpeta de la nueva VM. ovf:href es el nombre de archivo de destino. RTPathAbsExCxx no toma RTPATHABS_F_STOP_AT_BASE. El helper de ruta única inserta _%i antes del sufijo y no elimina el basename.
| ID | aún sin CVE |
| Clase | Escritura de archivos (ruta de destino OVF/OVA) |
| Alcance | Local (host) UI:R (la víctima importa un appliance hostil) |
| CWE | CWE-22 |
| CVSS | Alto: 7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Producto | Oracle VM VirtualBox OSS |
| Afectado | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| Autenticación | ninguna en VirtualBox. El usuario del host abre Archivo/Importar o VBoxManage import. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1. Arnés de código fuente. VirtualBox no se arranca. |
Entregar un directorio OVF o un OVA. Colocar ../somewhere/disk.vmdk o una ruta absoluta /path/disk.iso en ovf:href. El operador que lo importa escribe con CREATE_REPLACE esos bytes de imagen de disco con el UID del importador, incluidos directorios padre que no existían. Se requiere sufijo (vmdk / iso / otras extensiones de MediumFormat). Esto no es una escritura de authorized_keys sin sufijo.
| Privilegio | Método + sink | Qué otorga | Procedencia |
|---|---|---|---|
| Integridad | IAppliance::read copia File/href sin eliminar el basename (ovfreader.cpp). Appliance::interpret() establece dest = di.strHref (ApplianceImplImport.cpp 802-851). | El nombre de archivo de destino lo elige el atacante, incluidos ../ y rutas absolutas. | Probado en laboratorio (hrefs relativos y absolutos) |
| Integridad | i_ensureUniqueImageFilePath (ApplianceImpl.cpp 1126-1160) llama a RTPathAbsExCxx(strAbsName, aMachineFolder, aName) sin RTPATHABS_F_STOP_AT_BASE. La colisión inserta _%i antes del sufijo de aName, no de un basename. | El destino único sigue saliendo de la carpeta de la máquina. ../oracle/WITNESS.vmdk se convierte en ../oracle/WITNESS_1.vmdk. | Probado en laboratorio (unique-keeps-dotdot=yes) |
| Integridad | Importar i_importOneDiskImage AbsEx de nuevo (ApplianceImplImport.cpp 4169-4171). i_importCreateAndWriteDestinationFile (1043-1053) crea los directorios padre y luego RTFILE_O_CREATE_REPLACE. | Los bytes de imagen de disco aterrizan fuera de la carpeta de la VM. Un href absoluto ignora la carpeta de la máquina. El control disk.vmdk permanece dentro de la carpeta. | Probado en laboratorio (relative-escape=yes absolute-href=yes control-in-folder=yes) |
| Reconocimiento | El asistente de importación / VBoxManage import --dry-run muestra el destino. | La ruta es visible. No es una filtración de secretos por sí misma. | Inferido |
| Disponibilidad | Destino relativo que aterriza en el disco de otra VM. | Sobrescribir ese archivo con el UID del importador. | Inferido (misma escritura CREATE_REPLACE) |
| Cerrado | Destino sin sufijo de MediumFormat | La importación lanza has no extension. No es una escritura de authorized_keys / crontab sin sufijo. | Cerrado |
| Cerrado | Destino NVRAM | Forzado a {vmname}.nvram bajo la carpeta de la máquina. | Cerrado |
| Cerrado | Nombre de VM .. | sanitiseMachineFilename lo altera. | Cerrado |
| Cerrado | Carpetas compartidas / ExtraData / RawFile serie | Saneado en la ruta vbox:Machine. | Cerrado |
| Cerrado | Kernel del host, guest-a-host | No es este remanente. No se requiere arrancar la VM. Mismo UID que el importador. | Cerrado |
OVA es el recorrido limpio: el miembro del tar proporciona los bytes, href proporciona el destino escapado. Sin 3D, sin Guest Additions, sin VRDP, sin PUEL.
Me detuve en la etiqueta v7.2.20 (f2792cf44) tras la CPU de septiembre de 2026 y leí la importación de OVF. ExtraData, las carpetas compartidas, el destino de NVRAM y el RawFile del puerto serie ya están eliminados. El destino del disco no lo está. interpret() copia di.strHref directamente en el valor VBox de HardDiskImage:
Utf8Str strFilename = di.strHref;
/* ... */
i_ensureUniqueImageFilePath(strMachineFolder, devType, strFilename);
pNewDesc->i_addEntry(VirtualSystemDescriptionType_HardDiskImage,
hd.strDiskId,
di.strHref,
strFilename,
di.ulSuggestedSizeMB,
strExtraConfig);
ApplianceImpl.cpp 1126-1160 completa ese nombre contra la carpeta de la máquina sin RTPATHABS_F_STOP_AT_BASE, y luego modifica aName in situ:
int vrc = RTPathAbsExCxx(strAbsName, aMachineFolder, aName);
/* ... */
const char *pszSuffix = RTPathSuffix(aName.c_str());
offDashNum = pszSuffix ? (size_t)(pszSuffix - aName.c_str()) : aName.length();
aName.replace(offDashNum, cchDashNum, szTmp, cchTmp);
Import repite AbsEx sobre el dest aún relativo (ApplianceImplImport.cpp 4169-4171) y escrituras CREATE_REPLACE. Las pruebas de IPRT documentan la misma unión: el segundo argumento absoluto gana; /VirtualBox/Machines más ../VirtualBox.xml es /VirtualBox/VirtualBox.xml.
Errores ya registrados: tratar una escritura de authorized_keys sin sufijo como el residuo (la importación lanza excepción); dest de NVRAM (forzado dentro de la carpeta); nombre de VM .. (saneador); carpetas compartidas / ExtraData / RawFile de serie (ya saneados). Teatro: kernel del host, guest-a-host. El oráculo es una línea testigo fuera de la carpeta de la máquina más un disk.vmdk de control que se quedó en su sitio.
python3 vbox-ovf-href-dest-escape-Abraxas-Labs.py
o
cd lab
./run.sh
Arnés de origen de interpret dest-join, unique-path y la escritura de importación CREATE_REPLACE. Docker compose, loopback, sin binario de VirtualBox. Carpeta de máquina /work/Machines/ImportedVM. Oracle /work/oracle.
SUCCESS vbox-ovf-href-dest-escape relative-escape=yes unique-keeps-dotdot=yes absolute-href=yes control-in-folder=yes VBOX-OVF-HREF-DEST-ESCAPE-WITNESS
Eliminar el ovf:href del nombre base antes de que se convierta en un destino, o pasar RTPATHABS_F_STOP_AT_BASE (y rechazar nombres absolutos). Rechazar RTPATH_PROP_DOTDOT_REFS. La ruta única debería modificar el nombre base, no la cadena relativa.