inyección SMTP: ¿en qué me equivoco?

-1

En otro hilo un usuario intentaba usar inyecciones SMTP y, como prueba, tratando de inyectar un destinatario suplementario para este correo electrónico.

Mi comprensión del problema que le impide tener éxito fue lo siguiente:

  1. Utiliza Python SMTPlib, que filtra los parámetros (los datos inesperados se eliminan silenciosamente) precisamente para evitar tales ataques,
  2. Estaba inyectando datos en el lugar equivocado, afectando los datos del correo en lugar del intercambio de protocolo SMTP real.

Sin embargo, los siguientes comentarios muestran que mi comprensión es errónea y todavía no entiendo por qué. Por lo tanto, para evitar discusiones fuera de tema en este hilo anterior, abro una nueva pregunta con más detalles sobre mi punto de vista.

He escrito a continuación una prueba rápida de concepto, aún en Python, y voluntariamente no usar SMTPlib ya que, como se dijo anteriormente, esta biblioteca incluye protección contra la inyección de SMTP:

#! /usr/local/bin/python3.3

host = "smtp.example.com"
port = 2525

sender = "[email protected]"

# Injection occurs here:
recipient = "[email protected]>\r\nRCPT TO:<[email protected]"

msg = "From: \"Bob Example\" <[email protected]>\r\n" + \
    "To: \"Alice Example\" <[email protected]>\r\n" + \
    "Cc: [email protected]\r\n" + \
    "Date: Tue, 15 January 2008 16:02:43 -0500\r\n" + \
    "Subject: Test message\r\n" + \
    "\r\n" + \
    "This is a test\r\n"


import re
import socket
import time

def getReply(sock):
    time.sleep(0.1)
    reply = str(sock.recv(4096), "ascii")
    if reply[0] != '2' and reply[0] != '3':
        raise RuntimeError("SMTP error: " + reply)
    print("S: " + reply)

def sendCmd(sock, cmd):
    sock.sendall(bytes(cmd, "ascii"))
    print("C: " + cmd)
    getReply(sock)

sock = socket.create_connection((host, port))
getReply(sock)
sendCmd(sock, "EHLO somebody.example.com\r\n")
sendCmd(sock, "MAIL FROM:<" + sender + ">\r\n")
sendCmd(sock, "RCPT TO:<" + recipient + ">\r\n")
sendCmd(sock, "DATA\r\n")
sendCmd(sock, msg + "\r\n.\r\n")
sendCmd(sock, "QUIT\r\n")
sock.close()

Esta secuencia de comandos simula una inyección SMTP en el campo del destinatario.

Un servidor SMTP seguro puede detectar dicha inyección debido a la presencia de datos finales después del avance de línea al final del comando RCPT TO: . La siguiente salida se produce cuando se ejecutan estos scripts contra el servidor OpenBSD OpenSMTPD privado:

S: 220 smtp.example.com ESMTP OpenSMTPD

C: EHLO somebody.example.com

S: 250-smtp.example.com Hello somebody.example.com [127.0.0.1], pleased to meet you
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SIZE 36700160
250-DSN
250 HELP

C: MAIL FROM:<[email protected]>

S: 250 2.0.0: Ok

C: RCPT TO:<[email protected]>
RCPT TO:<[email protected]>

Traceback (most recent call last):
  File "./semail.py", line 31, in <module>
    sendCmd(sock, "RCPT TO:<" + recipient + ">\r\n")
  File "./semail.py", line 25, in sendCmd
    getReply(sock)
  File "./semail.py", line 19, in getReply
    raise RuntimeError("SMTP error: " + reply)
RuntimeError: SMTP error: 500 5.5.1 Invalid command: Pipelining not supported

Un servidor SMTP seguro detecta correctamente los datos sospechosos y rechaza la solicitud.

Sin embargo, el servidor de correo no seguro leerá la línea de datos entrantes por línea y no detectará el problema. Se ha obtenido el seguimiento a continuación al ejecutar el mismo script contra un importante proveedor de servicios de correo electrónico público:

S: 220 smtp.example.com ESMTP ready

C: EHLO somebody.example.com

S: smtp.example.com
250-PIPELINING
250-SIZE 41943040
250-8BITMIME
250 STARTTLS

C: MAIL FROM:<[email protected]>

S: 250 sender <[email protected]> ok

C: RCPT TO:<[email protected]>
RCPT TO:<[email protected]>

S: 250 recipient <[email protected]> ok
250 recipient <[email protected]> ok

C: DATA

S: 354 go ahead

C: From: "Bob Example" <[email protected]>
To: "Alice Example" <[email protected]>
Cc: [email protected]
Date: Tue, 15 January 2008 16:02:43 -0500
Subject: Test message

This is a test

.

S: 250 ok dirdel 1/1

C: QUIT

S: 221 smtp.example.com

Un servidor SMTP no seguro consume y ejecuta comandos inyectados. Aquí los destinatarios han recibido correctamente los correos electrónicos.

Mi conclusión después de esta prueba es que la inyección SMTP de los comandos RCPT TO: que usan el campo del destinatario es exitosa, y su ejecución hacia diferentes servidores muestra que algunos servidores están más protegidos que otros contra este ataque.

Además, en este ejemplo se usó un comando RCTP TO: como seguimiento de la pregunta original, sin embargo, en este paso solo se tiene acceso al debate del protocolo SMTP y es libre de inyectar cualquier comando en servidores vulnerables. / p>

Sin embargo, los comentarios en el hilo original parecen para indicar que actualmente me falta algo crucial en mi análisis y que, por lo tanto, tales conclusiones son irrelevantes.

¿Puede alguien ayudarme a determinar dónde me equivoco exactamente en mi análisis de este problema?

    
pregunta WhiteWinterWolf 14.05.2015 - 11:21
fuente

3 respuestas

2

El protocolo SMTP se basa en una serie de comandos y respuestas.

RFC 821 (abril de 1982) esperaba que el cliente leyera cada respuesta antes de continuar. De esta manera, si envío un correo electrónico a Alice, Bob y Carol, hay muchos puntos redondos, como hago: "RCPT Alice" (esperar respuesta), "RCPT Bob" (esperar respuesta), "RCPT Carol" ( espere la respuesta),.

Más adelante, RFC 1854 (octubre de 1995) definió la extensión PIPELINING, permitiendo al cliente enviar varios comandos en uno y garantizando que el servidor los procesará todos en orden (un servidor que no admita PIPELINING podría descartar bytes antes de su respuesta).

Por lo tanto, para un servidor que implementa la canalización, puedo hacer: "RCPT Alice", "RCPT Bob", "RCPT Carol",

También podría enviar, DATOS en una porción. Esto hace que la programación sea más sencilla (por ejemplo, un script de shell ficticio que distribuye el correo electrónico a un MDA), pero no es demasiado inteligente como para que lo haga un MTA completo, ya que no tiene mucho sentido enviar el contenido del correo electrónico a través de la red si ninguno de los destinatarios está disponible, o los destinatarios si se rechazó el CORREO.

Lo que llama un servidor SMTP no seguro es simplemente un servidor SMTP compatible con PIPELINING, y lo que llama un servidor SMTP seguro, uno lo bloquea de forma activa (tal vez como un intento de bloquear a los spammers, que a menudo simplemente descargan todos los comandos, no preocuparse por los errores).

En mi opinión, la protección contra este ataque debería ubicarse en el programa que proporciona el correo electrónico. Si pensaba que había enviado un destinatario, pero el servidor veía dos, la aceptación del segundo destinatario se vería como una respuesta a DATOS, mientras esperaba un 354 (o un error como 503, 554), y debería abortar en ese punto . (Esto es lo que Tony Meyer se refirió a cuando se habla de un error debido a estar fuera de secuencia)

    
respondido por el Ángel 14.05.2015 - 23:33
fuente
4

Creo que el punto que te falta es este:

La inyección de encabezado SMTP no es un ataque en un servidor de correo.

Es un ataque a un servidor web u otra aplicación que controla un servidor de correo en el back end.

Vea la página OWASP sobre Pruebas de inyección de IMAP / SMTP .

En su pregunta, su definición de "servidor SMTP seguro" no admite la canalización. La canalización es donde se pueden enviar múltiples encabezados sin esperar una respuesta a cada uno, como una forma de acelerar las comunicaciones con el servidor de correo.

Por lo tanto, la forma de atacar un servidor de correo con inyección de encabezado es atacar la aplicación que accede al servidor de correo, como una aplicación de correo electrónico basada en web. La vulnerabilidad es que la aplicación web está enviando entradas no saneadas directamente al servidor de correo, por lo que los caracteres como las nuevas líneas ingresadas en el campo To en realidad se están insertando en el sobre del correo en lugar de interpretarse como un conjunto de direcciones de correo electrónico. / p>

Esta es la razón por la que el uso de Python SMTPlib para la inyección de encabezados es incorrecto: los desarrolladores de aplicaciones ya son conscientes del problema de la inyección de encabezados y han asegurado el código para manejar las nuevas líneas inyectadas en los campos.

Por lo tanto, su script anterior no está probando una vulnerabilidad de inyección SMTP, es la vulnerabilidad .

    
respondido por el SilverlightFox 15.05.2015 - 11:33
fuente
0

El proceso de envío del correo electrónico abarca la generación del sobre del correo y el cuerpo del correo. Cualquier cosa que no sea parte del fragmento DATA es el sobre de correo. Esta es la separación clásica de los mensajes de control y la carga de datos en sí. Y también de manera similar a otros estándares, el correo resultante entregado por el agente de entrega local está en todos los aspectos prácticos, sujeto a los caprichos de la entrega ya sea para aplicar RCPT TO, FROM, etc. a los encabezados de correo, descartando cualquier ocurrencia de este tipo en el cuerpo del mensaje.

Esto se hace de hecho como parte del diseño, ya que el descubrimiento del destinatario no funcionaría si el cifrado se aplicara al sobre, pero los cuerpos de mensaje cifrados están bien. Esto está ligado firmemente al espíritu de Internet, donde, fundamentalmente, todo se transmite a través de redes que no son de confianza.

    
respondido por el munchkin 15.05.2015 - 06:38
fuente

Lea otras preguntas en las etiquetas