Hace una semana contaba cómo PHP2Shell salió a la luz antes de tiempo y obligó a mitigar sin parche. Ahora ha pasado algo parecido un nivel más abajo, en el firmware que arranca los servidores. TianoCore ha publicado un aviso de seguridad crítico para EDK II, la implementación de referencia de UEFI que usan como base casi todos los fabricantes de firmware: AMI, Insyde, Phoenix y también Project Mu, el fork de Microsoft.
El fallo, CVE-2026-97631, permite ejecutar código antes de que arranque el sistema operativo, enviando un paquete ICMP a una máquina mientras arranca por red.
Qué es el arranque PXE
PXE es el mecanismo que permite a un equipo arrancar descargando lo que necesita desde la red, en lugar de desde su disco. Es muy habitual en centros de datos: para instalar sistemas en muchas máquinas a la vez, para servidores sin disco o para recuperación. En EDK II lo implementa el controlador NetworkPkg/UefiPxeBcDxe.
Mientras dura el arranque por red, ese controlador deja abierta una recepción de mensajes de error ICMP y copia cada uno en un campo de 504 bytes de su estructura interna. Ahí está el problema.
El fallo, en unas pocas líneas de C
El código original copiaba el mensaje fragmento a fragmento así:
CopiedLen = 0;
IcmpError = (UINT8 *)&Mode->IcmpError;
for (Index = 0; Index < RxData->FragmentCount; Index++) {
CopiedLen += RxData->FragmentTable[Index].FragmentLength;
if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer,
RxData->FragmentTable[Index].FragmentLength);
} else {
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer,
CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
}
IcmpError += CopiedLen;
}
Tiene dos errores. El más grave está en la última línea: el puntero de destino avanza el total acumulado (CopiedLen) en lugar de la longitud del fragmento que se acaba de copiar. Y cuando se supera el tamaño del campo, en vez de dejar de copiar, sigue copiando bytes. Con un mensaje de tres fragmentos de 200 bytes se ve claro:
| Fragmento | CopiedLen | Se copia en el desplazamiento | Bytes copiados | ¿Dentro de los 504? |
|---|---|---|---|---|
| 1 | 200 | 0 | 200 | Sí |
| 2 | 400 | 200 | 200 | Sí |
| 3 | 600 | 600 | 96 | No, escribe a partir del byte 600 |
El tercer fragmento se escribe entero fuera del campo, con bytes que elige el atacante. Nada antes en la recepción limita la longitud del mensaje. El fallo está duplicado en el manejador de IPv4 y en el de IPv6.
La corrección, integrada en la rama principal de EDK II el 15 de octubre, limpia el campo, recorta cada fragmento a lo que queda de espacio y avanza el puntero sólo lo copiado:
ZeroMem (&Mode->IcmpError, sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
for (Index = 0, IcmpError = (UINT8 *)&Mode->IcmpError, CopiedLen = 0;
(Index < RxData->FragmentCount) &&
(CopiedLen < sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
Index++, IcmpError += FragmentLen, CopiedLen += FragmentLen)
{
FragmentLen = MIN (
RxData->FragmentTable[Index].FragmentLength,
(UINT32)(sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR) - CopiedLen)
);
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer, FragmentLen);
}
Además, el parche añade tests con GoogleTest que comprueban justo el caso de varios fragmentos.
Qué puede hacer un atacante
Según el aviso, basta con enviar un mensaje de error ICMP unicast a la IP de la máquina mientras arranca por red, desde cualquier distancia en la red y sin autenticarse. Hay dos niveles:
- Denegación de servicio: la corrupción provoca una excepción y el arranque se cuelga. Es determinista.
- Ejecución de código: si el atacante conoce la versión exacta del firmware, puede colocar en el mismo paquete un evento falso que el firmware acaba ejecutando en ring 0, en la fase DXE, antes de que exista ningún control de seguridad del sistema operativo y antes de que Secure Boot o el arranque medido hayan verificado nada.
HD Moore, creador de Metasploit, explicaba a Ars Technica que, en ese punto, el arranque todavía tiene acceso a componentes sensibles como el TPM, lo que podría servir para romper el cifrado de disco. Ars también recoge que el fallo lleva en el código unos 16 años.
Por qué no es tan grave como parece, y por qué sí lo es
Hay limitaciones importantes, que vale la pena tener claras antes de alarmarse:
- Sólo afecta mientras la máquina arranca por red. Un equipo que arranca desde su disco no está expuesto. Eso descarta a la mayoría de usuarios domésticos y de oficinas pequeñas.
- El atacante tiene que llegar a la máquina con ICMP en esa ventana, lo que en la práctica suele exigir estar ya dentro de la red.
- El exploit no es universal. Jesse Michael, de Eclypsium, señala que hay que adaptarlo a cada modelo, versión y configuración, porque las direcciones de memoria cambian.
- La corrección es sencilla. A diferencia de fallos como BootHole o BlackLotus, no hace falta revocar claves ni tocar las bases de datos de Secure Boot: basta con actualizar el firmware.
Pero hay otras razones para tomárselo en serio. EDK II está en la base de casi todo el firmware de servidores, así que el número de equipos afectados es enorme, y actualizar el firmware de miles de modelos depende de cada fabricante y suele ser lento. Moore cree que será un fallo “para siempre” en equipos que ya no reciben soporte. Y en centros de datos, que es justo donde más se usa PXE, alguien que ya está dentro de la red puede usarlo para comprometer máquinas por debajo del sistema operativo.
La divulgación que se adelantó
Lo encontraron Alex Matrosov, de Anthropic, y Dan Holmes-Mitra, de Google, que habían acordado mantenerlo en secreto hasta una divulgación coordinada prevista para enero. Pero según Ars Technica, en septiembre apareció en el repositorio público de EDK II un pull request de un desarrollador de AMI con la corrección y la descripción del fallo. Al detectarlo, TianoCore publicó el aviso el 22 de octubre.
Con el parche público, encontrar cómo provocar el fallo es inmediato, como acabamos de ver en la tabla. Es la misma situación que con PHP2Shell: el problema no es tanto que el parche se publique, sino que se publique antes de que los afectados tengan algo que instalar.
Qué hacer
En el momento de escribir esto, la información de los fabricantes es escasa: Intel dice que ninguno de sus productos con soporte de seguridad está afectado, pero que un fabricante de placas podría haber integrado el código; Arm dice que no se aplica directamente a sus productos; y AMD, Phoenix, AMI, Microsoft y Amazon no habían respondido a Ars. Con eso, lo razonable es:
- Preguntar al fabricante del servidor por una actualización de firmware que incluya la corrección, y aplicarla cuando exista.
- Desactivar el arranque por red en las máquinas que no lo necesiten. Muchos servidores lo tienen activo por defecto aunque nunca arranquen así.
- Aislar la red de aprovisionamiento donde sí se use PXE, para que sólo puedan llegar a esas máquinas los equipos que tienen que hacerlo.
- Mantener Secure Boot y el TPM activos, aunque no protejan frente a este fallo, y vigilar los logs.
Lo que me llevo
Me llama la atención que este fallo haya sobrevivido a años de fuzzing. Después de PixieFail, otro conjunto de fallos en el mismo código PXE de EDK II, hubo varios proyectos dedicados a buscar más, y EDK II está incluso en OSS-Fuzz. Y aun así, un error que se ve en una tabla de tres filas seguía ahí. Encaja con lo que contaba en el artículo sobre verificación formal con LLM: el fuzzing encuentra mucho, pero no garantiza haberlo probado todo.
También me deja la sensación de que estas semanas se está repitiendo el mismo patrón: fallos graves en código con muchos años encima y divulgaciones coordinadas que se rompen antes de tiempo. Para quien administra servidores, la consecuencia práctica es la misma de siempre, pero cada vez más urgente: saber qué tienes, qué firmware lleva cada máquina y qué servicios tiene activos aunque no los use.
Fuente: Pre-boot RCE in EDK II PXE driver, TianoCore, y Code-execution flaw in UEFI firmware affects most servers on planet Earth, Dan Goodin, Ars Technica.




