Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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 35 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.
-- Function to analyze RST packets and register them with their 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
end

-- Register the protocol as a postdisector.
-- This will ensure that the protocol is called after the standard dissectors.
register_postdissector(tcp_tagging_proto)

-- Dissector function for the custom protocol.
-- This function calls the two analysis functions to process each packet.
function tcp_tagging_proto.dissector(tvb, pinfo, tree)
    analyze_packet_rst(pinfo, tvb, tree) -- Call the function to analyze RST packets.
    analyze_packet_tag(pinfo, tvb, tree) -- Call the function to tag SYN-ACK packets.
end

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 35 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.
-- Function to analyze RST packets and register them with their 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
end

-- Register the protocol as a postdisector.
-- This will ensure that the protocol is called after the standard dissectors.
register_postdissector(tcp_tagging_proto)

-- Dissector function for the custom protocol.
-- This function calls the two analysis functions to process each packet.
function tcp_tagging_proto.dissector(tvb, pinfo, tree)
    analyze_packet_rst(pinfo, tvb, tree) -- Call the function to analyze RST packets.
    analyze_packet_tag(pinfo, tvb, tree) -- Call the function to tag SYN-ACK packets.
end