Uso básico de Wireshark (Parte 3: Los filtros)

   Del mismo modo que sucede con otros programas que muestran datos, Wireshark posee una serie de filtros para precisar la búsqueda de paquetes de datos en la red.
  Sin embargo, este analizador de protocolos posee dos grandes tipos diferenciados de filtros. Por una parte están los filtros de visualización ("display filters", en inglés), mientras que, por otra, se encuentran los filtros de captura ("capture filters", en inglés). Ambos tienen profundas diferencias entre sí.
  Mientras que los filtros de captura se utilizan antes de comenzar una captura de paquetes, los de visualización se emplean en cualquier momento de la misma. Además, los primeros son menos potentes que los segundos, y se suelen utilizar para delimitar el tamaño de una captura bruta, mientras que los segundos únicamente ocultan algunos paquetes de la lista. Al tener que definirse antes de comenzar la captura, los filtros de captura no se pueden modificar una vez haya comenzado la misma, mientras que los de visualización pueden cambiarse en caliente.

FILTROS DE CAPTURA

  Limita el número de paquetes que se pueden capturar en una captura. Este tipo de filtros está escrito en lenguaje de filtros libcap, que compone las expresiones de filtros. Una expresión de filtro está formada por uno o más primitivos que, a su vez, están compuestos de un identificador (nombre o número) precedido de uno o más cualificadores.
  Hay tres tipos de cualificadores:
  •   Tipo: Muestran a qué hace referencia el identificador, tanto si es un nombre como si es un número. Opciones en esta clase de cualificadores son "host" (cualificador predeterminado si no se especifica ninguno de tipo), "net", "port" y "portrange".
  •   Dirección (dir): Especifican una dirección particular de transferencia hacia y/o desde el identificador. Opciones de esta clase de cualificadores son "src", "dst", "src or dst" (cualificador predeterminado si no se especifica ninguno de dirección), "src and dst", "ra", "ta", "addr1", "addr2", "addr3", y "addr4" (las 6 últimas sólo son válidas para conexiones inalámbricas IEEE 802.11).
  •   Protocolo (proto): Restringen la correspondencia a un protocolo particular. Opciones de esta clase de cualificadores son "ether", "fddi", "tr", "wlan", "ip", "ip6", "arp", "rarp", "decnet", "tcp" y "udp". En este caso, si no se especifica un cualificador de protocolo, los predeterminados son todos aquellos compatibles con el cualificador tipo.
  Por lo tanto, la sintaxis de un filtro de captura sería:
[not]  <primitivo> <[and/or] [not] <primitivo>...>

  Entre los primitivos que más se suelen utilizar se encuentran:
  •   [src/dst] host <nombre o dirección IP de anfitrión>: Permite filtrar por el nombre o la dirección IP de un equipo anfitrión. Opcionalmente, se pueden utilizar los cualificadores de dirección "src" y/o "dst" si se está interesado únicamente en esas direcciones. Si no están presentes, se seleccionarán los paquetes donde la dirección especificada aparece como la dirección de origen o de destino. Por ejemplo: host 172.18.5.4 (sólo captura el tráfico de esa dirección IP). 
  •   ether [src/dst] host <nombre o dirección IP de anfitrión>: Permite filtrar en las direcciones ethernet del anfitrión. Opcionalmente, se pueden utilizar los cualificadores de dirección "src" y/o "dst" si se está interesado únicamente en esas direcciones. Si no están presentes, se seleccionarán los paquetes donde la dirección especificada aparece como la dirección de origen o de destino.
  •   gateway host <nombre o dirección IP de anfitrión>: Permite filtrar en paquetes que usan el anfitrión como puerta de enlace, es decir, donde el origen o el destino de Ethernet era el anfitrión, pero ni la dirección IP de origen ni de destino era el anfitrión.
  •   [src/dst] net <red> [{mask <máscara de red>}/{len <longitud en bytes>}]: Permite filtrar mediante números de red. Opcionalmente, se pueden utilizar los cualificadores de dirección "src" y/o "dst" si se está interesado únicamente en el origen o destino de una red concreta. Si no están presentes, se seleccionarán los paquetes que tenga la red especificada en la dirección de origen o de destino. Además, se puede especificar la máscara de red o el prefijo CIDR para la red si son diferentes de los del usuario. Por ejemplo: src net 192.168.0.0 mask 255.255.255.0 (captura el tráfico desde un rango de direcciones IP).
  •   [tcp/udp] [src/dst] port <nº de puerto>: Permite filtrar por los números de puerto de tipo TCP y UDP. Opcionalmente, se pueden utilizar los cualificadores de dirección "src" y/o "dst" y los de protocolo "tcp" y "udp" si se está interesado únicamente en los puertos de origen o de destino, o en los paquetes de TCP o UDP, respectivamente. Si no se especifican, los paquetes se seleccionarán para los protocolos TCP y UDP y cuando la dirección especificada aparezca en el campo del puerto de origen o de destino. Por ejemplo: port 53 (captura sólo el tráfico DNS). 
  •   less/reater <longitud>: Permite filtrar paquetes cuya longitud es menor o igual (o mayor o o igual) a la dada.
  •   ip/ether proto <protocolo>: Permite filtrar en un protocolo determinado tanto en la capa de Ethernet como en la de la IP. Por ejemplo: ether proto 0x888e (captura sólo el Ethernet de tipo EAPOL).
  •   ether/ip broadcast/multicast: Permite filtrar en difusión amplia o en multidifusión tanto en Ethernet como en IP.
  •   <expresión> relop <expresión>: Permite crear expresiones de filtro complejas que seleccionan bytes, o rangos de bytes, en paquetes.
  Puede verse una lista de primitivos más exhaustiva (en inglés) en el siguiente enlace.
  Una de las funciones principales de Wireshark es comprobar redes para poder detectar intrusiones y otros problemas, por lo que los filtros de captura específicos para estos fines suelen ser muy útiles. Así, por ejemplo, está el filtro que detecta al gusano Blaster (dst port 135 and tcp port 135 and ip[2:2]==48), el que detecta al gusano Welchia (icmp[icmptype]==icmp-echo and ip[2:2]==92 and icmp[8:4]==0xAAAAAAAA), uno genérico para gusanos maliciosos (dst port 135 or dst port 445 or dst port 1433  and tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) = 0 and src net <rango de direcciones IP de la red>), o el que detecta la vulnerabilidad Heartbleed (tcp src port 443 and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4] = 0x18) and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4 + 1] = 0x03) and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4 + 2] < 0x04) and ((ip[2:2] - 4 * (ip[0] & 0x0F)  - 4 * ((tcp[12] & 0xF0) >> 4) > 69))).
  En las siguientes imágenes puede verse un ejemplo del uso de este tipo de filtros:
Se introduce el filtro de captura en el lugar indicado antes de comenzar la captura de paquetes
Se selecciona la red donde se va a capturar y se pulsa en el botón "Start".
El programa mostrará un resultado como el siguiente.

  También es posible realizar análisis en remoto, transportando el contenido remoto por la red, lo que añade nuevos paquetes poco importantes a los que interesan al usuario. Para evitar esto, Wireshark intenta averiguar si está conectado de forma remota (observando algunas variables del entorno específicas) y crea automáticamente un filtro de captura que coincide con aspectos de la conexión.
  Las variables del entorno que suelen emplear son:
  •   SSH_CONNECTION: Para conexiones remotas por SSH. Su sintaxis es: <IP remota> <puerto remoto> <IP local> <puerto local>.  El filtro resultante sería: not (tcp port srcport and addr_family host srchost and tcp port dstport and addr_family host dsthost).
  •   SSH_CLIENT: Para conexiones remotas por SSH. Su sintaxis es: <IP remota> <puerto remoto> <puerto local>. El filtro resultante sería: not (tcp port srcport and addr_family host srchost and tcp port dstport).
  •   REMOTEHOST: Para conexiones remotas de tcsh y otras. Su sintaxis es: <nombre de remoto>. El filtro resultante sería: not addr_family host host.
  •   DISPLAY: Para conexiones remotas mediante x11. Su sintaxis es: [nombre del remoto]:<nº de display>. El filtro resultante sería: not addr_family host host.
  •   SESSIONNAME: Para conexiones remotas desde terminal de servidor. Su sintaxis es: <nombre del remoto>. El filtro resultante sería: not tcp port 3389.

FILTROS DE VISUALIZACIÓN

    El lenguaje para filtros de visualización de Wireshark pretende permitir al usuario controlar los paquetes que se muestran en la captura. Este tipo de filtros se pueden emplear para buscar un protocolo o un campo determinados, el valor de un campo, o la comparación de dos o más campos entre sí (en este último uso se pueden combinar las comparaciones mediante el uso de operadores lógicos, y paréntesis en expresiones complejas).
  En este caso, la sintaxis del filtro sería:
<protocolo de filtro de visualización>[<operador de comparación><valor de comparación>] [<operador lógico>] [expresión2]...

  Como se puede apreciar en la sintaxis, el filtro más simple que se puede emplear es escribir únicamente un protocolo de filtro de visualización. Entre los protocolos de este tipo más utilizados se encuentran:
  •   tcp.port[<operador de comparación><valor de comparación>]: Muestra sólo el tráfico de ese puerto de red. Este protocolo busca tanto en las direcciones del origen como en las de destino del puerto designado. Por ejemplo: tcp.port eq 25 (muestra sólo el tráfico de SMTP).   
  •   ip.addr[<operador de comparación><valor de comparación>]: Muestra el tráfico de esa dirección IP. Este protocolo busca tanto en las direcciones del origen como en las de destino de la dirección IP indicada. Por ejemplo: ip.addr==10.43.54.65 (muestra sólo el tráfico de la dirección IP 10.43.54.65).
  •   eth.addr[<operador de comparación><valor de comparación>]: Muestra el tráfico que pasa por la dirección MAC asignada (se obtiene el mismo resultado cambiando el inicio del filtro por "mac.addr"). Este protocolo busca tanto en las direcciones del origen como en las de destino de la dirección MAC determinada. Por ejemplo: eth.addr==00:50:56:AA:87:BC.
  •   ip.src==<red> and ip.dst==<red>: Muestra el tráfico de una red LAN, es decir, el que hay entre las estaciones de trabajo y los servidores de una red interna.
  •   ls_ads.opnum==0x09: Detecta el gusano Sasser, que afecta a ordenadores que funcionan con versiones vulnerables de Windows XP y Windows 2000, siendo su síntoma más popular el que el sistema muestre un contador de reinicio forzado.
  Se puede consultar una lista de protocolos de filtros de visualización más completa (en inglés) en el siguiente enlace, y una  completa lista de protocolos de red (en inglés) a los que se les puede aplicar dichos filtros en este otro; aunque también se puede ver una lista de estos últimos protocolos siguiendo la ruta "View > Internals > Supported Protocols" (o "Internals > Supported Protocols (slow!)", en versiones más antiguas del programa) en el menú principal del programa.

  Junto a los protocolos de filtro de visualización (o como parte de estos, según se mire), se encuentran los operadores de comparación, que permiten crear filtros que comparan valores, lo que los hacen más precisos. Estos operadores pueden expresarse en inglés o en lenguaje de programación similar al C, pudiendo combinarse ambos en un mismo filtro. La lista de operadores de comparación se muestra en la tabla siguiente:
InglésProgramaciónDescripción
eq==   Igual.
ne!=  No igual.
gt >  Mayor que.
lt<  Menor que.
ge>=  Mayor que o igual a.
le<=  Menor que o igual a.
contains
  Protocolo, campo o parte que contiene un valor.
matches~  Protocolo o campo de texto que iguala a una expresión regular compatible con Perl.
bitwise_and&  Bit a bit y que no es 0.

  Sin embargo, el operador "!=" tiene un defecto cuando se emplea en expresiones combinadas como "eth.addr", "ip.addr", "tcp.port", y "udp.port", y es que puede dar lugar al error ""!=" may have unexpected results". Para evitar este error, cuando se pretendan filtrar paquetes de datos que no contengan el valor especificado en la expresión, se debe utilizar el filtro "!(<expresión>)" [por ejemplo: !(ip.addr == 1.2.3.4) (muestra paquetes que no se encuentran ni en el origen ni en el destino de esa dirección IP)].
  Todos los campos de protocolo tienen un tipo de valor, que muchas veces coincide con un tipo de dato propio de cualquier lenguaje de programación. De este modo existen el booleano, el entero, el flotante y la cadena de texto (que distingue entre mayúsculas y minúsculas), pero también otros más específicos de la red como:
  •   Dirección MAC (o Ethernet): 6 bytes separados entre sí por un signo de dos puntos (":"), un punto ("."), o un guión ("-"), con uno o dos bytes entre separadores.
  •   Dirección IPv4: Normalmente se emplea este tipo de valor para probar si una dirección IPv4 determinada se encuentra en una subred concreta. El valor puede ser sólo la dirección IP (129.111.0.0), o bien la dirección IP con su correspondiente prefijo CIDR (129.111.0.0/16).
  •   Dirección IPv6: Se utiliza con la misma finalidad que la anterior.
  Como se ha comentado más arriba, es posible combinar expresiones para crear filtros de visualización más exactos, para lo cual se deben emplear operadores lógicos. Al igual que sucedía con los operadores de comparación, los operadores lógicos pueden expresarse mediante su expresión en inglés (o su acortamiento), o mediante su expresión de lenguaje de programación similar al lenguaje informático C. La siguiente tabla muestra la lista de operadores lógicos útiles para los filtros de visualización:

InglésProgramaciónDescripción
and&&   Y (AND) lógico.
or||  O (OR) lógico.
xor ^^  XOR lógico.
not!  NO (NOT) lógico.

[...]  Subsecuencia.
in
  Establecer membresía.

  Creando subsecuencias es posible precisar el resultado del filtro de visualización. Esta subsecuencia se establece mediante el llamado operador de corte, que consiste en delimitar uno o más rangos de valores entre dos corchetes, separando cada rango por coma si son más de uno (por ejemplo: eth.src[0:3,1-2,:4,4:,2] == 00:00:83:00:83:00:00:83:00:20:20:83). Dentro de los corchetes se pueden utilizar los siguientes formatos:
  •   A:B: Especifica un rango simple. "A" es el punto de origen y "B" es la longitud del rango. Por ejemplo: eth.src[0:3] == 00:00:83.
  •   A-B: Especifica un rango simple, donde "A" es el punto de origen y "B" el punto final. Por ejemplo: eth.src[1-2] == 00:83.
  •   :B: Toma todo desde el comienzo de una secuencia hasta lo determinado por "B". Por ejemplo: eth.src[:4] == 00:00:83:00.
  •   A:: Toma todo lo determinado por "A" hasta el final de una secuencia. Por ejemplo: eth.src[4:] == 20:20.
  •   A: Especifica un rango simple en el que se selecciona el elemento en la secuencia determinado por "A". Por ejemplo: eth.src[2] == 83.
  Por otra parte, es posible crear un campo de membresía introduciendo un grupo de valores o de campos en un operador de membresía, representado por llaves ("{...}"). La sintaxis sería: <protocolo de filtro de visualización> in {<grupo de valores o de campos>}. Por ejemplo: tcp.port in {80 443 8080} (muestra los paquetes TCP cuyo origen o destino son los puertos 80, 443, y 8080).

  Otro servicio que permite el lenguaje de los filtros de visualización es la de la conversión de tipos de datos en los valores de los campos, para lo que Wireshark posee las funciones de la siguiente tabla:

FunciónDescripción
upper   Convierte la cadena de un campo en mayúsculas.
lower  Convierte la cadena de un campo en minúsculas.
len   Devuelve la longitud de bytes de una cadena o campo de bytes.
count  Devuelve el nº de apariciones del campo en un marco.
string  Transforma un campo que no es de cadena en cadena.

  Mientras que las dos primeras funciones pueden usarse, entre otras cosas, para obtener resultados que no diferencien entre mayúsculas y minúsculas (por ejemplo: lower(http.server) contains "apache"), la tercera es muy útil para localizar peticiones HTTP con largas peticiones URIs (por ejemplo: len(http.request.uri) > 100),  aunque entrega la longitud de la cadena en Bytes y no en caracteres; por su parte, la cuarta función suele emplearse para encontrar paquetes con direcciones extra cuando existen errores ICMP o de tunelaje en un marco IP (por ejemplo: count(ip.addr) > 2), mientras que la quinta, adecuada para utilizar con operadores como "matches" y "contains", hace que los enteros se transformen en su representación decimal, y puede ser utilizada con direcciones IP o MAC (y algunas otras), mas no con campos de cadenas o de bytes {por ejemplo: string(ip.dst) matches "^172\.(1[6-9]|2[0-9]|3[0-1])\..{1,3}\.255" [empareja las direcciones IP que terminan en 255 en un bloque de subredes (172.16 a 172.31)]}.
  Por último, también se debe tener en cuenta que, debido a la propia evolución de la Informática, los protocolos y estándares suelen ser renombrados en numerosas ocasiones. En estos casos, aunque Wireshark suele emplear en sus campos y protocolos la nomenclatura antigua durante algunas versiones posteriores a su desaparición, suele mostrar un aviso indicando la obsolescencia del término a extinguir y que no asegura que en futuras versiones sea viable.
  A continuación se muestra un ejemplo visual (en varias imágenes) del empleo de este tipo de filtros:
Se escribe el filtro de visualización en la caja adecuada (puede ser antes de comenzar la captura o durante la misma).
Se selecciona la red donde se realizará la captura y se pulsará en el botón de "Start" (sólo si se utiliza el filtro antes de comenzar la misma; en caso contrario, se pulsará en la tecla "introducir" del teclado o en el botón correspondiente en esa parte del programa).
Wireshark mostrará un resultado como el siguiente.

  Aguardo que la presente entrada haya sido del gusto del lector. De ser así, espero que éste la comente y/o la comparta, por favor.
  

No hay comentarios:

Publicar un comentario

Deje aquí su comentario, si no puede comentar, pruebe a hacerlo desde otro navegador de red u otro equipo.