This post will explain how you can easily create protocol dissectorsin Wireshark, using the Lua programming language. This is can be useful when you’re working witha custom protocol that Wireshark doesn’t already have a dissector for. If Wireshark looks likethis for example
- How To Change Level Lua Chart
- C++ - Pushing A Lua Table - Stack Overflow
- When You Call Lua_next , The Second Argument Should Be The Index Of The Table. Since You're Just Pushing The Table Onto The Stack With Lua_getglob...
This is a tutorial describing how to change your context level when you call the the function 'printidentity'. Normally if you called the 'printidentity' function with Lua C Without changing anything to the level, it would print to the output: 'Current identity is 0', I'm showing you how to change it to any number 0-7. This tutorial shows you how to make your own full lua c roblox exploit using the wearedevs api brought to you by wearedevs you can make this exploit free. Rlua - High level bindings between Rust and Lua. This library is a high level interface between Rust and Lua. Its goal is to be an easy to use, practical, flexible, and safe API between Rust and Lua. Rlua is NOT designed to be a perfect zero cost wrapper over the Lua C API, because such a wrapper cannot maintain the safety guarantees that rlua.
Pandoc has a built-in Lua interpreter, so you do not need to install additional tools. The Lua scripts are called “Lua filters” for Pandoc. Next we give a quick example of raising the levels of headers by one, e.g., convert level 3 headers to level 2 headers. This may be useful when the top-level headers of your document are level 2 headers. See full list on codeproject.com.
it’s hard to tell what the various bytes in the data part represents.
Wireshark is written in C, and dissectors for Wireshark are generally also written in C. However,Wireshark has a Lua implementation that makes it easy for people who are unfamiliar with C to writedissectors. For those who are unfamiliar with Lua, it’s a very light-weight programming languagethat is designed to be implemented as a scripting language in applications to extend theirfunctionality.
The downside of using Lua is that the dissector will be slower than a dissector written in C.
Before we start writing the dissector, let’s go through a crash course on Lua. It’s not importantto know the language in detail, but we must know the basics.
Lua crash course
- Lua is multi-paradigm, and supports procedural style, functional programming to some degree, andit also has some object-oriented programming features. It doesn’t have classes, prototypes orinheritance out of the box, but they can be made by the programmer.
- It’s dynamically typed.
- Scope is either
local
orglobal
. It’s global if you don’t declare it. - Semicolons are not needed. Whitespace is not important like in Python.
- Lines that start with
--
are comments. - Don’t use
++
or+=
. Usei = i + 1
instead. - Not equal in conditionals is
~=
rather than!=
. - Its types are: string, number, boolean, nil, function, userdata, thread and table. Numberrepresents all numbers, both floating points and integers. Booleans are either true or false.Strings are either single-quote or double-quote. You can forget about thread and userdata.
- nil is a non-value. A variable will have the value nil before it’s assigned a proper value.
- In conditionals: nil and false are falsy, the rest are thruthy.
- Lua has a type called
table
, which is also the only data structure it has. Tables implementsassociative arrays. Associative arrays can be indexed by both numbers and other types, such asstrings. They have no fixed size and elements can be added dynamically. Tables are often calledobjects. They are created like this:
Values are assigned like this:
They can have functions and are generally very similar to objects in JavaScript.
- Conditional branching looks like this:
- Loops look like this:
That is i = first, last, delta.
break
can be used, but continue cannot.- Functions are declared like this:
and are called like this:
If you see functions called like this:
then the functions
func1
and func2
belongs to the table (object) a
. Using colon is syntacticsugar for passing the object itself as an argument to the function. That means a:func1()
issimilar to a.func1(a)
.That’s the important stuff. You can read the Lua 5.3 Reference Manualif you care about the details.
Setup
If you go to Help –> About Wireshark –> Folders, you’ll find all the folders Wireshark reads Luascripts from. Choose either the Personal Lua Plugins, Global Lua Plugins or Personal configurationfolder. E.g. C:Program FilesWiresharkplugins2.4.2 on Windows. The script will be active whenWireshark is started. You have to restart Wireshark after you do changes to the script, or reloadall the Lua scripts with Ctrl+Shift+L.
I’m using the latest version at the current date. What I’m doing here might not work on earlierversions.
The protocol
The most interesting protocol to investigate in this post would probably be a custom one thatWireshark doesn’t know of already, but all the custom protocols I’ve worked with have been workrelated and I can’t post information about them here. So instead we’ll look at theMongoDB wire protocol.
(There is already a Mongo dissector in Wireshark, but I will not use that one.)
According to the specification linked to above, the MongoDB wire protocol is a TCP/IP protocolusing port number 27017. The byte ordering is little endian, meaning the least significant bytecomes first. Most protocols are big endian. The only difference is the ordering of the bytes. Ifwe had an int32 for example, with these bytes:
00 4F 23 11
in big endian, then the little endianversion would be 11 23 4F 00
. This is something must to take into account when writing thedissector.In this post, I’ll only take a look at the header of the protocol. It looks like this
We can see that it has four int32s, each containing 4 bytes, because 4*8 = 32.
Setting up the boilerplate code
Let’s start by setting up some of the boilerplate code that’s needed in all dissectors:
We start my creating a Proto (protocol) object and call it
mongodb_protocol
. Thetable constructor takes two arguments: name
and description
. The protocol requires a fields
table and a dissector function. We haven’t added any fields yet, so the fields
table is empty. Thedissector function is called once for every packet of our type.The dissector function has three parameters:
buffer
, pinfo
and tree
. buffer
contains thepacket’s buffer and is a Tvb object. It contains the data we want to dissect. pinfo
contains the columns of the packet list and is a Pinfo object. Finally, tree
isthe tree root and is a TreeItem object.Inside the dissector function, we start by checking the length of the buffer and then returning ifit’s empty.
As mentioned before, the
pinfo
object contains the columns in the packet list. We can use it toset the protocol name when we receive a packet of MongoDB type. On the script’s first line we setthe name of the protocol to be “MongoDB” (by passing the name to the constructor). We set theprotocol column name hereand the protocol column name changes from TCP to MONGODB:
We must then create a sub tree in the tree structure found in the Packet Details pane. It done byadding an additional tree item to the tree object that was passed as an argument to the dissectorfunction.
The string is the name of the sub tree. Without having added any fields it will look like this:
Finally, we must assign the protocol to a port. In my case, I’ll use port 59274, because that’s theport I use to connect to the Mongo database.
'udp.port'
can also be used, if the protocol uses UDP rather than TCP.Adding fields
The script already runs at this stage, but it isn’t doing anything useful. For the script to dosomething useful we have to add the fields that we want to parse. Fields are made by creatingProtoField objects. We can start off simple by adding only the first field.The first field in the MongoDB wire protocol specification is the message length, which is an int32.
How To Change Level Lua Chart
We add the following above the dissector function:
The first argument is used as a label in the filter settings, second is used as a label in the subtree and the last is used to decide how the variable’s value should be displayed. In this case Iwant to show the value in decimal, but I could also use
base.HEX
to show it in hexadecimal format.Hexadecimal format doesn’t work for int32 though.ProtoField
has several types of functions we can use: uint8()
, uint16()
, string()
and so on.We have to use the one that matches the specification. A list of all the functions can be foundhere.We then add the field to the
fields
table of the protocol:C++ - Pushing A Lua Table - Stack Overflow
and finally add the field to the sub tree:
I use
add_le
rather than add
, because we are working with a little-endian protocol. If theprotocol was big endian we would have to use add
. The function takes two arguments: the field wemade further up, and a buffer range. We can get a range of the buffer by usingthe range function that is a part of the buffer object. buffer(offset,length)
is the short formfor the range function. buffer(0,4)
means we want to start at the first byte, and then take 4bytes. The reason we want to start at 0 is because we’re dealing with the first field in the header.We take 4 bytes because that is the size of an int32.After reloading the Lua script with Ctrl+Shift+L Wireshark should look like this:
We can see that it parses the messageLength correctly. We can also see that we don’t have to parseall the fields for this to work. We can gradually expand the plugin as we go.
The three other fields in the header are also int32s. We can add them just like the we did with themessage length field. The final script for this part will therefore look like this:
We have to increase the offset by 4 in the call to the range function (
buffer(offset,length)
) inorder to read 4 new bytes for every field. If we were dealing with something else than int32s wewould of course have to increase by something else.When You Call Lua_next , The Second Argument Should Be The Index Of The Table. Since You're Just Pushing The Table Onto The Stack With Lua_getglob...
The packet details pane finally looks like this:
and we are happy for now. In the next partI’ll look at debugging and more advanced parsing methods. Right now, we only see the numeric valuesof the opcodes, but the opcode name would be more interesting.