Wireshark
A popular tool to analyze and extract data from network packet captures
Last updated
A popular tool to analyze and extract data from network packet captures
Last updated
Wireshark is a GUI tool to analyze network packet captures. You can open .pcap
or .pcapng
files in the program and use filters to find specific packets. You can also use it to capture packets yourself from a certain interface, which could be really useful for debugging networking-related issues. It allows you to see exactly what packets are being sent.
You can capture packets in Linux using tcpdump
:
When in Wireshark, you see a list of all the packets on the top and detailed information about the contents of a packet on the bottom. Click on a packet at the top to analyze it at the bottom.
In the list of packets, the Info columns can be really useful. To quickly see what a packet is about, you can read a summary in that column.
To practice analyzing specific protocols, you can use some example captures that Wireshark gives to see how it works yourself.
tshark
is a command-line version of Wireshark that can make it easy to extract data from a capture. Often you're working in Wireshark, and then use TShark to get specific data that needs to be scripted.
The output of TShark can easily be used by other tools to analyze further.
-r
: File to read packets from (.pcap
)
-Y [filter]
: #filters to apply
-T fields
: Display only selected fields
-e [field]
: Field name to display (can be specified multiple times)
-E separator=,
: Separate fields with a comma
-E quote=d
: Surround fields with double-quotes
This field name can be found in Wireshark. Simply find a packet with the information you want to extract, select it by clicking on it, and then look on the bottom bar. It will show the field name in between the ()
brackets. You can also directly copy it by right-clicking, and going to Copy -> Field Name.
When you get a packet capture, it might only contain a few packets that you can look at yourself. But more often, you get a capture over a larger timeframe with lots of packets and different protocols. That is where you can use the statistics tools built into Wireshark to get a general idea of the capture.
All of this happens in the Statistics menu on the top bar:
One useful option is Protocol Hierarchy. It shows a list of all the protocols it finds in the capture, and how often they come up. In the following example, you can see NTP, DNS, TLS, and HTTP. You can also see that almost all packets are plain TCP:
Two other useful options are Conversations and Endpoints. First, the conversations show the communication between two endpoints, showing the number of packets, and much more detailed information. This is useful to find interesting conversations if you know an IP address for example. These endpoints are the from and to addresses of these conversations and show what parties were involved in the capture.
All of these menus can help give an initial idea of the capture, to get an idea of what to look at next.
Captures often contain a lot of packets, and of various types. That is why there is a display filter in Wireshark that you can use to only match certain types of packets. Just type the filter into the search bar to only see packets that match it:
You can find all the documentation about the syntax of these filters on the Official Wireshark Wiki page. Most of the time you start with a protocol, and add .
dots to get more specific.
Boolean operations like ==
(equals), !=
(not equals), &&
(and), ||
(or) work as well, allowing you to combine multiple filters together.
These filters are also really useful for looking at specific protocols, like for HTTP you can use just http
, or for Modbus you can use modbus
.
Tip: Wireshark allows you to add comments to captures, which may contain interesting information. Search for comments using the pkt_comment
filter, then you'll see the comments in the details of the packet (lime green)
Without knowing all the names of filters, you can also easily filter some properties by right-clicking on it in the packet details and selecting Apply as Filer. Then you can choose to include/exclude this specific value.
One last thing you might run into is the fact that you can't filter the Protocol or Info columns in the list of packets. This can be useful to quickly search in the Info column, and there is a Plugin for Wireshark that adds this called filtcols. Just install it and then you can use filtcols.protocol
and filtcols.info
as strings in the display filter.
There are lots of protocols that Wireshark automatically recognizes and gives information about. You can also extract information from some protocols, which is often a bit more work. Here are some common protocols and what you can do with them.
Filter: tcp
Lots of protocols use TCP as a base, and some protocols aren't recognized by Wireshark. That is why it's so useful to be able to look at TCP and find out exactly what the packet contains.
TCP works in streams. As packets often have a maximum size of about 1500 bytes, these streams have to be split into different packets. When having a packet selected, Wireshark can combine the packets together by following the stream, using the Analyze -> Follow -> TCP Stream menu (Ctrl+Shift+Alt+T). By default this will show the data as ASCII (readable text), but you can change it with the "Show data as" dropdown on the bottom.
This same Follow Stream option is very useful for extracting the raw packet data into some other place. Using the "Show data as Raw" option, you'll see the hex values of the data bytes, which you can decode from hex later to get the raw bytes.
Filter: http
HTTP is the communication that websites use. Normally encryption by HTTPS makes this not readable in a packet capture, but when the packets can be decrypted they turn into HTTP. It is built on TCP, meaning you can use the Follow TCP Stream menu to read the data going back and forth.
The basics of HTTP are pretty simple. A client sends a request to a server, which then sends back a response.
The first word in a request is the method. Commonly this includes GET
, POST
, HEAD
, DELETE
, PUT
and PATCH
. The GET
method is used to simply get some content, and POST
for sending data to the server that should do some action.
Then comes the path. This is the URL that is requested from the host. In some GET requests, this can also contain URL parameters like ?id=1
.
Then there are some headers, notably the Host
header which specifies what website the request was sent to. The User-Agent also gives some information about what browser/program made the request.
POST
requests often have a body with some content that is sent to the server. These are separated by &
characters, and the key-value pairs are separated by an =
equals sign.
The response gives the content that is displayed back in the browser. It first shows a status code that tells the browser some information, like if there was an error, or what kind of response it is.
Then come the response headers. One notable header is the Content-Type
, this says what format the response is in. For websites, this is often HTML. But other things like JSON or files can be specified here. The Set-Cookie
header can also set the Cookie
header for the next request. This is often used for authentication.
Lastly, there is the response data. In some cases, this is not directly readable because of some compression (seen by lots of .
dots instead of readable text). In this case, you can show the data as Raw and decode it from hex, to then decompress it with whatever method it was compressed (the Content-Type
header can help with this).
HTTP can also be used to download files from websites. These can also be found while looking through the HTTP packets, but you can also let Wireshark look for HTTP downloads and export them as files to analyze yourself. You can get a list of Objects by going to File -> Export Objects -> HTTP. In this list, you can select any file that looks interesting or Save All.
Filter: dns
DNS is very commonly found in packet captures because almost everything uses domain names nowadays. DNS can give away some information about what domains were visited if you have encrypted HTTPS traffic for example.
DNS can also be used by attackers to exfiltrate data. Sometimes HTTP or other ways of sending data are detected or not available, which is why you can use DNS to send small bits of information. Domain names can be a total of 253 characters long, and the parts between the .
dots are only 63 characters each. An attacker can set up NS records on their domain so that any *.attacker.com
domain is asked to a server of the attacker. This way, the attacker can let the client make a DNS request to secret.attacker.com
in order to leak the string "secret" to the attacker via DNS.
This is often done using Base32, an encoding that encodes any bytes to a longer string of 32 characters. This encoded string is then placed in front of an attacker's domain so that they get the encoded string exfiltrated over DNS, which they can later decode.
To filter and find all domain names you can use the TShark command-line program. With -r
you can specify a file, then a display filter with -Y
, and finally with -T fields
and -e
you can select specific fields to display:
Then you have all the DNS requests that were done in the capture. You can manually filter out the requests that look like DNS exfiltration (Grep can help). And then decode them from Base32 to get the data (or whatever encoding/encryption the malware used).
An attacker may also want to send commands/code to the victim to execute. It is also possible to request data via DNS, as this is the point of DNS. Some records like TXT records can contain larger chunks of text to be requested. TXT records aren't often seen in normal packet captures, so you should definitely look at them when they are in the capture.
Similarly to the Data Exfiltration, we can use TShark to extract all the TXT records from the capture. This time with the dns.txt
field:
Wireshark can also capture communication of USB devices. A USB keyboard for example sends lots of URB_INTERRUPT in
packets (see image).
You can extract the raw data using TShark:
Then you have the data in keystrokes.txt
, and you can use a tool like ctf-usb-keyboard-parser to decode the keystrokes to text.
Note: In the @carlospolop fork of this script backspaces are shown as ⌫
, but in the original, they actually remove the previous character. It might be useful to see the data that was removed with backspace so I suggest using the @carlospolop fork as linked above
Filter: modbus
Modbus is a protocol that has a few different versions. There is Modbus RTU (Remote Terminal Unit) which is used in serial communication. There is also the ASCII variant that also works on serial, and finally, Modbus TCP which goes over TCP (default: port 502). It is commonly used in industrial electronics to read and write simple values. You may find traffic like this in a network capture allowing you to see exactly what data is queried and returned. There are a few different data types it uses:
Coil
Read-write
1 bit
00001 – 09999
Discrete input
Read-only
1 bit
10001 – 19999
Input register
Read-only
16 bits
30001 – 39999
Holding register
Read-write
16 bits
40001 – 49999
These registers can contain numbers from 0-65535, and can be queried (function codes 3 & 4). The response may contain interesting values to look at. You can use TShark to extract the holding register numbers and values (change func_code
to 4
for input registers):
These can sometimes contain strings encoded in decimal, be sure to try and decode them in a CyberChef recipe.
HTTPS traffic is encrypted using Transport Layer Security (TLS). This means a normal packet capture cannot read the data being sent.
To decrypt this data you require a key. This can be the RSA private key of the website, starting with -----BEGIN PRIVATE KEY-----
, or using per-session key log files ((Pre)-Master Secret).
When you now click OK you will see the decrypted traffic like HTTP requests in your list of packets (filter http
). The raw data will still be the encrypted SSL/TLS data, so instead of following the TCP stream just look at the packet details on the bottom when selecting a packet.
The SSLKEYLOGFILE
environment variable can be set to a filename where browsers will log all the SSL keys used. You may find this file somewhere allowing you to use it to decrypt all the traffic made from that browser. The contents of the file should look something like this:
Putting this in Wireshark goes similar to the RSA keys, just go to Edit -> Preferences -> Protocols -> TLS and select the (Pre)-Master-Secret log filename. When you click on OK the packets will be decrypted again and you can view the real data.
You can capture Wifi traffic all around you using a network card that supports monitoring mode. When a Wifi network requires a password to connect to, all the traffic is encrypted. In Wireshark, this encrypted data looks like packets with the protocol 802.11, and "Data" in the info column. You'll be able to see what MAC addresses the communication is between, but not what the data is.
To decrypt this data you need the key/password of the Wifi network. There are a few different types of encryption for Wifi:
WEP: A hexadecimal key used for all traffic. The first standard, and pretty easy to crack with brute force (example: a1:b2:c3:d4:e5
)
WPA/WPA2: A password/SSID combination, with a different encryption key for each connected device (example: MyPassword:MySSID
)
WPA-PSK: WPA with a Pre-Shared Key. 64 bytes in hex (example: 01020304...61626364
)
When you have found a WEP key (eg. by cracking it), you can instantly decrypt all the traffic from anyone.
But a WPA key is unique for all connected devices. To be able to decrypt WPA traffic, you need the EAPOL handshake for that device. This handshake is done when you authenticate with the network, so every time you connect. If you're lucky the capture contains the moment when the device connects meaning you have this EAPOL handshake. It consists of 4 parts, and all 4 need to be included to decrypt the traffic. You can filter for eapol
to find if you have parts 1-4:
First choose the Key type, and then put the key into the Key field in the hex format for WEP, or the MyPassword:MySSID
format for WPA (you can find the SSID with the wlan.ssid
filter). Finally, click OK when your password is set.
wep
0102030405060708090a0b0c0d
wpa-pwd
MyPassword:MySSID
wpa-pwd
MyPassword
wpa-psk
a66e97b9a1008a97285c7ec2b95082bed3541d3dd01165b0128f7f3c18563797
You should now see some encrypted traffic turn into normal traffic, like TCP and UDP. To be sure you can use the filtcols.protocol != "802.11"
filter to only show normal traffic.
<- Conversations
<- Endpoints
This view can give a quick idea of what readable text is contained in the packets. You can also cycle through all the streams in the whole capture using the number on the right. If there aren't too many TCP streams, this can quickly show you the contents of the packets and what readable text they contain. Protocols like HTTP or SMTP work completely in readable text, so they should be very easily findable with this technique.
To decrypt data when you have the key go to Edit -> Preferences -> Protocols -> TLS and click Edit by the RSA keys list. Here you can click the icon to add an entry containing the IP address and port of the target website (you can find this in the SSL/TLS packets), and the protocol, which will be http
for HTTPS. Finally the path to the file containing the RSA key.
To then actually decrypt the traffic using the network key/password, go to Edit -> Preferences -> Protocols -> IEEE 802.11 and click Edit by the Decryption keys. Here you can click the icon to add a key.