Correo electrónico
Desde hace muchos años los sistemas de correo electrónico de una organización han sido para los piratas una fuente inagotable de puntos de entrada a la misma; lo más probable es que si le preguntamos a cualquier administrador de máquinas Unix con algo de experiencia cuál ha sido el software que más problemas de seguridad le ha causado nos responda sin dudarlo: sendmail, por supuesto. Y ya no sólo sendmail y el protocolo SMTP, sino que también, con la popularización de POP3, los servidores de este protocolo son un peligro potencial a tener en cuenta en cualquier entorno informático donde se utilice el correo electrónico: es decir, en todos.
De entrada, un programa como sendmail - lo ponemos como ejemplo por ser el más popular, pero podríamos hablar en los mismos términos de casi cualquier servidor SMTP - proporciona demasiada información a un atacante que simplemente conecte a él:
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 luisa ESMTP Sendmail 8.9.3/8.9.3; Mon, 29 Oct 2001 03:58:56 +0200
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Y no sólo se proporcionan datos útiles para un pirata como la versión del programa utilizada o la fecha del sistema, sino que se llega incluso más lejos: tal y como se instalan por defecto, muchos servidores SMTP (aparte de sendmail, algunos tan populares como Netscape Messaging Server) informan incluso de la existencia o inexistencia de nombres de usuario y de datos sobre los mismos:
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 luisa ESMTP Sendmail 8.9.3/8.9.3; Mon, 29 Oct 2001 04:03:22 +0200
vrfy root
250 El Spiritu Santo <root@luisa>
expn root
250 El Spiritu Santo <root@luisa>
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Parece evidente que de entrada estamos dándole a cualquier pirata demasiada información sobre nuestro entorno de trabajo; una de las primeras cosas que deberíamos hacer en todos nuestros servidores de correo es deshabilitar este tipo de opciones. En concreto, para deshabilitar las órdenes vrfy y expn, en sendmail.cf debemos modificar la línea
O PrivacyOptions=authwarnings
para que no se proporcione información, de la forma siguiente:
O PrivacyOptions=goaway
Para conseguir que que sendmail además tampoco informe de su versión y la fecha del sistema - algo recomendable, evidentemente - la entrada a modificar es SmtpGreetingMessage. Si lo hacemos, y además hemos deshabilitado las PrivacyOptions, cuando alguien conecte a nuestro servidor verá algo similar a:
luisa:/# egrep "Privacy|Greeting" /etc/sendmail.cf
O PrivacyOptions=goaway
O SmtpGreetingMessage=Servidor
luisa:/# telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 Servidor ESMTP
vrfy root
252 Cannot VRFY user; try RCPT to attempt delivery (or try finger)
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:/#
En realidad, si un atacante quiere conocer la versión del servidor que estamos utilizando aún no lo tiene difícil, ya que simplemente ha de teclear una orden como `help':
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 Servidor ESMTP
help
214-This is Sendmail version 8.9.3
214-Topics:
214- HELO EHLO MAIL RCPT DATA
214- RSET NOOP QUIT HELP VRFY
214- EXPN VERB ETRN DSN
214-For more info use "HELP <topic>".
214-To report bugs in the implementation send email to
214- sendmail-bugs@sendmail.org.
214-For local information send email to Postmaster at your site.
214 End of HELP info
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Para evitar esto debemos modificar convenientemente el fichero sendmail.hf (en función del Unix utilizado su ubicación en la estructura de directorios cambiará) de forma que se restrinjan más los mensajes que proporciona el demonio en una sesión interactiva; para obtener información sobre este fichero, así como del resto de configuraciones de sendmail podemos consultar [CA97a]. Debemos tener presente que conocer ciertos datos que el programa proporciona puede facilitarle mucho la tarea a un pirata; ocultar esta información no es ni mucho menos una garantía de seguridad, ni por supuesto ha de suponer uno de los pilares de nuestra política, pero si con un par de pequeñas modificaciones conseguimos quitarnos de encima aunque sólo sea a un atacante casual, bienvenidas sean - aunque muchos consideren esto una apología del security through obscurity -.
Independientemente del programa que utilicemos como servidor de correo y su versión concreta, con vulnerabilidades conocidas o no, otro gran problema de los sistemas de correo SMTP es el relay: la posibilidad de que un atacante interno utilice nuestros servidores para enviar correo electrónico a terceros, no relacionados con nuestra organización. Aunque en principio esto a muchos les pueda parecer un mal menor, no lo es; de entrada, si nuestros servidores permiten el relay estamos favoreciendo el SPAM en la red, el envío de e-mail no deseado con fines casi siempre publicitarios, algo que evidentemente a nadie le hace gracia recibir. Además, el relay causa una negación de servicio contra nuestros usuarios legítimos, tanto desde un punto de vista estrictamente teórico - alguien consume nuestros recursos de forma no autorizada, degradando así el servicio ofrecido a nuestros usuarios legítimos - como en la práctica: cuando un robot encuentra un servidor SMTP en el que se permite el relay lo utiliza masivamente mientras puede, cargando enormemente la máquina y entorpeciendo el funcionamiento normal de nuestros sistemas. Por si esto fuera poco, si se incluye a nuestra organización en alguna `lista negra' de servidores que facilitan el SPAM se causa un importante daño a nuestra imagen, e incluso ciertos dominios pueden llegar a negar todo el correo proveniente de nuestros servidores.
Sólo existe una manera de evitar el relay: configurando correctamente todos nuestros servidores de correo. Por supuesto, esto es completamente dependiente de los programas (sendmail, iPlanet...) utilizados en nuestro entorno, por lo que es necesario consultar en la documentación correspondiente la forma de habilitar filtros que eviten el relay; por Internet exiten incluso filtros genéricos para los servidores más extendidos, por lo que nuestro trabajo no será excesivo ni complicado. Si queremos verificar que nuestros servidores no permiten el relay podemos ejecutar, desde una dirección externa a nuestra organización, el siguiente programa:
luisa:~$ cat security/prog/testrelay.sh
#!/bin/sh
# Este script comprueba que un servidor de correo no permite el relay.
# Basado en los test disponibles en
# http://133.30.50.200/~takawata/d/resource/relaytest.html
# Necesitamos netcat (nc) instalado en el sistema.
# Toni Villalon <toni@aiind.upv.es>, 03 Enero 2000
# NOTA: Es necesario personalizar la variable DSTADDR
#
# Argumentos erroneos?
if (test $# -lt 1); then
echo "Uso: $0 mail.dominio.com"
exit
fi
# Especificamos una direccion origen (no es necesario que sea real)
SRCADDR=prova@prova.com
SRCUSR=`echo $SRCADDR|awk -F@ '{print $1}'`
SRCDOM=`echo $SRCADDR|awk -F@ '{print $2}'`
# Direccion destino, para comprobar si realmente llega el mail
# SUSTITUIR POR UNA QUE PODAMOS COMPROBAR!!!
DSTADDR=toni@aiind.upv.es
DSTUSR=`echo $DSTADDR|awk -F@ '{print $1}'`
DSTDOM=`echo $DSTADDR|awk -F@ '{print $2}'`
# Direccion IP del host a testear
TESTIP=`host $1|grep address|tail -1|awk '{print $4}'`
if [ $? -ne 0 ]; then
TESTIP=`/usr/bin/nslookup $1|grep ^Address|awk -F: 'NR2 {print $2}'`
fi
# Ejecutable NetCat
NC=/usr/local/bin/nc
# Conectamos al servidor y lanzamos los test
# No ponemos todo en un 'cat <<EOF' porque si se generan errores, el servidor
# de correo nos tirara y quedaran test sin realizarse
#
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCADDR>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 1
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 2
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: < >
RCPT TO: <$DSTADDR>
DATA
Relay test no. 3
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 4
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@[$TESTIP]>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 5
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTUSR%$DSTDOM@$1>
DATA
Relay test no. 6
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTUSR%$DSTDOM@[$TESTIP]>
DATA
Relay test no. 7
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTADDR">
DATA
Relay test no. 8
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTUSR%$DSTDOM">
DATA
Relay test no. 9
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR@$1>
DATA
Relay test no. 10
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTADDR"@$1>
DATA
Relay test no. 11
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR@[$TESTIP]>
DATA
Relay test no. 12
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <@$1:$DSTADDR>
DATA
Relay test no. 13
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <@[$TESTIP]:$DSTADDR>
DATA
Relay test no. 14
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR>
DATA
Relay test no. 15
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR@$1>
DATA
Relay test no. 16
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR@[$TESTIP]>
DATA
Relay test no. 17
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCADDR>
RCPT TO: <$1!$DSTADDR>
DATA
Relay test no. 18
.
QUIT
EOF
luisa:~$
Es muy importante para nosotros cuidar cualquier aspecto de la seguridad relativo a nuestros sistemas de correo, ya que en la actualidad el correo electrónico constituye uno de los servicios básicos de cualquier empresa; simplemente hemos de contar el número de e-mails que solemos recibir al día para hacernos una idea del desastre que supondría un fallo en los sistemas encargados de procesarlo.
Ataques vía web
Durante los últimos años los servidores web se han convertido en una excelente fuente de diversión para piratas: cualquier empresa que se precie, desde las más pequeñas a las grandes multinacionales, tiene una página web en las que al menos trata de vender su imagen corporativa. Si hace unos años un pirata que quisiera atacar a una empresa (y no a todas, ya que muy pocas tenían representación en la red) tenía que agenciarselas para obtener primero información de la misma y después buscar errores de configuración más o menos comunes de sus sistemas (o esperar al próximo bug de sendmail), hoy en día le basta con teclear el nombre de su objetivo en un navegador y añadir la coletilla `.com' detrás del mismo para contactar con al menos una de sus máquinas: su servidor web.
Los ataques a las páginas web de una organización son casi siempre los más `vistosos' que la misma puede sufrir: en cuestión de minutos piratas de todo el mundo se enteran de cualquier problema en la página web principal de una empresa más o menos grande pueda estar sufriendo, y si se trata de una modificación de la misma incluso existen recopilatorios de páginas `hackeadas'. Por supuesto, la noticia de la modificación salta inmediatamente a los medios, que gracias a ella pueden rellenar alguna cabecera sensacionalista sobre `los piratas de la red', y así se consigue que la imagen de la empresa atacada caiga notablemente y la del grupo de piratas suba entre la comunidad 'underground' nacional o internacional.
La mayor parte de estos ataques tiene éxito gracias a una configuración incorrecta del servidor o a errores de diseño del mismo: si se trata de grandes empresas, los servidores web suelen ser bastante complejos (alta disponiblidad, balanceo de carga, sistemas propietarios de actualización de contenidos...) y difíciles de administrar correctamente, mientras que si la empresa es pequeña es muy posible que haya elegido un servidor web simple en su instalación y administración pero en el cual es casi (>casi?) imposible garantizar una mínima seguridad: sí, hablamos de Microsoft Internet Information Server, un sistema que reconocidos expertos en seguridad han recomendado públicamente no utilizar en entornos serios. Sea por el motivo que sea, la cuestión es que cada día es más sencillo para un pirata ejecutar órdenes de forma remota en una máquina, o al menos modificar contenidos de forma no autorizada, gracias a los servidores web que un sistema pueda albergar.
Cualquier analizador de vulnerabilidades que podamos ejecutar contra nuestros sistemas (NESSUS, ISS Security Scanner, NAI CyberCop Scanner...) es capaz de revelar información que nos va a resultar útil a la hora de reforzar la seguridad de nuestros servidores web; incluso existen analizadores que están diseñados para auditar únicamente este servicio, como whisker. Ejecutando este último contra una máquina podemos obtener resultados similares a los siguientes:
anita:~/security/whisker$ ./whisker.pl -h luisa
-- whisker / v1.4.0 / rain forest puppy / www.wiretrip.net --
= - = - = - = - = - =
= Host: luisa
= Server: Apache/1.3.19 (Unix) PHP/4.0.4pl1 mod_ssl/2.8.2 OpenSSL/0.9.5a
+ 200 OK: HEAD /docs/
+ 200 OK: HEAD /cgi-bin/Count.cgi
+ 200 OK: HEAD /cgi-bin/textcounter.pl
+ 200 OK: HEAD /ftp/
+ 200 OK: HEAD /guestbook/
+ 200 OK: HEAD /usage/
anita:~/security/whisker$
Podemos ver que el servidor nos proporciona excesiva información sobre su configuración (versión, módulos, soporte SSL...), y que la herramienta ha obtenido algunos archivos y directorios que pueden resultar interesantes para un atacante: en el caso de los CGI no tiene más que acercarse a alguna base de datos de vulnerabilidades (especialmente recomendables son
http://www.securityfocus.com/## o http://icat.nist.gov/##) e introducir en el buscador correspondiente el nombre del archivo para obtener información sobre los posibles problemas de seguridad que pueda presentar. El caso de los directorios es algo diferente, pero típicamente se suele tratar de nombres habituales en los servidores que contienen información que también puede resultarle útil a un potencial atacante.
>Cómo evitar estos problemas de seguridad de los que estamos hablando? Una medida elemental es eliminar del servidor cualquier directorio o CGI de ejemplo que se instale por defecto; aunque generalmente los directorios (documentación, ejemplos...) no son especialmente críticos, el caso de los CGIs es bastante alarmante: muchos servidores incorporan programas que no son ni siquiera necesarios para el correcto funcionamiento del software, y que en ciertos casos - demasiados - abren enormes agujeros de seguridad, como el acceso al código fuente de algunos archivos, la lectura de ficheros fuera del DocumentRoot, o incluso la ejecución remota de comandos bajo la identidad del usuario con que se ejecuta el demonio servidor.
Otra medida de seguridad básica es deshabilitar el Directory Indexing que por defecto muchos servidores incorporan: la capacidad de obtener el listado de un directorio cuando no existe un fichero index.html o similar en el mismo; se trata de una medida extremadamente útil y sobre todo sencilla de implantar, ya que en muchos casos un simple `chmod -r' sobre el directorio en cuestión es suficiente para evitar este problema. A primera vista esta medida de protección nos puede resultar curiosa: a fin de cuentas, a priori todo lo que haya bajo el Document Root del servidor ha de ser público, ya que para eso se ubica ahí. Evidentemente la teoría es una cosa y la práctica otra muy diferente: entre los ficheros de cualquier servidor no es extraño encontrar desde archivos de log - por ejemplo, del cliente FTP que los usuarios suelen usar para actualizar remotamente sus páginas, como WS/SMALL>_FTP.LOG - hasta paquetes TAR con el contenido de subdirectorios completos. Por supuesto, la mejor defensa contra estos ataques es evitar de alguna forma la presencia de estos archivos bajo el Document Root, pero en cualquier caso esto no es siempre posible, y si un atacante sabe de su existencia puede descargarlos, obteniendo en muchos casos información realmente útil para atacar al servidor (como el código de ficheros JSP, PHP, ASP...o simplemente rutas absolutas en la máquina), y una excelente forma de saber que uno de estos ficheros está ahí es justamente el Directory Indexing; por si esto no queda del todo claro, no tenemos más que ir a un buscador cualquiera y buscar la cadena `Index of /admin', por poner un ejemplo sencillo, para hacernos una idea de la peligrosidad de este error de configuración.
Además, en cualquier servidor web es muy importante el usuario bajo cuya identidad se ejecuta el demonio httpd: ese usuario no debe ser nunca el root del sistema (evidente), pero tampoco un usuario genérico como nobody; se ha de tratar siempre de un usuario dedicado y sin acceso real al sistema. Por supuesto, las páginas HTML (los ficheros planos, para entendernos) nunca deben ser de su propiedad, y mucho menos ese usuario ha de tener permiso de escritura sobre los mismos: con un acceso de lectura (y ejecución, en caso de CGIs) es más que suficiente en la mayoría de los casos. Hemos de tener en cuenta que si el usuario que ejecuta el servidor puede escribir en las páginas web, y un pirata consigue - a través de cualquier tipo de error (configuración, diseño del demonio...) - ejecutar órdenes bajo la identidad de dicho usuario, podrá modificar las páginas web sin ningún problema (que no olvidemos, es lo que perseguirá la mayoría de atacantes de nuestro servidor web).
Igual de importante que evitar estos problemas es detectar cuando alguien trata de aprovecharlos intentando romper la seguridad de nuestros servidores; para conseguirlo no tenemos más que aplicar las técnicas de detección de intrusos que veremos en el capítulo siguiente. Una característica importante de los patrones de detección de ataques vía web es que no suelen generar muchos falsos positivos, por lo que la configuración de la base de datos inicial es rápida y sencilla, al menos en comparación con la detección de escaneos de puertos o la de tramas con alguna característica especial en su cabecera.