
Un SQLi clásico abrió la puerta a Apple
Dos investigadores de ProjectDiscovery — Harsh Jaiswal y Rahul Maini — encontraron una vulnerabilidad de SQL injection en un sistema interno de Apple que los llevó, paso a paso, desde un simple error 500 hasta ejecución remota de código. Y el punto de partida no fue una tecnología de punta, sino un CMS escrito en ColdFusion que muchos daban por muerto hace quince años.
Se trata de Mura/Masa CMS, un fork open source que Apple usaba dentro de su portal Book Travel. Cuando uno ve ColdFusion en un pentest, sabe que la mesa está servida. La antigüedad del stack, sumada a la costumbre de concatenar strings en las consultas, es prácticamente una invitación.
Del string concatenado al RCE
El camino que siguieron es, honestamente, una clase gratis de code review ofensivo. Bajaron el código fuente de Mura y escribieron un parser en CFML que recorre cada .cfm y .cfc buscando un patrón: bloques cfquery que usen arguments.X directamente, sin el tag cfqueryparam. Lo mismo que hace Semgrep, pero ajustado a la sintaxis de CFML.
El sink ganador estaba en la función getObjects, específicamente en el parámetro ContentHistID:
where tcontent.contenthistid ='#arguments.contentHistID#'
Sin parametrizar. Cero sanitización. Lucee escapa la comilla simple con backslash, así que para romper el filtro bastaba con enviar x\' en el payload. Pero faltaba un detalle: la función dspObjects chequea la propiedad isOnDisplay antes de llamar a getObjects, y parecía imposible setearla desde la URL.
El momento ah, ya caché llegó cuando descubrieron que agregar un parámetro previewID con cualquier valor encendía esa bandera. Una sola línea de código en el handler. Cadena completa:
JSON API → processAsyncObject → displayregion → dspObjects() → getObjects()
De error 500 a cuenta de admin
En local la explotación fue directa, porque el SQLi era error-based: el motor escupía la consulta y los datos sensibles. La cadena para llegar a RCE fue:
- Resetear la contraseña de un usuario admin.
- Exfiltrar el token y el ID del usuario por la inyección.
- Usar el endpoint legítimo de reset de contraseña.
- Instalar un plugin que subió un archivo
.cfmmalicioso.
En el ambiente de Apple los errores estaban suprimidos y se convirtió en blind SQLi. Pero como los tokens son UUIDs, exfiltrarlos caracter por caracter con boolean-based no fue tanto drama. Lo reportaron, lo parchearon en dos horas, y el equipo de seguridad les respondió con la clásica nota de good catch. Buena pega de ambos lados.
Lo que más me molesta de esta historia
Lo que no me deja tranquilo es la otra cara. Mientras Apple respondió rápido y bien, el equipo de Mura CMS simplemente no contestó. Cero respuesta por múltiples canales durante los 90 días de disclosure. El fork Masa CMS, en cambio, sí sacó parches (versiones 7.4.6, 7.3.13 y 7.2.8) y le asignaron el CVE-2024-32640. Pero el original quedó a la deriva.
Si tú mantienes un sistema que todavía corre CFML — y créeme, hay varios en la banca, en municipalidades y en isapres — esto es para que te tiemble la mano. Una vulnerabilidad reportada por terceros, sin parche upstream, significa parchear a mano, mantener tu fork, o seguir corriendo software con un agujero conocido. Ninguna de las tres opciones es cómoda, pero la peor es no enterarse.
Lo que aprendemos al otro lado
Mi lectura, después de digerir el writeup completo:
Primero, que el clásico SQL injection no se muere. Llevamos dos décadas hablando de parametrizar consultas, y todavía hay código nuevo y viejo que concatena. Las herramientas de análisis estático existen, los linters de CFML existen, pero alguien tiene que correrlas.
Segundo, que un bug bounty no es magia. La cadena de éxito fue code review dedicado, una herramienta custom, perseverancia con el bypass de isOnDisplay, y un reporteo limpio. Eso no lo hace una IA, lo hace un par de weones con tiempo y curiosidad.
Tercero, para los que administramos infra: cuando adoptes un CMS open source, fíjate quién lo mantiene, qué tan activo está su GitHub, y cuánto tardan en responder un issue de seguridad. Si nadie responde en 90 días, asumes que estás solo. Y si estás solo, más te vale tener tu propio equipo de revisión o un partner que lo haga por ti.
Yo no voy a dejar de mirar hacia el código viejo. De hecho, voy a revisarlo con más ganas. Si un equipo de dos encontró RCE en Apple por una concatenación de strings, cuántas puertas así siguen abiertas en servicios que uso todos los días. Mejor pensarlo ahora que después.
Fuente de inspiración: Hacking Apple – SQL Injection to Remote Code Execution