En el proyecto en desarrollo del servidor de correo OpenBSD se ha detectado (CVE-2020-7247), que permite ejecutar comandos shell de forma remota en el servidor con privilegios de usuario root. La vulnerabilidad fue identificada durante una auditoría repetida realizada por la empresa Qualys Security (la auditoría anterior de OpenSMTPD en 2015, y la nueva vulnerabilidad está presente desde mayo de 2018). El problema se encuentra en la versión de OpenSMTPD 6.6.2. Se recomienda a todos los usuarios que instalen urgentemente la actualización (para OpenBSD, la corrección se puede instalar a través de syspatch).
Se han propuesto dos variantes de ataque. La primera variante funciona en la configuración predeterminada de OpenSMTPD (aceptando solicitudes solo desde localhost) y permite explotar el problema localmente, cuando el atacante tiene la capacidad de acceder a la interfaz de red local (loopback) en el servidor (por ejemplo, en sistemas de hosting). La segunda variante se manifiesta en caso de que OpenSMTPD esté configurado para aceptar solicitudes de red externas (servidor de correo que recibe correo de terceros). Los investigadores han preparado un prototipo de exploit que funciona exitosamente tanto con la variante de OpenSMTPD incluida en OpenBSD 6.6 como con la versión portátil para otros sistemas operativos (realizado en Debian Testing).
El problema es causado por un error en la función smtp_mailaddr(), que se llama para verificar la validez de los valores en los campos "MAIL FROM" y "RCPT TO", que determinan el remitente / destinatario y se transmiten durante la conexión con el servidor de correo. Para verificar la parte de la dirección de correo que precede al símbolo "@", se llama a la función valid_localpart() en smtp_mailaddr(), que considera válidos los caracteres "!#$%&’*\/¿?^`{|}~+-=_", de acuerdo con los requisitos de la RFC 5322.
A su vez, la escapada directa de la cadena se realiza en la función mda_expand_token(), que solo reemplaza los caracteres "!#$%&’*?`{|}~" (MAILADDR_ESCAPE). Posteriormente, la cadena preparada en mda_expand_token() se utiliza al invocar el agente de entrega (MDA) mediante el comando 'execle("\/bin\/sh", "\/bin\/sh", "-c", mda_command,…'. En caso de colocar el correo en mbox a través de \/bin\/sh, se ejecuta la cadena "\/usr\/libexec\/mail.local -f %%{mbox.from} %%{user.username}", donde el valor "%{mbox.from}" incluye datos escapados del parámetro "MAIL FROM".
При этом непосредственное экранирование строки производится в функции mda_expand_token(), которая заменяет только символы «!#$%&’*?`{|}~» (MAILADDR_ESCAPE). В дальнейшем, подготовленная в mda_expand_token() строка используется при вызове агента доставки (MDA) при помощи команды ‘execle(«/bin/sh», «/bin/sh», «-c», mda_command,…’. В случае помещения письма в mbox через /bin/sh запускается строка «/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}», где значение «%{mbox.from}» включает экранированные данные из параметра «MAIL FROM».
La vulnerabilidad radica en que smtp_mailaddr() tiene un error lógico que, al recibir un dominio vacío en el email, la función devuelve un código de verificación exitoso, incluso si la parte de la dirección antes de «@» contiene caracteres no válidos. Luego, al preparar la cadena con la función mda_expand_token(), no se escapan todos los posibles caracteres especiales de shell, sino solo los caracteres especiales permitidos en una dirección de correo electrónico. Así, para ejecutar su propio comando, basta con usar en la parte local del email el símbolo «;» y un espacio, los cuales no forman parte del conjunto MAILADDR_ESCAPE y no se escapan. Por ejemplo:
$ nc 127.0.0.1 25
HELO professor.falken
MAIL FROM:<;sleep 66;>
RCPT TO:<root>
DATA
.
QUIT
Después de esta sesión, OpenSMTPD ejecutará un comando a través de shell al entregar en mbox.
/usr/libexec/mail.local -f ;sleep 66; root
Sin embargo, las posibilidades de ataque están limitadas por el hecho de que la parte local de la dirección no puede exceder los 64 caracteres, y los caracteres especiales ‘$’ y ‘|’ se reemplazan por «:» al escaparse. Para eludir esta limitación, se utiliza el hecho de que el cuerpo del correo se transmite después de iniciar /usr/libexec/mail.local a través del flujo de entrada, es decir, a través de manipulaciones con la dirección se puede iniciar solo el intérprete de comandos sh y utilizar el cuerpo del correo como un conjunto de instrucciones. Dado que al principio del correo se especifican los encabezados SMTP de servicio, se sugiere usar la llamada al comando read en un bucle para omitirlos. El exploit funcionante adquiere un aspecto similar al siguiente:
$ nc 192.168.56.143 25
HELO professor.falken
MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>
RCPT TO:<root@example.org>
DATA
#0
#1
…
#d
for i in W O P R; do
echo -n «($i) » && id || break
done > /root/x.»`id -u`».»$$»
.
QUIT
Fuente: opennet.ru
