
Oracle VM VirtualBox 7.2.20 - Alta - Locale - Lettura di file - Path join dell'extent FLAT sparse VMDK
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-vmdk-sparse-extent
Classe: Lettura di file Portata: Locale (host) UI:R
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
Un utente host che importa una directory OVF o un OVA il cui disco è un descrittore VMDK sparse più un extent FLAT apre un percorso host indicato in quell'extent e copia quei byte nel disco importato. Dopo vmdkParseDescriptor, ogni extent con pszBasename che inizia con RTPATH_SLASH viene usato così com'è; altrimenti RTPathJoinA(descriptor dir, pszBasename) che segue ../. FLAT e HOSTED_SPARSE eseguono poi vmdkFileOpen su quel percorso completo. streamOptimized (il consueto export di VirtualBox, magic VMDK) è un singolo file e non segue questo percorso. L'importazione accetta comunque lo specificatore sparse.
| ID | nessuna CVE al momento |
| Classe | Lettura di file (percorso extent FLAT/sparse di VMDK sparse) |
| Portata | Locale (host) UI:R (la vittima importa un appliance ostile) |
| CWE | CWE-22 |
| CVSS | Alto: 7.7 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N |
| Prodotto | Oracle VM VirtualBox OSS |
| Affetto | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| Auth | nessuna su VirtualBox. L'utente host apre File/Import o VBoxManage import. |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1. Harness sorgente. VirtualBox non viene avviato. |
Distribuire una directory OVF o un OVA. Inserire un descrittore VMDK sparse (# Disk DescriptorFile, createType="monolithicFlat") accanto a un extent FLAT il cui basename tra virgolette è ../../somewhere/secret o /path/secret. L'operatore che lo importa apre quel percorso host con l'UID che esegue l'importazione e copia i byte nel disco di destinazione. streamOptimized (magic VMDK 0x564D444B) non consulta il nome FLAT incorporato. Si tratta di una lettura di file che l'UID di VBox può aprire, non di una scrittura senza suffisso di authorized_keys.
| Privilegio | Metodo + sink | Cosa concede | Provenienza |
|---|---|---|---|
| Ricognizione | Importazione di un VMDK sparse ASCII. Dopo vmdkParseDescriptor, RTPathJoinA(descriptor dir, pszBasename) senza collasso di ../ (VMDK.cpp 3472-3503). FLAT vmdkFileOpen di quel percorso completo. L'importazione copia quei byte nella dest. | Byte di file host nominati tramite ../ finiscono nel disco importato. Nel lab pszBasename ../../oracle/VBOX-VMDK-SPARSE-EXTENT-WITNESS unito a /work/import/disk/../../oracle/... e copiato in /work/import/out.vmdk. | Dimostrato nel lab (relative-escape=yes) |
| Ricognizione | Stessa procedura. pszBasename[0] == RTPATH_SLASH viene usato così com'è (VMDK.cpp 3477-3485). | Percorso host assoluto aperto e copiato. Nel lab /work/oracle/VBOX-VMDK-SPARSE-EXTENT-WITNESS. | Dimostrato nel lab (absolute-extent=yes) |
| Ricognizione | Controllo FLAT disk-flat.vmdk unito sotto la directory del descrittore. | Rimane nella cartella. Nel lab nome completo /work/import/disk/disk-flat.vmdk. Byte CONTROL-FLAT-NOT-ORACLE. | Dimostrato nel lab (control-in-folder=yes) |
| Ricognizione | streamOptimized con magic VMDK. vmdkDescriptorRead usa vmdkDescriptorReadSparse. FLAT ASCII incorporato che nominava l'oracle. | Non ha aperto il nome incorporato. La dest è rimasta il file stream (STREAMOPTIMIZED-SELF-NOT-ORACLE). | Dimostrato nel lab (streamoptimized-consults-extent=no) |
| Ricognizione | Avvio del guest, poi lettura del volume convertito. | Il guest vede i contenuti del file host leggibili dall'UID dell'importer che sono finiti nella dest. | Dedotto (stessa copia; il lab non avvia un guest) |
| Disponibilità | Dest di importazione già esistente, o un successivo attach del disco convertito. | Disponibilità di sovrascrittura del disco dest. I contenuti diventano il file host aperto. | Dedotto (stessa scrittura della dest) |
| Chiuso | VMDK streamOptimized (normale esportazione VirtualBox) | Ramo magic. File singolo. Il nome FLAT incorporato non viene aperto. | Chiuso |
| Chiuso | Lettera di unità Windows assoluta (C:\...) | Potrebbe non intercettare pszBasename[0] == RTPATH_SLASH. Il codice definisce l'hack il controllo assoluto (@todo implement proper path absolute check). | Chiuso |
| Chiuso | Scritture senza suffisso (authorized_keys, crontab) | Non è un residuo di scrittura. L'apertura dell'extent è una lettura del percorso host nominato. | Chiuso |
| Chiuso | Kernel host, guest-to-host, altre VM, memoria VBoxSVC | Non è questo residuo. Nessun avvio di VM necessario per la copia. Stesso UID dell'importer. | Chiuso |
OVA segue la stessa procedura una volta che il descrittore sparse è su disco: il membro tar fornisce il descrittore più (opzionale) FLAT nella cartella; il basename dell'extent fornisce l'apertura con escape. Nessun 3D, nessun Guest Additions, nessun VRDP, non PUEL.
Mi sono fermato sul tag v7.2.20 (f2792cf44) dopo la CPU di settembre 2026 e ho letto l'importazione VMDK. ExtraData, cartelle condivise, dest NVRAM e serial RawFile sono già rimossi. La dest ovf:href è un residuo adiacente. La normale esportazione VirtualBox è streamOptimized. interpret() accetta comunque lo specificatore sparse (g_pszVMDKSparseURI). Dopo vmdkParseDescriptor, il basename dell'extent viene unito senza collassare ../ né rifiutare percorsi assoluti:
/* Hack to figure out whether the specified name in the
* extent descriptor is absolute. Doesn't always work, but
* should be good enough for now. */
char *pszFullname;
/** @todo implement proper path absolute check. */
if (pExtent->pszBasename[0] == RTPATH_SLASH)
{
pszFullname = RTStrDup(pExtent->pszBasename);
/* ... */
}
else
{
char *pszDirname = RTStrDup(pImage->pszFilename);
RTPathStripFilename(pszDirname);
pszFullname = RTPathJoinA(pszDirname, pExtent->pszBasename);
/* ... */
}
pExtent->pszFullname = pszFullname;
RTPathJoinA bilancia solo le barre. Non comprime ... FLAT e HOSTED_SPARSE aprono quindi quella stringa:
case VMDKETYPE_FLAT:
rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszBasename, pExtent->pszFullname,
VDOpenFlagsToFileOpenFlags(uOpenFlags, false /* fCreate */));
vmdkDescriptorRead esegue lo split sul magic. Il magic sparse VMDK (0x564D444B) richiama vmdkDescriptorReadSparse e mantiene il file già aperto come extent. L'ASCII richiama vmdkDescriptorReadAscii e il join di cui sopra.
Vicoli ciechi già registrati: trattare streamOptimized come questo residuo (il magic non consulta il nome FLAT incorporato); trattare un percorso assoluto con lettera di unità Windows come il controllo slash Unix; trattare la sovrascrittura del disco di destinazione come una scrittura di authorized_keys senza suffisso; avviare una VM quando l'harness sorgente del join è sufficiente. Teatro: kernel host, guest-to-host. L'oracolo è una riga testimone esterna alla cartella del descrittore più un disk-flat.vmdk di controllo rimasto al suo posto.