
VirtualBox 7.2.20 - Élevé - Local - Écriture de fichier - Évasion de la destination href OVF
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-ovf-href-dest-escape
Classe : Écriture de fichier Portée : Local (hôte) UI:R
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
Un utilisateur hôte qui importe une appliance OVF/OVA hostile écrit des octets d'image disque en dehors du dossier de la nouvelle VM. ovf:href est le nom de fichier de destination. RTPathAbsExCxx ne prend pas RTPATHABS_F_STOP_AT_BASE. L'assistant de chemin unique insère _%i avant le suffixe et ne supprime pas le basename.
| ID | pas encore de CVE |
| Classe | Écriture de fichier (chemin de destination OVF/OVA) |
| Portée | Local (hôte) UI:R (la victime importe une appliance hostile) |
| CWE | CWE-22 |
| CVSS | Élevé : 7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Produit | Oracle VM VirtualBox OSS |
| Affecté | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| Auth | aucune sur VirtualBox. L'utilisateur hôte ouvre Fichier/Importer ou VBoxManage import. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement. Harnais source. VirtualBox n'est pas démarré. |
Livrer un répertoire OVF ou une OVA. Placer ../somewhere/disk.vmdk ou un chemin absolu /path/disk.iso dans ovf:href. L'opérateur qui l'importe effectue une écriture CREATE_REPLACE de ces octets d'image disque avec l'UID de l'importateur, y compris les répertoires parents qui n'existaient pas. Suffixe requis (vmdk / iso / autres extensions MediumFormat). Il ne s'agit pas d'un dépôt sans suffixe de authorized_keys.
| Privilège | Méthode + sink | Ce que cela accorde | Provenance |
|---|---|---|---|
| Intégrité | IAppliance::read copie File/href sans suppression de basename (ovfreader.cpp). Appliance::interpret() définit dest = di.strHref (ApplianceImplImport.cpp 802-851). | Le nom de fichier de destination est choisi par l'attaquant, y compris ../ et les chemins absolus. | Prouvé en lab (hrefs relatifs et absolus) |
| Intégrité | i_ensureUniqueImageFilePath (ApplianceImpl.cpp 1126-1160) appelle RTPathAbsExCxx(strAbsName, aMachineFolder, aName) sans RTPATHABS_F_STOP_AT_BASE. La collision insère _%i avant le suffixe de aName, pas un basename. | La destination unique sort toujours du dossier de la machine. ../oracle/WITNESS.vmdk devient ../oracle/WITNESS_1.vmdk. | Prouvé en lab (unique-keeps-dotdot=yes) |
| Intégrité | Import i_importOneDiskImage AbsEx à nouveau (ApplianceImplImport.cpp 4169-4171). i_importCreateAndWriteDestinationFile (1043-1053) crée les parents mkdir puis RTFILE_O_CREATE_REPLACE. | Les octets d'image disque atterrissent en dehors du dossier de la VM. Un href absolu ignore le dossier de la machine. Le contrôle disk.vmdk reste dans le dossier. | Prouvé en lab (relative-escape=yes absolute-href=yes control-in-folder=yes) |
| Recon | L'assistant d'import / VBoxManage import --dry-run affiche la destination. | Le chemin est visible. Pas une fuite de secret en soi. | Déduit |
| Disponibilité | Destination relative qui atterrit sur le disque d'une autre VM. | Écraser ce fichier avec l'UID de l'importateur. | Déduit (même écriture CREATE_REPLACE) |
| Fermé | Destination sans suffixe MediumFormat | L'import lève has no extension. Pas une écriture sans suffixe de authorized_keys / crontab. | Fermé |
| Fermé | Destination NVRAM | Forcée à {vmname}.nvram sous le dossier de la machine. | Fermé |
| Fermé | Nom de VM .. | sanitiseMachineFilename le mutile. | Fermé |
| Fermé | Dossiers partagés / ExtraData / RawFile série | Assainis sur le chemin vbox:Machine. | Fermé |
| Fermé | Noyau hôte, invité-vers-hôte | Pas ce reliquat. Aucun démarrage de VM requis. Même UID que l'importateur. | Fermé |
L'OVA est le chemin propre : le membre tar fournit les octets, href fournit la destination échappée. Pas de 3D, pas de Guest Additions, pas de VRDP, pas de PUEL.
Je me suis placé sur le tag v7.2.20 (f2792cf44) après le CPU de septembre 2026 et j'ai lu l'import OVF. ExtraData, les dossiers partagés, la destination NVRAM et le RawFile série sont déjà retirés. La destination du disque ne l'est pas. interpret() copie di.strHref directement dans la valeur 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 complète ce nom par rapport au dossier de la machine sans RTPATHABS_F_STOP_AT_BASE, puis modifie aName sur place :
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);
L'import répète AbsEx sur la dest encore relative (ApplianceImplImport.cpp 4169-4171) et effectue des écritures CREATE_REPLACE. Les tests IPRT documentent la même jointure : le second argument absolu l'emporte ; /VirtualBox/Machines plus ../VirtualBox.xml donne /VirtualBox/VirtualBox.xml.
Fausses pistes déjà consignées : traiter une écriture authorized_keys sans suffixe comme le résidu (l'import lève une exception) ; la dest NVRAM (forcée dans le dossier) ; le nom de VM .. (assainisseur) ; les dossiers partagés / ExtraData / le RawFile série (déjà assainis). Théâtre : noyau hôte, invité-vers-hôte. L'oracle est une ligne témoin en dehors du dossier de la machine plus un disk.vmdk de contrôle resté en place.
python3 vbox-ovf-href-dest-escape-Abraxas-Labs.py
ou
cd lab
./run.sh
Harnais source d'interprétation de dest-join, unique-path et de l'écriture d'import CREATE_REPLACE. Docker compose, loopback, pas de binaire VirtualBox. Dossier machine /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
Supprimer le basename de ovf:href avant qu'il ne devienne un dest, ou passer RTPATHABS_F_STOP_AT_BASE (et rejeter les noms absolus). Rejeter RTPATH_PROP_DOTDOT_REFS. Le chemin unique doit modifier le basename, pas la chaîne relative.