Wireshark Lua API: How to get TCP header info? - lua

I'm writing a dissector (to be added to DissectorTable.get("tcp.port")) for a TCP-based application. I've gone through the Wireshark API doc but could not find out how to get TCP header's info like
SYN/ACK flags
Sequence number
ACK'ed sequence number
UPDATE:
Based on the answer I'd put example snippet here. Just FYI.
local proto = Proto("myproto", "my proto")
-- ...
-- ...
--
-- A Field object can only be created *outside* of the callback
-- functions of dissectors, post-dissectors, heuristic-dissectors,
-- and taps.
--
local F_tcp_seq_rel = Field.new('tcp.seq') -- relative seq num
local F_tcp_seq_raw = Field.new('tcp.seq_raw') -- raw seq num
function proto.dissector(tvbuf, pinfo, tree)
-- ...
-- ...
local seq_rel = F_tcp_seq_rel() -- yes the Field object is callable!
local seq_raw = F_tcp_seq_raw()
-- ...
-- ...
end
DissectorTable.get("tcp.port"):add(12345, proto)

The way to get any field data, TCP or otherwise, is via a Field Extractor. So for example:
local tcp_flags_syn = Field.new("tcp.flags.syn")
local tcp_flags_ack = Field.new("tcp.flags.ack")
-- If you want relative sequence/acknowledgment numbers:
local tcp_seq = Field.new("tcp.seq")
local tcp_ack = Field.new("tcp.ack")
-- If you want absolute sequence/acknowledgment numbers:
local tcp_seq_raw = Field.new("tcp.seq_raw")
local tcp_ack_raw = Field.new("tcp.ack_raw")
If you need additional help using these fields, you may want to look at some of the Lua examples provided on the Wireshark Examples and/or Contrib wiki pages.

Related

I need anyone that can, decode "Luraph Obfuscator" [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I paid an untrusted developer for a script. And as I thought he scammed me. He did send me code, but he obfuscated the script. It is for a game called "Roblox" that uses Lua, the code will be down below. As from I can tell by running it, it might work. But I would need to change the script for it to work. Does anyone know to to decode the obfuscation?
https://pastebin.com/B8SZmZGE
local ilIillllII1i1lliliI = assert local II1ll1iliIIIIillIli = select local lIlillIlIi11I1lIIi11I = tonumber local i1li1IIIII1IIilIil1 = unpack local iIl1IIlI11i1il1ilII = pcall local lIlI1IiiIlIl1i11ll1Il = setfenv local iIIlilIlllIliiIili1 = setmetatable local ii1Iiill11ii1IIIill = type local lIll1I1ll1lliilII1Il1 = getfenv local IiIi1llliiIIllllI1i = tostring local Ii1IIill1ilI1lilIiI = error local iilli1lIi11lllIli1l = string.sub local lIlI1li1ll1lliliIlI = string.byte local lIli1Ill1liIlilIIIiiI = string.char local I1ii1iIIl1lI1Iii1iI = string.rep local iiiIiI11IIllIiliI1I = string.gsub local illlIIIllliill1l1ll = string.match local iIi1l1liili1I11l1II = 1 local function lIll1iillI1ll1iiIiIll(IIiiiIiiIllIl1i1i1I, iIililIlliIII11illi) local i1iiI1I1iII1iiIiil1 IIiiiIiiIllIl1i1i1I = iiiIiI11IIllIiliI1I(iilli1lIi11lllIli1l(IIiiiIiiIllIl1i1i1I, 5), "..", function(llii1Ii11lI1llilill) if lIlI1li1ll1lliliIlI(llii1Ii11lI1llilill, 2) == 71 then i1iiI1I1iII1iiIiil1 = lIlillIlIi11I1lIIi11I(iilli1lIi11lllIli1l(llii1Ii11lI1llilill, 1, 1)) return
Ok so I am turtsis and I see that people have been stealing my answer and posting it on v3rmillion as there own. So I will post another answer but this time a better one on how to actually get contents of it. So basically if you didn’t read my other answer then don’t and just read this one:
Luraph is a custom lbi which is a lua bytecode interpreter. If you do string.dump(function) you will get luaQ as the output. That is why people use unluaC or luadec to get the source to these dumps. This is called bytecode which is different then string:byte() as it is a non readable lua format in lua 5.1 and up. To be able to use these encoded strings/functions you will need a lbi. What a lbi does is it interpreted the bits and deserialzes them. Here is a example of a commonly used lbi https://github.com/JustAPerson/lbi/blob/master/src/lbi.lua
Ok so now to the part where you get contents of it.
In lua (and other coding languages) there is things called opcodes. Opcodes control the base of lua and there is quite a few of them. Some of the most commonly known and most useful ones are these:
LOADK - loads a constant to the register
LOADBOOL - loads a bool to the register
LOADNIL - loads a nil to the register
JMP - jump
ADD - Adds a new thing to the register
SUB - Subtracts something from the register
There is many more but those are the main ones we will be focusing on.
Ok so to get those normally you would need a external program called unluac or luadec but for this we will be doing it in base lua. I recommend using repl.it to run the code.
So the main thing we will need is LOADK as it loads a constant
A constant is a variable or anything really that doesn’t change ex: local value = 1
Now what isn’t a constant is something that changes.
Now you probaly have heard of iron brew and synapse xen both are very known lua obfuscators created by 3ds and Defcon42
Iron brew and xen have something in common (well the base) they aren’t lbis so you don’t usually get the opcodes from them. But they have a table that has all the constants in them (xen is encrypted) to get these tables there is a whole process with table.concat and global but that’s not luraph that’s other obfuscators. Luraph is different Though because it is a lbi so there is no need for a table with all the constants in it. Instead to get the constants we need a way to get the instructions from a script. Opcodes are instructions. They are instructions because opcodes tell lua what to do with code. Ok so how do we get these instructions?
Here is a article on opcodes and instructions:
http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf
So they all have signatures:
"sBx"
"A"
"A", "B"
"A", "Bx"
"A", "C"
"A", "sBx"
"A", "B", "C”
You get opcodes args from these instructions.
Now different obfuscators have different opcodes instructions so for luraph you will have to find them. Ok so use a dissembler or make Your own but here is a disassembler made by my friend:
https://github.com/op0x59/reddisassembler
You will need to go onto repl.it and make a repo then add the code and format it etc with the settings. Where in the settings it has opcodes you will need to manually get these from luraph.
So there you go that’s how you can do it. If you need more help dm me on discord:
turtsis#6969
Or
turtsis#2785
ALSO WHOEVER IS STEALING MY ANSWERS ON HERE AND POSTING THEM ON V3RMILLION WITH OUT CREDITING ME PLEASE STOP OR GIVE ME CREDIT.
Basically it uses bytecode (\144\22\99\88) but it has a custom interpreter and a custom bytecode vm to make it have a bytecode like this:
LPH|3EE5491D2B1A00192574A22B510A02002GE5E7E9E42GE5F53GE5F53GE5CD3GE5FDE42GE5C13GE5F934B71
So you will need to rename the variables and functions into something like variable1, variable2 so that you are able to read it. Then find parts that are junk code like
function 1iiii1i1i(i1i1ijj1jijij)
local 1j1j1jj1j1jijijij = (((10*2)/2)-3/9)
end
1iiii1i1i(90, 0)
Which are completely useless and are meant to trick decompilers into looping random number functions. to check if stuff like: iIi1l1liili1I11l1II = iIi1l1liili1I11l1II + 4 return Ii1IiI1I111I1II1IIi * 16777216 + iIII1iIiI1l1IlIIlii * 65536 + IIill111lli111ll1li * 256
These are junk code just look for it in the rest of the code (using ctrl+F) and look if it has a use. If it does, then check if that use has a use and so on until you find if it is part of the vm. The thing is though is that it might loadstring another loadstring for many times until it will take VERY LONG to decompile this. So if you really need the source contact me on discord and I can hook you up (turtsis#2785) or put a couple of hours into this
Using a Lua beautfier can make it easier to understand.
Such as: [http://blackmiaool.com/lua-beautify/][1] (https://github.com/blackmiaool/lua-beautify)
This question is 5 months old but here you go anyway:
local L3_0, L4_1, L5_2, L6_3, L7_4
L3_0 = "rebel alience"
L4_1 = "Wasp"
L5_2 = "Bottom Small Mining Laser"
L6_3 = "Adamantite Ore"
for _FORV_7_ = 1, 10 do
workspace.Ships[L3_0][L4_1][L5_2].RemoteFireCommand:InvokeServer(CFrame.new(0, 0, 0,0.996030748, -7.7674794E-4, 0.0890064985, 0, 0.999961913, 0.00872653536, -0.0890098885,-0.00869189762, 0.995992839), workspace.Asteroids[L6_3],workspace.Asteroids[L6_3], workspace.Asteroids[L6_3].CenterPoint)
wait(3)
end
It's a simple remote event.
You can find the tool used here, it's open source:
https://github.com/TheGreatSageEqualToHeaven/LuraphDeobfuscator
The script is
local L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, L20, L21, L22
L0 = "rebel alience"
L1 = "Wasp"
L2 = "Bottom Small Mining Laser"
L3 = "Adamantite Ore"
for L7 = L4, L5, L6 do
L8 = Workspace
L8 = L8.Ships
L8 = L8[L0]
L8 = L8[L1]
L8 = L8[L2]
L8 = L8.RemoteFireCommand
L9 = L8
L8 = L8.InvokeServer
L10 = CFrame
L10 = L10.new
L11 = 0
L12 = 0
L13 = 0
L14 = 0.996030748
L15 = -7.7674794E-4
L16 = 0.0890064985
L17 = 0
L18 = 0.999961913
L19 = 0.00872653536
L20 = -0.0890098885
L21 = -0.00869189762
L22 = 0.995992839
L10 = L10(L11, L12, L13, L14, L15, L16, L17, L18, L19, L20, L21, L22)
L11 = Workspace
L11 = L11.Asteroids
L11 = L11[L3]
L12 = Workspace
L12 = L12.Asteroids
L12 = L12[L3]
L13 = Workspace
L13 = L13.Asteroids
L13 = L13[L3]
L13 = L13.CenterPoint
L8(L9, L10, L11, L12, L13)
L8 = wait
L9 = 3
L8(L9)
end
The variables are not the normal variables and it may appear a bit confusing because I was using an auto deobfuscator
i might be late but
rebel alience
Wasp
Bottom Small Mining Laser
Adamantite Ore
1
10
Workspace
Ships
RemoteFireCommand
InvokeServer
CFrame
new
0
0.996030748
-0.00077674794
0.0890064985
0.999961913
0.00872653536
-0.0890098885
-0.00869189762
0.995992839
Asteroids
CenterPoint
wait
3
1337
I have a luraph dumper the dumped version of that script is only showing one variable which is "1337" I hope this helped!
One of the easiest things to do is to create a script destroying all the Luraph's scripts. Deleting those junk codes would still be a better option, but this would do its work for some time.
What it does, is that it basically destroys these scripts forever. One of the most fun things is that it doesn't even have to destroy them forever. Luraph scripts have a limited number, how many times they could multiply making Luraph's scripts crash.
local condition = true
local Oofer = workspace.Camera
while condition do
workspace.Camera:ClearAl1Children ()
wait (2)
end

How can I get the number of times an enttry in a table was listed

I need to find a way to see how many times an entry is listed in a table.
I have tried looking at other code for help, and looking at examples online none of them help
local pattern = "(.+)%s?-%s?(.+)"
local table = {"Cald_fan:1", "SomePerson:2", "Cald_fan:3","anotherPerson:4"}
for i,v in pairs(table) do
local UserId, t = string.match(v, pattern)
for i,v in next,UserId do
--I have tried something like this
end
end
it is suppose to say Cald_fan was listed 2 times
Something like this should work:
local pattern = "(.+)%s*:%s*(%d+)"
local tbl = {"Cald_fan:1", "SomePerson:2", "Cald_fan:3","anotherPerson:4"}
local counts = {}
for i,v in pairs(tbl) do
local UserId, t = string.match(v, pattern)
counts[UserId] = 1 + (counts[UserId] or 0)
end
print(counts['Cald_fan']) -- 2
I renamed table to tbl (as using table variable makes the table.* functions not available) and fix the pattern (you had unescaped '-' in it, while your strings had ':').
If the format of your table entries is consistent, you can simply split the strings apart and use the components as keys in a map of counters.
It looks like your table entries are formatted as "[player_name]:[index]", but it doesn't look like you care about the index. But, if the ":" will be in every table entry, you can write a pretty reliable search pattern. You could try something like this :
-- use a list of entries with the format <player_name>:<some_number>
local entries = {"Cald_fan:1", "SomePerson:2", "Cald_fan:3","anotherPerson:4"}
local foundPlayerCount = {}
-- iterate over the list of entries
for i,v in ipairs(entries) do
-- parse out the player name and a number using the pattern :
-- (.+) = capture any number of characters
-- : = match the colon character
-- (%d+)= capture any number of numbers
local playerName, playerIndex = string.match(v, '(.+):(%d+)')
-- use the playerName as a key to count how many times it appears
if not foundPlayerCount[playerName] then
foundPlayerCount[playerName] = 0
end
foundPlayerCount[playerName] = foundPlayerCount[playerName] + 1
end
-- print out all the players
for playerName, timesAppeared in pairs(foundPlayerCount) do
print(string.format("%s was listed %d times", playerName, timesAppeared))
end
If you need to do pattern matching in the future, I highly recommend this article on lua string patterns : http://lua-users.org/wiki/PatternsTutorial
Hope this helps!

How to get the TCP stream number with a listener?

I an analysing a very large PCAP holding many HTTP transactions, some of which interest me. I am using tshark with a Lua script essentially to query all packets that match a filter.
tshark -X lua_script:filter.lua -r some.pcap -q
So far so good. However, I am looking specifically for the value of a packet's TCP stream number which goes by the name tcp.stream inside Wireshark. Can anyone say what changes I require to filter.lua to print that?
-- filter.lua
do
local function init_listener()
local tap = Listener.new("http","http contains someKeyValue && tcp.port eq 1234")
function tap.reset()
end
function tap.packet(pinfo,tvb,ip)
print("Found my packet ... now what?")
end
function tap.draw()
end
end
init_listener()
end
The documentation on what pinfo, tvb and ip are is unforthcoming.
You can access the TCP stream number through a Field.
local tcp_stream = Field.new("tcp.stream").value
The value of the Field is the value for the current packet. You don't need to create a new Field each time. This allows you to make the Field a constant and create a function that returns the TCP stream number of the current packet. It is also possible to call the Field value to get the FieldInfo value which may include additional useful information.
You want the filter.lua to look like:
-- filter.lua
do
local function init_listener()
local get_tcp_stream = Field.new("tcp.stream")
local tap = Listener.new("http","http contains someKeyValue && tcp.port eq 1234")
function tap.reset()
end
function tap.packet(pinfo,tvb,ip)
print(tostring(get_tcp_stream()))
end
function tap.draw()
end
end
init_listener()
end
https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Field.html#lua_class_Field

Why are local variables accessed faster than global variables in lua?

So I was reading Programing in Lua 2nd Ed and I came across this paragraph here:
It is good programming style to use local variables whenever
possible. Local variables help you avoid cluttering the global
environment with unnecessary names. Moreover, the access to local
variables is faster than to global ones.
Could anyone explain why this is? And is this "feature" only in Lua, or is it in other languages aswell? (e.g. C, C++, Java)
The difference in running time is due to the difference between hash table lookup and array lookup. An interpreter might be able to place a local variable in a CPU register, but even without such cleverness local variables are faster to access.
Global variables in Lua are stored in tables. Generally, anyone can modify these tables, and therefore the interpreter has to lookup a value anew every time it is being accessed. Local variables on the other hand disappear only when they go out of scope. Therefore they can have fixed locations in an array.
The benchmark program below calls a dummy function in a loop. The benchmark shows how the running time goes up the more tables the program has to jump through.
Other dynamic languages should be expected to have similar characteristics; see for example the Python benchmark at the very end.
Some relevant links:
Optimising Using Local Variables (Lua)
Local Variables (Python performance tips)
Optimizing Global Variable/Attribute Access. A (withdrawn) Python proposal on the lookup of global vs. local objects.
File demo.lua:
local M = {}
_G.demo = M
function M.op(x) return x end
return M
File main.lua:
local M = require "demo"
op = demo.op
local outer_op = demo.op
function iter_op(n)
local inner_op = demo.op
for i = 1, n do
-- Example running times for n = 100,000,000 (Lua 5.2.0):
-- Lookup a table (demo or _G), then lookup 'op'
-- within that table:
--
-- demo.op(i) --> 0:40
-- _G.op(i) --> 0:39
-- Lookup 'op' within a known local table (M or the table of
-- globals):
--
-- M.op(i) --> 0:30
-- op(i) --> 0:30
-- Dereference a local variable declared inside or outside
-- of this iter_op() function:
--
-- inner_op(i) --> 0:23
-- outer_op(i) --> 0:22
end
end
iter_op(100000000)
File main.py:
import demo # Contains 'def op(x): return x'.
global_op = demo.op
def iter_op(n):
local_op = demo.op
for i in xrange(n):
# Example running times for n = 50,000,000 (Python 2.6.5):
# demo.op(i) # 0:50
# global_op(i) # 0:41
local_op(i) # 0:36
iter_op(50000000)
In any language local variables will be faster. You will need to understand what a register is and what the thread stack is to understand my explanation. Most local variables are implemented as a register variable or pushed near the top of the local stack, so they are generally accessed much more quickly. Global variables are stored further up the stack (if they are not on the heap) so computing their address to access them is slower.
I'm making some assumptions here about the inner workings of Lua, but this makes sense from a computer architecture standpoint.

Jump to a specific time in a file?

I'm trying to make a VLC script that checks if the "random" button is on, and if so when it jumps to a random file, instead of starting at time=0, it starts at a random time.
So far, it's looking to me like it should be a playlist script and I can get the duration from the playlist object, but in this documentation page doesn't show how to jump to a specific time from within the Lua script.
How can that be done in Lua?
Actually, the documentation does say you can do it...though not in so many words. Here's what it says about the interface for playlist parsers:
VLC Lua playlist modules should define two functions:
* probe(): returns true if we want to handle the playlist in this script
* parse(): read the incoming data and return playlist item(s)
Playlist items use the same format as that expected in the
playlist.add() function (see general lua/README.txt)
If you follow through to the description of playlist.add() it says the items have a big list of fields you can provide. There are plenty of choices (.name, .title, .artist, etc.) But the only required one seems to be .path...which is "the item's full path / URL".
There's no explicit mention of where to seek, but one of the parameters you can choose to provide is .options, said to be "a list of VLC options. It gives fullscreen as an example. If a parallel to --fullscreen works, can other command-line options like --start-time and --stop-time work as well?
On my system they do, and here's the script!
-- randomseek.lua
--
-- A compiled version of this file (.luac) should be put into the proper VLC
-- playlist parsers directory for your system type. See:
--
-- http://wiki.videolan.org/Documentation:Play_HowTo/Building_Lua_Playlist_Scripts
--
-- The file format is extremely simple and is merely alternating lines of
-- filenames and durations, such as if you had a file "example.randomseek"
-- it might contain:
--
-- foo.mp4
-- 3:04
-- bar.mov
-- 10:20
--
-- It simply will seek to a random location in the file and play a random
-- amount of the remaining time in the clip.
function probe()
-- seed the random number since other VLC lua plugins don't seem to
math.randomseed(os.time())
-- tell VLC we will handle anything ending in ".randomseek"
return string.match(vlc.path, ".randomseek$")
end
function parse()
-- VLC expects us to return a list of items, each item itself a list
-- of properties
playlist = {}
-- I'll assume a well formed input file but obviously you should do
-- error checking if writing something real
while true do
playlist_item = {}
line = vlc.readline()
if line == nil then
break --error handling goes here
end
playlist_item.path = line
line = vlc.readline()
if line == nil then
break --error handling goes here
end
for _min, _sec in string.gmatch( line, "(%d*):(%d*)" )
do
duration = 60 * _min + _sec
end
-- math.random with integer argument returns an integer between
-- one and the number passed in inclusive, VLC uses zero based times
start_time = math.random(duration) - 1
stop_time = math.random(start_time, duration - 1)
-- give the viewer a hint of how long the clip will take
playlist_item.duration = stop_time - start_time
-- a playlist item has another list inside of it of options
playlist_item.options = {}
table.insert(playlist_item.options, "start-time="..tostring(start_time))
table.insert(playlist_item.options, "stop-time="..tostring(stop_time))
table.insert(playlist_item.options, "fullscreen")
-- add the item to the playlist
table.insert( playlist, playlist_item )
end
return playlist
end
Just use this:
vlc.var.set(input, "time", time)
There is a seek method in common.lua.
Usage examples:
require 'common'
common.seek(123) -- seeks to 02m03s
common.seek("50%") -- seeks to middle of video

Resources