domingo, 8 de enero de 2012

Tcpdump, una introducción

Usando sistemas de escritorio (Windows o Linux, hay para los dos) regularmente se usan herramientas de captura de paquetes mas avanzadas/completas pero finalmente, incluso estas herramientas tienen sus orígenes en tcpdump. Creo que antes hemos dicho que la mejor manera de aprender sobre protocolos es usando este tipo de herramientas y como ya saben la ganancia que representan las aplicaciones de linea de comandos, aquí les va un tuto muy interesante acerca de la mencionada herramienta. El autor es Henry Van Styn y el original lo pueden encontrar aquí (viene de Linux Journal) hoy la traducción es de Jorge. Esta va a ser semana de redes, pueden apostar. 

Tcpdump, una introducción ("tcpdump fu" en el original)
La captura de paquetes es una de las formas más poderosas y fundamentales  para analizar las redes. Usted puede aprender prácticamente todo lo que está pasando dentro de una red mediante la intercepción y el examen de los datos  en bruto (sin formato) que por ella circulan. Las modernas herramientas de análisis de redes son capaces de capturar, interpretar y describir este tráfico de la red de una manera  entendible por el ser humano. 

tcpdump es una de las principales herramientas de captura de paquetes ("sniffing") que proporcionan estas capacidades de análisis, y aunque ahora comparte el campo con muchas otras utilidades, sigue siendo una de las más potentes y flexibles. 

Si piensa que tcpdump ha quedado obsoleto por la aparición de herramientas con interfaz gráfica como Wireshark, piénselo de nuevo. Wireshark es una gran aplicación, pero simplemente no es la herramienta adecuada para el trabajo en cada situación. Como una utilidad de linea de comandos refinada, universal y ligera - parecida a cat, less o hexdump - tcpdump satisface otro tipo de necesidad. 

Una de las mayores fortalezas de tcpdump es su conveniencia. Utiliza un enfoque de "uno-al-mando" que da como resultado respuestas rápidas y puntuales. Funciona a través de una sesión SSH, no necesita  entornos gráficos (X) y es más probable que sea allí cuando usted la necesite. Y, dado que utiliza convenciones de linea de comandos estándar (como escribir en STDOUT, que puede ser redireccionado), tcpdump se puede utilizar en todo tipo de formas creativas, interesantes y de gran utilidad. 

En este artículo, presento los fundamentos de la captura de paquetes, y hago un desglose de la sintaxis y el uso de tcpdump. Muestro cómo usar tcpdump para concentrarse en paquetes específicos, y revelar la información útil que contienen. Expongo algunos ejemplos del mundo real de cómo tcpdump puede ayudar a poner los detalles de lo que está sucediendo en su red al alcance de su mano, y por qué tcpdump sigue siendo la herramienta que todo administrador debe tener en su caja de herramientas.

Conceptos esenciales 
Antes de que pueda empezar a dominar tcpdump, usted debe entender algunos de los fundamentos que se aplican en la utilización de todos los sniffers: 
  • La captura de paquetes es pasiva, no transmite o modifica el tráfico de la red. 
  • Usted puede sólo capturar los paquetes que recibe su sistema. En una red típica de computación, esto excluye el tráfico unicast entre los demás equipos (los paquetes que no son enviados hacia o desde su computadora). 
  • Usted puede capturar sólo los paquetes dirigidos a su sistema, a menos que configure la interfaz de red en modo promiscuo. 
Se supone que usted está interesado en ver algo más que su tráfico local, por lo que tcpdump inicia de forma automática en modo promiscuo (lo que requiere privilegios de root). Pero, para que la tarjeta de red pueda recibir los paquetes, en el primer lugar usted tiene que estar donde  esté el tráfico de red, por así decirlo. 

Anatomía de un comando tcpdump 
Un comando tcpdump consta de dos partes: un conjunto de opciones seguido por una expresión de filtro: 

La expresión identifica que paquetes capturar, y las opciones definen, en parte, cómo se muestran esos paquetes, así como otros aspectos del comportamiento del programa. 

Opciones 
Las opciones tcpdump siguen las convenciones estándar de la sintaxis de los modificadores/banderas de la línea de comandos. Algunas  opciones aceptan un parámetro, como -i para especificar la interfaz de captura, mientras que otras son opciones  independientes y pueden ser agrupadas, como -v para ofrecer más información y -n para desactivar la resolución de nombres. 
Las páginas de man para tcpdump muestran todas las opciones disponibles, pero aquí están algunas de las más notables:
  • -i interfaz: interfaz para escuchar. 
  • -v,-vv,-vvv: más detallado. 
  • -q: menos detallado. 
  • -e: impresión de los niveles de enlace de las cabeceras (Ethernet). 
  • -N: mostrar los nombres de los host. 
  • -t: No imprimir las marcas de tiempo. -n: desactivar la búsqueda de nombres. 
  • -s0 (o -s 0): utilizar la captura máxima, captura paquetes completos (por defecto en las versiones recientes de tcpdump). 

Ninguna de estas opciones son necesarias. Las opciones suministradas por el usuario simplemente modifican el comportamiento por defecto del programa, que es capturar desde primera interfaz, y luego imprimir en la pantalla, en un formato de una sola línea, las descripciones de los paquetes coincidentes. 

Expresión de filtro 
La expresión de filtro es el criterio booleano (verdadero o falso) de coincidencia  de paquetes. Todos los paquetes que no coincidan con la expresión son ignorados. 

La sintaxis de la expresión de filtro es robusta y flexible. Está formada principalmente por palabras clave llamadas primitivas, las cuales representan diferentes clasificadores de coincidencia de paquetes, tales como el protocolo, la dirección, el puerto y el sentido. Estas pueden ser concatenadas  utilizando y/o,  agrupadas y anidadas con paréntesis, y negadas con not  para conseguir prácticamente cualquier criterio. 

Debido a que las primitivas tienen nombres descriptivos y hacen gran parte del trabajo pesado, las expresiones de filtro son generalmente fáciles de entender, de leer y de construir. La sintaxis se describe en la página de man para pcap-filter, pero aquí hay algunos ejemplos de las expresiones de filtro: 

  • tcp 
  • port 25 and not host 10.0.0.3 
  • icmp or arp or udp 
  • vlan 3 and ether src host aa:bb:cc:dd:ee:ff 
  • arp o udp port 53 
  • icmp y \ (dst host mrorange o dst host mrbrown\)  

Al igual que las opciones, las expresiones de filtro no son necesarias. Una expresión de filtro vacío, simplemente coincide con todos los paquetes. 

Entendiendo la salida de tcpdump.
Qué sentido tiene la salida depende del conocimiento que tenga usted de los protocolos en cuestión tcpdump ajusta su salida para que coincida con los protocolos de un paquete dado. 

Por ejemplo, los paquetes ARP aparecen de este modo cuando tcpdump es llamado con las opciones -t  y -n (marcas de tiempo activadas y resolución de nombres desactivada): 

arp who-has 10.0.0.1 tell 10.0.0.2 

arp reply 10.0.0.1 is-at 00:01:02:03:04:05

ARP es un protocolo simple que se usa para resolver direcciones IP a direcciones MAC. Como se puede ver arriba, tcpdump describe estos paquetes en un formato sencillo. Los paquetes DNS, por otra parte, se muestran completamente diferentes: 

IP 10.0.0.2.50435 > 10.0.0.1.53: 19+ A? linuxjournal.com. (34)  

IP 10.0.0.1.53 > 10.0.0.2.50435: 19 1/0/0 A 76.74.252.198 (50)

A primera vista puede parecer críptico, pero tiene más sentido cuando se conoce cómo trabajan las capas del protocolo. DNS es un protocolo más complicado de entender que ARP, pero también opera en un nivel superior. Esto significa que se ejecuta sobre la parte superior de otros protocolos de nivel inferior, que también se muestran en la salida. 
A diferencia de ARP, que es un protocolo de capa 3 no enrutable, DNS es un protocolo que abarca toda la Internet. Sus mecanismos de transporte se basan en UDP e IP, lo que lo convierte en un protocolo  de capa 5 (UDP es de capa 4, e IP es de capa 3). 

La información UDP/IP subyacente consistente en un par IP/puerto de origen y destino, se muestra en el lado izquierdo de los dos puntos, seguido por el resto de la información específica del DNS a la derecha. 
A pesar de que esta información sobre DNS todavía se muestra en un formato altamente condensado, ud debería ser capaz de reconocer los elementos esenciales si conoce los fundamentos del DNS. El primer paquete es una consulta a linuxjournal.com, y el segundo paquete es una respuesta, dando la dirección 76.74.252.198. Este es el tipo de paquetes que se generan a partir de las búsquedas  simples de DNS. 

Vea la sección "OUTPUT FORMAT" de la página de man de tcpdump para una descripción completa de todos los formatos de salida de cada protocolo específico. Algunos protocolos están mejor explicados que otros por su formato de salida, pero he encontrado que tcpdump hace un trabajo bastante bueno en general para mostrar la información más útil acerca de un determinado protocolo. 

Archivos de captura. 
Además de su comportamiento normal de imprimir las descripciones de los paquetes en la pantalla, tcpdump también soporta un modo de operación en el que escribe los paquetes a un archivo en lugar de la pantalla. Este modo se activa cuando se utiliza la opción -w para especificar un archivo de captura de salida. 
Al escribir en un archivo, tcpdump utiliza un formato completamente diferente a cuando escribe en la pantalla. Al escribir en la pantalla,  lo que se imprime son las descripciones de los paquetes en formato de texto. Al escribir en un archivo, el paquete se escribe tal como está, sin analizar. 

En vez de hacer una captura en vivo, tcpdump también puede leer desde un archivo de captura existente como entrada con la opción -r. Dado que los archivos de captura de tcpdump utilizan el formato universal de "pcap", también pueden ser abiertos por otras aplicaciones, como Wireshark
Esto le da la opción de capturar los paquetes con tcpdump en un host, pero realizar el análisis en un host diferente mediante la transferencia y la carga del archivo de captura. Esto le permite utilizar Wireshark en su estación de trabajo local sin tener que conectarlo a la red y la ubicación desde la que necesita capturar los paquetes. 

Analizando Protocolos de Aplicaciones basados en TCP.
tcpdump está basado en el análisis de paquetes, y funciona muy bien para los protocolos que no son orientados a conexión,  los protocolos basados en paquetes como IP, UDP, DHCP, DNS e ICMP. Sin embargo, no puede analizar directamente los protocolos "orientados a  conexión", como HTTP, SMTP e IMAP, porque estos trabajan completamente diferente.
Ellos no tienen el concepto de "paquetes". Por el contrario, operan en conexiones basadas en flujos de datos TCP, que proporcionan una capa de comunicaciones abstracta. Estos protocolos de aplicación son más similares a programas de consola interactivos que a protocolos de red basados en paquetes. 

TCP maneja de manera transparente todos los detalles subyacentes necesarios para poder proveer conexiones fiables de extremo a extremo. Esto incluye la encapsulación de los datos, en función del flujo, en paquetes (llamados segmentos) que se pueden enviar a través de la red. Todos estos detalles están ocultos debajo de la capa de aplicación. 
Con el objetivo de capturar protocolos de aplicaciones basados en TCP, se necesita un paso adicional más allá de capturar el paquete. Debido a que cada segmento de TCP es sólo una parte de los datos de la aplicación, no pueden ser utilizados individualmente para obtener información significativa. Primero debe volver  a montar las sesiones TCP (o flujos) de los conjuntos combinados de los distintos segmentos/paquetes. Los datos del protocolo de aplicación se encuentran directamente dentro de las sesiones. 

tcpdump no tiene una opción de ensamblar las sesiones TCP directamente desde los paquetes, pero puede "simularlo" mediante el uso de lo que yo llamo "el truco de cadenas (strings en el original ndt) de tcpdump".

El truco de cadenas de tcpdump
Generalmente cuando estoy capturando el tráfico, es sólo con fines de realizar un análisis casual. Los datos no tienen que ser perfectos si muestran lo que estoy buscando y me ayudan a desarrollar una idea. 
En estos casos, la velocidad y la comodidad reinan. El siguiente truco es en este sentido uno de mis técnicas favoritas de tcpdump. Funciona porque: 
  1. Los segmentos TCP se envían por lo general en orden cronológico. 
  2. Los protocolos de aplicaciones basadas en texto producen segmentos TCP con texto. 
  3. Los datos que rodean el texto, como cabeceras de los paquetes, generalmente no son de texto. 
  4. El comando UNIX strings, filtra los datos binarios del flujo de datos preservando sólo texto (caracteres imprimibles). 
  5. Cuando tcpdump se llama con -w imprime paquetes sin formato a STDOUT. 
Lo unimos todo, y formamos un comando que obtiene en tiempo real los datos de sesión HTTP: 

tcpdump -l -s0 -w - tcp dst port 80 | strings

La opción -l anterior activa un buffer de línea, lo que hace que los datos se muestren en  pantalla de inmediato. 

Lo que sucede es que tcpdump imprime los datos binarios sin formato en la pantalla. Esto da un giro con la opción -w donde el nombre de archivo especial - escribe a STDOUT en lugar de a un archivo. Normalmente, al hacer esto se mostraría todo tipo de basura, pero ahí es donde viene a cuento el comando strings que solo permite que se impriman en pantalla los datos reconocidos como texto. 
Hay algunas advertencias a tener en cuenta. En primer lugar, los datos de varias sesiones recibidas simultáneamente se muestran al mismo tiempo, lo que afecta el resultado final. Mientras más refinada sea la expresión de filtrado, esto representará menos problemas. Incluso ud debería ejecutar comandos separados (en diferentes shell) para las sesiones de cliente y servidor:

tcpdump -l -s0 -w - tcp dst port 80 | strings 

tcpdump -l -s0 -w - tcp src port 80 | strings

También, debe estar preparado para ver algunos caracteres confusos aquí y allá donde quiera que una secuencia de datos binarios resulte similar a caracteres de texto. Usted puede reducir esto mediante el aumento de min-len (vea la página de man para strings). 

Este truco funciona igual de bien para otros protocolos basados en texto. 

Análisis  HTTP y SMTP 
Usando el truco de strings en la sección anterior, usted puede capturar datos HTTP, aunque tcpdump en realidad no entienda nada al respecto. Luego de capturados, ud podrá analizarlos de varias maneras. 
Si quieres ver todos los sitios web accedidos por "davepc" en tiempo real, por ejemplo, puede ejecutar este comando en el cortafuegos (suponiendo que la interfaz interna sea eth1): 

tcpdump -i eth1 -l -s0 -w - host davepc and port 80 \ | strings | grep 'GET\|Host'

En este ejemplo, estoy usando un comando grep para mostrar sólo las líneas con GET o Host. Estas cadenas se muestran en las peticiones HTTP y en conjunto muestran las direcciones URL a las que se accede. 

Esto funciona igual de bien para SMTP. Usted puede ejecutar esto en el servidor de correo para ver los remitentes y los destinatarios de correo electrónico: 

tcpdump -l -s0 -w - tcp dst port 25 | strings \ | grep -i 'MAIL FROM\|RCPT TO'
  
Estos son sólo algunos ejemplos para ilustrar lo que es posible hacer. Usted, evidentemente, podría llevarlos más allá de grep. Podría ir tan lejos como para escribir un script en Perl y hacer todo tipo de cosas sofisticadas. Probablemente no le tome tanto tiempo, sin embargo a ese nivel ya existen mejores herramientas que en realidad están diseñadas para hacer ese tipo de cosas. 
El verdadero valor de tcpdump es la capacidad de hacer este tipo de cosas de forma interactiva o a voluntad. Es el poder de mirar cualquier aspecto dentro de su red siempre que lo desee sin mucho esfuerzo. 

Depurando rutas y enlaces VPN 
tcpdump es muy útil en la depuración de las VPN y otras conexiones de red, mostrando donde aparecen los paquetes  y donde no. Digamos que usted ha creado una VPN enrutable entre dos redes  la 10.0.50.0/24 y 192.168.5.0/24 como se ilustra a continuación: 
Si está operando correctamente, las estaciones de cada redes deben ser capaces de hacer ping entre sí. Sin embargo, si usted no recibe respuestas al ping realizado a D desde el equipo A, por ejemplo, puede usar tcpdump para identificar donde se produce la ruptura exactamente: 

tcpdump -tn icmp and host 10.0.50.2

En este ejemplo, durante un ping desde 10.0.50.2 a 192.168.5.38, cada ronda (ida y vuelta del ping) debe aparecer como un par de paquetes como se ve a continuación, sin tener en cuenta de cuál de los cuatro sistemas se ejecuta el comando tcpdump

IP 10.0.50.2 > 192.168.5.38: ICMP echo request, 
->id 46687, seq 1, length 64 

IP 192.168.5.38 > 10.0.50.2: ICMP echo reply, 
->id 46687, seq 1, length 64

Si los paquetes de solicitud llegan a la estación C (la puerta de enlace remota), pero no a D, esto indica que la VPN está funcionando, pero podría haber un problema de enrutamiento. Si el host D recibe la solicitud, pero no genera una respuesta, es probable que tenga bloqueado ICMP. Si se genera una respuesta pero no llegan a C, entonces quizas D no tenga configurada la puerta de enlace correcta para volver a 10.0.50.0/24. 
Usando tcpdump, puede seguir el ping a través de los ocho posibles puntos de fallo  a medida que se abre camino de ida y vuelta a través de la red. 

Conclusiones. 
Espero que este artículo haya despertado su interés por tcpdump y le haya dado algunas ideas nuevas. Esperemos que haya disfrutado con los ejemplos que apenas se acercan a la realidad de lo que es posible. 
Además de sus muchas características y opciones integradas, como he mostrado en varios ejemplos, tcpdump puede ser utilizado como un conducto de paquetes de datos dirigiendo su salida a la entrada de otros comandos para expandir aún más las posibilidades, incluso si usted logra agotar sus posibilidades. Las formas de usar tcpdump sólo están limitadas por su imaginación. 
tcpdump también es una increíble herramienta de aprendizaje. No hay mejor manera de aprender cómo trabajan las redes y los protocolos que observando sus paquetes reales. 

No olvide las páginas de man para tcpdump y pcap-filter  para obtener más detalles e información. 

El legado de tcpdump / libpcap 
tcpdump ha sido la herramienta de captura de paquetes de facto durante los últimos 25 años. Esta realmente generó  todo  una categoría de utilidades de redes basadas en sniffing y análisis de paquetes. Antes de tcpdump, la captura de paquetes demandaba demasiado procesamiento lo que la hacía muy poco práctica. tcpdump introdujo algunas innovaciones y optimizaciones clave que ayudaron a hacer que la captura de paquetes fuera más viable, tanto para los sistemas regulares como para las redes con mucho tráfico. 
Las utilidades que llegaron después no sólo siguieron el ejemplo de tcpdump, sino que también incorporaron directamente sus funcionalidades de captura de paquetes. Esto fue posible porque desde muy temprano, los autores tcpdump decidieron separar el código de captura en una librería portable llamada libpcap

Wireshark, ntop, snort, iftop, ngrep y cientos de otras aplicaciones y utilidades disponibles en la actualidad se basan en libpcap. Incluso la mayoría de aplicaciones de captura de paquetes para Windows se basan en un "port" de libpcap llamado WinPcap.