Source: http://alfonsocruz.blogspot.com/2008/08/ataque-dns-id-hacking.html
Timestamp: 2018-06-19 21:50:07+00:00

Document:
Ing. Cruz: Ataque DNS ID Hacking
Ataque DNS ID Hacking
Ataque DNS ID Hacking.
Explicación del Mecanismo del Protocolo del DNS.
En primer lugar, debemos saber cómo trabaja el DNS. Se explicarán sólamente los hechos más importantes de este protocolo. Para hacer eso, seguiremos la manera de un paquete de petición de DNS de la A a la Z.
El cliente (cliente.prueba.com) envía una petición de resolución del dominio "www.pagina.com". Para resolver el nombre, cliente.prueba.com utiliza "dns.prueba.com" para el DNS. Obsérvese el cuadro siguiente.
| 111.1.2.123 = cliente.prueba.com |
| 111.1.2.222 = dns.prueba.com |
| IP_ADDR:PORT->IP_ADDR:PORT |
| ex: |
| 111.1.2.123:2999->111.1.2.222:53 |
gethosbyname("www.pagina.com");
[cliente.prueba.com] [dns.prueba.com]
111.1.2.123:1999 --->[?www.pagina.com]------> 111.1.2.222:53
Aquí vemos nuestra petición de resolución del nombre del puerto fuente 1999 que está preguntando al DNS en el puerto 53. (Nota: El DNS siempre está en el puerto 53.)
Ahora que dns.prueba.com ha recibido la petición de la resolución de cliente.prueba.com, dns.prueba.com tendrá que resolver el nombre, como sigue.
[dns.prueba.com] [ns.internic.net]
111.1.2.222:53-------->[dns?www.pagina.com]----> 198.41.0.4:53
dns.prueba.com pregunta a ns.internic.net quién es el servidor de nombres raíz para la dirección de www.pagina.com, y si no la tiene, envía la petición a un servidor de nombres que tenga autoridad en dominios '.com'.(Nota: Preguntamos a internic porque podría tener esta petición en su caché.)
[ns.internic.net] [ns.prueba.com]
198.41.0.4:53 ------>[ns otro.com es 144.44.44.4]------> 111.1.2.222:53
Aquí podemos ver que ns.internic.net contestó a ns.prueba.com (que es el DNS que tiene autoridad sobre el dominio prueba.com), que el servidor de nombres de otro.com tiene la IP 144.44.44.4 (vamos a llamarlo ns.otro.com). Ahora nuestro ns.prueba.com pedirá a ns.otro.com la dirección de www.pagina.com, pero éste no la tiene y transmitirá la petición al DNS de pagina.com el cuál tiene autoridad para pagina.com.
[ns.prueba.com] [ns.otro.com]
111.1.2.222:53 ------>[?www.pagina.com]-----> 144.44.44.4:53
Respuesta de ns.otro.com:
[ns.otro.com] [ns.prueba.com]
144.44.44.4:53 ------>[ns para pagina.com is 31.33.7.4]---> 144.44.44.4:53
Ahora que conocemos qué dirección IP tiene autoridad en el dominio "pagina.com" (lo llamaremos ns.pagina.com), le preguntamos cuál es la IP de la máquina www (www.pagina.com).
[ns.prueba.com] [ns.pagina.com]
111.1.2.222:53 ----->[?www.pagina.com]----> 31.33.7.4:53
Y ahora tenemos por lo menos nuestra respuesta.
[ns.pagina.com] [ns.prueba.com]
31.33.7.4:53 ------->[www.pagina.com == 31.33.7.44] ----> 111.1.2.222:53
Teniendo la respuesta, podemos remitirla a nuestro cliente cliente.prueba.com.
[ns.prueba.com] [cliente.prueba.com]
111.1.2.222:53 ------->[www.pagina.com == 31.33.7.44]----> 111.1.2.123:1999
Ahora cliente.prueba.com sabe la IP de www.pagina.com.
Ahora vamos a imaginarnos que quisiéramos tener el nombre de una máquina a partir de su IP, para hacer esto, la manera de proceder será una poco diferente porque la IP tendrá que ser transformada:
Ejemplo: 100.20.40.3 se convertirán en 3.40.20.100.in-addr.arpa
Este método es sólamente para la petición de la resolución de IP (DNS reverso). Así que vamos a observar en la práctica cuando tomamos la IP de www.pagina.com (31.33.7.44 o "44.7.33.31.in-addr.arpa" después de la traducción en un formato comprensible por DNS).
gethostbyaddr("31.33.7.44");
[cliente.prueba.com] [ns.prueba.com]
111.1.2.123:2600 ----->[?44.7.33.31.in-addr.arpa]-----> 111.1.2.222:53
Enviamos nuestra petición a ns.prueba.com
[ns.prueba.com] [ns.internic.net]
111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 198.41.0.4:53
ns.internic.net enviará la IP de un servidor de nombres que tenga autoridad en '31.in-addr.arpa'.
198.41.0.4:53 --> [DNS para 31.in-addr.arpa es 144.44.44.4] -> 111.1.2.222:53
Ahora ns.prueba.com hará la misma pregunta al DNS en 144.44.44.4.
111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 144.44.44.4:53
En efecto, el mecanismo es casi igual que el usado para la resolución de nombre. Ahora vamos a estudiar el formato de los mensajes del DNS.
\ PREGUNTA \
\ RESPUESTA \
\ Etc... NO IMPORTA \
Estructura de los paquetes DNS.
ID: El ID permite identificar cada paquete DNS, puesto que los intercambios entre los servidores de nombres son desde el puerto 53 a el puerto 53, y además, puede ser que sea más de una petición a la vez, así que el ID es la única manera de reconocer las diversas peticiones del DNS. Banderas: El área de las banderas se divide en varias partes:
4 bits 3 bits (siempre 0)
[QR | opcode | AA| TC| RD| RA | zero | rcode ]
| |_ |_ |_ _| |______ 4 bits
| |_ 1 bit
QR: Si el bit QR = 0, significa que el paquete es una pregunta, si no es una respuesta. opcode: Si el valor es 0 para una petición normal, 1 para una petición de reserva, y 2 para una petición de estado. AA: Si es igual a 1, dice que el servidor de nombres tiene una respuesta autoritaria. TC: No importa. RD: Si esta bandera está a 1, significa "petición recursiva", por ejemplo cuando cliente.prueba.com pregunta a ns.prueba.com para resolver el nombre, la bandera dice al DNS asumir esta petición. RA: Si se fija a 1, significa que la recursión está disponible. Este bit se coloca a 1 en la respuesta del servidor de nombres si soporta la recursión. Zero: Aquí son tres ceros... rcode: Contiene los mensajes de error de regreso para las peticiones DNS, si es 0 significa "no error", 3 significa ``error de nombre".
Las 2 banderas siguientes no tienen ninguna importancia para nosotros.
PREGUNTA DNS:
Abajo se muestra el formato de una pregunta DNS:
| Nombre de la pregunta |
| Tipo de pregunta | Tipo de consulta |
La estructura de la pregunta es como sigue:
www.pagina.com será [3|w|w|w|5|p|a|g|i|n|a|3|c|o|m|0] para una dirección IP es lo mismo.
44.33.88.123.in-addr.arpa sería: [2|4|4|2|3|3|2|8|8|3|1|2|3|7|i|n|-|a|d|d|r|4|a|r|p|a|0]
Nota: Existe un formato de compresión, pero no lo utilizaremos.
Tipo de pregunta: Abajo se muestran los valores que se utilizan la mayoría de las veces:
Nota: Hay más de 20 tipos de diverso valores.
A | 1 | IP Address (resolviendo un nombre a una IP)
PTR | 12 | Pointer (resolviendo una IP a un nombre)
Tipo de consulta: Los valores son iguales que el tipo de pregunta.
RESPUESTA DNS:
Las respuestas tienen un formato que llamamos RR.
Abajo se muestra el formato de una respuesta (un RR)
| Nombre de Dominio |
| Tipo | Clase |
| TTL (Tiempo de Vida) |
| Longitud de Datos del Recurso | |
|-------------------------------------------+ |
| Dato del Recurso |
Nombre del Dominio: El nombre del dominio en reportes para el siguiente recurso. El nombre del dominio se almacena de la misma manera que la parte de la pregunta para la petición de la resolución de www.pagina.com, la bandera ``Nombre del Dominio`` contendrá:
[3|w|w|w|5|p|a|g|i|n|a|3|c|o|m|0]
Tipo: El tipo de bandera es igual que el ``tipo de consulta'' en la parte de la pregunta del paquete.
Clase: La bandera Clase es igual a 1 para los datos de Internet. Tiempo de Vida: Esta bandera explica en segundos el tiempo-vida de la información en la caché del servidor de nombres. Longitud de datos del Recurso: La longitud de los datos del Recurso, por ejemplo si la longitud de los datos del recurso es 4, significa que los datos en los Datos del Recurso es de longitud 4 bytes. Datos del Recurso: Aquí ponemos la IP por ejemplo (por lo menos en nuestro caso).
Aquí es cuando ns.prueba.com pide a ns.pagina.com la dirección de www.pagina.com
ns.prueba.com:53 ---> [?www.pagina.com] ----> ns.pagina.com:53
| ID = 1999 | QR = 0 opcode = 0 RD = 1 |
| Número de Preguntas = htons(1) | Número de Respuestas = 0 |
| Número de RR autoritativo = 0 | Número de RR suplementario = 0 |
La parte de la pregunta.
| Nombre de la Pregunta = [3|w|w|w|5|p|a|g|i|n|a|3|c|o|m|0] |
| Tipo de Pregunta = htons(1) | Tipo de consulta=htons(1) |
Ahora vamos a observar fijamente la respuesta de ns.pagina.com
ns.pagina.com:53 -->[IP of www.pagina.com is 31.33.7.44] -->ns.prueba.com:53
| ID = 1999 | QR=1 opcode=0 RD=1 AA =1 RA=1 |
| Número de Preguntas = htons(1) | Número de Respuestas = htons(1) |
| Tipo de Pregunta = htons(1) | Tipo de Consulta = htons(1) |
| Nombre del Dominio = [3|w|w|w|5|p|a|g|i|n|a|3|c|o|m|0] |
| Tipo = htons(1) | Clase = htons(1) |
| Tiempo de Vida = 999999 |
| Longitud de Datos del Recurso = htons(4) | Datos del Recurso=inet_addr("31.33.7.44") |
Enseguida se muestra el análisis de las banderas:
En la respuesta QR = 1 porque es una respuesta. AA = 1 porque el servidor de nombres tiene autoridad en su dominio. RA = 1 porque la recursión está disponible.
ns.prueba.com;53 ----->[?www.pagina.com] ------> ns.pagina.com:53
ns.prueba.com <-------........... ns.pagina.com
|<--[IP para www.pagina.com es 1.2.3.4]<-- atacante.malo.com
Pero en la práctica tenemos que suponer un buen ID. Si estamos en una LAN, podemos escuchar para conseguir este ID y responder antes que el servidor de nombres (es fácil en una red local).
Si deseamos hacer esto remotamente no tenemos muchas opciones, tenemos sólamente 4 métodos básicos:
Probar aleatoriamente todos los valores posibles de la bandera ID. Debemos contestar antes que el ns (ns.pagina.com en este ejemplo). Este método es obsoleto a menos que deseemos saber el ID o cualquier otra condición favorable para su predicción. Algunas peticiones DNS (200 o 300) en orden para incrementar las oportunidades de obtener un buen ID. Inundar el DNS para evitar su trabajo. El servidor de nombres se caerá y mostrará el error siguiente: >> Oct 06 El 05:18:12 ADM named[1913 ]: db_free: DB_F_ACTIVE set - ABORT at this
O podemos utilizar la vulnerabilidad en las versiones 8.1.x, 4.9.3, 4.9.5 y 4.9.6 de BIND descubierta por SNI (Secure Networks, Inc.) con la predicción del ID.
Puede escuchar fácilmente los mensajes que viene a un DNS al azar (ns.ejemplo.com para este ejemplo). Preguntamos NS.victima.com para resolver (aleatorio).ejemplo.com. NS.victima.com pedirá a ns.ejemplo.com resolver (aleatorio).ejemplo.com ns.victima.com --> [?(aleatorio).ejemplo.com ID = 444 ] --> ns.ejemplo.com
Ahora tenemos el ID del mensaje de NS.victima.com, y sabemos qué rango ID tendremos que utilizar. (ID = 444 en este ejemplo). Entonces hacemos una petición de resolución por ejemplo a www.microsoft.com para NS.victima.com
(Nosotros) --> [?www.microsoft.com ] --> ns.victima.com
nc.victima.com --> [?www.microsoft.com ID = 446 ] --> ns.microsoft.com
Inundamos el servidor de nombres ns.victima.com con el ID (444) que tenemos y entonces lo aumentamos.
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 444] --> ns.victima.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 445] --> ns.victima.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 446] --> ns.victima.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 447] --> ns.victima.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 448] --> ns.victima.com
ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 449] --> ns.victima.com
(Ahora sabemos que los ID's son predecibles, y aumentan solamente. Inundamos ns.victim.com con respuestas engañosas con ID 444+. Las versiones de 8.3.4, 4.9.11 y las recientes 8.2.x y 9.x de BIND no son vulnerables a este tipo de ataque.)

References: resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución