La puerta ya estaba abierta: dos exposiciones críticas que no requirieron ningún exploit

Telemetría de agua y energía de decenas de instalaciones. La ubicación en tiempo real de casi mil vehículos. Dos exposiciones críticas que no requirieron un 0-day, un exploit sofisticado ni siquiera credenciales.
Durante un programa de bug bounty autorizado, encontré dos exposiciones críticas dentro del mismo proveedor de conectividad IoT. La primera permitía que cualquier persona desde Internet pudiera leer y escribir telemetría asociada a infraestructura de agua y energía. La segunda exponía la ubicación en tiempo real y el historial de recorridos de casi mil vehículos pertenecientes a distintas organizaciones.
No exploté una versión vulnerable de ningún software. No necesité un 0-day. Ni siquiera necesité credenciales. Los sistemas simplemente me dejaron entrar. Y ambos estaban en producción.
Un broker que confiaba en todos
El primer hallazgo empezó con un broker MQTT.
MQTT se usa ampliamente para transmitir telemetría entre sensores, medidores, controladores y otros dispositivos conectados. En entornos industriales, eso puede incluir desde el caudal de agua y los niveles de un reservorio hasta el consumo eléctrico. Este broker en particular estaba expuesto directamente a Internet a través del puerto 1883, lo cual ya es inusual para producción. Así que intenté conectarme sin usuario ni contraseña.
El broker respondió: CONNACK, return code 0. Conexión aceptada.
Eso ya era un problema serio. Desde Mosquitto 2.0, el acceso anónimo no está habilitado por defecto. Alguien había configurado explícitamente este broker para permitirlo. Pero poder conectarme era solo el comienzo.
MQTT expone estadísticas internas del broker a través del árbol de tópicos $SYS. Sin autenticarme, pude consultarlas y ver más de dos millones de mensajes procesados en producción, además de decenas de mensajes retenidos. Después me suscribí a #, que en MQTT significa: mandame todo.
En pocos minutos podía ver telemetría asociada a decenas de instalaciones. Caudal de agua, volumen acumulado, niveles de reservorios, mediciones de pH, voltaje, corriente eléctrica, consumo energético. Los nombres de los tópicos permitían asociar los flujos de información con instalaciones individuales. No eran datos de prueba. Reflejaban la operación de infraestructura real de agua y energía en múltiples industrias.
Entonces surgió la pregunta más seria: ¿también podía escribir?
Envié un mensaje inofensivo a un tópico creado específicamente para la prueba autorizada. PUBLISH rc=0. Aceptado. Tampoco había ACLs que impidieran que un cliente anónimo publicara en otros tópicos. Junto con el cliente, validamos que la telemetría pertenecía a instalaciones realmente operativas y que era posible realizar escrituras anónimas en el mismo entorno.
En ese momento, el hallazgo dejó de ser únicamente una exposición de información. El sistema estaba dispuesto a confiar en datos provenientes de una fuente no autenticada en Internet.
Un hallazgo técnico puede verse muy diferente cuando lo llevás a un escenario real. Imaginá que un atacante publica un valor de pH aparentemente normal mientras la medición real está fuera del rango esperado. El dashboard sigue mostrando un valor normal aunque la condición real no lo sea. O que alguien recopila durante un período prolongado información sobre el consumo de agua y energía, patrones que revelan cuándo opera una instalación, cuándo baja su producción y cuándo se detiene. Dependiendo de cómo se use esa telemetría en otros sistemas, la manipulación de valores también podría interferir con el monitoreo operativo o con procesos que dependan de esas mediciones.
Ninguno de estos escenarios empieza explotando una vulnerabilidad de software. Empiezan conectándose a un servicio que nunca debería haber confiado en un cliente anónimo desde Internet.
Casi mil vehículos en un mapa
El segundo hallazgo era técnicamente muy diferente.
Una aplicación de gestión de flotas incluía una key de un servicio de búsqueda de terceros directamente en su JavaScript público. Tener una key en el frontend no es automáticamente una vulnerabilidad. Estos servicios pueden usar keys restringidas, diseñadas específicamente para funcionar desde el navegador. El problema era a qué podía acceder esta key en particular.
Permitía listar índices que nunca deberían haber estado disponibles para un cliente público. Un índice de usuarios con aproximadamente 180 entradas. Uno de dispositivos con aproximadamente 880. Uno de eventos con más de 800.000.
Usando la misma key, consulté el índice de dispositivos. La respuesta contenía casi mil vehículos pertenecientes a decenas de organizaciones. Para cada uno, la información disponible incluía latitud y longitud, velocidad, IMEI, identificador de SIM, organización y eventos históricos. No existía aislamiento entre tenants en esta capa. La credencial del frontend de un cliente podía acceder a datos pertenecientes a otras organizaciones.
Y como el índice de eventos contenía cientos de miles de registros históricos, no solo era posible saber dónde estaba un vehículo en un momento determinado. También era posible reconstruir dónde había estado.
Los índices expuestos contenían además información personal y, en algunos casos, seeds de autenticación de segundo factor almacenadas en texto plano.
De nuevo, no hubo ningún exploit complejo. La credencial ya se enviaba al navegador de cada visitante. Simplemente tenía muchos más permisos de los que debería haber tenido.
Las coordenadas dentro de una respuesta de API pueden parecer un dato más. Cuando esas coordenadas se conectan a lo largo del tiempo, la situación cambia. Una ubicación en tiempo real muestra dónde está un activo en este momento. El historial de ubicaciones revela rutas y rutinas. Los patrones repetidos pueden exponer cómo opera una organización. A nivel individual, los datos de ubicación también pueden revelar información sobre las personas que usan esos vehículos. El problema técnico era una credencial con permisos excesivos. La exposición real era mucho más amplia: información operativa de múltiples organizaciones accesible mediante una credencial incluida en JavaScript público.
El problema detrás de los dos problemas
Un broker MQTT y un servicio de búsqueda usado por una plataforma de gestión de flotas no tienen mucho en común desde lo técnico. Pero el problema de seguridad detrás de ambos era muy parecido.
En los dos casos, un servicio tenía mayor exposición de la prevista. Los permisos eran más amplios de lo necesario, los trust boundaries no estaban correctamente definidos y el resultado era accesible desde Internet. Ninguno de los hallazgos dependía de un CVE sin parchear ni de una vulnerabilidad desconocida en el software. Todo estaba funcionando. El problema era que funcionaba bajo supuestos equivocados sobre quién debía poder acceder a qué.
Y esa diferencia importa más de lo que parece.
Los equipos de seguridad dedican mucho tiempo a seguir CVEs, aplicar parches y responder a vulnerabilidades recién descubiertas. Todo eso es necesario. Pero no toda exposición crítica tiene un CVE asociado. A veces el software está completamente actualizado y funciona exactamente como fue configurado. El problema es la configuración.
Las vulnerabilidades que nadie necesita explotar
Ambos hallazgos empezaron con algo simple: observar cómo se comunicaba un sistema y preguntarme qué le permitiría hacer a un usuario externo.
Eso es parte de lo que hace interesantes a este tipo de exposiciones desde la perspectiva de un pentester. No siempre existe una función vulnerable esperando ser explotada. A veces el trabajo consiste en entender la arquitectura, identificar dónde se depositó confianza de forma incorrecta y poner a prueba los supuestos detrás de ella.
Todas las pruebas descritas acá se hicieron con autorización. Los atacantes no tienen esa restricción.
Por eso, después de encontrar exposiciones como estas, quedan algunas preguntas. ¿Cuántos servicios están hoy expuestos a Internet sin que nadie sepa realmente qué permiten hacer? ¿Cuántas credenciales acumularon permisos que nadie recuerda haber otorgado? ¿Cuántos sistemas confían en los datos simplemente porque llegaron a través del protocolo esperado, sin comprobar quién los envió?
Solemos pensar en un ciberataque como alguien buscando la forma de atravesar una puerta cerrada. En estos dos casos, no había ninguna cerradura que romper.
La puerta ya estaba abierta.
Todas las pruebas descritas en este artículo se realizaron como parte de un programa de bug bounty autorizado y fueron reportadas a través de los canales correspondientes. Hosts, credenciales, organizaciones, identificadores y volúmenes exactos fueron ocultados o modificados para proteger a las partes afectadas.



