Aquí podría ser tu PUBLICIDAD


Inyección de encabezado SMTP en ASP.NET?

votos
8

Mi sitio web ASP.NET tiene un controlador de error global que me envía un correo electrónico (y otro desarrollador) cuando hay algún tipo de error en la aplicación web. Recientemente recibimos un error que contenía un CC a una dirección de correo electrónico de la que nunca habíamos oído hablar. Lo aterrador es que la lista de desarrolladores a los que se envía el correo electrónico de error está codificada en código ASP.NET compilado. No vemos cómo se podría haber agregado el CC.

También sospechamos mucho del juego sucio porque la solicitud que causó el error fue un intento de utilizar uno de nuestros formularios para enviar spam. La dirección IP que envió la solicitud también se encuentra en http://www.projecthoneypot.org/ .

Nuestra mejor suposición ahora es que la solicitud fue malformada de alguna manera que inyectó un encabezado CC en el correo electrónico. El problema es que no podemos entender cómo se podría hacer esto. Estamos usando System.Net.Mail para enviar los correos electrónicos y parece protegernos contra este tipo de cosas. El sujeto del objeto MailMessage solo acepta una sola línea para que no cree un asunto multilínea con una línea CC. Configurar las direcciones a y cc en MailMessage parece bastante robusto. Y no veo cómo podría agregar un encabezado CC en el cuerpo del mensaje. No puedo encontrar ninguna información sobre esto y me gustaría saber si esto es un problema real.

EDITAR: Alguien pidió el código. Es un poco largo, pero aquí está:

public class Global : System.Web.HttpApplication
{
    protected void Application_Error(Object sender, EventArgs e)
    {
        // Get the last exception.
        Exception objException = Server.GetLastError();

        // Work out the error details based on the exception.
        string ErrorType = ;
        string ErrorDescription = ;
        string ErrorHtml = ;

        if (objException == null)
        {
            // This should never occur.
            ErrorType = Unknown Error;
            ErrorDescription = Unknown Error;
        }
        else if (objException.GetType() == typeof(HttpException))
        {
            // This will occur when the ASP.NET engine throws a HttpException.
            HttpException objHttpException = objException as HttpException;
            if (objHttpException.GetHttpCode() == 404)
            {
                string Resource = Globals.GetFullUrl(this.Context);
                Server.ClearError();
                Response.Redirect(/ResourceNotFound.aspx?BadUrl= + Server.UrlEncode(Resource));
                return;
            }
            else
            {
                ErrorType = objHttpException.GetHttpCode().ToString();
                ErrorDescription = objHttpException.Message;
            }
        }
        else if (objException.GetType() == typeof(HttpUnhandledException) && objException.InnerException != null && objException.InnerException.GetType() == typeof(HttpException))
        {
            // This will occur when the code throws a HttpException (e.g. a fake 404).
            HttpException objHttpException = objException.InnerException as HttpException;
            if (objHttpException.GetHttpCode() == 404)
            {
                string Resource = Globals.GetFullUrl(this.Context);
                Server.ClearError();
                Response.Redirect(/ResourceNotFound.aspx?BadUrl= + Server.UrlEncode(Resource));
                return;
            }
            else
            {
                ErrorType = objHttpException.GetHttpCode().ToString();
                ErrorDescription = objHttpException.Message;
            }
        }
        else if (objException.GetType() == typeof(HttpUnhandledException))
        {
            // This will occur when a page throws an error.
            HttpUnhandledException objHttpUnhandledException = (HttpUnhandledException) objException;
            ErrorType = objHttpUnhandledException.GetHttpCode().ToString();
            if (objHttpUnhandledException.InnerException != null)
                ErrorDescription = objHttpUnhandledException.InnerException.Message;
            else
                ErrorDescription = objHttpUnhandledException.Message;
            if (objHttpUnhandledException.GetHtmlErrorMessage() != null)
            {
                ErrorHtml = objHttpUnhandledException.GetHtmlErrorMessage();
            }
        }
        else if (objException.GetType() == typeof(HttpRequestValidationException) && !Globals.IsTtiUser(this.Context))
        {
            // Do nothing.  This is mostly just spider junk and we don't want to know about it.
        }
        else
        {
            // This will occur when the ASP.NET engine throws any error other than a HttpException.
            ErrorType = objException.GetType().Name;
            ErrorDescription = objException.Message;
        }

        // Send an email if there's an error to report.
        if (ErrorType !=  || ErrorDescription != )
        {
            Globals.SendErrorEmail(this.Context, ErrorType, ErrorDescription, ErrorHtml);
        }
    }

    public static void SendErrorEmail (HttpContext context, string errorType, string errorDescription, string errorHtml)
    {
        // Build the email subject.
        string Subject = EM:  + errorType + :  + context.Request.ServerVariables[SCRIPT_NAME];

        // Build the email body.
        string Body;

        StringBuilder sb = new StringBuilder();
        sb.Append(Server:\r\n);
        sb.Append(Globals.Server.ToString() + \r\n);
        sb.Append(\r\n);
        sb.Append(URL:\r\n);
        sb.Append(Globals.GetFullUrl(context) + \r\n);
        sb.Append(\r\n);
        sb.Append(Error Type + :\r\n);
        sb.Append(errorType + \r\n);
        sb.Append(\r\n);
        sb.Append(Error Description + :\r\n);
        sb.Append(errorDescription + \r\n);
        sb.Append(\r\n);
        sb.Append(Referring Page:\r\n);
        sb.Append(context.Request.ServerVariables[HTTP_REFERER] + \r\n);
        sb.Append(\r\n);
        sb.Append(Date/Time:\r\n);
        sb.Append(DateTime.Now.ToString() + \r\n);
        sb.Append(\r\n);
        sb.Append(Remote IP:\r\n);
        sb.Append(context.Request.ServerVariables[REMOTE_ADDR] + \r\n);
        sb.Append(\r\n);
        sb.Append(User Agent:\r\n);
        sb.Append(context.Request.ServerVariables[HTTP_USER_AGENT] + \r\n);
        sb.Append(\r\n);
        sb.Append(Crawler:\r\n);
        sb.Append(context.Request.Browser.Crawler.ToString() + \r\n);
        sb.Append(\r\n);
        sb.Append(Admin User:\r\n);
        sb.Append(context.User.Identity.Name + \r\n);
        sb.Append(\r\n);
        sb.Append(\r\n);
        Body = sb.ToString();

        // If there's HTML to represent the error (usually from HttpUnhandledException),
        // then stuff the body text into the HTML (if possible).
        bool HtmlMessage = false;

        if (errorHtml != )
        {
            Regex r = new Regex((?<thebodytext><body.*?>), RegexOptions.IgnoreCase);
            if (r.IsMatch(errorHtml))
            {
                Body = Body.Replace(\r\n, <br>);
                Body = r.Replace(errorHtml, ${thebodytext} + Body, 1);
                HtmlMessage = true;
            }
        }

        // Send an email to the TTI developers.
        MailMessage objMail;
        objMail = new MailMessage();
        objMail.From = new MailAddress(from-address);
        objMail.To.Add(new MailAddress(to-address));
        objMail.CC.Add(new MailAddress(cc-address));
        objMail.CC.Add(new MailAddress(another-cc-address));
        if (HtmlMessage)
            objMail.IsBodyHtml = true;
        else
            objMail.IsBodyHtml = false;
        if (errorType == 404)
            objMail.Priority = MailPriority.Low;
        else
            objMail.Priority = MailPriority.High;
        objMail.Subject = Subject;
        objMail.Body = Body;

        try
        {
            SmtpClient objSmtpClient = new SmtpClient();
            objSmtpClient.Send(objMail);
        }
        finally
        {
            // Do nothing.
        }
    }
}
Publicado el 12/03/2009 a las 16:36
fuente por usuario Ben Mills
En otros idiomas...        العربية       

3 respuestas

votos
4

Pude ver que este es el objetivo de un ataque MUY creativo ... Estás rellenando los datos controlados por el usuario en tu cuerpo de mensaje ... En ese punto, el uso astuto de datos binarios PODRÍA dar como resultado un CUERPO que envíe los datos adecuados durante el proceso. Sesión SMTP para formatearla JUSTO BIEN ... Si puedo, sugiero que se convierta el cuerpo en texto ASCII o durante la creación de cadenas, escriba un sanitizador de cadenas que solo permita caracteres RFC. (Filtra las URL, el REFERRER, la dirección remota y el UserAgent). Esos son sus puntos de ataque más probables.

Un segundo pensamiento podría ser construir un correo electrónico básico en el código, y ADJUNTAR el cuerpo que ha construido como texto, HTML o archivo PDF.

Tenga en cuenta que los datos SMTP ENVELOPE NO son lo mismo que los datos del mensaje ... Si alguien era lo suficientemente astuto como para enviar el cuerpo correcto que provocó que se enviara un CRLFCRLF.CRLFCRLF durante la parte del cuerpo, eso terminaría el envío, y luego si siguieran enviando datos, podrían enviar todo el CORREO DE: RCPT A :, DATOS, etc. ... (Por supuesto, este es un escenario improbable ...) ...

ME ENCANTARÍA ver el origen RAW del correo electrónico que recibiste ... (Como en el volcado hexadecimal de la transacción SMTP real, no es lo que Outlook quiere que veas, ni lo que sea).

También puedes intentar codificar tu cuerpo usando QP o B64 antes de enviar el mensaje ... Eso podría resolver tu problema ...

Esta es una interesante, y estoy esperando el resultado de la misma.

Respondida el 18/03/2009 a las 01:26
fuente por usuario LarryF


Aquí podría ser tu PUBLICIDAD


votos
1

Su código parece muy seguro, así que no creo que el problema esté de su lado.

IMO, ya sea que alguien haya interceptado el mensaje SMTP mientras se estaba enviando al servidor de correo y le haya inyectado la línea CC: adicional; o el servidor de correo ha sido comprometido.

Si no puede encontrar una respuesta, le sugiero que se contacte directamente con Microsoft; es posible que haya descubierto un exploit en .NET Framework.

Respondida el 18/03/2009 a las 12:05
fuente por usuario Ian Kemp

votos
0

Como solución alternativa, ¿por qué no codifica el mensaje de correo electrónico mediante una inscripción asimetría (por ejemplo, inscripción de clave pública)? De esa forma solo el destinatario previsto podrá leerlo.

De esta forma, incluso si los malos obtienen una copia de tu mensaje (por cualquier medio), les será de utilidad.

Seamos realistas, si tienes un sitio web de alto perfil como el FBI o Google, muchas personas muy creativas pasarán mucho tiempo y harán todo lo posible para contraerlo. Es extremadamente importante proteger los mensajes de error detallados.

Respondida el 19/07/2009 a las 07:35
fuente por usuario JonnyBoats