Después de una noche con poco sueño (vueltas, vueltas al incidente intentando comprender qué ha podido pasar, qué nos hemos podido pasar por alto, qué nos falta por probar), volvemos cargados de cafeína a la Organización.
Autopsy ha terminado el procesado de la imagen de disco duro, pero tras un análisis superficial de los resultados nuestra teoría inicial se confirma: el equipo del usuario está limpio. De hecho, está tan limpio que el correo malicioso ni siquiera llegó a tocar ese equipo. Por lo tanto, se confirma que todo lo que haya pasado ha tenido que pasar en el Exchange.
Seguimos dándole vueltas al incidente, y hay algo que nos reconcome: si los atacantes tuvieran control completo del Exchange, habrían podido borrar el correo de la carpeta de los Elementos Recuperables, cosa que no han hecho. Pero lo que sí que han logrado ha sido poder borrarlo de la tabla EventHistoryDB, que opera a más bajo nivel… ¿o a lo mejor no lo han hecho?
Nos acercamos con croissants al área de Sistemas (la comida gratis abre muchas puertas), y nos sentamos los tres con el administrador de Exchange para repasar con él todos los comandos ejecutados. Y nada más verlo ejecutar el primer comando entendemos lo que está sucediendo. La salida del comando de Powershell es algo similar a esta (en blanco está oculto lo que no es necesario):
Si se observa con cuidado, el ItemEntryID es un valor bastante largo y separado por guiones, lo que hace que en una pantalla de terminal de Windows de 80 columnas el valor ocupe varias líneas. Nosotros habíamos visto el problema de los guiones y lo teníamos controlado, pero en los logs del Message Tracking el ItemEntryID (ahí sin guiones) siempre cabía en una línea. Y cuando buscamos cadenas en logs, fgrep es una herramienta estupenda que hace exactamente lo que le dicen, por lo que si le pides que busque una cadena completa que está en varias líneas… no la va a encontrar.
Tras una ristra de tacos que harían sonrojarse a un estibador marsellés, invocaciones a primigenios de Lovecraft y blasfemias múltiples variadas, volvemos a repetir la búsqueda. Ahora sí. Encontramos el maldito ItemEntryID en la EventHistoryDB cual pistola humeante, y confiesa lo sucedido con todo lujo de detalles:
- Se creó un objeto de correo en t=0 (acción ObjectCreated).
- En t+5 minutos el correo electrónico fue enviado (acción MailSubmitted).
- En t+6 el correo fue eliminado del buzón (acción ObjectDeleted).
Y lo más importante: todas estas acciones fueron realizadas a través de OWA ¿No quedamos en que el OWA tenía el acceso restringido por una VPN para la que el usuario no tenía credenciales de acceso? Vamos a tener que tener unas serias palabras con ese OWA…
Solicitamos a Sistemas los logs de los dos nodos CAS (Client Access Server) del cluster, que son los que ofrecen el servicio de OWA. Media hora más tarde nos entregan 200Mb de logs en formato texto de las últimas 72h, con un formato similar a este (si te parecen muy parecidos a los de IIS es porque en realidad CAS ofrece los servicios web a través de un IIS):
Dado que tenemos un log razonablemente estructurado podemos empezar a aplicar la técnica de “decapado”: empezamos a quitar campos que no aportan valor y eliminamos aquellos que son conocidos. En este caso la técnica funciona de maravilla porque a los 5 minutos María exclama: ¿Firefox? ¿Por qué tantas entradas con Firefox, si no lo tenemos desplegado en la Organización?
Los usuarios suelen ser animales de costumbres: si en el trabajo usan Internet Explorer y Chrome, es más que probable que en casa usen lo mismo. Si pivotamos sobre este User-Agent en los logs, nos encontramos con el premio gordo: una dirección IP pública de la Organización que NO es el acceso VPN. Si abrimos con un navegador esa dirección IP, las piezas empiezan a encajar en su sitio porque aparece lo que esperábamos:
La pregunta es simple: ¿Qué hace un OWA en una IP pública distinta al acceso por VPN? Tras consultarlo varias veces con Sistemas y Redes, desfacemos el entuerto: es la IP correspondiente al acceso para los móviles.
Cuando la gente de Sistemas montó el Exchange tuvo en cuenta que el acceso para el OWA tenía que estar protegido, y por ello se publicó en una IP interna a la que solo se accedía por la VPN.
Sin embargo, a la hora de dar el servicio de correo móvil no tuvieron en cuenta que ActiveSync y OWA (que al parecer se instalan por defecto) usan el mismo puerto, por lo que al tener el acceso abierto para los móviles estaban dejando a la vez acceso al OWA a TODA la Organización.
La fiesta no termina ahí: pivotando sobre la subred de direccionamiento público encontramos OTRA dirección IP pública (el backup del acceso de los móviles)… y accesos desde ambas IP a otras tres cuentas de usuario distintas a la de nuestro paciente cero. Acabamos de cantar bingo, damas y caballeros.
Una vez identificado realmente el incidente, pasamos rápidamente a la fase de contención. No podemos cerrar tal cual el acceso de los móviles (hay que mantener el servicio activo), pero gracias a $deity los cortafuegos de la Organización tienen estudios suficientes como para saber poner filtros por URI. Generamos a través de los logs y de un par de búsquedas de Internet un diccionario rápido de términos a prohibir en la URI y los pasamos a la gente de Seguridad Perimetral para que los implementen en ambos accesos.
En segundo lugar procedemos a forzar el cambio de contraseñas de todos los usuarios afectados (asegurándonos previamente de que la política de contraseñas es fuerte: 12 caracteres mínimo, con requisitos de complejidad y caducidad mensual).
Una vez cerradas las puertas a los atacantes, pasamos a la fase de erradicación: recogemos evidencias de los equipos de los otros tres usuarios afectados, y las analizamos en busca de cualquier comportamiento malicioso. Revisamos a su vez en el Exchange todos los correos enviados en los últimos días, para comprobar que no se han enviado más correos maliciosos.
Sin embargo, aún nos quedan algunos flecos por resolver. Mi compañera me enseña los logs del OWA, y me señala unas líneas. Lo que hay en esos logs, y la conclusión del misterio, en el último capítulo…
Para cuándo la parte 4? Llevo un día esperando 😠
PD: me encanta tu historia, quiero más.