Wireshark Dissector Tutorial (Practical Examples)
Wireshark Dissector Tutorial (Practical Examples)
Wireshark dissectors can be useful when you are working with a custom protocol that Wireshark doesn’t already have a
dissector for. I will create a dissector for the following payload (the data).
The first 3 packets belong to the TCP 3-way handshaking. After the TCP connection has established, the client sends some
data that Wireshark’s dissectors do not understand in packet number 4.
We will create a simple protocol and write a dissector for it. The protocol is based on a request and response. With this
protocol a client can ask the server if the service on the server is up or not. The server responses back, informing the
service is up or down.
For sake of simplicity, we will create 2 bytes protocol, which will be working in client and server architecture. The client will
be able to query the service status on the server. The server will response the client with a relevant answer. The first byte
is used to distinguish whether the message type is a "question" or an "answer". The second byte will be used for the
content of the "answer" or the "question".
ALSO READ: Troubleshooting TLS Failures using Wireshark
For example:
When the first byte is 0x01, it means the client is questioning the server.
1. 1. When the second byte is 0x01, it means the client is asking if the service up or not.
2. When the second byte is other than 0x01, it means the client is asking some other question.
When the first byte is 0x02, it means the server is answering the client.
1. 1. When the second byte is 0x01, it means "Yes, the service is up"
2. When the second byte is 0x02, it means "No, the service is down"
3. When the second byte is other than 0x01 and 0x02, it means the answer is something else.
There are dissectors that run after all the other dissectors have run, giving the programmer access to fields defined in
other dissectors. These are referred to as post-dissectors
A chained dissector is similar to the post-dissector in that it runs after other dissectors so that you can access the fields
for other dissectors.
ALSO READ: 16 Linux ip command examples to configure network interfaces (cheatsheet)
The difference is that a chained dissector doesn't run against every packet, only those packets that are handled by the
dissector off of which you are chaining. Chained dissectors are handy for extending an existing dissector without having to
rewrite it completely, whereas post-dissectors are useful for adding a new dissector that provides additional context based
on what other fields are set.
This is a very common method used. Wireshark has a Lua implementation that makes it easy for people who are
unfamiliar with C to write dissectors. Lua is a scripting language in that Lua code is read from a plain text script/source file
and then executed by the Lua interpreter—a compiled executable itself—dynamically at runtime. Another word for scripting
language is interpreted or managed language. Because the code is interpreted at runtime, and generally all memory
access is managed by the runtime, Lua, in this case, is the interpreter.
ALSO READ: Kerberos Authentication Packet Analysis with Wireshark
Step-1: Declare the protocol. My protocol short name (display filter name) will be "ulive.lua". The long name in the
protocol tree will be "Service State Protocol".
ulive_protocol = Proto("ulive", "Service State Protocol")
Step-2: Declare the fields with their types. We will have 3 fields which are:
msg_type =ProtoField.uint8("ulive.MessageType","MessageType",base.DEC)
question_type =ProtoField.uint8("ulive.Question","Question",base.DEC)
answer_type =ProtoField.uint8("ulive.Answer","Answer",base.DEC)
The dissector must register its data fields with Wireshark so that Wireshark knows how to display them. If you do not
register the fields, you will get the error above.
buffer: It is the data on the top of TCP. The dissector will walk through the buffer of bytes.
pinfo: It contains the data about the packet.
tree: The tree on which we append our subtree.
ALSO READ: Analyze TCP Receive Window with Wireshark [Step-by-Step]
Step-5: Specify which port and protocol will ve used. I will use TCP and and port 12345. When Wireshark come across a
packet with these parameters, it will use my dissector.
local tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(12345,ulive_protocol)
port = 12345
try:
host_ip = socket.gethostbyname('192.168.1.5') # server ip address or host name
except socket.gaierror:
# it fails to resolve the host name
print("there has been an error resolving the host")
sys.exit()
s.connect((host_ip, port))
s.send(bytes.fromhex(MESSAGE1)) # it will test MESSAGE1
s.close()
while True:
c, addr = s.accept()
print('Got connection from', addr)
#data = c.recv(1024)
c.send(bytes.fromhex(MESSAGE4))
c.close()
Step-2: A window appears, then click "Folder" tab and you will see a list of paths. Click on "Personal Lua Plugins". If you
have not created the directory before, click "Yes" button to create the directory.
Step-3: Reload your Wireshark to activate the dissector, then open packets you captured or my packets below. You should
see something like below.
Final thoughts
Wireshark may not dissect a proprietary protocol if you use one of them in your enterprise. With help of Lua, you can
create your own dissector and easily integrate it with Wireshark.
Further Reading
Dissectors