Índice

Introducción
Uso básico
Interpretando la salida
Filtros

Introducción

Tcpdump (y su port a Windows, Windump) son programas cuya utilidad principal es analizar el tráfico que circula por la red. Se apoya en la librería de captura pcap, la cual presenta una interfaz uniforme y que esconde las peculiaridades de cada sistema operativo a la hora de capturar tramas de red. Para seguir el manual es necesario unos conocimientos basicos del protocolo TCP/IP, remitiéndome al TCP/IP Illustrated, Volumen 1 de Stevens, para quien esté interesado.

Aunque viene incluido con la mayoría de las distribuciones de Linux, sus fuentes pueden encontrarse en www.tcpdump.org

El port completo para Windows, tanto de las librerias como del tcpdump puede encontrarse en la web de la Politécnica de Torino. Es un simple binario, que necesita tener instalado el port de las pcap para windows para funcionar.

Uso básico

Lo primero que debemos averiguar cuando estamos usando el tcpdump, es las interfaces que queremos escuchar. Por defecto cuando se ejecuta sin parámetros, en los Linux se pone a escuchar en la eth0, mientras que en Windows hay que especificarla la interfaz donde quiere escuchar.

Para averiguar la interfaces en cualquier Unix recurrimos al comando ifconfig -a el cual nos da una lista de las interfaces que tenemos, así como sus parametros de configuración.


[terron@ux02 ~]$ /sbin/ifconfig -a
eth0      Link encap:Ethernet  HWaddr addr
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:646760 errors:0 dropped:0 overruns:0 frame:0
          TX packets:449673 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          Interrupt:5 Base address:0x2c20

eth1      Link encap:Ethernet  HWaddr addr
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1321583 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1778135 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          Interrupt:9 Base address:0x3000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:3924  Metric:1
          RX packets:39747 errors:0 dropped:0 overruns:0 frame:0
          TX packets:39747 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0

[terron@ux02 ~]$
(en el ejemplo anterior estan borradas las direcciones ip)

En el caso de Windows, podemos recurrir al propio windump, para que nos liste las interfaces que tenemos. Para ello ejecutamos un Windump -D y nos dara la información que buscamos:

C:\Documents and Settings\terron\download>windump -D
1.\Device\Packet_NdisWanIp (NdisWan Adapter)
2.\Device\Packet_{8435447C-6020-481F-A720-44D940909166} (Intel 8255x-based Integ
rated Fast Ethernet)

Usando los datos del ejemplo anterior, en el Linux si queremos escuchar en la interfaz eth0, usaremos tcpdump -i eth0, mientras que en el caso de Windows si queremos escuchar en la ethernet usaremos windump -i \Device\Packet_{8435447C-6020-481F-A720-44D940909166}.

Cuando estamos leyendo la red, puede que no nos interese que el tcpdump intente resolver los nombres de las maquinas (pueden que no estin dadas de alta en el DNS, por motivos de seguridad, etc), para ello disponemos de la opción -n.

Para establecer la longitud de los datos que captura tcpdump usamos -s len, donde len es la longitud que nos interesa. Por defecto el tcpdump sólo captura los primeros 68 bytes, lo cual es útil si lo único que se quiere son las cabaceras IP, TCP o UDP, pero que en caso de estar esnifando protocolos como el NFS truncan los datos. En ese caso podemos ajustar la longitud de la captura a la MTU del medio que estamos usando con esta opción. Por ejemplo para capturar toda la trama ethernet podemos usar -s 1500.

En función de la cantidad de información que queramos a la hora de que el tcpdump nos interprete, podemos usar -v,-vv,-vvv, aumentando el grado de información con cada una de las opciones.

Si queremos imprimir el contenido del paquete, podemos usar la opción -x. Si ademas queremos que nos imprima en ASCII el contenido de los paquetes podemos usar -X. La longitud que imprime viene determinada por la opción -s o los 68 bytes que usa captura por defecto.

Podemos trabajar offline con el tcpdump. Si queremos grabar nuestra captura para posteriormente leerla y analizarla usamos la opción -w file donde file es el nombre del fichero donde queremos grabar la captura de datos. Posteriormente podemos leer y analizar offline con -r file. Además este tipo de ficheros de captura lo pueden leer otros analizadores como por ejemplo Ethereal.

Interprentando la salida

Lo primero que hay que decir es que la salida depende del protocolo que estemos analizando. Para empezar comentar que todas las capturas del tcpdump tienen como primer campo una marca de tiempo, que indica cuando ha sido capturado el paquete.

Peticiones ARP/RARP

El protocolo ARP (address reslotion protocol), sobre ethernet está documentado en la RFC 826. RARP puede encontrarse en la RFC 1293. Las peticiones arp aparecen de la siguiente manera:

18:33:49.908612 arp who-has 192.168.1.2 tell 192.168.1.1
18:33:49.908691 arp reply 192.168.1.2 is-at 0:2:a5:ee:ec:10

En este caso, la máquina 192.168.1.1 pregunta por la dirección ethernet 192.168.1.2 (suponemos ambas máquinas en la misma subred). Como vemos la 192.168.1.2 responde. En este caso, vemos los valores numéricos puesto que he usado la opcin -n. En caso, las mayúsculas indican la máquina por la cual se está preguntando, y la minúscula la máquina que hace la pregunta.

18:33:49.908612 arp who-has MAQUINA tell otra
18:33:49.908691 arp reply MAQUINA is-at 0:2:a5:ee:ec:10

TCP

La linea general de un paquete TCP es como sigue:
src > dst: flags [dataseq ack window urgent options]

El protocolo TCP se define en la RFC 793 En principio src, dst y flags estan siempre presentes. Los otros dependiendo del tipo de conexión TCP que se trate. El significado de dichos parámetros es:

En el siguiente ejemplo, (viene en la página de manual del tcpdump), podemos ver:

  1. rtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024>
  2. csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
  3. rtsg.1023 > csam.login: . ack 1 win 4096
  4. rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
  5. csam.login > rtsg.1023: . ack 2 win 4096
  6. rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
  7. csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
  8. csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
  9. csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1

Esto simula una conexión originada por la máquina rtsg con destino a csam, con el servicio rlogin.

El significado de las líneas anteriores es:

  1. Inicio de conexion de rtsg -> csam SYN ISN 768512 ventana de 4096
  2. SYN de csam -> rtsg ISN 947648 ventana de 4096 ACK del SYN anterior.
  3. ACK del SYN mandado por csam. No hay flags
  4. 1 byte de datos de rtsg -> csam. Flag PUSH activado., (los números de secuencia son relativos al ISN a menos que especifiquemos la opción -S, en cuyo caso pone los números de secuencia se imprimen de manera absoluta).
  5. ACK del byte de datos anterior por parte de csam.
  6. 19 bytes de datos de rtsg a csam.
  7. csam manda 1 byte de datos a rtsg, y manda el ACK de los 19 bytes enviados por rtsg. La ventana de recepcisn ha bajado en 19 bytes. Flag PUSH
  8. csam envía un byte de datos urgente. Flag PUSH.
  9. Idem anterior.

UDP

Un paquete UDP se imprime de la siguiente manera:
origen.srcport > destino.dsrpot: udp len
Ejemplo:
12:35:21.457350 10.10.109.10.1025 > 192.168.1.2.1345: udp 121 [ttl 1]

En algunos casos, puede interpretar protocolos que vayan encapsulado en los paquetes UDP, como NFS o DNS. El grado de detalle en la interpretación de estos protocolos dependerá del grado de detalle (controlado con la opción -v) que queramos darle.

Fragmentos de datagramas IP

Los datagramas fragmentados se indican con una expresión al lado de los mismos entre paréntesis:
(frag id:size@offset+) (frag id:size@offset)

Los datos del protocolo del nivel superior, sólo se imprimen en el primer fragmento.

Filtros

Es lo mas importante que nos permite hacer el tcpdump, el uso de filtros. Un filtro es una expresión que va detrás de las opciones y que nos permite seleccionar los paquetes que estamos buscando. En ausencia de ésta, el tcpdump volcará todo el tráfico que vea el adaptador de red seleccionado.

La expresión que se usa para definir el filtro tiene una serie de primitivas y tres posibles modificadores a las mismas. Esta expresión sera verdadera o falsa y hara que se imprima o no el paquete de datos.

Los 3 modificadores posibles son:

Siempre podemos combinar expresiones con ayuda de paréntesis. Ojo con el tema de los paréntesis en los shell de Unix, porque son metacaracteres interpretan.

A continuació se dan las primitivas que pueden usarse. Lo que aperece entre [ y ] es opcional, y el | significa "o". El resto se tiene que poner si queremos poner el filtro con el comportamiento.

Combinando los filtros

Se pueden combinar las expresiones anteriores con los ayuda de los operadores not, and y or (corresponden a la negación, el y lógico y el o lógico, dando lugar a filtros más complejos. Podemos usar también los equivalentes del lenguaje C: !, && o ||.

Ejemplos:

Filtros Avanzados

Para los realmente muy cafeteros, el tcpdump permite hacer filtros a mano, indicando que bytes de la trama queremos pillar y como los queremos interpretar. Cuando queremos definir filtros de esta manera la expresión general es:

expr relop expr

Donde relop puede ser cualquiera de las operaciones de relación de C: >,<, >= <=, = y !=. expr es una expresión aritmética compuesta por una serie de números enteros, los operadores binarios de C, (+, -, *, /, & y |), un operador de longitud, len, y una serie de palabras reservadas que nos permiten el acceso a los diferentes paquetes de datos (ether, fddi, tr, ip, arp, rarp, tcp, udp, icmp e ip6).

Para acceder a los datos dentro de un paquete, usamos los modificadores anteriores y una expresión entera. Opcionalmente podemos especificar el tamaño de los datos que accedemos.

proto [expr : tam]

Asm por ejemplo, el primer byte de la trama ethernet será ether[0], la primera palabra será ether[0:2]. El parámetro tam puede ser 1 (por defecto y no hace falta especificarlo), 2 o 4. Por ejemplo,

Una nota, al menos en la página de manual de la versión 3.6.2 hacen notar que cuando se especifica tcp, udp u otro procolo de nivel superior se hace referencia a IPv4. Esta limitación sin embargo no aparece en OpenBSD.

Otra nota a tener en cuenta: en caso de usar tcp[indice] o udp[indice], implicitamente se aplica una regla para averiguar si es un paquete fragmentado, es decir, usando la notacisn de estos filtros ip[0:2] & 0x1fff = 0. udp[0] o tcp[0] se refieren al primer byte de la cabecera UDP o TCP.


La mayoría de la doc aquí contenida se ha obtenido de la pagina de manual del tcpdump de una Redhat Linux y del OpenBSD. De hecho, la sección de filtrosl procede en su totalidad de la página de manual del mismo, aunque he cambiado algunos detalles a la hora de expresarlos.