
VirtualBox 7.2.20 - Alta - Local - Desbordamiento de heap - HGCM SSM cParms wrap
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-hgcm-ssm-cparms
Clase: Desbordamiento de heap Alcance: Local (host)
Oracle VM VirtualBox OSS 7.2.20 (f2792cf44) - Oracle
El HGCM en vivo sigue rechazando cParms > 32. La carga de estado guardado no. vmmdevR3HgcmLoadState lee cParms del .sav sin ningún límite VMMDEV_MAX_HGCM_PARMS, y luego dimensiona el comando con uint32_t cbCmd. Con cParms = 0x4000000 ese producto se desborda hasta sizeof(VBOXHGCMCMD) (~120). El primer almacenamiento de enmType ya es una escritura de 4 bytes más allá del bloque.
Un usuario del host que restaura un estado guardado hostil desborda el heap del proceso de la VM. Un invitado no puede plantar esto mediante Save.
| ID | aún sin CVE |
| Clase | Desbordamiento de heap (escritura fuera de límites en el proceso de la VM; no es un escape al kernel del host) |
| Alcance | Local (host) (UI:R restauración de estado guardado / snapshot) |
| CWE | CWE-190, CWE-787 |
| CVSS | Alto: 7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Producto | VirtualBox OSS |
| Afectado | 7.2.20 (f2792cf44f663989818507e36d3db5f978523c5e) |
| Autenticación | usuario del host restaura una VM guardada, un snapshot o un .sav |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1. Arnés de código fuente. Sin arranque de VirtualBox, sin análisis de .sav. |
Entregar al operador una carpeta de VM cuyo estado guardado lleva una llamada CALL de VMMDev HGCM pendiente. El operador hace clic en Start sobre una VM guardada, restaura un snapshot o adopta el .sav. La restauración de la consola recorre SSMR3 hasta vmmdevR3LoadExec y luego hasta vmmdevR3HgcmLoadState. Eso es UI:R. El residuo es el analizador, no una hiperllamada del invitado.
VMMDev está activado por defecto. Sin 3D. Sin Guest Additions. Sin VRDP. No es PUEL.
| Paso | Dónde | Qué otorga |
|---|---|---|
| Restauración | UI del host / VBoxManage startvm sobre una VM guardada | El usuario del host abre el .sav hostil. Ese es el único clic necesario. |
| Unidad SSM | VMMDev vmmdevR3HgcmLoadState (VMMDevHGCM.cpp:2043-2091) | SSMGetU32 hacia cParms sin límite VMMDEV_MAX_HGCM_PARMS (32). |
| Desbordamiento de asignación | vmmdevR3HgcmCmdAlloc (VMMDevHGCM.cpp:376-381) | uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (40+24). cParms = 0x4000000 se desborda hasta ~120. RTMemAllocZ de ese tamaño tiene éxito frente al presupuesto del heap. |
| Primer almacenamiento | bucle de carga paGuestParms[i].enmType (VMMDevHGCM.cpp:2085-2091) | paGuestParms es pCmd + sizeof(VBOXHGCMCMD), que ya es el final de la asignación tras el desbordamiento. El primer dword de tipo es una escritura fuera de límites de 4 bytes. El flujo solo necesita la cabecera CALL más un tipo de parámetro. No necesita 67 millones de registros. |
| Tipo | Procedencia | Qué obtiene el atacante |
|---|---|---|
| Reconocimiento | ninguna | Los bytes de desbordamiento son elegidos por el sav. Esto no es una fuga. El contenido del heap no se devuelve al archivo. |
| Integridad | probado en laboratorio | cParms=0x4000000 envuelve uint32_t cbCmd a 120. Un almacenamiento enmType con i=0 destruye un canario 0xA5. canary0=56424f58 es el prefijo VBOX de VBOX-HGCM-SSM-CPARMS-WITNESS. El control cParms=2 deja el canario intacto. |
| Integridad | inferido | Posteriores registros de parm controlados por el sav (dword de tipo más campos de 32/64 bits o descriptores de puntero) escriben linealmente fuera del RTMemAllocZ de ~120 bytes en VirtualBoxVM / VBoxHeadless. Eso es una primitiva de escritura en el proceso de la VM, de la misma clase que la memcorr de migración de QEMU. Este paquete no demuestra control del puntero de instrucción. |
| Disponibilidad | inferido | Caída de VBoxVM si la destrucción no se convierte en una escritura controlada. El arnés es una destrucción de canario, no una caída del proceso de VirtualBox. |
vmmdevR3HgcmCallAlloc en vivo sigue rechazando cParms > 32 (VMMDevHGCM.cpp:921-926). Un invitado no puede plantar la envoltura mediante un Save legítimo.VMMDEV_MAX_HGCM_PARMS 32, VMMDEV_MAX_HGCM_DATA_SIZE 128MiB).offValue / cbValue al completarse es una segunda escritura en el heap del anfitrión solo si los clientes HGCM restauran en el mismo sav. No es este laboratorio.El host-user / host-kernel completo todavía necesita un remanente de endurecimiento. Combinar esta destrucción con el bypass público de IDispatch queda descartado.
Fijé la etiqueta v7.2.20 de VirtualBox/virtualbox con peel f2792cf44. Lo primero que leí fue el HGCM en vivo porque CVE-2013-5892 era de esta clase: envoltura del tamaño de argumentos en VBOXHGCMCMD. La ruta en vivo todavía tiene el límite:
ASSERT_GUEST_STMT_RETURN( cParms <= (cbHGCMCall - sizeof(VMMDevHGCMCall)) / cbHGCMParmStruct
&& cParms <= VMMDEV_MAX_HGCM_PARMS,
LogRelMax(50, ("VMMDev: request packet with invalid number of HGCM parameters: ...")),
VERR_INVALID_PARAMETER);
Load no lo hace. vmmdevR3HgcmLoadState toma cParms del sav y llama al mismo asignador:
const uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (sizeof(VBOXHGCMGUESTPARM) + sizeof(VBOXHGCMSVCPARM))
+ (enmCmdType == VBOXHGCMCMDTYPE_CONNECT ? sizeof(HGCMServiceLocation) : 0);
AssertCompile comenta en este pin que CMD está en 120, guestparm en 40, svcparm en 24. cParms = 0x4000000 hace que el producto de 64 bits sea 0x100000000 + 120. El almacenamiento en uint32_t conserva 120. Luego:
for (i = 0; i < cParms; ++i)
{
VBOXHGCMGUESTPARM * const pGuestParm = &pCmd->u.call.paGuestParms[i];
rc = pHlp->pfnSSMGetU32(pSSM, &u32);
pGuestParm->enmType = (HGCMFunctionParameterType)u32;
paGuestParms se encuentra en pCmd + sizeof(VBOXHGCMCMD). Tras el desbordamiento circular, ese es el final de la asignación. El primer almacenamiento ya está fuera de límites.
Desvíos erróneos ya registrados: tratar el HGCM activo como el residuo (sigue limitado a 32); recorrer 67 millones de almacenamientos en el arnés (el primer dword es la prueba); afirmar que un invitado puede implantar esto mediante Save; inflar el aplastamiento del heap del proceso de la VM hasta un escape al kernel del host; encadenar IDispatch público.