tcpdump para todos los públicos

TCPDump tiene filtros para su mejor manejo. Estos filtros pueden llegar a ser tan sofisticados como queramos y extraer cualquier tipo de datos de los datagramas, paquetes, etc que circulen a través de nuestra red.

Como la mejor manera de explicar el funcionamiento de los filtros es la práctica, vamos a analizar una combinación y encadenamiento de filtros con un ejemplo muy simple.

Ejemplo

Tenemos el servidor de correos un tanto colapsado, este servidor no aguanta demasiadas conexiones, o el tráfico es mayor de lo previsto. Analicemos entonces qué es lo que pasa.

Vamos a crear un filtro para averiguar las conexiones al puerto 110 de nuestro servidor de correos.

Aquí vemos algunas opciones ya comentadas y otras nuevas:

  • –q establecemos el indicador de salida rápida que hará que nos devuelva menos información y que las líneas sean más cortas. Esto es así, porque, en realidad, sólo nos interesa los host/IP y las marcas de tiempo, ya que, como veremos más adelante, estamos filtrando establecimientos de conexión TCP al puerto 110.
  • -n no resolver nombres de host
  • -X vuelca en la consola los datos.
  • s 0 es el snaplen. A cero estamos cogiendo los paquetes completos. Si hubiéramos puesto -s 512 se capturarían sólo los primeros 512 bytes del paquete tcp.
  • tcp[13] = 2 esta es la parte interesante. Con este filtro estamos diciendo a windump que queremos escoger los paquetes TCP cuyo indicador, bandera o flag sea SYN “S”. Para entender esto hay que tener en cuenta cómo es el formato de una cabecera TCP, que los indicadores o flags se encuentran en el octeto 13.
  • and port 110, unido a lo anterior, analizará el puerto 110. Podriamos añadir que lo hiciera sólo para un determinado host:and port 110 and host ALFON.

Formato de la cabecera (header) del TCP:

  • Puerto origen(16 bits). Puerto de la máquina origen. Al igual que el puerto destino es necesario para identificar la conexión actual.
  • Puerto destino(16 bits). Puerto de la máquina destino.
  • Número de secuencia(32 bits). Indica el número de secuencia del primer byte que trasporta el segmento.
  • Número de acuse de recibo (32 bits). Indica el número de secuencia del siguiente byte que se espera recibir. Con este campo se indica al otro extremo de la conexión que los bytes anteriores se han recibido correctamente.
  • Posición de los datos (4 bits). Longitud de la cabecera medida en múltiplos de 32 bits (4 bytes). El valor mínimo de este campo es 5, que corresponde a un segmento sin datos (20 bytes).
  • Reservado (6 bits). Bits reservados para un posible uso futuro.
  • Bits de código o indicadores (6 bits). Los bits de código determinan el propósito y contenido del segmento. A continuación se explica el significado de cada uno de estos bits (mostrados de izquierda a derecha) si está a 1:

URG. El campo Puntero de urgencia contiene información válida.

ACK. El campo Número de acuse de recibo contiene información válida, es decir, el segmento actual lleva un ACK. Observemos que un mismo segmento puede transportar los datos de un sentido y las confirmaciones del otro sentido de la comunicación.

PSH. La aplicación ha solicitado una operación push (enviar los datos existentes en la memoria temporal sin esperar a completar el segmento).

RST. Interrupción de la conexión actual.

SYN. Sincronización de los números de secuencia. Se utiliza al crear una conexión para indicar al otro extremo cual va a ser el primer número de secuencia con el que va a comenzar a transmitir (veremos que no tiene porqué ser el cero).

FIN. Indica al otro extremo que la aplicación ya no tiene más datos para enviar. Se utiliza para solicitar el cierre de la conexión actual.

  • Ventana (16 bits). Número de bytes que el emisor del segmento está dispuesto a aceptar por parte del
    destino.
  • Suma de verificación (24 bits). Suma de comprobación de errores del segmento actual. Para su cálculo se utiliza una pseudo-cabecera que también incluye las direcciones IP origen y destino.
  • Puntero de urgencia(8 bits). Se utiliza cuando se están enviando datos urgentes que tienen preferencia sobre todos los demás e indica el siguiente byte del campo Datos que sigue a los datos urgentes. Esto le permite al destino identificar donde terminan los datos urgentes. Nótese que un mismo segmento puede contener tanto datos urgentes (al principio) como normales (después de los urgentes).
  • Opciones(variable). Si está presente únicamente se define una opción: el tamaño máximo de segmento que será aceptado.
  • Relleno. Se utiliza para que la longitud de la cabecera sea múltiplo de 32 bits.
  • Datos. Información que envía la aplicación.

¿Qué significa realmente tcp[13] = 2?

En el flag SYN, que es utilizado para la sincronización de los números de la secuencia tendremos:

r r r UAPRSF
——————
0 0 0 0 0 0 1 0
(en binario)
——————
7 6 5 4 3 2 1 0

vemos que el byte 7 y 6 están reservados, el 5 es para URGENT, el 4 es para ACK, el3 es para PUSH, el 2 es para RESET y el byte 0 para FIN. Tenemos entonces el octeto completo.

En binario quedaría como acabamos de ver: 0 0 0 0 0 0 1 0, que pasado a base decimal, vemos que es el 2, de ahí viene tcp[13] = 2.

*Es fácil deducir entonces que para detectar un SYN/ACK: 0 0 0 1 0 0 1 0, el 18 en base decimal, entonces tcp[13] = 18.

Lo vemos más claramente en las siguientes líneas.

La teoría

Antes que nada, decir que TCPDump usa el formato: proto[x:y] = valor para leer datos en cabeceras de los protocolos involucrados.

  • proto (protocolo) puede ser ip, arp, rarp, tcp, udp, icmp, etc
  • [x:y] x es el octeto ó byte de comienzo e y significa: “leer” y bytes a partir del byte x
  • Si sólo aparece [x] es lo mismo que decir [x:1], es decir leer sólo el byte x, esto lo hace TCPDump por defecto.

Ya sabemos que significa cada uno de los valores. Vamos entonces a averiguar de dónde sacamos el 13 de la expresión tcp[13] = 2

*por maty: la escala que está encima del dibujo está mal.

Vamos a analizar la cabecera por filas:

  • puerto origen = 2 bytes u octetos o 16 bits
  • puerto destino = 2 bytes u octetos. La cuenta siempre empieza por el 0, con lo cual los octetos van del 0 al 3
  • número secuencia = 4 bytes u octetos, es decir del 4 al 7
  • número acuse recibo = 4 bytes u octetos del 8 al 11

OJO: Tenemos doce octetos (0,1, …11) Hemos de tener en cuenta que se empieza a contar desde cero, es decir, el primer byte es el octeto 0.

El siguiente octeto es el 12 (el décimo tercero) va desde el bits 0 al 7 que corresponden a posición de datos u offset -4 bits- y a Reservado-4+2-;dos bits de Reservado pertenecen ya al siguiente octeto el 13, que tiene los 2 bits reservados anteriores y 6 que son los flags (UAPRSF). 6 + 2 = 8 bits que es el octeto o byte 13 (o décimo cuarto).

Vamos a analizar ahora de dónde viene el valor 2 de la expresión tcp[13] = 2

Esta es la representación de octeto ó byte 13. Si ponemos el flag SYN activado y el resto NO activados, resulta que SYN lo ponemos a 1 y el resto a 0:

Queda entonces: 0 0 0 0 0 0 1 0 (los dos primeros bits dijimos que eran reservados y siempre están a 0)

U A P R S F
——————
0 0 0 0 0 0 1 0
(en binario)
——————
7 6 5 4 3 2 1 0

Si pasamos este número (0 0 0 0 0 0 1 0 ), que es binario, a decimal nos queda el número decimal 2 (2 elevado a 1), que es el valor que debemos de introducir para que la expresión quede así:

tcp[13] = 2

Esto le dice a windump o TCPDump que busque en la cabecera TCP el valor 2 que se encuentra en el byte u octeto 13. Y ya sabemos que corresponde al flag SYN activado (y los otros flags/banderas estarán desactivados).

Usando esta técnica, con windump o tcpdump, podríamos detectar escaneos y otras intrusiones en nuestros sistemas.

Siguiendo con el ejemplo práctico y quitando la opción -X que ahora es irrelevante:

Faltan muchas líneas, pero podemos observar en éstas que algunos host tenían sus clientes de correo configurados para “mirar” el correo cada minuto. En la realidad fueron casi todos, con lo cual tenían el servidor bastante atareadillo.

tcpdump -qn -s 0 -i eth0 tcp[13] = 18 and port 80

Aquí vemos algunas opciones ya comentadas y otras nuevas:

–q estableceremos el indicador de salida rápida que hará que nos devuelva menos información y que las líneas sean más cortas.

Esto es así porque en realidad sólo nos interesa los host/IP y las amrcas de tiempo.

-n no resolver nombres de host

– s 0 es el snaplen. A cero estamos cogiendo los paquetes completos. Si hubiéramos puesto -s 512 se capturarían sólo los primeros 512 bytes del paquete tcp.

tcp[13] = 2 esta es la madre del cordero. con este filtro estamos diciendo a tcpdump que queremos escoger los paquetes TCP cuyo indiccador, bandera o flag sea SYN “S”. Para entender esto hay que tener en cuenta como es el formato de un paquete TCP, que los indicadores o flags se encuentran en el octeto 13.
Vamos a echarle un ojo a ese octeto 13 y simulemos que el flag SYN está activo:

U A P R S F
——————
0 0 0 0 0 0 1 0
——————
7 6 5 4 3 2 1 0

vemos que el byte 7 y 6 estánm reservados., el 5 es para URGENT, 4 es para ACK, 3 es para PUSH, 2 es para RESET y el byte o para FIN. Tenemos entonces el octeto completo. En binario quedaría como acabamos de ver:

0 0 0 0 0 0 1 0

si pasamos este binario a decimal nos da 2

de ahí viene tcp[13] = 2.

Es facil deducir entonces que para detectar un SYN/ACK:

0 0 0 1 0 0 1 0

si pasamos este binario a decimal nos da 18

entonces tcp[13] = 18

and port 80 esto es que unido a lo anterior analice el puerto 80.

Podriamos añadir que lo hiciera sólo para un dterminado host:

and port 80 and host ALFON.

MAS OPCIONES DE CONFIGURACIÓN:

Mostrar todos los paquetes URG :

 # tcpdump 'tcp[13] & 32 != 0'

Mostrar todos los paquetes ACK :

 # tcpdump 'tcp[13] & 16 != 0'

Show me all PSH packets:

 # tcpdump 'tcp[13] & 8 != 0'

Show me all RST packets:

 # tcpdump 'tcp[13] & 4 != 0'

Show me all SYN packets:

 # tcpdump 'tcp[13] & 2 != 0'

Show me all FIN packets:

 # tcpdump 'tcp[13] & 1 != 0'
  • Display all IPv6 Traffic:
·          # tcpdump ip6
  • Show all traffic with both SYN and RST flags set: (should never happen)
·          # tcpdump 'tcp[13] = 6'
  • Show all traffic with the “evil bit” set:
·          # tcpdump 'ip[6] & 128 != 0'

Show me all SYN-ACK packets:

 # tcpdump 'tcp[13] = 18'

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *