9. Fase 4: Explotación de las vulnerabilidades
9.1. Ataques de Inyección de Código
9.1.2. Inyección de Código en servicio SMTP
La seguridad en la capa de transporte (TLS, por sus siglas en inglés Transfer Protocol Layer), es un protocolo criptográfico definido por el Grupo de Trabajo de Ingeniería de Internet (IETF, por sus siglas en inglés Internet Engineering Task Force) utilizado para garantizar comunicaciones seguras por una red.
Muchas aplicaciones con cliente SMTP no verifican que el servidor TLS esté
certificado. Estos clientes SMTP son vulnerables a ataques tales como la inyección de
comandos. Sus sesiones TLS están encriptadas pero no protegidas, por lo tanto, una falla de inyección de texto plano puede existir en dichos clientes, la cual se da en la forma que manejan las respuestas de SMTP sobre TLS del servidor.
IMAP, NNTP y FTP. Implementaciones de estos protocolos pueden verse afectados por el mismo defecto.
Existen dos formas en que los protocolos de texto sin formato pueden proporcionar
encriptación con TLS. La primer forma es escuchando en dos puertos: un puerto que es
siempre texto sin formato y un segundo puerto que siempre está encriptado con TLS. La otra forma es usando un solo puerto en el que la comunicación comience sin cifrar, pero pueda "actualizarse" a una conexión encriptada TLS utilizando un comando de nivel de aplicación específico para el protocolo.
HTTP / HTTPS usa exclusivamente el primer enfoque, con los puertos 80 y 443. El
segundo enfoque, llamado STARTTLS, es utilizado por SMTP, XMPP, IMAP y POP3,
aunque varios de estos protocolos también son compatibles con el primer enfoque.
Cuando IETF estandarizó el uso de TLS con IMAP y POP3 en 1999, prescribió el uso de STARTTLS y dio varias razones por las cuales STARTTLS debería usarse en lugar de un TLS alternativo. Estas fueron básicamente:
1. Los puertos separados llevan a un esquema de URL separado, lo que significa que el usuario tiene que elegir entre ellos. El software suele ser más apto que el usuario a la hora de tomar estas decisiones.
2. Los puertos separados han provocado que los clientes implementen solo dos políticas
de seguridad: “utilizar TLS” o “no utilizar TLS”. La política de seguridad deseable "utilizar TLS cuando esté disponible" sería engorrosa con el modelo de puerto separado, pero es simple con STARTTLS.
3. Los puertos separados implican un modelo de "seguro" o "no seguro", que puede ser engañoso. Por ejemplo, el puerto "seguro" puede ser inseguro porque está utilizando software criptográfico export-crippled, el cual está limitado a una clave de tamaño pequeño. De esta manera, el texto cifrado que se consigue con él puede descifrarse por medio de fuerza bruta. En su caso contrario, el puerto normal podría estar utilizando un mecanismo SASL que incluye una capa de seguridad.
4. Los números de puerto son un recurso limitado.
El problema es que salvo la cuarta razón, se han encontrado argumentos suficientes como para desacreditar el resto de estas razones previamente mencionadas.
Comenzando por el motivo número uno, el cual no siempre es cierto. A menos que el
software mantenga una base de datos de los hosts que deberían usar TLS, es incapaz de
elegir entre TLS y no TLS en lugar del usuario sin ser susceptible a ataques activos.
De la misma manera, el segundo motivo es discutible ya que "utilizar TLS cuando está disponible" también es susceptible a ataques activos. Ya que si el software detecta que TLS no está disponible, no tiene forma de saber si es porque el servidor no lo admite o si un atacante lo está bloqueando.
Por último, la razón tres puede haber tenido algún sentido en 1999, pero ciertamente no lo hace hoy. La preocupación de la cifra de exportación se debatió cuando se eliminaron los controles de exportación en 2000, lo que provocó la desaparición de cifras cifradas por la exportación. Si bien en ese momento las capas de seguridad SASL eran de lo más viable, en la actualidad TLS las ha superado.
Entonces, STARTTLS realmente no es mejor que usar un puerto alternativo de TLS. Pero eso no es todo. Hay varias razones por las que STARTTLS es realmente peor para la seguridad.
La primera de ellas es que STARTTLS hace que sea imposible finalizar TLS de
forma independiente del protocolo. Resulta trivial terminar un protocolo de puerto
independiente como HTTPS en un software proxy como titus (Totally Isolated TLS
Unwrapping Server, o en su traducción al castellano , Servidor Desempaquetado TLS Totalmente Aislado) o en un balanceador de carga de hardware. Tan solo se debe aceptar la conexión TLS y generar un proxy sobre el texto plano enviado al puerto no-TLS del servidor. Por otro lado, la terminación de un protocolo STARTTLS requiere que el terminador TLS comprenda que el protocolo es proxy, por lo que puede vigilar el comando STARTTLS y solo actualizar a TLS una vez que se envía el comando.
Esto es preocupante ya que es deseable terminar la conexión TLS en servidores
SMTP, IMAP y XMPP dentro del entorno altamente aislado de titus, para que una
vulnerabilidad en la implementación de TLS no pueda comprometer el estado de ellos.
Desafortunadamente STARTTLS hace que esto sea innecesariamente difícil de concretar.
Otra forma en que STARTTLS perjudica la seguridad es agregando complejidad.
Aquí es donde se puede encontrar como ejemplo la vulnerabilidad que se explotará a
continuación, la cual lleva el identificador CVE-2011-0411. Esta vulnerabilidad es causada
STARTTLS. De esta forma se permite inyectar comandos SMTP que serán ejecutados por el servidor durante la fase de la conexión que se supone que debe estar protegida con TLS.
Es posible demostrar este problema modificando tan solo una línea del código fuente
del comando s_client en OpenSSL. Este comando puede establecer una conexión con soporte
directo TLS, SMTP sobre TLS, o un puñado de otros protocolos sobre TLS. En este caso se modificará la línea 1129 (con OpenSSL 1.0.0, archivo ubicado en /apps/s_client.c).
Línea original: BIO_printf (sbio, "STARTTLS \ r \ n");
Línea modificada: BIO_printf (sbio, "STARTTLS \ r \ nRSET \ r \ n");
Figura 9-8: Inyección de comando RSET en el archivo s_client.s
De esta forma, el comando s_client envía el comando STARTTLS ("encender TLS")
inmediatamente seguido de un comando RSET. Este comando se utiliza en condiciones
normales para especificar que la transacción del correo debe ser abortada. Cualquier emisor, receptor y data del correo debe ser abortada, a su vez los buffers y tablas de estado deben
limpiarse. El receptor debe enviar “250 OK” de respuesta a este comando sin ningún argumento. Esto es efectivamente equivalente a un NOOP emitido inmediatamente luego de un comando EHLO.
Ambos comandos se envían como texto plano en el mismo paquete TCP / IP, y llegan juntos al servidor. Los "\ r \ n" son los caracteres de retorno y de nueva línea, estos son necesarios para finalizar un comando SMTP.
Cuando un servidor SMTP tiene la falla de inyección de texto plano lee primero el comando STARTTLS, cambia al modo SMTP-sobre-TLS y, solo en ese caso, el servidor lee el comando RSET.
Se debe tener en cuenta que que el comando RSET se transmitió durante la fase SMTP de texto sin pantalla cuando no hay protección, dado esto, el servidor lee el comando como si se recibiera a través del canal protegido por TLS.
Figura 9-9: Verificación de ejecución del comando RSET (inyectado)
Por lo tanto, el resultado del comando s_client mostrará dos "250" como respuestas del servidor SMTP en lugar de uno. El primer "250" es normal y está presente incluso cuando el servidor no está defectuoso. La segunda respuesta "250" es para el comando RSET, e indica que el servidor SMTP tiene la falla de inyección de texto plano.
Es importante aclarar que se utilizó el comando RSET ya que es relativamente inofensivo y cuadra de forma oportuna para ejemplificar este ataque. Pero un atacante real
puede hacer uso de combinaciones de comandos muchos más dañinos, los cuales pueden
generar un flujo de acción no deseado que comprometa sustancialmente la seguridad del