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.