↓ Ir al contenido

Dos casillas comprometidas, 475 mil correos en cola y una IP en listas negras

·1184 palabras·6 mins
Valeri Macarov
Autor
Valeri Macarov
Escribo sobre lo que aprendo, lo que armo, lo que funciona y lo que falla.

El 10 de agosto a la tarde tenía 385.120 mensajes atascados en la cola del PMG de un cliente y la IP pública de esa empresa figuraba en siete listas negras al mismo tiempo. Ni hardware roto ni error de configuración: una sola casilla de correo con la contraseña robada, enviando spam masivo desde hacía tres días.

La plataforma es la de siempre: PMG 6.0-4 como puerta de enlace, Zimbra 8.8.15 como servidor de correo y HAProxy delante de ambos. Es la misma de la que ya conté una caída más rara de lo habitual. El detalle incómodo de este entorno: ni PMG ni Zimbra tenían límites de envío por casilla ni MFA. Con la contraseña en mano, el atacante tenía un emisor de spam ilimitado.

Una casilla que de golpe enviaba 30.000 correos
#

La estadística de remitentes salientes del PMG del 10 de agosto era imposible de malinterpretar: una casilla con 30.113 envíos en el día, contra 1 o 10 del resto de los usuarios.

La forense sobre los logs de Zimbra contó lo que ya viene siendo costumbre: no fue fuerza bruta. El 7 de agosto a las 18:44 alguien autenticó con el dominio mal escrito (le faltaba el .uy), obtuvo «account not found», y 21 segundos después probó con el dominio correcto y entró. Cero contraseñas fallidas antes del éxito: la contraseña ya la tenía. El vector más probable es phishing o un infostealer en la máquina de la usuaria.

Lo que vino después tenía formato de operación profesional: autenticación por SMTP AUTH en el puerto de submission (7073), no por webmail; un bloque completo de IPs rotando un host por lote; destinatarios generados por diccionario contra iCloud y dominios typosquatted. Tres días de envío ininterrumpido hasta que bloqueamos la cuenta el 10 a la mañana.

La contención (y lo que salió mal)
#

El procedimiento era el de manual: bloquear la cuenta, cambiar la contraseña, cortar las sesiones SMTP vivas y revisar la cola. Lo que no esperaba era el tamaño de esa cola.

# cuántos mensajes hay en cola y cuántos son de la casilla comprometida
$ echo "Total en cola:"; find /var/spool/postfix/deferred/ -type f | wc -l
Total en cola:
385120

Una muestra con qshape deferred mostraba el destino típico del spam: gmail, yahoo, mail.com, aol… y a MAILER-DAEMON como remitente de buena parte del contenido: rebotes que generaba nuestro propio servidor contra lo que el spam había roto.

Cuando confirmé que la casilla comprometida era la inmensa mayoría, paré Postfix y borré la cola completa:

$ postfix stop
$ postsuper -d ALL
postsuper: Deleted: 475098 messages
$ postfix start

Suena drástico, y lo es: ahí había correo legítimo que iba a quedar en el camino. Pero cada minuto de cola era spam reintentando salir y quemando lo que quedaba de reputación. La lección práctica: no borres a ciegas; primero confirmá con qshape que el remitente sospechoso es la mayoría.

Y porque nunca falta, en el camino se sumaron tres sustos:

  • Zimbra quedó 55 minutos offline: una operación de snapshot de Proxmox dejó la VM bloqueada y el PMG acumuló 173 mensajes con «No route to host» mientras duró.
  • Al día siguiente el correo seguía trabado y la culpa era del propio blindaje: fail2ban en Zimbra había baneado al PMG en dos jails durante el ataque. Otros 79 mensajes con «Connection refused» hasta limpiar los bans. El gateway va en el ignoreip de fail2ban, siempre.
  • Quedaron 93 mensajes de MAILER-DAEMON: backscatter generado por nuestro propio spam, todos inofensivos. Se purgan sin culpa.

La factura: siete listas negras y una IP nueva
#

En paralelo había que recuperar la entregabilidad. MXToolbox mostraba la IP listada en 7 de 60 RBLs: Abusix, Hostkarma, ivmSIP, PSBL, s5h.net, SpamCop y TRUNCATE. Google y Microsoft nos aplicaban rate limit. Lo único que seguía llegando era Protonmail, que no consulta esas listas.

El orden importa: primero se corta la causa (cuenta bloqueada, cola vacía) y recién después se pide el deslistado. Spamhaus tarda 24–48 horas, Barracuda 12–24, y las solicitudes repetidas no aceleran nada. Mientras tanto, los rechazos: destinatarios importantes que contestaban con un 554 por DNSBL.

Aun así, la reputación quedó quemada y los rate limits persistían. Terminamos moviendo el correo saliente a una IP pública nueva, con el PTR verificado en los dos sentidos (dig -x y resolución directa) antes de mandar el primer mensaje. A veces es más rápido empezar de cero con la reputación que insistir con la quemada.

Un mes después, la misma película
#

El 6 de septiembre la estadística del PMG volvió a mostrar una casilla desbordada: ~4.939 destinatarios únicos en poco más de un día, otra vez contra iCloud y dominios typosquatted. Cuatro IPs extranjeras rotando por turnos, 49 autenticaciones exitosas y cero intentos fallidos previos: otra contraseña robada. El atacante ni siquiera tocó el webmail, solo SMTP AUTH.

La diferencia con agosto fue la latencia: 28 horas desde el primer envío hasta el cierre de la cuenta, contra los tres días de la vez anterior. Cerrada la casilla, el atacante intentó volver a autenticar durante una hora y se encontró con la puerta cerrada.

El modus operandi era idéntico al incidente anterior: mismo patrón de rotación de IPs, mismos destinatarios generados por máquina, mensajes de tamaño uniforme con Message-ID aleatorio (firma de una herramienta de spam, no el JavaMail.zimbra de Zimbra). Apostaría a que era el mismo actor, o al menos el mismo infostealer acechando en la organización.

Qué me llevé
#

  • Las cuentas comprometidas avisan. Más de 1.000 envíos desde una misma casilla es señal de alarma, no un lunes concurrido. Agregué a la rutina el conteo rápido por usuario SASL:

    sed -n 's/.*sasl_username=//p' /var/log/zimbra.log | sort | uniq -c | sort -n
  • MFA en todas las casillas. Ninguna de las dos cuentas lo tenía. Con la segunda ya no era una recomendación teórica.

  • Límites de envío por casilla. PMG 6.x no los trae: el staff de Proxmox lo confirmó sin vueltas («There are no such limits»). La defensa se arma en otra capa, con CBPolicyD dentro de Zimbra o postfwd dentro de PMG. Tengo la investigación hecha y da para otro post.

  • El firewall miente si mirás un solo puerto. La regla de geoIP cubría HTTPS, pero el spam salió por el puerto de submission (7073): el atacante autenticó desde cualquier parte del mundo sin tocar la puerta protegida.

  • fail2ban puede pegarte un tiro en el pie. Casi 80 mensajes perdidos porque el banhammer baneó al propio PMG. Whitelist de los gateways, sin excepciones.

Dos incidentes, casi el mismo guion y la misma lección: la seguridad del correo no está en el antispam, está en notar a tiempo cuándo una casilla dejó de ser de su dueño. Lo demás —colas, listas negras, IP nueva— es administrar las consecuencias.

Fin del artículo

Escrito con la ayuda de IA generativa mediante OpenCode. La revisión final y la responsabilidad por el contenido son mías. Human in the loop.

Valeri Macarov

Infraestructura Linux · Automatización · Desarrollo web

Ciudad de la Costa, Canelones, Uruguay

Contame tu caso [email protected]
Más artículos

Relacionados