| Técnicas de Detección Avanzada de interconectividad: Detección de equipos conectados a la red | ||
|---|---|---|
| Anterior | Capítulo 5. Obtención de respuesta del servidor ante una petición válida | Siguiente |
El protocolo ICMP fue originalmente diseñado para indicar errores en los procesos de transmisión de datos como una ayuda a la capa IP.
Debido a la creciente necesidad de seguridad muchos son los que están bloqueando todos los tipos de paquetes ICMP, pero si bien algunos son realmente dañinos (smurf broadcast, pings de tamaño excesivo, demasiadas respuestas simulando destinos inalcanzables, etc) otros son de gran ayuda en la comunicación como por ejemplo las marcas de tiempo (timestamps).
Es el primer método que deberíamos de probar ante la gran mayoría de máquinas no protegidas, se trata de enviar una petición de eco llamada ping (tipo 8) y esperar una respuesta de eco llamada pong (tipo 0)
En concreto el tipo 8 de ICMP tiene la siguiente estructura:
Veamos un simple ping lanzado desde un linux:
delorian:~# ping -c 1 xxx.xxx.xxx.xxx PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 56 data bytes 64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=255 time=0.4 ms --- xxx.xxx.xxx.xxx ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.4/0.4/0.4 ms
Desgraciadamente suele ser el primer tipo de filtro que se pone a la mayoría de las máquinas que deben quedar expuestas al exterior, por lo que es muy poco probable que recibamos respuesta.
Este tipo de peticiones deben ser siempre filtradas en un entorno protegido, pues pueden dar lugar a ataques de tipo smurf y a colapsos.
Puede ser muy útil en redes Unix pues la mayoría de los Unix responden a peticiones contra la dirección de red o la de broadcast, devolviendo al origen un mensaje de vuelta de eco (tipo 0) delatando la presencia de muchas máquinas, junto con la estructuracion de la red en subredes.
Por contra, los Windows NT 4.0 con Service Pack superior o igual a 4, los Windows 2000 y toda la familia de Windows 9x y Millenium no responden por defecto a este tipo de mensajes ICMP.
Veamos un ping lanzado contra una red de tipo C en la que hay 5 máquinas actualmente levantadas, de las cuales dos son linux (.1 y .2), otro es un Solaris (.3) y los dos restantes son Windows 98 (.4 y .5) que no responden ni a una petición a la red ni a la dirección de broadcast:
delorian:~# hping2 -1 xxx.xxx.xxx.0 -c 1 default routing interface selected (according to /proc) HPING xxx.xxx.xxx.0 (eth0 xxx.xxx.xxx.0): icmp mode set, 28 headers + 0 data bytes 28 bytes from xxx.xxx.xxx.1: icmp_seq=0 ttl=255 id=43 rtt=0.2 ms 28 bytes from xxx.xxx.xxx.2: icmp_seq=0 ttl=255 id=310 rtt=0.3 ms 50 bytes from xxx.xxx.xxx.3: icmp_seq=0 ttl=255 id=323 rtt=0.8 ms --- xxx.xxx.xxx.xxx hping statistic --- 1 packets tramitted, 3 packets received, -100% packet loss round-trip min/avg/max = 0.2/0.4/0.8 ms
Similares resultados hubiéramos obtenido si hiciésemos una petición a la dirección xxx.xxx.xxx.255 de broadcast: los dos Windows no responderían, mientras que los Unix sí lo harían.
Cada router periódicamente envía mediante multicast una trama ICMP por cada una de sus interfaces advirtiendo de su presencia a posibles equipos que pudieran estar buscando el router más cercano. Esta norma estándar por otra parte se implementa a nivel de aplicación mediante RIP, ya sea con el antiguo demonio routed o el nuevo gated. Cualquier máquina puede estar ejecutando uno de estos demonios y pudiera dar a conocer sus rutas, pero es obligatorio para los routers, de tal forma que en general las máquinas a las que no se configura un gateway por defecto suelen escuchar dicho tráfico y hacen peticiones, pero no aceptan peticiones de otras máquinas (modo silencioso), mientras que los routers deben configurarse para que si respondan ante este tipo de peticiones. En redes grandes el uso de encaminamiento dinámico puede ser una ventaja, pero en redes pequeñas y fáciles de administrar su uso suele estar desaconsejado por problemas de seguridad.
Hping y hping2 son herramientas excepcionales para la construcción de paquetes, pero por desgracia aún no soportan varios tipos de paquetes ICMP (9,10,12,13,14,15,16,17) por lo que deberemos recurrir a otro tipo de herramientas como sing e icmpush entre otras.
Ésta es la estructura de un paquete ICMP tipo 10 de descubrimiento de router:
0 1 2 3
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 31
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Tipo | Código | Comprobación de CRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reservado |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Veamos una solicitud de router utilizando icmpush:
delorian# icmpush -vv -rts xxx.xxx.xxx.xxx ->
Outgoing interface = xxx.xxx.xxx.xxx -> ICMP total size = 8 bytes ->
Outgoing interface = xxx.xxx.xxx.xxx -> MTU = 1500 bytes -> Total packet
size (ICMP + IP) = 28 bytes ICMP Router Solicitation packet sent to
xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
Receiving ICMP replies ...
-----------------------------------------------------
xxx.xxx.xxx.xxx ...
Type = Router Solicitation (0xA)
Code = 0x0 Checksum = 0xFFF5
Id = 0x0 Seq# = 0x0
-----------------------------------------------------
xxx.xxx.xxx.xxx -> Router Advertisment (xxx.xxx.xxx.xxx)
icmpush: Program finished OK
A menudo un cortafuegos puede estar haciendo el papel de router interno para una DMZ (o «zona desmilitarizada») pero siempre debería tener deshabilitado todo el tráfico de multicast (al igual que el broadcast) de cara al exterior. De no ser esto así un posible atacante, que encuentre entre varias máquinas una que conteste al tipo de solicitud de router (tipo 9), puede dirigir sus esfuerzos hacia este equipo con grandes posibilidades de abrir una brecha en nuestra red.
Las marcas de tiempo (timestamps) se usan a menudo como protección para evitar la falsificación de paquetes TCP alterando su secuencia, pero una forma alternativa de aprovecharse de dicha información es solicitando una marca de tiempo a un servidor mediante una petición ICMP de tipo 13 a la que el servidor responderá con su hora actual. No sólo nos revelará que el equipo está activo sino que además en función de su zona horaria podremos deducir su situación geográfica.
Por desgracia es común entre los Windows no responder a este tipo de peticiones, mientras que la mayor parte de las variantes Unix responden correctamente. Esto puede utilizarse para reconocer los sistemas operativos implicados, aparte de ser muy útil para la detección de servidores *NIX.
Aquí se muestra la estructura típica de un mensaje ICMP tipo 13 de petición de tiempo:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Tipo | Código | Comprobación de CRC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identificador | Número de secuencia | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Marca de tiempo del remitente | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Marca de tiempo del receptor | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Marca de tiempo de la transmisión | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Veamos una petición a un linux con kernel 2.2.16:
delorian:~# icmpush -vv -tstamp xxx.xxx.xxx.xxx
-> Outgoing interface = xxx.xxx.xxx.xxx
-> ICMP total size = 20 bytes
-> Outgoing interface = xxx.xxx.xxx.xxx
-> MTU = 1500 bytes
-> Total packet size (ICMP + IP) = 40 bytes
ICMP Timestamp Request packet sent to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
Receiving ICMP replies ...
-----------------------------------------------------
xxx.xxx.xxx.xxx ...
Type = Timestamp Request (0xD)
Code = 0x0 Checksum = 0x83D0
Id = 0x7B6 Seq# = 0xC2BB
-----------------------------------------------------
xxx.xxx.xxx.xxx -> Timestamp Reply transmited at 16:52:10
icmpush: Program finished OK
Se trata de un tipo de peticiones obsoletas en la actualidad que proporcionan a un cliente la dirección de red del equipo que responde.
A pesar de ser bastante obsoleto muchos de los Unix siguen respondiendo a este tipo de peticiones mientras que los Windows no lo hacen.
La simpleza de este tipo de paquetes queda reflejada en su estructura:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Tipo | Código | Comprobación de CRC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identificador | Número de secuencia | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Veamos una petición un Solaris 2.6:
delorian:~# icmpush -v -info xxx.xxx.xxx.xxx ICMP Info Request packet sent to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) Receiving ICMP replies ... xxx.xxx.xxx.xxx ->Info Reply (xxx.xxx.xxx.xxx) icmpush: Program finished OK
Este tipo de solicitudes se hacen para obtener la dirección de la máscara de subred en una red local. Si la petición tiene éxito, se deberá devolver una respuesta ICMP de tipo 18 con dicha información.
A diferencia de lo que ocurría con la petición de descubrimiento de IP's de tipo 15, los Linux no responden por defecto a este tipo de peticiones, mientras que los Windows por defecto sí lo hacen. Esto puede ser muy útil a la hora de detectar la presencia de Windows aparte de para obtener valiosísima información de cómo está estructurada la red internamente. No sólo Windows responde a este tipo de peticiones sino que algunos tipos de Unix poco seguros por defecto también responden, como es el caso de las diversas versiones de SunOS y Solaris.
Aquí podemos ver la estructura de un datagrama de petición de máscara:
0 1 2 3 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 31 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Tipo | Código | Comprobación de CRC | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identificador | Número de secuencia | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Dirección de la máscara de subred | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Aquí vemos una petición ICMP de máscara a un Windows 98 contestada con un ICMP tipo 18 indicando una máscara de tipo C:
delorian:~# icmpush -v -mask xxx.xxx.xxx.xxx ICMP Address Mask Request packet sent to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) Receiving ICMP replies ... xxx.xxx.xxx.xxx -> Address Mask Reply (255.255.255.0) icmpush: Program finished OK
A pesar de que los diversos métodos de obtener información mediante ICMP en general pueden ser bastante satisfactorios, debemos tener en cuenta que no siempre nos valen para el propósito de la detección de máquinas remotas en tanto en cuanto las propias RFCs nos aseguran que no siempre debe generarse un paquete ICMP.
La RFC 1122 asegura que al menos hay tres posibles casos tipificados en los que un mensaje de error ICMP no debe enviarse:
No se debe enviar un error ICMP de respuesta ante la recepción de otro mensaje ICMP de error.
Esto evita bucles de mensajes ICMP's.
No se debe enviar respuesta ICMP ante la recepción de un datagrama destinado a una dirección de broadcast o multicast, ni siquiera un broadcast a nivel de enlace (arp's de bootp por ejemplo)
Esto determina que por ejemplo los paquetes UDP de videoconferencia no deberán generar tráfico ICMP de error, pues es preferible perder cierta información a saturar la línea.
No deberá de enviarse ninguna respuesta ICMP ante la llegada de un fragmento no inicial o un datagrama cuya dirección de origen no defina a una única máquina.
Por ejemplo, un datagrama con dirección origen la IP de una red, de broadcast, multicast, una dirección de loopback o una dirección de clase E.
Estos tres tipos de mensajes podrían resumirse con las siguiente frase: "Nunca deberá enviarse una respuesta ICMP ante la llegada de otro paquete ICMP, ni en ningún otro caso en el que o bien el destino o bien el origen no correspondan con una IP que identifique unívocamente a una máquina"