Using Lua to tag SYN-ACK followed by a RST
I have a large capture file and need to select all SYN-ACKs which result in an RST packet. There are thousands of those, so this is not a manual job.
I came up with the following solution: Create a Lua script to find all RST packets and go over the capture again to tag all matching SYN-ACK packets. Reason for the 2nd pass is that the RST obviously occurs AFTER the SYN-ACK.
I am new to Lua but managed to get a long way with the help of google and Chat-GPT, but I simply don't get all the way there. The current error is on line 34 and is that there is 'No such 'fields' method/field for object type 'Pinfo' But, everytime I address it I run into other errors.
Anybody with Lua experience who knows what I am doing wrong?
Script:
-- Define a custom field for tagging purposes.
-- This field will be used to indicate whether a TCP SYN packet is followed by an RST packet.
local f_tcp_syn_followed_by_rst = ProtoField.bool("tcp.syn_followed_by_rst", "SYN followed by RST", 8, nil, 0x01)
-- Create a new protocol to hold the custom field.
-- This protocol will be used for tagging TCP packets in Wireshark.
local tcp_tagging_proto = Proto("tcp_tagging", "TCP Tagging Protocol")
tcp_tagging_proto.fields = { f_tcp_syn_followed_by_rst }
-- Tables to hold the stream information
-- This table will keep track of TCP streams that have an RST packet.
local rst_stream_table = {}
-- Define field extractors
local tcp_stream_field = Field.new("tcp.stream")
local tcp_flags_field = Field.new("tcp.flags")
-- Function to analyze RST packets and register them with their stream number.
-- This function will be called for each packet to check if it is an RST packet and record its stream number.
local function analyze_packet_rst(pinfo, tvb, tree)
local tcp_stream = tcp_stream_field().value -- Extract the numeric value
local flags = tcp_flags_field().value -- Extract the numeric value
local rst_flag = bit32.band(flags, 0x04) ~= 0 -- Check if the RST flag is set.
-- If the RST flag is set, record the stream number in the rst_stream_table.
if rst_flag then
rst_stream_table[tcp_stream] = true
end
end
-- Function to find SYN-ACK packets and tag them if an RST was found for the same stream.
-- This function tags SYN-ACK packets that are followed by an RST packet in the same TCP stream.
local function analyze_packet_tag(pinfo, tvb, tree)
local tcp_stream = pinfo.fields.tcp.stream -- Get the TCP stream number from the packet info.
local flags = tvb(13, 1):uint() -- Extract the TCP flags from the packet.
local syn_flag = bit32.band(flags, 0x02) ~= 0 -- Check if the SYN flag is set.
local ack_flag = bit32.band(flags, 0x10) ~= 0 -- Check if the ACK flag is set.
-- If this is a SYN-ACK packet and the stream has an RST, set the custom field to true.
if syn_flag and ack_flag and rst_stream_table[tcp_stream] then
local subtree = tree:add(tcp_tagging_proto, tvb()) -- Add the protocol to the packet tree.
subtree:add(f_tcp_syn_followed_by_rst, tvb(), true) -- Set the custom field value.
pinfo.cols.info:append(" [SYN followed by RST]") -- Append a note to the packet info column.
end ...