Así fue como una corporación de un billón perdió en una prueba de regresión.
Hace cinco años, el 23 de mayo de 2020, ocurrió un precedente histórico en la comunidad de jailbreakers: se publicó públicamente el exploit tachy0n, un 0Day funcional para iOS 13.5 que permitía obtener privilegios a nivel de kernel. Fue la última vez que una versión moderna de iOS fue vulnerada antes de recibir un parche. Nueve días después, Apple lanzó una actualización de seguridad y, mes y medio más tarde, apareció un fork del exploit llamado tardy0n. Hoy esta historia se considera una línea divisoria entre el antiguo y el nuevo enfoque de Apple en cuanto a seguridad del sistema.
Tachy0n explotaba una vulnerabilidad en la llamada al sistema lio_listio
, que gestiona operaciones asincrónicas de archivos. El error consistía en una condición de carrera entre dos hilos que podían intentar liberar la misma estructura lio_context
. Si la operación finalizaba demasiado rápido, la estructura se liberaba dos veces, lo que permitía al atacante ocupar de nuevo ese espacio en memoria con contenido propio y manipularlo a conveniencia.
Lo interesante es que no se trataba de un bug nuevo. Antes de su publicación como 0Day, ya había sido usado por el mismo equipo en un exploit 1Day para el jailbreak Spice, dirigido a iOS 11. Allí se usó de dos formas: en una app y en el proceso del sistema racoon. Este último resultó especialmente útil por sus privilegios elevados y acceso a funciones como sysctl
, lo que facilitaba la obtención de direcciones de objetos en el kernel.
El exploit fue implementado con todas las técnicas clásicas de la era previa a iOS 14: condiciones de carrera, manipulación de estructuras mach_port
, suplantación de descriptores y uso controlado de spray de objetos a través de IOSurface::setValue
. Se engañaba al kernel haciendo que dos objetos OSData diferentes apuntaran al mismo búfer, el cual luego se reemplazaba gradualmente —primero con punteros, después con estructuras falsas del kernel.
Uno de los pasos más inusuales fue el uso de IOBufferMemoryDescriptor
, obtenido mediante la interfaz AGX (IOAcceleratorFamily2), para acceder a una región de memoria predecible con dirección conocida. Así se colocaban estructuras falsas de task y mach port en el kernel, logrando el control total del sistema. Para hacer que esa memoria permaneciera residente, el autor llamaba al método especial processSidebandBuffer
con un stub válido en la estructura, provocando un fallo y la inicialización física de las páginas.
La publicación del exploit provocó una reacción inmediata en la comunidad de seguridad. Apenas cuatro horas después del lanzamiento del código, Brandon Azad de Project Zero identificó y describió la vulnerabilidad, y nueve días después Apple lanzó una actualización que solucionaba específicamente ese fallo. Curiosamente, el bug resurgió como resultado de una corrección previa de fuga de memoria hecha en iOS 12 —todo indica que su reaparición fue producto de una fusión descuidada de ramas de XNU sin pruebas de regresión adecuadas.
La historia de tachy0n evidenció las carencias sistemáticas del enfoque de Apple en aquella época. Mientras unos desarrolladores intentaban detectar y corregir errores manualmente, otros, como el autor del jailbreak unc0ver, obtenían resultados con métodos simples pero laboriosos, como el testeo regresivo de vulnerabilidades antiguas. Así fue como se descubrió este bug.
Sin embargo, en iOS 14 todo cambió radicalmente. Apple abandonó los parches puntuales y comenzó a proteger mecanismos completos de explotación. Los asignadores kalloc y zalloc fueron rediseñados, se introdujeron kheaps —zonas de memoria separadas para datos de usuario y objetos del kernel—, y surgió el concepto de “sequestering” para aislar tipos de objetos, además de páginas aleatorias de protección y mayor aleatorización. Esto prácticamente eliminó la posibilidad de sobrescribir objetos de forma confiable entre zonas, haciendo que la explotación fuese mucho más compleja e inestable.
Además, Apple comenzó a reforzar de forma específica la seguridad de los objetos más usados en exploits. Las estructuras de mensajes del kernel fueron firmadas, los búferes de pipes protegidos con PAC, y cualquier intento de usar tipos de objetos ajenos causaba pánicos inmediatos del sistema. Como resultado, desarrollar exploits se volvió tan costoso y difícil que la información pública prácticamente desapareció: desde iOS 14 hasta hoy no se ha publicado ningún exploit completo para las versiones 17 y 18, a pesar de los ataques observados en entornos reales.
La historia de tachy0n se percibe ahora como el acto final de una era en la que el jailbreak era un pasatiempo de masas y se podía lograr una LPE de kernel simplemente revisando rastreadores de bugs. Hoy, a las puertas de iOS 19, incluso investigadores con décadas de experiencia se enfrentan a un muro casi impenetrable de aislamientos, firmas, PACs y comprobaciones de runtime reiniciables.
Pero precisamente por eso, los relatos detallados de exploits como este, a pesar de su antigüedad, siguen siendo increíblemente valiosos —como monumento a una era pasada y como enciclopedia de técnicas antiguas que aún pueden enseñar algo.