Advanced Filtering Techniques in Wireshark

The Wireshark system accesses the network through pcap (libpcap and Winpcap). Rather than providing the packet collection service and the data analysis function as two separate units, Wireshark integrates the pcap service into the main Wireshark system. This means that the utilities of Wireshark can be applied at the data collection interface of the Wireshark filtering language that was designed to analyze displayed packets in the Wireshark data viewer.

Why filter packets?

When you start reading network packets from the networks, all of that data gets held in memory. Ultimately, those packets can be stored to a file. You are not going to need to see all of those packets and so the Wireshark system will gather many, many packets that don’t interest you.

Shifting packet filtering from the data viewer to the packet capture system greatly reduces the amount of data that you end up having to hold. You can reduce collection to only those packets that are going to be of use.

Capture filters and display filters have different syntaxes. There are more conditions available for display filters than for capture filters. The two filtering systems are unique to Wireshark.

Capture filters

Capture filters limit the packages that are collected by pcap. They can greatly reduce the number of packages that are read into Wireshark. Applying a capture filter doesn’t block the option to also apply a display filter. However, display filters can be removed/reversed but capture filters cannot.

The capture filter field is located around the middle of the Wireshark Home screen.

Capture filters

Display filters

Display filters operate on the records that have been captured and are currently loaded into the data viewer of Wireshark. It is possible to save a display filter and apply it repeatedly by recalling it. You can delete all or part of a display filter and rewrite it. Like capture filters, display filters can be composite conditions, joined together by Boolean operators.

The display filter field is just about the packet display panel in the data explorer screen.

Display filters

Capture filter syntax

Capture filters focus on limiting traffic that is read into the Wireshark system for analysis.

Evaluation operators

An evaluation will cause a packet to be captured if its result is true and ignored if it is false. The operator can be >, <, >=, <=, =, or !=.

Evaluations are performed in C syntax. The expression on either side of the operator can be a constant or an arithmetic expression. These can include:

  • Arithmetic operators: + (plus), – (minus), * (multiply), / (divide), % (modulo), ++ (increment), and – (decrement)
  • Bitwise operators: & (and), | (or), ^ (xor), << (left shift), and >> (right shift)

Evaluations can be combined and manipulated by using logical operators, each of which has two formats:

  • NOT: !, not
  • AND: &&, and
  • OR: ||, or
  • XOR: ^^, xor

IP address filters

A capture filter can be as simple as one keyword. For example, it is possible to limit capture to just IPv4 traffic and remove transactions for lower-layer tasks, such as ARP queries, by using the filter:

ip

If you are using IPv6, you would filter with:

ip6

It is possible to specify whether you want all traffic to and from a particular node,

host 192.168.75.1

only the traffic where that address is the source,

src 192.168.75.1

or only the traffic where that address is the destination.

dst 192.168.75.1

A single clause can relate to a range of IP addresses with two notation options:

net 192.168.0.0/24

net 192.168.0.0 mask 255.255.255.0

By using the Boolean operators not, and, and, or, you can quickly build up precise targets for a capture session. Use combinations of ranges and individual addresses

src net 192.168.0.0/24 and not dst 172.75.5.1 or broadcast

Use brackets to make the application of operators clearer – even where they are not syntactically necessary.

src net 192.168.0.0/24 and ((not dst 172.75.5.1) or broadcast)

src net 192.168.0.0/24 and(not(dst 172.75.5.1 or broadcast))

The keywords broadcast and multicast are available to pick up those types of traffic.

If you are scanning for packets from a remote location that has an associated domain name, you can use that domain as a filter:

host www.comparitech.com

Examining packet contents

It is possible to specify which byte of a header should be examined. This is a number that is included in square brackets after the name of the protocol to be examined, so when dealing with IP packets, that protocol is ip. An IP packet header is usually 20 or 24 bytes long. Specify a particular byte. The first byte is number 0, so to get to the eighth byte, you would use

ip[8]

You can see the layout of an IP packet header in RFC 791.

An alternative syntax for this byte isolation expression gives two values separated by a colon. This tells the packet scanner to start at the byte position specified in the first number and extract multiple bytes, the total quantity of which is given by the second value:

ip[10:2]

This extracts the IP packet’s header checksum.

Many header fields occupy less space than a full byte and so are combined within a byte; others are composed of inner elements that provide meaningful information. In order to access these elements, you have to use a bit mask.

A bit mask needs to be a full byte with ones in the place of the bytes that you want to get rid of and zeros in the positions of the bits that you want to examine. So:

11111100

will leave you with the last two bits in the byte.

The bit mask has to be “ANDed” with the source byte to isolate the required bits.

Port filters

You can reduce your packet capture to specific protocols/applications by specifying port filters.

You can limit packet capture to just packets with TCP or UDP ports:

tcp

or

udp

There is also an icmp filter that will just give you Internet Control Message Protocol traffic, namely, Ping.

The tcp and udp filters can be used on their own, in conjunction with IP filters:

host 192.168.75.1 and tcp

or to specify which transport protocol should be examined for a specific port:

tcp port 135

It is possible to just view Web traffic by looking for HTTP or HTTPS

port 80 or port 443 or port 8080

A nice trick for examining plain text protocol traffic is to examine the character within each packet and filter on those. In this technique, you need to convert the character that you are looking for into the hexadecimal ASCII code. The following filter achieves this specification:

port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420

This filter is very sophisticated. It looks at the packet header in hexadecimal and only extracts those that have “47455420” which is hexadecimal for “GET “.

You can see the layout of a TCP header in RFC 791. The portrange keyword lets you specify a series of ports:

portrange 1417-1420

Entering a capture filter

The Capture Filter field includes an autocomplete function.

Entering a capture filter

This generates a list of possible subsequent keywords, and you can speed up the capture process by clicking on an entry in the list instead of continuing to type. The autocomplete is fine if you are just entering a standard filter, but it won’t help you if you are trying complicated formulas, such as bitwise examinations.

Display filter syntax

The Display filters operate on data that has already been read in from the network. Once you stop a capture, the Wireshark system automatically stores all captured packets to a file, while also making them available in the packet viewer screen.

As can be seen in the autocomplete example below, the filter keywords are presented as functions in packages, making it a much more formalized language than the Capture Filter system.

Wireshark display filter syntax

There are a few differences in the language for the display filter than that used for the capture filters.  Probably the most fundamental difference that often trips people up are the evaluation operators. In the display filters, these are:

  • Equals: eq or ==
  • Not equals: ne or !=
  • Greater than: gt or >
  • Less than: lt or <
  • Greater than or equal to: ge or >=
  • Less than or equal to: le or <=

We’re not going to go over all the important commands in the display filter language of Wireshark because there are too many commands. You can access the official Wireshark Reference Guide to explore all the possible functions and values in the Wireshark Display Filter library. The autocomplete function will help you to keep your filter statements syntactically correct.

Partial and multiple matches

The display filters of Wireshark include two more evaluation operators that can be used to seek for partial matches, these are:

  • contains
  • matches

These two operators remove the need for wildcards. You can also concatenate conditions if you have character matches that do not need to be immediately adjacent. However, you need to be careful not to make seek terms too short, otherwise you won’t filter out many packets. Here are some examples:

http.host contains “bigsite”

http.host matches “bigsite\\.(com|org|biz)”

Both of these filters would match with bigsite.com, bigsite.org, and bigsite.biz. However, the contains option would match with a much wider range of domain names, such as averybigsite.com and bigsite.net.

Where you want to match all of a field’s value but with a number of possible values, you could use the set specification, “in.”

This lets you create a list of values to match to. The format for a list of items uses braces ({}) to contain the list; elements are separated by commas (,). Here is an example:

http.request.method in {"HEAD", "GET"}

Numeric values can be entered as a range and a set can include a mix of ranges and individual items. For example:

ip.addr in {192.168.10.1..192.168.10.9, 142.250.179.238}

Matching values can sometimes fail when the native data types of the two values are different. It is possible to look up the data type of some fields and many data types, such as port numbers, can be guessed. In order to ensure the packet field that you want to filter on is the same type as the constant you write for the match. You can just force the type by converting it to the type you use for the constant.

Functions that you can use for this purpose include:

  • string – converts a non-string field to a string
  • vals – converts a field value to its value string
  • dec – converts an unsigned integer field to a decimal string
  • hex – Converts an unsigned integer field to a hexadecimal number

Matches can also be made simpler by manipulating fields in packets before a test is applied. These functions include:

  • upper – converts all characters in a string to uppercase
  • lower – converts all characters in a string to lowercase
  • abs – Removes the polarity of a number

Other functions can provide a single value from a group of records. For example, you could find the highest value of a particular field in all packets. There are also functions that provide statistics about a value. The functions in this division are:

  • count – the number of packets that match a given pattern
  • len – the byte length of a string or bytes field
  • max – the maximum value from all packets in a specified field that match a given pattern
  • min – the maximum value from all packets in a specified field that match a given pattern

Assembling advanced filters

Keep in mind that you can always combine conditions in one filter. If your searches don’t work, check the data type of the field that you are filtering on and make sure that the constant you give for a match is of the same type.