From 0d6da1b8d38bcf03e2efee00bc556af8cd049822 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 7 Oct 2011 09:51:07 +0000 Subject: [PATCH] Use all interfaces by default in targets-ipv6-multicast-*. --- scripts/targets-ipv6-multicast-echo.nse | 84 +++++++++++------- .../targets-ipv6-multicast-invalid-dst.nse | 85 ++++++++++++------- scripts/targets-ipv6-multicast-slaac.nse | 84 ++++++++++++------ 3 files changed, 170 insertions(+), 83 deletions(-) diff --git a/scripts/targets-ipv6-multicast-echo.nse b/scripts/targets-ipv6-multicast-echo.nse index 1fac140c2..081fdbf8c 100644 --- a/scripts/targets-ipv6-multicast-echo.nse +++ b/scripts/targets-ipv6-multicast-echo.nse @@ -31,31 +31,39 @@ catch = function() end try = nmap.new_try(catch) -local function get_identifier(ip6_addr) - return string.sub(ip6_addr, 9, 16) +local function get_interfaces() + local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") + or nmap.get_interface() + + -- interfaces list (decide which interfaces to broadcast on) + local interfaces = {} + if interface_name then + -- single interface defined + local if_table = nmap.get_interface_info(interface_name) + if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + interfaces[#interfaces + 1] = if_table + else + stdnse.print_debug("Interface not supported or not properly configured.") + end + else + for _, if_table in ipairs(nmap.list_interfaces()) do + if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + table.insert(interfaces, if_table) + end + end + end + + return interfaces end -action = function() - local if_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface() - if not if_name then - return "Error: need an interface name.\n" - .. "Use -e or --script-args " .. SCRIPT_NAME .. ".interface=." - end +local function single_interface_broadcast(if_nfo, results) + stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device) - local if_nfo, err = nmap.get_interface_info(if_name) - if not if_nfo then - stdnse.print_debug(err) - return false - end - if if_nfo.link ~= "ethernet" then - stdnse.print_debug("Not a Ethernet link.") - return false - end + local condvar = nmap.condvar(results) local src_mac = if_nfo.mac local src_ip6 = packet.ip6tobin(if_nfo.address) local dst_mac = packet.mactobin("33:33:00:00:00:01") local dst_ip6 = packet.ip6tobin("ff02::1") - local id_set = {} ---------------------------------------------------------------------------- --Multicast echo ping probe @@ -63,8 +71,8 @@ action = function() local dnet = nmap.new_dnet() local pcap = nmap.new_socket() - try(dnet:ethernet_open(if_name)) - pcap:pcap_open(if_name, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 129") + try(dnet:ethernet_open(if_nfo.device)) + pcap:pcap_open(if_nfo.device, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 129") local probe = packet.Frame:new() probe.mac_src = src_mac @@ -87,8 +95,6 @@ action = function() local start_time = nmap:clock() local cur_time = nmap:clock() - local addrs = {} - repeat local status, length, layer2, layer3 = pcap:pcap_receive() cur_time = nmap:clock() @@ -97,12 +103,11 @@ action = function() else local reply = packet.Frame:new(layer2..layer3) if reply.mac_dst == src_mac then - local identifier = get_identifier(reply.ip6_src) - if not id_set[identifier] then - id_set[identifier] = true - local target_str = packet.toipv6(reply.ip6_src) + local target_str = packet.toipv6(reply.ip6_src) + if not results[target_str] then target.add(target_str) - addrs[#addrs + 1] = target_str + results[#results + 1] = target_str + results[target_str] = true end end end @@ -111,7 +116,28 @@ action = function() dnet:ethernet_close() pcap:pcap_close() - if #addrs > 0 then - return stdnse.format_output(true, addrs) + condvar("signal") +end + +action = function() + local threads = {} + local results = {} + local condvar = nmap.condvar(results) + + for _, if_nfo in ipairs(get_interfaces()) do + -- create a thread for each interface + local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) + threads[co] = true + end + + repeat + condvar "wait" + for thread in pairs(threads) do + if coroutine.status(thread) == "dead" then threads[thread] = nil end + end + until next(threads) == nil + + if #results > 0 then + return stdnse.format_output(true, results) end end diff --git a/scripts/targets-ipv6-multicast-invalid-dst.nse b/scripts/targets-ipv6-multicast-invalid-dst.nse index 76740c10c..8f4d03cc4 100644 --- a/scripts/targets-ipv6-multicast-invalid-dst.nse +++ b/scripts/targets-ipv6-multicast-invalid-dst.nse @@ -33,10 +33,6 @@ catch = function() end try = nmap.new_try(catch) -local function get_identifier(ip6_addr) - return string.sub(ip6_addr, 9, 16) -end - --- Build an IPv6 invalid extension header. -- @param nxt_hdr integer that stands for next header's type local function build_invalid_extension_header(nxt_hdr) @@ -53,27 +49,39 @@ local function build_invalid_extension_header(nxt_hdr) return ext_header end -action = function() - local if_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface() - if not if_name then - return "Error: need an interface name.\n" - .. "Use -e or --script-args " .. SCRIPT_NAME .. ".interface=." +local function get_interfaces() + local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") + or nmap.get_interface() + + -- interfaces list (decide which interfaces to broadcast on) + local interfaces = {} + if interface_name then + -- single interface defined + local if_table = nmap.get_interface_info(interface_name) + if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + interfaces[#interfaces + 1] = if_table + else + stdnse.print_debug("Interface not supported or not properly configured.") + end + else + for _, if_table in ipairs(nmap.list_interfaces()) do + if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + table.insert(interfaces, if_table) + end + end end - local if_nfo, err = nmap.get_interface_info(if_name) - if not if_nfo then - stdnse.print_debug(err) - return false - end - if if_nfo.link ~= "ethernet" then - stdnse.print_debug("Not a Ethernet link.") - return false - end + return interfaces +end + +local function single_interface_broadcast(if_nfo, results) + stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device) + + local condvar = nmap.condvar(results) local src_mac = if_nfo.mac local src_ip6 = packet.ip6tobin(if_nfo.address) local dst_mac = packet.mactobin("33:33:00:00:00:01") local dst_ip6 = packet.ip6tobin("ff02::1") - local id_set = {} ---------------------------------------------------------------------------- --Multicast invalid destination exheader probe @@ -81,8 +89,8 @@ action = function() local dnet = nmap.new_dnet() local pcap = nmap.new_socket() - try(dnet:ethernet_open(if_name)) - pcap:pcap_open(if_name, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 4") + try(dnet:ethernet_open(if_nfo.device)) + pcap:pcap_open(if_nfo.device, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 4") local probe = packet.Frame:new() probe.mac_src = src_mac @@ -127,13 +135,11 @@ action = function() local reply = packet.Frame:new(layer2) if reply.mac_dst == src_mac then reply = packet.Packet:new(layer3) - local target_addr = reply.ip6_src - local identifier = get_identifier(reply.ip6_src) - if not id_set[identifier] then - id_set[identifier] = true - local target_str = packet.toipv6(target_addr) + local target_str = packet.toipv6(reply.ip6_src) + if not results[target_str] then target.add(target_str) - addrs[#addrs + 1] = target_str + results[#results + 1] = target_str + results[target_str] = true end end end @@ -142,7 +148,28 @@ action = function() dnet:ethernet_close() pcap:pcap_close() - if #addrs > 0 then - return stdnse.format_output(true, addrs) + condvar("signal") +end + +action = function() + local threads = {} + local results = {} + local condvar = nmap.condvar(results) + + for _, if_nfo in ipairs(get_interfaces()) do + -- create a thread for each interface + local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) + threads[co] = true + end + + repeat + condvar "wait" + for thread in pairs(threads) do + if coroutine.status(thread) == "dead" then threads[thread] = nil end + end + until next(threads) == nil + + if #results > 0 then + return stdnse.format_output(true, results) end end diff --git a/scripts/targets-ipv6-multicast-slaac.nse b/scripts/targets-ipv6-multicast-slaac.nse index 18c0a9360..02eed6593 100644 --- a/scripts/targets-ipv6-multicast-slaac.nse +++ b/scripts/targets-ipv6-multicast-slaac.nse @@ -29,6 +29,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"discovery","broadcast"} +require 'ipOps' require 'nmap' require 'target' require 'packet' @@ -89,27 +90,39 @@ local function build_router_advert(mac_src,prefix,prefix_len,valid_time,preferre return icmpv6_payload end -action = function() - local if_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface() - if not if_name then - return "Error: need an interface name.\n" - .. "Use -e or --script-args " .. SCRIPT_NAME .. ".interface=." +local function get_interfaces() + local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") + or nmap.get_interface() + + -- interfaces list (decide which interfaces to broadcast on) + local interfaces = {} + if interface_name then + -- single interface defined + local if_table = nmap.get_interface_info(interface_name) + if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + interfaces[#interfaces + 1] = if_table + else + stdnse.print_debug("Interface not supported or not properly configured.") + end + else + for _, if_table in ipairs(nmap.list_interfaces()) do + if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then + table.insert(interfaces, if_table) + end + end end - local if_nfo, err = nmap.get_interface_info(if_name) - if not if_nfo then - stdnse.print_debug(err) - return false - end - if if_nfo.link ~= "ethernet" then - stdnse.print_debug("Not a Ethernet link.") - return false - end + return interfaces +end + +local function single_interface_broadcast(if_nfo, results) + stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device) + + local condvar = nmap.condvar(results) local src_mac = if_nfo.mac local src_ip6 = packet.ip6tobin(if_nfo.address) local dst_mac = packet.mactobin("33:33:00:00:00:01") local dst_ip6 = packet.ip6tobin("ff02::1") - local id_set = {} ---------------------------------------------------------------------------- --SLAAC-based host discovery probe @@ -117,8 +130,8 @@ action = function() local dnet = nmap.new_dnet() local pcap = nmap.new_socket() - try(dnet:ethernet_open(if_name)) - pcap:pcap_open(if_name, 128, true, "src ::0/128 and dst net ff02::1:0:0/96 and icmp6 and ip6[6:1] = 58 and ip6[40:1] = 135") + try(dnet:ethernet_open(if_nfo.device)) + pcap:pcap_open(if_nfo.device, 128, true, "src ::0/128 and dst net ff02::1:0:0/96 and icmp6 and ip6[6:1] = 58 and ip6[40:1] = 135") local actual_prefix = string.sub(src_ip6,1,8) local ula_prefix, prefix_len = get_radom_ula_prefix() @@ -153,8 +166,6 @@ action = function() local start_time = nmap:clock() local cur_time = nmap:clock() - local addrs = {} - repeat local status, length, layer2, layer3 = pcap:pcap_receive() cur_time = nmap:clock() @@ -170,11 +181,11 @@ action = function() local identifier = get_identifier(reply.ns_target) --Filter out the reduplicative identifiers. --A host will send several NS packets with the same interface identifier if it receives several RA packets with different prefix during the discovery phase. - if not id_set[identifier] then - id_set[identifier] = true - local actual_addr_str = packet.toipv6(actual_prefix .. identifier) + local actual_addr_str = packet.toipv6(actual_prefix .. identifier) + if not results[actual_addr_str] then target.add(actual_addr_str) - addrs[#addrs + 1] = actual_addr_str + results[#results + 1] = actual_addr_str + results[actual_addr_str] = true end end end @@ -184,7 +195,30 @@ action = function() dnet:ethernet_close() pcap:pcap_close() - if #addrs > 0 then - return stdnse.format_output(true, addrs) + condvar("signal") +end + +action = function() + local threads = {} + local results = {} + local condvar = nmap.condvar(results) + + for _, if_nfo in ipairs(get_interfaces()) do + -- create a thread for each interface + if ipOps.ip_in_range(if_nfo.address, "fe80::/10") then + local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) + threads[co] = true + end + end + + repeat + condvar "wait" + for thread in pairs(threads) do + if coroutine.status(thread) == "dead" then threads[thread] = nil end + end + until next(threads) == nil + + if #results > 0 then + return stdnse.format_output(true, results) end end