Uno de los ataques más comunes a las aplicaciones consiste en introducir datos, no verificados por éstas, que alteran el comportamiento de la aplicación. El ejemplo más común de este tipo de ataque es el de inyección SQL, que consiste en introducir datos a una aplicación Web para manipular una base de datos.
Es posible aplicar el mismo principio de ataque en aplicaciones de envío de correo electrónico basadas en php. Este tipo de aplicaciones se encuentra en páginas de Internet que proveen al usuario la facilidad de enviar un e-mail al administrador del site o a una persona para recomendarle dicha página. El usuario debe introducir su dirección de correo y el mensaje que desea enviar.
Esta información es capturada muchas veces sin verificar, por un script, y usada para construir el correo y después enviarlo.
Un e-mail esta compuesto por el cuerpo y los encabezados. El RFC 822 describe los campos que pueden definirse dentro de los encabezados. Ejemplo de estos campos es el destinario (“To:”), el tema del correo (“Subject:”), el emisor del correo (“From:”), la copia carbón (“Cc:”) y la copia ciega (“Bcc:”). Dependiendo de cómo esté configurado el cliente del correo electrónico, algunos encabezados permanecen ocultos y otros no. La gente dedicada al cómputo forence utiliza la información almacenada dentro de estos campos para comprobar la autenticidad de un mensaje electrónico.
PHP (PHP Hypertext Pre-processor, definición recursiva como la de GNU) es un lenguaje de programación interpretado que se emplea para el desarrollo de páginas Web dinámicas. Es muy común encontrar la combinación Apache como servidor Web, PHP como lenguaje de desarrollo y MySQL como motor de base de datos. Este lenguaje cuenta con una función para la construcción y envío de e-mails denominada “mail()”, cuya sintaxis es la siguiente: “mail($destinatario,$tema,$mensaje,$encabezados)”.
La función anterior produce un correo electrónico dirigido a “destinatario”, con el subject especificado por el parámetro “tema”, el cuerpo definido en “mensaje” y los“encabezados” pasados en el último parámetro.
El ejemplo “mail(toto@acme.com","Hola","Probando,\nAdios","From:user1@alguien.org\n”)” produce el siguiente correo:
To: toto@acme.com
Subject: Hola
From: user1@alguien.org
Probando,
Adios
Ahora bien, lo interesante se encuentra en el último parámetro de la función, ya que es posible añadir o modificar otros encabezados a través suyo. También es posible utilizar los parámetros destinatario, tema o mensaje, pero es más complicado.
De acuerdo con el RFC 822, los campos del encabezado pasados están separados por un carácter de retorno (LF, con un valor hexadecimal de 0x0A). Tomando en cuenta esto, es posible inyectar encabezados si no se verifica el valor pasado como último parámetro a la función mail( ).
Consideremos la siguiente cadena de caracteres: “From:user1@organiza.org %0ACc:u1@univ.org%0ABcc:u2@univ.org, u3@univ.org”, donde la primera cadena (hasta antes de los caracteres “%0A”) representa el campo que describe al emisor del correo, “%0A” es el valor hexadecimal del carácter de salto de línea, “Cc:” apunta a la dirección de copia del correo y “Bcc”, las direcciones ocultas de otros destinatarios.
Si esta cadena se pasa como último parámetro del ejemplo anterior, el correo generado sería el siguiente:
To: toto@acme.com
Subject: Hola
From: user1@alguien.org
Cc:u1@univ.org
Bcc:u2@univ.org,u3@univ.org
Probando,
Adios
Como se puede ver, el correo no sólo se esta enviando al destinatario original (toto@acme.com), sino también a otros destinatarios (u1, u2 y y3). Esta misma metodología también permite añadir un encabezado “To:” e incluso un cuerpo de mensaje diferente, y enviarlo a los usuarios que uno desee. Para el primer caso, si pasa como último parámetro la cadena de caracteres “user1@alguien.com%0ATo:@tusa@rancho.com”, se producirá lo siguiente:
To: toto@acme.com
Subject: Hola
From: user1@alguien.org
To: tusa@rancho.com
Probando,
Adios
De la misma forma que se pudo repetir un encabezado “To”, también es posible repetir un encabezado “Subject”.
Para definir un cuerpo de mensaje diferente es necesario tomar en cuenta dos factores. En primer lugar, no existe una cadena que identifique al mensaje (como “To:”, “Bcc:” o “From:”). El segundo factor a tomar en cuenta es la forma en que se diferencian los mensajes: un carácter LF sin nombre de encabezado da inicio al cuerpo del mensaje, por lo que en lugar de poner un LF y el nombre del campo, tan sólo se insertará un LF y después se añadirá el mensaje.
Ahora bien, la cadena user1@alguien.com%0A%0AUn%20NUEVO%20MENSAJE! producirá el siguiente correo:
To: toto@acme.com
Subject: Hola
From: user1@alguien.org
To: tusa@rancho.com
NUEVO MENSAJE
Probando,
Adios
Cabe notar que el mensaje inyectado precede al mensaje original. Es posible añadir más encabezados; en especial, el encabezado Content-Type nos permitiría inyectar contenido tipo HTML o MIME. Está técnica es usada para el envío de spam, en cuyo caso el correo se genera en un servidor de correo cualquiera. La persona encargada del envío del spam debe encontrar sitios vulnerables a este tipo de inyección y, mediante un script, inyectar la lista de destinatarios y el mensaje que desea enviar. Si el servidor atacado pertenece a una organización confiable, es muy probable que el detector de spam deje pasar el e-mail pensando que no es un correo basura debido a su procedencia.
Como en todo ataque de inyección, la mejor forma de protegerse es verificando los datos de las entradas. Basta con correr un script o una función que verifique que los datos pasados como parámetro a la función “mail( )” no contienen caracteres como “Cc” o “Bcc”. Tampoco hay que olvidar que es importante que los desarrolladores de aplicaciones, sobre todo las accesibles desde Internet, estén concientes de este tipo de amenazas.
Asimismo, es importante verificar las bitácoras del servidor de correo de la organización para estar seguros de que ningún e-mail no autorizado está saliendo de la empresa. Si en las bitácoras aparecen correos enviados a personas que no tienen ninguna relación con la organización es importante revisar el código de las páginas. |