aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wireshark/sharkfest_scripts/README.md11
-rw-r--r--wireshark/sharkfest_scripts/dns_request_reply_ratio.lua123
-rw-r--r--wireshark/sharkfest_scripts/http_request_reply_ratio.lua125
-rw-r--r--wireshark/sharkfest_scripts/tcp_no_data_exchanged.lua127
4 files changed, 386 insertions, 0 deletions
diff --git a/wireshark/sharkfest_scripts/README.md b/wireshark/sharkfest_scripts/README.md
new file mode 100644
index 000000000..43d5b8d0f
--- /dev/null
+++ b/wireshark/sharkfest_scripts/README.md
@@ -0,0 +1,11 @@
+# Companion Wireshark Scripts
+
+This folder contains some scripts we developed for the Sharkfest conference. They are used
+to detect specific attacks and security flaws.
+
+In order to test these scripts you can use the following pcaps:
+- https://github.com/NewBee119/ctf_ics_traffic
+- https://www.netresec.com/?page=pcapfiles
+
+or pcaps from nDPI test directory
+- https://github.com/ntop/nDPI/tree/dev/tests/pcap
diff --git a/wireshark/sharkfest_scripts/dns_request_reply_ratio.lua b/wireshark/sharkfest_scripts/dns_request_reply_ratio.lua
new file mode 100644
index 000000000..4cac059f4
--- /dev/null
+++ b/wireshark/sharkfest_scripts/dns_request_reply_ratio.lua
@@ -0,0 +1,123 @@
+
+--
+-- Sharkfest 2021
+--
+-- This is going to be an example of a lua script that can be written for cybersecurity reasons.
+-- DNS Request/Reply Ratio:
+
+
+local f_dns_response_flag = Field.new("dns.flags.response")
+local f_ip_src = Field.new("ip.src")
+local f_ip_dst = Field.new("ip.dst")
+
+--############################################
+
+local function getstring(finfo)
+ local ok, val = pcall(tostring, finfo)
+ if not ok then val = "(unknown)" end
+ return val
+end
+
+--############################################
+
+local function processResponse(dns_table, req_or_rep, src, dst)
+ local key = src .. "->" .. dst
+
+ -- Create the table entry if needed
+ if not dns_table[key] then
+ dns_table[key] = {
+ requests = 0,
+ replies = 0,
+ }
+ end
+
+ -- Increase the stats
+ dns_table[key][req_or_rep] = dns_table[key][req_or_rep] + 1
+
+ return dns_table
+end
+
+--############################################
+
+local function processPackets(pinfo,tvb, dns_table)
+ -- Call the function that extracts the field
+ local dns = f_dns_response_flag()
+
+ --Check if there is an DNS request or reply
+ if dns then
+ if dns.value == false then
+ local src = getstring(f_ip_src().value)
+ local dst = getstring(f_ip_dst().value)
+
+ dns_table = processResponse(dns_table, "requests", src, dst)
+ else
+ local dst = getstring(f_ip_src().value)
+ local src = getstring(f_ip_dst().value)
+
+ dns_table = processResponse(dns_table, "replies", src, dst)
+ end
+ end
+
+ return dns_table
+end
+
+--############################################
+
+local function dnsReqRepRatio()
+ -- Declare the window we will use
+ local tw = TextWindow.new("DNS Request/Reply Ratio")
+
+ local dns_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)
+ dns_table = processPackets(pinfo,tvb, dns_table)
+ end
+
+ -- This function will be called once every few seconds to update our window
+ function tap.draw(t)
+ tw:clear()
+
+ for flow in pairs(dns_table) do
+ local requests = dns_table[flow]["requests"]
+ local replies = dns_table[flow]["replies"]
+ local ratio = 0
+ local danger = ""
+
+ if replies == 0 then
+ ratio = 0
+ else
+ ratio = requests/replies
+ end
+
+ if ratio ~= 1 then
+ danger = "-- DANGER: RATIO NOT 1 --\n"
+ end
+
+ tw:append(danger .. flow .. ":\n\tRatio: " .. (ratio) .. "\n\tRequests: " .. requests .. "\n\tReplies: " .. replies .. "\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()
+ dns_table = {}
+ end
+
+ -- Ensure that all existing packets are processed.
+ retap_packets()
+end
+
+-- Register the menu Entry
+register_menu("Sharkfest/DNS Request-Reply Ratio", dnsReqRepRatio, MENU_TOOLS_UNSORTED) \ No newline at end of file
diff --git a/wireshark/sharkfest_scripts/http_request_reply_ratio.lua b/wireshark/sharkfest_scripts/http_request_reply_ratio.lua
new file mode 100644
index 000000000..1e89ec033
--- /dev/null
+++ b/wireshark/sharkfest_scripts/http_request_reply_ratio.lua
@@ -0,0 +1,125 @@
+
+--
+-- Sharkfest 2021
+--
+-- This is going to be an example of a lua script that can be written for cybersecurity reasons.
+-- HTTP Request/Reply Ratio:
+-- the ratio of HTTP requests and replies should be alwais close to 1, because, if not, usually means
+-- that there are problems with the client that is sending the requests or there are problems with
+-- the server that should receive those requests.
+
+local f_http_request = Field.new("http.request")
+local f_http_reply = Field.new("http.response")
+local f_ip_src = Field.new("ip.src")
+local f_ip_dst = Field.new("ip.dst")
+
+--############################################
+
+local function getstring(finfo)
+ local ok, val = pcall(tostring, finfo)
+ if not ok then val = "(unknown)" end
+ return val
+end
+
+--############################################
+
+local function processResponse(http_table, req_or_rep, src, dst)
+ local key = src .. "->" .. dst
+
+ -- Create the table entry if needed
+ if not http_table[key] then
+ http_table[key] = {
+ requests = 0,
+ replies = 0,
+ }
+ end
+
+ -- Increase the stats
+ http_table[key][req_or_rep] = http_table[key][req_or_rep] + 1
+
+ return http_table
+end
+
+--############################################
+
+local function processPackets(pinfo,tvb, http_table)
+ -- Call the function that extracts the field
+ local http_request = f_http_request()
+ local http_reply = f_http_reply()
+
+ --Check if there is an HTTP request or reply
+ if http_request then
+ local src = getstring(f_ip_src().value)
+ local dst = getstring(f_ip_dst().value)
+
+ http_table = processResponse(http_table, "requests", src, dst)
+ elseif http_reply then
+ local dst = getstring(f_ip_src().value)
+ local src = getstring(f_ip_dst().value)
+
+ http_table = processResponse(http_table, "replies", src, dst)
+ end
+
+ return http_table
+end
+
+--############################################
+
+local function httpReqRepRatio()
+ -- Declare the window we will use
+ local tw = TextWindow.new("HTTP Request/Reply Ratio")
+
+ local http_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)
+ http_table = processPackets(pinfo,tvb, http_table)
+ end
+
+ -- This function will be called once every few seconds to update our window
+ function tap.draw(t)
+ tw:clear()
+
+ for flow in pairs(http_table) do
+ local requests = http_table[flow]["requests"]
+ local replies = http_table[flow]["replies"]
+ local ratio = 0
+ local danger = ""
+
+ if replies == 0 then
+ ratio = 0
+ else
+ ratio = requests/replies
+ end
+
+ if ratio ~= 1 then
+ danger = "-- DANGER: RATIO NOT 1 --\n"
+ end
+
+ tw:append(danger .. flow .. ":\n\tRatio: " .. (ratio) .. "\n\tRequests: " .. requests .. "\n\tReplies: " .. replies .. "\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()
+ http_table = {}
+ end
+
+ -- Ensure that all existing packets are processed.
+ retap_packets()
+end
+
+-- Register the menu Entry
+register_menu("Sharkfest/HTTP Request-Reply Ratio", httpReqRepRatio, MENU_TOOLS_UNSORTED) \ No newline at end of file
diff --git a/wireshark/sharkfest_scripts/tcp_no_data_exchanged.lua b/wireshark/sharkfest_scripts/tcp_no_data_exchanged.lua
new file mode 100644
index 000000000..7d9ac9839
--- /dev/null
+++ b/wireshark/sharkfest_scripts/tcp_no_data_exchanged.lua
@@ -0,0 +1,127 @@
+
+--
+-- Sharkfest 2021
+--
+-- 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 .. ":" .. src_port .. "->" .. dst .. ":" .. dst_port
+
+ -- Create the table entry if needed
+ if not tcp_table[key] then
+ local key2 = dst .. ":" .. dst_port .. "->" .. src .. ":" .. src_port
+ if not tcp_table[key2] then
+ tcp_table[key] = {
+ payload = 0,
+ fin = false
+ }
+ else
+ key = key2
+ end
+ end
+
+ -- Increase the stats
+ tcp_table[key]["payload"] = tcp_table[key]["payload"] + getstring(payload.value)
+
+ 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 tcpPayload()
+ -- 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()
+
+ for flow in pairs(tcp_table) do
+ local payload = tcp_table[flow]["payload"]
+ local fin = tcp_table[flow]["fin"]
+ local danger = ""
+
+ if tonumber(payload) == 0 then
+ danger = "-- DANGER: NO DATA EXCHANGED FOR THIS FLOW --\n"
+ end
+
+ tw:append(danger .. flow .. ":\n\tPayload: " .. payload .. "\n\tFlow Ended: " .. tostring(fin) .. "\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 No Data Exchanged", tcpPayload, MENU_TOOLS_UNSORTED) \ No newline at end of file