La caída de CrowdStrike se debió a una discrepancia de 21 frente a 20 campos. Kestrel verifica el código antes del reinicio.
CrowdStrikeSeguridad de endpointsResiliencia de TI

La caída de CrowdStrike dependió de un recuento: 21 campos donde el kernel esperaba 20. Ninguna capa independiente verificaba.

Ashutosh SinghalAshutosh Singhal20 de julio de 202611 min

El 19 de julio de 2024, una única actualización de un proveedor provocó la caída de millones de equipos Windows en menos de 90 minutos, y la causa fue un simple número. Un archivo de canal de «Rapid Response Content» de CrowdStrike declaró 21 campos donde el intérprete de kernel desplegado esperaba 20. El campo adicional produjo una lectura fuera de límites (out-of-bounds read), una pantalla azul instantánea y, debido a que el bloqueo se produjo en una fase tan temprana del arranque, el agente afectado nunca pudo reiniciarse para recibir una orden de reversión (rollback). La recuperación obligó a acudir físicamente a cada máquina y repararla a mano en Modo Seguro.

Leí más de una vez el propio análisis de causa raíz de CrowdStrike, publicado aquel agosto, antes de que saliera a la luz lo que realmente me inquietaba. No fue un ciberataque. No fue un modelo defectuoso. Fue un hecho aritmético decidible, 21 frente a 20, alojado en una carga útil que ninguna capa independiente comprobó jamás antes de que llegara a producción. El validador del proveedor lo aprobó. Las empresas que quedaron paralizadas no eran dueñas de ese validador. Eran dueñas de las consecuencias.

He dedicado el último periodo a crear una demo en torno a esa brecha: una consola que llamé Kestrel, que se sitúa entre un proveedor de software y una flota de producción y decide, mediante código, qué tiene permiso para enviar el proveedor. Puede ver cómo funciona en veriprajna.com/demos/software-update-integrity. Lo que me sorprendió durante su desarrollo fue el lugar exacto donde residía la solución. Empecé convencido de que necesitaría un modelo más inteligente, pero unas pocas líneas de Python simple detectaron el fallo antes que nada.

Reconstruí la caída y luego dejé que el código decidiera

Reconstruí la firma de fallo del 19 de julio como un caso de prueba (fixture) y apunté mi propio sistema hacia ella, esperando casi quedar decepcionado por mi propia repetición. El paquete es C-00000291, un archivo de canal de Rapid Response Content de un proveedor ficticio que denominé SentinelEdge, enviado a una flota sintética de 8.500 terminales llamada Acme Financial. Ninguna de ellas son empresas reales. La firma de fallo sí es la auténtica: un esquema declarado de 20 que crece a 21, distribuido al 100 % de la flota en una sola oleada, sin plan de despliegue canary.

La compuerta (gate) se activa ante cuatro comprobaciones a la vez, y cada una de ellas es aritmética pura o una consulta directa, jamás un juicio discrecional. La diferencia de esquema detecta 21 campos donde el intérprete espera 20 y marca la lectura fuera de límites. Un entorno aislado (sandbox) simulado, que es un modelo determinista de resultados por perfil y no una granja de máquinas virtuales Windows reales, genera un bucle de reinicio en 5 de los 6 perfiles de la flota a lo largo de los ciclos de reinicio. Lo deduce a partir de una señal de compatibilidad de controladores independiente de la verificación de esquema, de modo que ambos hallazgos se corroboran mutuamente en lugar de ser un simple eco. El detector de agente inerte marca el bucle de reversión como verdadero, porque el agente bloqueado es el mismo que tendría que recibir la reversión, y está inerte antes del arranque. El radio de impacto es del 100 % frente a una política canary del 5 %. Veredicto: BLOCK. En pantalla se lee: bloqueado antes de que cualquier terminal de producción se reiniciara.

La consola Kestrel mostrando el panel Block Rollout para el paquete C-00000291 del proveedor SentinelEdge, con las cuatro pruebas deterministas, una flota de 8.500 terminales y un tiempo de inactividad evitado estimado en 5.000.000 $.
C-00000291, la firma del 19 de julio reproducida. La compuerta activa las cuatro comprobaciones: discrepancia en el recuento de campos del esquema (20 esperados, 21 proporcionados), bucle de reinicio en sandbox en 5/6 perfiles, bucle de reversión de agente inerte y un radio de impacto del 100 % frente a la política canary del 5 %. Veredicto BLOCK, tiempo de inactividad evitado estimado en 5.000.000 $.

El tiempo de inactividad evitado estimado en esa única actualización figura como 5.000.000 $, y quiero ser exacto sobre lo que representa esa cifra. Es el modelo propio de la demo: la proporción afectada multiplicada por un coste de 5 millones de dólares por hora y por un suelo de recuperación de una hora, con la fórmula visible en pantalla. No es dinero que un cliente haya ahorrado. La recuperación real del 19 de julio tardó días, no una hora, por lo que el suelo fijado es deliberadamente conservador.

El caso verde me asustó más que el rojo

Estaba más inquieto por el caso verde que por el rojo, porque una capa de gobernanza que bloquea la actualización peligrosa y al mismo tiempo estrangula la segura no es más que una interrupción programada por uno mismo. El mismo proveedor ficticio envía RRC-7741, una actualización benigna de firmas de detección, con esquema declarado de 20 a 20 y un plan canary escalonado del 1,2 %. El equipo de agentes se ejecuta, el esquema coincide, 5 de 6 perfiles superan sus ciclos de reinicio, el bucle de agente inerte es falso, el radio de impacto queda dentro de la política. Veredicto: APPROVE ROLLOUT, liberado a un anillo canary de 102 terminales. Verde, rápido, sin sobresaltos.

La consola Kestrel mostrando el panel verde Approve Rollout para RRC-7741 distribuido a un anillo canary del 1,2 %, con la traza de evaluación 7/7 y el registro de evidencias.
La actualización benigna del mismo proveedor, RRC-7741. El esquema coincide, 5/6 perfiles superan sus ciclos de reinicio, bucle de agente inerte falso, radio de impacto del 1,2 % dentro de la política. Veredicto APPROVE ROLLOUT, distribuido a un canary de 102 terminales, registro de evidencias sha256:798431b4c96612a9.

En las seis actualizaciones benignas del conjunto, la compuerta produjo cero bloqueos falsos. Lo digo con el denominador explícito, porque seis son seis, y no permitiré que se redondee al alza como una promesa sobre su flota. El valor del caso ALLOW es más acotado y más importante que un porcentaje. Una compuerta solo es creíble si resulta invisible con tráfico normal e inamovible en el único evento capaz de tumbar su infraestructura.

Por qué retiré el veredicto del modelo

Comencé este desarrollo asumiendo que la parte difícil radicaba en el razonamiento, y que un modelo más agudo o un crítico más perspicaz sería lo que atraparía la actualización defectuosa. Me equivoqué de una forma que tardé en admitir. Hay un equipo de LLM dentro de Kestrel: un normalizador, un intérprete de sandbox y dos críticos opuestos, uno que defiende que la actualización es segura y otro que argumenta que fallará. La pareja contradictoria se gana su lugar porque somete el veredicto a una auditoría adversaria (red-teaming) desde ambas direcciones antes de decidir nada. Pero ninguno de esos agentes emite el veredicto.

El veredicto lo determinan dos archivos Python ordinarios, verifier.py y gate.py, que residen completamente fuera del marco de agentes. El equipo funciona sobre Pydantic AI con el modelo predeterminado claude-opus-4-8, y todo el sistema también funciona sin conexión y sin clave de API mediante un mecanismo consultivo determinista de respaldo. En cada uno de esos modos, la compuerta es idéntica y devuelve la misma decisión, porque la decisión es aritmética, no inferencia. Los agentes asesoran, el código decide. Un agente consultivo que se incline por «permitir» no puede revocar un hallazgo determinista crítico, y eso no es una cuestión de gustos.

Una capa construida para auditar al proveedor no puede aceptar la palabra del proveedor en materia de seguridad. Tampoco puede aceptar la palabra de su propio modelo.

Esa frase explica la arquitectura elegida. La confianza en un producto cuya única función es gobernar lo que distribuye un proveedor nunca debe pasar por un componente al que se pueda convencer de decir que sí.

Lo que entregaría a un auditor

Mantuve la Ley de Ciberresiliencia de la UE (CRA) abierta en un segundo monitor mientras creaba el registro de evidencias, porque ese registro es el artefacto que realmente tendría que defender. Cada decisión exporta un archivo HTML inmutable y un archivo JSON firmado que contiene un hash de contenido SHA-256, el veredicto, las pruebas deterministas, los resultados de sandbox por perfil, los veredictos de los agentes consultivos con el identificador de su modelo, las reglas de política activadas y una traza de evaluación paso a paso donde cada paso registra su propia latencia.

La vista de decisión de Kestrel para el paquete bloqueado C-00000291, que muestra el registro de evidencias con sha256:0f4f71b2bd7d1753 y botones para abrir el registro HTML y el JSON firmado.
El registro de evidencias exportado para la actualización bloqueada. Un hash de contenido SHA-256, un registro HTML abierto y un archivo JSON firmado, emitido sobre la propia decisión.

La traza es la pieza que subestimé hasta que hice clic en un paso concreto. Un evento indica: «Normalizar manifiesto firmado del proveedor, completado en 184 ms», y se conserva junto con el resultado de la decisión para su revisión en auditorías. Cada paso es verificable. Un regulador no tiene por qué confiar a ciegas en mi panel. Puede recalcular la aritmética y obtener la misma respuesta.

Una ventana modal de paso de la traza de evaluación de Kestrel que muestra «Normalizar manifiesto firmado del proveedor, completado en 184 ms», con una nota de que el evento se conserva para auditoría.
Un paso de la traza de evaluación, desplegado: Normalizar manifiesto firmado del proveedor, completado en 184 ms, conservado con el resultado de la decisión para la revisión de auditoría.

Soy meticuloso con lo que es y lo que no es la firma. Es un hash SHA-256 local, no una infraestructura de clave pública (PKI) corporativa. El canal de actualizaciones del proveedor y los tickets de ITSM que lo respaldan son stubs de prueba, no conectores en tiempo real. El registro está concebido para alinearse con exigencias regulatorias: la notificación de incidentes en plazos breves del CRA, la divulgación en un plazo de cuatro días hábiles de incidentes de ciberseguridad relevantes exigida por la SEC, y los litigios de responsabilidad planteados por Delta v. CrowdStrike en el condado de Fulton en 2025. Concebido para alinearse con. No certifica a nadie, no constituye asesoramiento legal, y quien le venda un registro de auditoría que supuestamente le otorgue cumplimiento normativo solo busca venderle algo.

Hay otra decisión de la que estoy orgulloso, y es una negativa. El caso XX-0000 es un blob de contenido propietario cifrado que la compuerta no puede analizar, por lo que no hace suposiciones. Devuelve ABSTAIN y lo deriva a un humano, porque una compuerta que valida lo que no puede descifrar es peor que no tener compuerta. Los hosts heredados que el sandbox no puede modelar se marcan y se excluyen, nunca se asumen seguros. El vocabulario consta de cuatro términos: ALLOW, HOLD, BLOCK, ABSTAIN, y este último es el que defendería con mayor firmeza.

Lo que 12 de 12 tiene derecho a significar

Debo detenerme aquí, porque es justo en este punto donde un fundador empieza a redondear al alza. Y llamé a la empresa Veriprajna, «sabiduría verdadera», por lo que el redondeo está descartado. En un conjunto fijo y etiquetado de doce actualizaciones, la compuerta adopta la decisión correcta en las doce. Seis de ellas son benignas y no bloquea ninguna. Una de ellas es el honesto ABSTAIN. El marcador muestra 12/12 decisiones verificadas, 0/6 bloqueos falsos y 13,3 millones de dólares en tiempo de inactividad evitado estimado en el conjunto, de los cuales 5 millones corresponden al bloqueo del caso CrowdStrike.

El panel de referencia de Kestrel indicando 12/12 decisiones verificadas, 0/6 bloqueos falsos y 13,3 M$ de exposición evitada en todo el conjunto de pruebas de despliegue etiquetadas.
El marcador de valor sobre el conjunto de pruebas etiquetadas: 12/12 decisiones verificadas, 0/6 bloqueos falsos en actualizaciones benignas, 13,3 M$ de tiempo de inactividad evitado estimado en el conjunto. Denominadores pequeños, declarados a propósito.

Ahora la parte que me niego a abreviar. Son resultados sobre doce elementos etiquetados, no una promesa sobre la próxima actualización que reciba su flota. Seis elementos benignos son seis. Esto no equivale a «bloquea el 100 % de las actualizaciones dañinas», nunca lo será, y si alguna vez me leen escribir esa frase, deberían dejar de leerme. El número que defiendo es de otra índole: misma entrada, misma decisión, en cada ejecución, porque el veredicto no contiene temperatura de modelo. Ejecute el conjunto de pruebas mañana y devolverá resultados idénticos byte a byte, lo que permite auditar una capa determinista como jamás se podría auditar una probabilística.

La pregunta que me acompaña

Lo que permanece conmigo tras este proyecto es lo ordinario que fue el fallo. Veintiún campos donde se esperaban veinte. Un número que cualquier verificador independiente podría haber detectado por pura aritmética antes de que una sola máquina se reiniciara, si hubiera habido un verificador independiente entre el proveedor y la flota. No lo había. Hoy en día, casi siempre sigue sin haberlo.

Toda empresa ejecuta entre ocho y doce agentes con privilegios de kernel procedentes de proveedores que no controla, y cada uno de ellos puede inyectar un archivo directamente en el ring 0. Las herramientas SBOM vigilan el código abierto. La gestión de identidades vigila los accesos. Nadie lee la actualización propietaria del proveedor a su llegada para demostrar que es segura. Kestrel no es un EDR y nunca toca el kernel. Se sitúa por encima de esos agentes y gobierna lo que tienen permiso para distribuir. Esa es la capa que intenté construir, y el desglose completo está en veriprajna.com/demos/software-update-integrity.

Y si prefiere verlo en acción antes que leerme describiéndolo, aquí tiene todo el sistema ejecutándose de principio a fin.

Así que esto es lo que ahora pregunto sobre cada flota que conozco: cuando llegue la próxima actualización de un proveedor, ¿qué se interpondrá entre ese archivo y la producción, y podrá justificar su funcionamiento? Si la respuesta es un comité asesor de cambios (CAB) que confía ciegamente en el proveedor, entonces la aritmética que derribó millones de máquinas sigue funcionando sin supervisión. No avisará. Tendrá exactamente el mismo aspecto que cada actualización previa, hasta el preciso instante del reinicio.

Investigación relacionada

También publicado en

Construya su IA con confianza.

Colabore con un equipo que cuenta con amplia experiencia en la creación de la próxima generación de IA empresarial. Permítanos ayudarle a diseñar, construir e implementar una estrategia de IA en la que pueda confiar.

Veriprajna consultora de Deep Tech está especializada en la creación de sistemas de IA críticos para la seguridad en los sectores de salud, finanzas y ámbitos regulatorios. Nuestras arquitecturas se validan conforme a protocolos establecidos, con documentación de cumplimiento integral.