diff options
author | Matteo Biscosi <biscosi@ntop.org> | 2021-06-11 11:00:06 +0200 |
---|---|---|
committer | Matteo Biscosi <biscosi@ntop.org> | 2021-06-11 11:00:06 +0200 |
commit | a01a2b7443b75da3d5c1ea8316eb4e25ae452719 (patch) | |
tree | 7c3db5390c3e0dd1a552e48d795f6323c0705b35 /wireshark/sharkfest_scripts/tcp_syn_scan.lua | |
parent | 6704649a75a748574f031ba8f110dd6cfa4fbb06 (diff) |
Changed output for the sharkfest lua scripts
Diffstat (limited to 'wireshark/sharkfest_scripts/tcp_syn_scan.lua')
-rw-r--r-- | wireshark/sharkfest_scripts/tcp_syn_scan.lua | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/wireshark/sharkfest_scripts/tcp_syn_scan.lua b/wireshark/sharkfest_scripts/tcp_syn_scan.lua new file mode 100644 index 000000000..abfeee596 --- /dev/null +++ b/wireshark/sharkfest_scripts/tcp_syn_scan.lua @@ -0,0 +1,161 @@ +-- +-- (C) 2021 - ntop.org +-- +-- This is going to be an example of a lua script that can be written for cybersecurity reasons. +-- TCP No Data Exchanged: +-- The TCP No Data Exchanged is a really important script to check if flows are suspicious +-- Because usually, a typic TCP traffic, have some payload and it is not 0. Instead, in some attacks, +-- for example the TCP SYN Scan or SYN Flood, there is a lot of TCP traffic with no data. + +local f_tcp_traffic = Field.new("tcp") +local f_tcp_payload = Field.new("tcp.len") +local f_ip_src = Field.new("ip.src") +local f_ip_dst = Field.new("ip.dst") +local f_port_src = Field.new("tcp.srcport") +local f_port_dst = Field.new("tcp.dstport") +local f_conn_fin = Field.new("tcp.flags.fin") + +--############################################ + +local function getstring(finfo) + local ok, val = pcall(tostring, finfo) + if not ok then val = "(unknown)" end + return val +end + +--############################################ + +local function processResponse(tcp_table, src, src_port, dst, dst_port, payload) + local key = src .. " -> " .. dst + + -- Create the table entry if needed + if not tcp_table[key] then + local key2 = dst .. "->" .. src + if not tcp_table[key2] then + tcp_table[key] = { + payload = 0, + fin = false, + contacted_ports = 0, + dst_ports = {} + } + else + -- Switching src and dst ports and ip + local tmp = dst + key = key2 + dst = src + src = tmp + tmp = src_port + src_port = dst_port + dst_port = tmp + end + end + + -- Increase the stats + tcp_table[key]["payload"] = tcp_table[key]["payload"] + getstring(payload.value) + + if not tcp_table[key]["dst_ports"][dst_port] then + tcp_table[key]["dst_ports"][dst_port] = 1 + tcp_table[key]["contacted_ports"] = tcp_table[key]["contacted_ports"] + 1 + end + + if getstring(f_conn_fin().value) == true then + tcp_table[key]["fin"] = true + end + + return tcp_table +end + +--############################################ + +local function processPackets(pinfo,tvb, tcp_table) + -- Call the function that extracts the field + local tcp_traffic = f_tcp_traffic() + local tcp_payload = f_tcp_payload() + + --Check if there is an HTTP request or reply + if tcp_traffic then + local src = getstring(f_ip_src().value) + local dst = getstring(f_ip_dst().value) + local src_port = getstring(f_port_src().value) + local dst_port = getstring(f_port_dst().value) + + tcp_table = processResponse(tcp_table, src, src_port, dst, dst_port, tcp_payload) + end + + return tcp_table +end + +--############################################ + +local function tcpSynScan() + -- Declare the window we will use + local tw = TextWindow.new("TCP No Data Exchanged") + + local tcp_table = {} + + local tap = Listener.new(); + + local function removeListener() + -- This way we remove the listener that otherwise will remain running indefinitely + tap:remove(); + end + + -- We tell the window to call the remove() function when closed + tw:set_atclose(removeListener) + + -- This function will be called once for each packet + function tap.packet(pinfo,tvb) + tcp_table = processPackets(pinfo,tvb, tcp_table) + end + + -- This function will be called once every few seconds to update our window + function tap.draw(t) + tw:clear() + + local dangerous_flows = {} + local ok_flows = {} + + for flow, data in pairs(tcp_table) do + local payload = data["payload"] + local contacted_ports = data["contacted_ports"] + + if tonumber(payload) == 0 and tonumber(contacted_ports) > 10 then + dangerous_flows[#dangerous_flows + 1] = data + dangerous_flows[#dangerous_flows]["flow"] = flow + else + ok_flows[#ok_flows + 1] = data + ok_flows[#ok_flows]["flow"] = flow + end + end + + if #dangerous_flows > 0 then + tw:append("------------- DETECTED TCP SYN SCAN -------------\n\n") + tw:append("TOT SUSPICIOUS FLOWS DETECTED:\t" .. #dangerous_flows .. "\n") + else + tw:append("------------- TCP SYN SCAN NOT DETECTED -------------\n\n") + end + + tw:append("TOTAL FLOWS DETECTED:\t\t" .. #dangerous_flows + #ok_flows .. "\n\n") + + for _, data in pairs(dangerous_flows) do + local flow = data["flow"] + local payload = data["payload"] + local contacted_ports = data["contacted_ports"] + + tw:append(flow .. ":\n\tTotal ports scanned:\t" .. tostring(contacted_ports) .. "\n\n"); + end + end + + -- This function will be called whenever a reset is needed + -- e.g. when reloading the capture file + function tap.reset() + tw:clear() + tcp_table = {} + end + + -- Ensure that all existing packets are processed. + retap_packets() +end + +-- Register the menu Entry +register_menu("Sharkfest/TCP SYN Scan", tcpSynScan, MENU_TOOLS_UNSORTED) |