La técnica más fundamental durante la enumeración de servicios es la captura de banderas o banner grabbing. Ésta técnica consiste en establecer conexiones con servicios remotos, y analizar la respuesta que éstos servicios nos regresan. Aunque no lo parezca, la respuesta puede ser sumamente informativa.
Por ejemplo, si abres la terminal de comandos y escribes:
$ curl -I http://alanchavez.com
Mi servidor te responderá con el siguiente mensaje:
HTTP/1.1 200 OK Date: Thu, 22 Jan 2015 04:47:28 GMT Server: Apache X-Pingback: http://alanchavez.com/xmlrpc.php X-Powered-By: W3 Total Cache/0.9.4.1 Cache-Control: max-age=3600 Expires: Thu, 22 Jan 2015 05:47:28 GMT Vary: Accept-Encoding,Cookie,User-Agent Content-Type: text/html; charset=UTF-8
Como puedes observar, los headers te muestran el tipo de servidor web que utiliza mi página web (Apache), e incluso regresa un encabezado opcional "X-Powered-By" junto con el programa y su versión que mi servidor utiliza para el caché de archivos.
Si pones otros sitios en la terminal, observarás que la respuesta del servidor cambia dependiendo de las tecnologías que se utilicen para servir el servicio que intentas enumerar. Por ejemplo:
$ curl -I domain.tld HTTP/1.1 200 OK Server: nginx Date: Thu, 22 Jan 2015 04:54:31 GMT Content-Type: text/html Connection: keep-alive X-Powered-By: PHP/5.4.34 Set-Cookie: bb_sessionhash=577b3f36586e0bf13917dc5aad5be133; path=/; HttpOnly Set-Cookie: bb_lastvisit=1421902471; expires=Fri, 22-Jan-2016 04:54:31 GMT; path=/ Set-Cookie: bb_lastactivity=0; expires=Fri, 22-Jan-2016 04:54:31 GMT; path=/ Vary: Accept-Encoding
En el caso anterior, puedes ver la versión de PHP que el servicio utiliza para generar la página.
Otra excelente herramienta para empezar a capturar banderas es telnet. Telnet es una reliquia de tiempos inmemoriales, es una herramienta de comunicación remota entre computadoras, y en la gran mayoría de los sistemas operativos ya viene instalada de fábrica (a excepción de Windows, por supuesto, a menos de que utilices Windows Server).
Por ejemplo, usando telnet puedes obtener la misma información de mi servidor usando el siguiente comando:
$ telnet alanchavez.com 443 Trying 69.89.25.141... Connected to alanchavez.com. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https:///">here</a>.</p> <hr> <address>Apache Server at alanchavez.com Port 80</address> </body></html>
El primer argumento de telnet es el hostname, y el segundo argumento es el puerto. Telnet es una excelente herramienta para capturar banderas de servicios comunes como HTTP (puerto 80), FTP (puerto 21) o SMTP (puerto 25)
Sin embargo, para capturar banderas de servicios personalizados y/o ocultos, la herramienta por excelencia para ésta tarea es netcat.
Netcat, en el mundo de la seguridad informática, se conoce como "la navaja suiza" de los expertos en seguridad. Cuando ésta herramienta es utilizada por expertos, netcat se convierte en una arma de "destrucción masiva", y creéme, no estoy exagerando.
Por ejemplo, si ingresas la siguiente instrucción en tu terminal:
$ nc -v alanchavez.com 443
Mi servidor te responderá con lo siguiente:
found 0 associations found 1 connections: 1: flags=82<CONNECTED,PREFERRED> outif en1 src 192.168.1.134 port 49300 dst 69.89.25.141 port 443 rank info not available TCP aux info available Connection to alanchavez.com port 443 [tcp/https] succeeded!
En ese punto, mi servidor se encuentra esperando por más instrucciones de tu parte. Si posteriormente ingresas:
GET / HTTP/1.1
Seguido de un <Enter> mi servidor responderá con el siguiente mensaje:
HTTP/1.1 301 Moved Permanently Date: Thu, 22 Jan 2015 05:14:32 GMT Server: Apache Location: https:///400.shtml Cache-Control: max-age=3600 Expires: Thu, 22 Jan 2015 06:14:32 GMT Vary: Accept-Encoding Content-Length: 291 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https:///400.shtml">here</a>.</p> <hr> <address>Apache Server at alanchavez.com Port 443</address> </body></html>
Con ésta técnica tan sencilla, un atacante puede obtener información acerca de los servicios que se encuentran corriendo en tu servidor, y un administrador de sistemas que no es cauteloso, puede revelar información valiosa como las versiones y el nombre del servicio operando en un puerto.
Conociendo esas 2 piezas de información, un atacante puede enfocarse solamente en encontrar vulnerabilidades para ése servicio y esa versión específicamente, para poder comprometer un servidor.
Medidas Preventivas
Es importante que tus servidores no revelen mas información de la necesaria. Por ejemplo cuando instalas Apache, abre el archivo httpd.conf generalmente localizado en /etc/httpd/conf/httpd.conf
Y busca la directiva ServerSignature, si esta directiva se encuentra encendida (On), cambia su valor por Off:
ServerSignature Off
Posteriormente, busca la directiva ServerTokens, y si el valor de ésta directiva es OS, cámbialo por el de Prod:
ServerTokens Prod
Si utilizas PHP, abre el archivo php.ini generalmente localizado en /etc/php.ini y busca la directiva expose_php y asegúrate que su valor sea el de Off:
expose_php = Off
Reinicia Apache para que los cambios tomen efecto, y asegúrate de que tu servidor no filtre información innecesariamente.
Notas adicionales
Si quieres aprender más acerca de seguridad, estoy iniciando un curso de seguridad informática, si te suscribes a mi lista de correo o me dejas un comentario en ésta entrada, te mantendré actualizado acerca del lanzamiento del mismo.