PATH:
usr
/
share
/
nmap
/
scripts
local bin = require "bin" local math = require "math" local nmap = require "nmap" local packet = require "packet" local stdnse = require "stdnse" local tab = require "tab" local table = require "table" description = [[ Tries to discover firewall rules using an IP TTL expiration technique known as firewalking. To determine a rule on a given gateway, the scanner sends a probe to a metric located behind the gateway, with a TTL one higher than the gateway. If the probe is forwarded by the gateway, then we can expect to receive an ICMP_TIME_EXCEEDED reply from the gateway next hop router, or eventually the metric itself if it is directly connected to the gateway. Otherwise, the probe will timeout. It starts with a TTL equals to the distance to the target. If the probe timeout, then it is resent with a TTL decreased by one. If we get an ICMP_TIME_EXCEEDED, then the scan is over for this probe. Every "no-reply" filtered TCP and UDP ports are probed. As for UDP scans, this process can be quite slow if lots of ports are blocked by a gateway close to the scanner. Scan parameters can be controlled using the <code>firewalk.*</code> optional arguments. From an original idea of M. Schiffman and D. Goldsmith, authors of the firewalk tool. ]] --- -- @usage -- nmap --script=firewalk --traceroute <host> -- -- @usage -- nmap --script=firewalk --traceroute --script-args=firewalk.max-retries=1 <host> -- -- @usage -- nmap --script=firewalk --traceroute --script-args=firewalk.probe-timeout=400ms <host> -- -- @usage -- nmap --script=firewalk --traceroute --script-args=firewalk.max-probed-ports=7 <host> -- -- -- @args firewalk.max-retries the maximum number of allowed retransmissions. -- @args firewalk.recv-timeout the duration of the packets capture loop (in milliseconds). -- @args firewalk.probe-timeout validity period of a probe (in milliseconds). -- @args firewalk.max-active-probes maximum number of parallel active probes. -- @args firewalk.max-probed-ports maximum number of ports to probe per protocol. Set to -1 to scan every filtered port. -- -- -- @output -- | firewalk: -- | HOP HOST PROTOCOL BLOCKED PORTS -- | 2 192.168.1.1 tcp 21-23,80 -- | udp 21-23,80 -- | 6 10.0.1.1 tcp 67-68 -- | 7 10.0.1.254 tcp 25 -- |_ udp 25 -- -- -- 11/29/2010: initial version -- 03/28/2011: added IPv4 check -- 01/02/2012: added IPv6 support author = "Henri Doreau" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"safe", "discovery"} -- TODO -- o add an option to select gateway(s)/TTL(s) to probe -- o remove traceroute dependency -----= scan parameters defaults =----- -- number of retries for unanswered probes local DEFAULT_MAX_RETRIES = 2 -- packets capture loop timeout in milliseconds local DEFAULT_RECV_TIMEOUT = 20 -- probe life time in milliseconds local DEFAULT_PROBE_TIMEOUT = 2000 -- max number of simultaneously neither replied nor timed out probes local DEFAULT_MAX_ACTIVE_PROBES = 20 -- maximum number of probed ports per protocol local DEFAULT_MAX_PROBED_PORTS = 10 ---------------------------------------- -- global scan parameters local MaxRetries local RecvTimeout local ProbeTimeout local MaxActiveProbes local MaxProbedPorts -- cache ports to probe between the hostrule and the action function local FirewalkPorts -- ICMP constants local ICMP_TIME_EXCEEDEDv4 = 11 local ICMP_TIME_EXCEEDEDv6 = 03 -- Layer 4 specific function tables local proto_vtable = {} -- Layer 3 specific function tables for the scanner local Firewalk = {} --- Printable representation of a v4 or v6 IP address. -- @param addr Binary representation of the address -- @return the printable representation of the address, as a string. local function toip(addr) -- XXX Beware this function uses nmap.address_family() to format the result. if nmap.address_family() == "inet" then return packet.toip(addr) else return packet.toipv6(addr) end end --- lookup for TTL of a given gateway in a traceroute results table -- @param traceroute a host traceroute results table -- @param gw the IP address of the gateway (as a decimal-dotted string) -- @return the TTL of the gateway or -1 on error local function gateway_ttl(traceroute, gw) for ttl, hop in ipairs(traceroute) do -- check hop.ip ~= nil as timedout hops are represented by empty tables if hop.ip and hop.ip == gw then return ttl end end return -1 end --- get the protocol name given its "packet" value -- @param proto the protocol value (eg. packet.IPPROTO_*) -- @return the protocol name as a string local function proto2str(proto) if proto == packet.IPPROTO_TCP then return "tcp" elseif proto == packet.IPPROTO_UDP then return "udp" end return nil end --= -- Protocol specific functions are broken down per protocol, in separate tables. -- This design eases the addition of new protocols. -- -- Layer 4 (TCP, UDP) tables are duplicated to distinguish IPv4 and IPv6 -- versions. --= --- TCP related functions (IPv4 versions) local tcp_funcs_v4 = { --- update the global scan status with a reply -- @param scanner the scanner handle -- @param ip the ICMP time exceeded error packet -- @param ip2 the ICMP payload (our original expired probe) update_scan = function(scanner, ip, ip2) local port = ip2.tcp_dport if port and scanner.ports.tcp[port] then stdnse.print_debug("Marking port %d/tcp v4 as forwarded (reply from %s)", ip2.tcp_dport, ip.ip_src) -- mark the gateway as forwarding the packet scanner.ports.tcp[port].final_ttl = gateway_ttl(scanner.target.traceroute, ip.ip_src) scanner.ports.tcp[port].scanned = true -- remove the related probe for i, probe in ipairs(scanner.active_probes) do if probe.proto == "tcp" and probe.portno == ip2.tcp_dport then table.remove(scanner.active_probes, i) end end else stdnse.print_debug("Invalid reply to port %d/tcp", ip2.tcp_dport) end end, --- create a TCP probe packet -- @param host Host object that represents the destination -- @param dport the TCP destination port -- @param ttl the IP time to live -- @return the newly crafted IP packet getprobe = function(host, dport, ttl) local pktbin = bin.pack("H", "4500 0014 0000 4000 8000 0000 0000 0000 0000 0000" .. "0000 0000 0000 0000 0000 0000 6002 0c00 0000 0000 0204 05b4" ) local ip = packet.Packet:new(pktbin, pktbin:len()) ip:tcp_parse(false) ip:ip_set_bin_src(host.bin_ip_src) ip:ip_set_bin_dst(host.bin_ip) ip:set_u8(ip.ip_offset + 9, packet.IPPROTO_TCP) ip.ip_p = packet.IPPROTO_TCP ip:ip_set_len(pktbin:len()) ip:tcp_set_sport(math.random(0x401, 0xffff)) ip:tcp_set_dport(dport) ip:tcp_set_seq(math.random(1, 0x7fffffff)) ip:tcp_count_checksum() ip:ip_set_ttl(ttl) ip:ip_count_checksum() return ip end, } -- UDP related functions (IPv4 versions) local udp_funcs_v4 = { --- update the global scan status with a reply -- @param scanner the scanner handle -- @param ip the ICMP time exceeded error packet -- @param ip2 the ICMP payload (our original expired probe) update_scan = function(scanner, ip, ip2) local port = ip2.udp_dport if port and scanner.ports.udp[port] then stdnse.print_debug("Marking port %d/udp v4 as forwarded", ip2.udp_dport) -- mark the gateway as forwarding the packet scanner.ports.udp[port].final_ttl = gateway_ttl(scanner.target.traceroute, ip.ip_src) scanner.ports.udp[port].scanned = true for i, probe in ipairs(scanner.active_probes) do if probe.proto == "udp" and probe.portno == ip2.udp_dport then table.remove(scanner.active_probes, i) end end else stdnse.print_debug("Invalid reply to port %d/udp", ip2.udp_dport) end end, --- create a generic UDP probe packet, with IP ttl and destination port set to zero -- @param host Host object that represents the destination -- @param dport the UDP destination port -- @param ttl the IP time to live -- @return the newly crafted IP packet getprobe = function(host, dport, ttl) local pktbin = bin.pack("H", "4500 0014 0000 4000 8000 0000 0000 0000 0000 0000" .. "0000 0000 0800 0000" ) local ip = packet.Packet:new(pktbin, pktbin:len()) ip:udp_parse(false) ip:ip_set_bin_src(host.bin_ip_src) ip:ip_set_bin_dst(host.bin_ip) ip:set_u8(ip.ip_offset + 9, packet.IPPROTO_UDP) ip.ip_p = packet.IPPROTO_UDP ip:ip_set_len(pktbin:len()) ip:udp_set_sport(math.random(0x401, 0xffff)) ip:udp_set_dport(dport) ip:udp_set_length(ip.ip_len - ip.ip_hl * 4) ip:udp_count_checksum() ip:ip_set_ttl(ttl) ip:ip_count_checksum() return ip end, } --- TCP related functions (IPv6 versions) local tcp_funcs_v6 = { --- update the global scan status with a reply -- @param scanner the scanner handle -- @param ip the ICMP time exceeded error packet -- @param ip2 the ICMP payload (our original expired probe) update_scan = function(scanner, ip, ip2) local port = ip2.tcp_dport if port and scanner.ports.tcp[port] then stdnse.print_debug("Marking port %d/tcp v6 as forwarded (reply from %s)", ip2.tcp_dport, ip.ip_src) -- mark the gateway as forwarding the packet scanner.ports.tcp[port].final_ttl = gateway_ttl(scanner.target.traceroute, ip.ip_src) scanner.ports.tcp[port].scanned = true -- remove the related probe for i, probe in ipairs(scanner.active_probes) do if probe.proto == "tcp" and probe.portno == ip2.tcp_dport then table.remove(scanner.active_probes, i) end end else stdnse.print_debug("Invalid reply to port %d/tcp", ip2.tcp_dport) end end, --- create a TCP probe packet -- @param host Host object that represents the destination -- @param dport the TCP destination port -- @param ttl the IP time to live -- @return the newly crafted IP packet getprobe = function(host, dport, ttl) local pktbin = bin.pack("H", "4500 0014 0000 4000 8000 0000 0000 0000 0000 0000" .. "0000 0000 0000 0000 0000 0000 6002 0c00 0000 0000 0204 05b4" ) local tcp = packet.Packet:new(pktbin, pktbin:len()) local ip = packet.Packet:new() tcp:tcp_parse(false) tcp:tcp_set_sport(math.random(0x401, 0xffff)) tcp:tcp_set_dport(dport) tcp:tcp_set_seq(math.random(1, 0x7fffffff)) tcp:tcp_count_checksum() tcp:ip_count_checksum() -- Extract layer 4 part and add it as payload to the IP packet local tcp_buf = tcp.buf:sub(tcp.tcp_offset + 1, tcp.buf:len()) ip:build_ipv6_packet(host.bin_ip_src, host.bin_ip, packet.IPPROTO_TCP, tcp_buf, ttl) return ip end, } -- UDP related functions (IPv6 versions) local udp_funcs_v6 = { --- update the global scan status with a reply -- @param scanner the scanner handle -- @param ip the ICMP time exceeded error packet -- @param ip2 the ICMP payload (our original expired probe) update_scan = function(scanner, ip, ip2) local port = ip2.udp_dport if port and scanner.ports.udp[port] then stdnse.print_debug("Marking port %d/udp v6 as forwarded (reply from %s)", ip2.udp_dport, ip2.ip_src) -- mark the gateway as forwarding the packet scanner.ports.udp[port].final_ttl = gateway_ttl(scanner.target.traceroute, ip.ip_src) scanner.ports.udp[port].scanned = true for i, probe in ipairs(scanner.active_probes) do if probe.proto == "udp" and probe.portno == ip2.udp_dport then table.remove(scanner.active_probes, i) end end else stdnse.print_debug("Invalid reply to port %d/udp", ip2.udp_dport) end end, --- create a generic UDP probe packet, with IP ttl and destination port set to zero -- @param host Host object that represents the destination -- @param dport the UDP destination port -- @param ttl the IP time to live -- @return the newly crafted IP packet getprobe = function(host, dport, ttl) local pktbin = bin.pack("H", "4500 0014 0000 4000 8000 0000 0000 0000 0000 0000" .. "0000 0000 0800 0000" ) local udp = packet.Packet:new(pktbin, pktbin:len()) local ip = packet.Packet:new() udp:udp_parse(false) udp:udp_set_sport(math.random(0x401, 0xffff)) udp:udp_set_dport(dport) udp:udp_set_length(8) udp:udp_count_checksum() udp:ip_count_checksum() -- Extract layer 4 part and add it as payload to the IP packet local udp_buf = udp.buf:sub(udp.udp_offset + 1, udp.buf:len()) ip:build_ipv6_packet(host.bin_ip_src, host.bin_ip, packet.IPPROTO_UDP, udp_buf, ttl) return ip end, } --= -- IP-specific functions. The following tables provides scanner functions that -- depend on the IP version. --= -- IPv4 functions local Firewalk_v4 = { --- IPv4 initialization function. Open injection and reception sockets. -- @param scanner the scanner handle init = function(scanner) local saddr = packet.toip(scanner.target.bin_ip_src) scanner.sock = nmap.new_dnet() scanner.pcap = nmap.new_socket() -- filter for incoming ICMP time exceeded replies scanner.pcap:pcap_open(scanner.target.interface, 104, false, "icmp and dst host " .. saddr) local try = nmap.new_try() try(scanner.sock:ip_open()) end, --- IPv4 cleanup function. Close injection and reception sockets. -- @param scanner the scanner handle shutdown = function(scanner) scanner.sock:ip_close() scanner.pcap:pcap_close() end, --- check whether an incoming IP packet is an ICMP TIME_EXCEEDED packet or not -- @param src the source IP address -- @param layer3 the IP incoming datagram -- @return whether the packet seems to be a valid reply or not check = function(src, layer3) local ip = packet.Packet:new(layer3, layer3:len()) return ip.ip_bin_dst == src and ip.ip_p == packet.IPPROTO_ICMP and ip.icmp_type == ICMP_TIME_EXCEEDEDv4 end, --- update global state with an incoming reply -- @param scanner the scanner handle -- @param pkt an incoming valid IP packet parse_reply = function(scanner, pkt) local ip = packet.Packet:new(pkt, pkt:len()) if ip.ip_p ~= packet.IPPROTO_ICMP or ip.icmp_type ~= ICMP_TIME_EXCEEDEDv4 then return end local is = ip.buf:sub(ip.icmp_offset + 9) local ip2 = packet.Packet:new(is, is:len(), true) -- check ICMP payload if ip2.ip_bin_src == scanner.target.bin_ip_src and ip2.ip_bin_dst == scanner.target.bin_ip then -- layer 4 checks local proto_func = proto_vtable[proto2str(ip2.ip_p)] if proto_func then -- mark port as forwarded and discard any related pending probes proto_func.update_scan(scanner, ip, ip2) else stdnse.print_debug("Invalid protocol for reply (%d)", ip2.ip_p) end end end, } -- IPv6 functions local Firewalk_v6 = { --- IPv6 initialization function. Open injection and reception sockets. -- @param scanner the scanner handle init = function(scanner) local saddr = packet.toipv6(scanner.target.bin_ip_src) scanner.sock = nmap.new_dnet() scanner.pcap = nmap.new_socket() -- filter for incoming ICMP time exceeded replies scanner.pcap:pcap_open(scanner.target.interface, 1500, false, "icmp6 and dst host " .. saddr) local try = nmap.new_try() try(scanner.sock:ip_open()) end, --- IPv6 cleanup function. Close injection and reception sockets. -- @param scanner the scanner handle shutdown = function(scanner) scanner.sock:ip_close() scanner.pcap:pcap_close() end, --- check whether an incoming IP packet is an ICMP TIME_EXCEEDED packet or not -- @param src the source IP address -- @param layer3 the IP incoming datagram -- @return whether the packet seems to be a valid reply or not check = function(src, layer3) local ip = packet.Packet:new(layer3) return ip.ip_bin_dst == src and ip.ip_p == packet.IPPROTO_ICMPV6 and ip.icmpv6_type == ICMP_TIME_EXCEEDEDv6 end, --- update global state with an incoming reply -- @param scanner the scanner handle -- @param pkt an incoming valid IP packet parse_reply = function(scanner, pkt) local ip = packet.Packet:new(pkt) if ip.ip_p ~= packet.IPPROTO_ICMPV6 or ip.icmpv6_type ~= ICMP_TIME_EXCEEDEDv6 then return end local is = ip.buf:sub(ip.icmpv6_offset + 9, ip.buf:len()) local ip2 = packet.Packet:new(is) -- check ICMP payload if ip2.ip_bin_src == scanner.target.bin_ip_src and ip2.ip_bin_dst == scanner.target.bin_ip then -- layer 4 checks local proto_func = proto_vtable[proto2str(ip2.ip_p)] if proto_func then -- mark port as forwarded and discard any related pending probes proto_func.update_scan(scanner, ip, ip2) else stdnse.print_debug("Invalid protocol for reply (%d)", ip2.ip_p) end end end, } --- Initialize global function tables according to the current address family local function firewalk_init() if nmap.address_family() == "inet" then proto_vtable.tcp = tcp_funcs_v4 proto_vtable.udp = udp_funcs_v4 Firewalk = Firewalk_v4 else proto_vtable.tcp = tcp_funcs_v6 proto_vtable.udp = udp_funcs_v6 Firewalk = Firewalk_v6 end end --- generate list of ports to probe -- @param host the destination host object -- @return an array of the ports to probe, sorted per protocol local function build_portlist(host) local portlist = {} local combos = { {"tcp", "filtered"}, {"udp", "open|filtered"} } for _, combo in ipairs(combos) do local i = 0 local port = nil local proto = combo[1] local state = combo[2] repeat port = nmap.get_ports(host, port, proto, state) -- do not include administratively prohibited ports if port and port.reason == "no-response" then local pentry = { final_ttl = 0, -- TTL of the blocking gateway scanned = false, -- initial state: unprobed } portlist[proto] = portlist[proto] or {} portlist[proto][port.number] = pentry i = i + 1 end until not port or i == MaxProbedPorts end return portlist end --- wrapper for stdnse.parse_timespec() to get specified value in milliseconds -- @param spec the time specification string (like "10s", "120ms"...) -- @return the equivalent number of milliseconds or nil on failure local function parse_timespec_ms(spec) local t = stdnse.parse_timespec(spec) if t then return t * 1000 else return nil end end --- set scan parameters using user values if specified or defaults otherwise local function getopts() -- assign parameters to scan constants or use defaults MaxRetries = tonumber(stdnse.get_script_args("firewalk.max-retries")) or DEFAULT_MAX_RETRIES MaxActiveProbes = tonumber(stdnse.get_script_args("firewalk.max-active-probes")) or DEFAULT_MAX_ACTIVE_PROBES MaxProbedPorts = tonumber(stdnse.get_script_args("firewalk.max-probed-ports")) or DEFAULT_MAX_PROBED_PORTS -- use stdnse time specification parser for ProbeTimeout and RecvTimeout local timespec = stdnse.get_script_args("firewalk.recv-timeout") if timespec then RecvTimeout = parse_timespec_ms(timespec) if not RecvTimeout then stdnse.print_debug("Invalid time specification for option: firewalk.recv-timeout (%s)", timespec) return false end else -- no value supplied: use default RecvTimeout = DEFAULT_RECV_TIMEOUT end timespec = stdnse.get_script_args("firewalk.probe-timeout") if timespec then ProbeTimeout = parse_timespec_ms(timespec) if not ProbeTimeout then stdnse.print_debug("Invalid time specification for option: firewalk.probe-timeout (%s)", timespec) return false end else -- no value supplied: use default ProbeTimeout = DEFAULT_PROBE_TIMEOUT end return true end --- host rule, check for requirements before to launch the script hostrule = function(host) if not nmap.is_privileged() then nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {} if not nmap.registry[SCRIPT_NAME].rootfail then stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME) end nmap.registry[SCRIPT_NAME].rootfail = true return false end if not host.interface then return false end -- assign user's values to scan parameters or use defaults if not getopts() then return false end -- get the list of ports to probe FirewalkPorts = build_portlist(host) -- schedule the execution if there are filtered ports to probe return (next(FirewalkPorts) ~= nil) end --- return the initial TTL to use (the one of the last gateway before the target) -- @param host the object representing the target with traceroute results available -- @return the IP TTL of the last gateway before the target local function initial_ttl(host) if not host.traceroute then if not nmap.registry['firewalk'] then nmap.registry['firewalk'] = {} end if nmap.registry['firewalk']['traceroutefail'] then return nil end nmap.registry['firewalk']['traceroutefail'] = true if nmap.verbosity() > 0 then stdnse.print_debug("%s requires unavailable traceroute informations.", SCRIPT_NAME) end return nil end stdnse.print_debug("Using ttl %d", #host.traceroute) return #host.traceroute end --- convert an array of ports into a port ranges string like "x,y-z" -- @param ports an array of numbers -- @return a string representing the ports as folded ranges local function portrange(ports) table.sort(ports) local numranges = {} if #ports == 0 then return "(none found)" end for _, p in ipairs(ports) do local stored = false -- iterate over the ports list for k, range in ipairs(numranges) do -- increase an existing range by the left if p == range["start"] - 1 then numranges[k]["start"] = p stored = true -- increase an existing range by the right elseif p == range["stop"] + 1 then numranges[k]["stop"] = p stored = true -- port contained in an already existing range (catch doublons) elseif p >= range["start"] and p <= range["stop"] then stored = true end end -- start a new range if not stored then local range = {} range["start"] = p range["stop"] = p table.insert(numranges, range) end end -- stringify the ranges local strrange = {} for i, val in ipairs(numranges) do local start = tostring(val["start"]) local stop = tostring(val["stop"]) if start == stop then table.insert(strrange, start) else -- contiguous ranges are represented as x-z table.insert(strrange, start .. "-" .. stop) end end -- ranges are delimited by `,' return stdnse.strjoin(",", strrange) end --- return a printable report of the scan -- @param scanner the scanner handle -- @return a printable table of scan results local function report(scanner) local entries = 0 local output = tab.new(4) tab.add(output, 1, "HOP") tab.add(output, 2, "HOST") tab.add(output, 3, "PROTOCOL") tab.add(output, 4, "BLOCKED PORTS") tab.nextrow(output) -- duplicate traceroute results and add localhost at the beginning local path = { -- XXX 'localhost' might be a better choice? {ip = toip(scanner.target.bin_ip_src)} } for _, v in pairs(scanner.target.traceroute) do table.insert(path, v) end for ttl = 0, #path - 1 do local fwdedports = {} for proto, portlist in pairs(scanner.ports) do fwdedports[proto] = {} for portno, port in pairs(portlist) do if port.final_ttl == ttl then table.insert(fwdedports[proto], portno) end end end local nb_fports = 0 for _, proto in pairs(fwdedports) do for _ in pairs(proto) do nb_fports = nb_fports + 1 end end if nb_fports > 0 then entries = entries + 1 -- the blocking gateway is just after the last forwarding one tab.add(output, 1, tostring(ttl)) -- timedout traceroute hops are represented by empty tables if path[ttl + 1].ip then tab.add(output, 2, path[ttl + 1].ip) else tab.add(output, 2, "???") end for proto, ports in pairs(fwdedports) do if #fwdedports[proto] > 0 then tab.add(output, 3, proto) tab.add(output, 4, portrange(ports)) tab.nextrow(output) end end end end if entries > 0 then return "\n" .. tab.dump(output) else return "None found" end end --- check whether the scan is finished or not -- @param scanner the scanner handle -- @return if some port is still in unknown state local function finished(scanner) for proto, ports in pairs(scanner.ports) do -- ports are sorted per protocol for _, port in pairs(ports) do -- if a port is still unprobed => we're not done! if not port.scanned then return false end end end -- every ports have been scanned return true end --- send a probe and update it -- @param scanner the scanner handle -- @param probe the probe specifications and related informations local function send_probe(scanner, probe) local try = nmap.new_try(function() scanner.sock:ip_close() end) stdnse.print_debug("Sending new probe (%d/%s ttl=%d)", probe.portno, probe.proto, probe.ttl) -- craft the raw packet local pkt = proto_vtable[probe.proto].getprobe(scanner.target, probe.portno, probe.ttl) try(scanner.sock:ip_send(pkt.buf, scanner.target)) -- update probe informations probe.retry = probe.retry + 1 probe.sent_time = nmap.clock_ms() end --- send some new probes -- @param scanner the scanner handle local function send_next_probes(scanner) -- this prevents sending too much probes at the same time while #scanner.active_probes < MaxActiveProbes do local probe -- perform resends if #scanner.pending_resends > 0 then probe = scanner.pending_resends[1] table.remove(scanner.pending_resends, 1) table.insert(scanner.active_probes, probe) send_probe(scanner, probe) -- send new probes elseif #scanner.sendqueue > 0 then probe = scanner.sendqueue[1] table.remove(scanner.sendqueue, 1) table.insert(scanner.active_probes, probe) send_probe(scanner, probe) -- nothing else to send right now else return end end end --- wait for incoming replies -- @param scanner the scanner handle local function read_replies(scanner) -- capture loop local timeout = RecvTimeout repeat local start = nmap.clock_ms() scanner.pcap:set_timeout(timeout) local status, _, _, l3, _ = scanner.pcap:pcap_receive() if status and Firewalk.check(scanner.target.bin_ip_src, l3) then Firewalk.parse_reply(scanner, l3) end timeout = timeout - (nmap.clock_ms() - start) until timeout <= 0 or #scanner.active_probes == 0 end --- delete timedout probes, update pending probes -- @param scanner the scanner handle local function update_probe_queues(scanner) local now = nmap.clock_ms() -- remove timedout probes for i, probe in ipairs(scanner.active_probes) do if (now - probe.sent_time) >= ProbeTimeout then table.remove(scanner.active_probes, i) if probe.retry < MaxRetries then table.insert(scanner.pending_resends, probe) else -- decrease ttl, reset retries counter and put probes in send queue if probe.ttl > 1 then probe.ttl = probe.ttl - 1 probe.retry = 0 table.insert(scanner.sendqueue, probe) else -- set final_ttl to zero (=> probe might be blocked by localhost) scanner.ports[probe.proto][probe.portno].final_ttl = 0 scanner.ports[probe.proto][probe.portno].scanned = true end end end end end --- fills the send queue with initial probes -- @param scanner the scanner handle local function generate_initial_probes(scanner) for proto, ports in pairs(scanner.ports) do for portno in pairs(ports) do -- simply store probe parameters and craft packet at send time local probe = { ttl = scanner.ttl, -- initial ttl value proto = proto, -- layer 4 protocol (string) portno = portno, -- layer 4 port number retry = 0, -- retries counter sent_time = 0 -- last sending time } table.insert(scanner.sendqueue, probe) end end end --- firewalk entry point action = function(host) firewalk_init() -- global script initialization process -- scan handle, scanner state is saved in this table local scanner = { target = host, ttl = initial_ttl(host), ports = FirewalkPorts, sendqueue = {}, -- pending probes pending_resends = {}, -- probes needing to be resent active_probes = {}, -- probes currently neither replied nor timedout } if not scanner.ttl then return nil end Firewalk.init(scanner) generate_initial_probes(scanner) while not finished(scanner) do send_next_probes(scanner) read_replies(scanner) update_probe_queues(scanner) end Firewalk.shutdown(scanner) return report(scanner) end
[+]
..
[-] qscan.nse
[edit]
[-] oracle-brute.nse
[edit]
[-] smtp-vuln-cve2011-1764.nse
[edit]
[-] broadcast-pc-duo.nse
[edit]
[-] targets-ipv6-multicast-mld.nse
[edit]
[-] http-backup-finder.nse
[edit]
[-] http-sitemap-generator.nse
[edit]
[-] cassandra-brute.nse
[edit]
[-] snmp-win32-services.nse
[edit]
[-] ftp-brute.nse
[edit]
[-] irc-botnet-channels.nse
[edit]
[-] rsync-brute.nse
[edit]
[-] icap-info.nse
[edit]
[-] citrix-brute-xml.nse
[edit]
[-] iax2-version.nse
[edit]
[-] nfs-ls.nse
[edit]
[-] ndmp-fs-info.nse
[edit]
[-] cvs-brute-repository.nse
[edit]
[-] http-drupal-modules.nse
[edit]
[-] mysql-databases.nse
[edit]
[-] xmpp-info.nse
[edit]
[-] pgsql-brute.nse
[edit]
[-] ssl-google-cert-catalog.nse
[edit]
[-] smtp-commands.nse
[edit]
[-] rpcinfo.nse
[edit]
[-] snmp-hh3c-logins.nse
[edit]
[-] dns-zone-transfer.nse
[edit]
[-] murmur-version.nse
[edit]
[-] metasploit-xmlrpc-brute.nse
[edit]
[-] http-brute.nse
[edit]
[-] nessus-xmlrpc-brute.nse
[edit]
[-] krb5-enum-users.nse
[edit]
[-] vuze-dht-info.nse
[edit]
[-] smb-ls.nse
[edit]
[-] openlookup-info.nse
[edit]
[-] hadoop-namenode-info.nse
[edit]
[-] informix-tables.nse
[edit]
[-] http-vuln-cve2010-0738.nse
[edit]
[-] omp2-brute.nse
[edit]
[-] http-headers.nse
[edit]
[-] bitcoin-info.nse
[edit]
[-] smb-psexec.nse
[edit]
[-] eppc-enum-processes.nse
[edit]
[-] afp-brute.nse
[edit]
[-] iscsi-brute.nse
[edit]
[-] http-enum.nse
[edit]
[-] smb-enum-sessions.nse
[edit]
[-] daytime.nse
[edit]
[-] mongodb-info.nse
[edit]
[-] omp2-enum-targets.nse
[edit]
[-] p2p-conficker.nse
[edit]
[-] teamspeak2-version.nse
[edit]
[-] http-wordpress-brute.nse
[edit]
[-] riak-http-info.nse
[edit]
[-] http-joomla-brute.nse
[edit]
[-] path-mtu.nse
[edit]
[-] targets-traceroute.nse
[edit]
[-] snmp-win32-users.nse
[edit]
[-] http-unsafe-output-escaping.nse
[edit]
[-] http-traceroute.nse
[edit]
[-] ftp-anon.nse
[edit]
[-] mysql-info.nse
[edit]
[-] mtrace.nse
[edit]
[-] openvas-otp-brute.nse
[edit]
[-] lltd-discovery.nse
[edit]
[-] ssl-enum-ciphers.nse
[edit]
[-] dict-info.nse
[edit]
[-] netbus-version.nse
[edit]
[-] nfs-statfs.nse
[edit]
[-] hostmap-bfk.nse
[edit]
[-] dns-random-txid.nse
[edit]
[-] http-affiliate-id.nse
[edit]
[-] socks-brute.nse
[edit]
[-] bitcoin-getaddr.nse
[edit]
[-] acarsd-info.nse
[edit]
[-] http-cakephp-version.nse
[edit]
[-] oracle-enum-users.nse
[edit]
[-] dns-brute.nse
[edit]
[-] http-google-malware.nse
[edit]
[-] hostmap-robtex.nse
[edit]
[-] http-barracuda-dir-traversal.nse
[edit]
[-] http-auth-finder.nse
[edit]
[-] resolveall.nse
[edit]
[-] informix-query.nse
[edit]
[-] mysql-users.nse
[edit]
[-] nrpe-enum.nse
[edit]
[-] mysql-empty-password.nse
[edit]
[-] broadcast-xdmcp-discover.nse
[edit]
[-] ip-geolocation-geobytes.nse
[edit]
[-] cups-info.nse
[edit]
[-] tftp-enum.nse
[edit]
[-] http-icloud-sendmsg.nse
[edit]
[-] nbstat.nse
[edit]
[-] ajp-headers.nse
[edit]
[-] nexpose-brute.nse
[edit]
[-] giop-info.nse
[edit]
[-] sip-call-spoof.nse
[edit]
[-] broadcast-tellstick-discover.nse
[edit]
[-] dns-nsec3-enum.nse
[edit]
[-] http-grep.nse
[edit]
[-] http-drupal-enum-users.nse
[edit]
[-] smb-enum-processes.nse
[edit]
[-] maxdb-info.nse
[edit]
[-] rtsp-url-brute.nse
[edit]
[-] ganglia-info.nse
[edit]
[-] ip-geolocation-maxmind.nse
[edit]
[-] traceroute-geolocation.nse
[edit]
[-] rpcap-info.nse
[edit]
[-] http-waf-detect.nse
[edit]
[-] ms-sql-dac.nse
[edit]
[-] citrix-enum-servers.nse
[edit]
[-] http-vmware-path-vuln.nse
[edit]
[-] mongodb-brute.nse
[edit]
[-] http-passwd.nse
[edit]
[-] x11-access.nse
[edit]
[-] http-generator.nse
[edit]
[-] ms-sql-info.nse
[edit]
[-] http-method-tamper.nse
[edit]
[-] http-robtex-shared-ns.nse
[edit]
[-] http-majordomo2-dir-traversal.nse
[edit]
[-] ms-sql-empty-password.nse
[edit]
[-] broadcast-netbios-master-browser.nse
[edit]
[-] citrix-enum-servers-xml.nse
[edit]
[-] broadcast-networker-discover.nse
[edit]
[-] mrinfo.nse
[edit]
[-] lexmark-config.nse
[edit]
[-] http-frontpage-login.nse
[edit]
[-] smtp-open-relay.nse
[edit]
[-] http-git.nse
[edit]
[-] targets-asn.nse
[edit]
[-] http-favicon.nse
[edit]
[-] backorifice-info.nse
[edit]
[-] http-vuln-cve2011-3192.nse
[edit]
[-] realvnc-auth-bypass.nse
[edit]
[-] broadcast-wpad-discover.nse
[edit]
[-] http-methods.nse
[edit]
[-] smb-check-vulns.nse
[edit]
[-] sshv1.nse
[edit]
[-] broadcast-bjnp-discover.nse
[edit]
[-] http-title.nse
[edit]
[-] broadcast-novell-locate.nse
[edit]
[-] smb-vuln-ms10-054.nse
[edit]
[-] afp-showmount.nse
[edit]
[-] broadcast-rip-discover.nse
[edit]
[-] http-slowloris.nse
[edit]
[-] nat-pmp-mapport.nse
[edit]
[-] ftp-libopie.nse
[edit]
[-] targets-ipv6-multicast-echo.nse
[edit]
[-] nessus-brute.nse
[edit]
[-] membase-brute.nse
[edit]
[-] ip-geolocation-ipinfodb.nse
[edit]
[-] smb-print-text.nse
[edit]
[-] smtp-enum-users.nse
[edit]
[-] ajp-brute.nse
[edit]
[-] bitcoinrpc-info.nse
[edit]
[-] auth-owners.nse
[edit]
[-] targets-ipv6-multicast-invalid-dst.nse
[edit]
[-] afp-path-vuln.nse
[edit]
[-] oracle-brute-stealth.nse
[edit]
[-] http-vlcstreamer-ls.nse
[edit]
[-] auth-spoof.nse
[edit]
[-] nping-brute.nse
[edit]
[-] broadcast-dropbox-listener.nse
[edit]
[-] afp-ls.nse
[edit]
[-] broadcast-db2-discover.nse
[edit]
[-] quake3-info.nse
[edit]
[-] snmp-sysdescr.nse
[edit]
[-] dhcp-discover.nse
[edit]
[-] ms-sql-config.nse
[edit]
[-] http-comments-displayer.nse
[edit]
[-] smb-vuln-ms10-061.nse
[edit]
[-] ipv6-node-info.nse
[edit]
[-] http-awstatstotals-exec.nse
[edit]
[-] ldap-rootdse.nse
[edit]
[-] rtsp-methods.nse
[edit]
[-] smb-enum-domains.nse
[edit]
[-] sniffer-detect.nse
[edit]
[-] hbase-master-info.nse
[edit]
[-] modbus-discover.nse
[edit]
[-] http-rfi-spider.nse
[edit]
[-] msrpc-enum.nse
[edit]
[-] mysql-query.nse
[edit]
[-] ftp-vsftpd-backdoor.nse
[edit]
[-] domcon-brute.nse
[edit]
[-] citrix-enum-apps-xml.nse
[edit]
[-] pjl-ready-message.nse
[edit]
[-] sip-brute.nse
[edit]
[-] http-vuln-cve2011-3368.nse
[edit]
[-] firewalk.nse
[edit]
[-] http-gitweb-projects-enum.nse
[edit]
[-] http-open-redirect.nse
[edit]
[-] ajp-methods.nse
[edit]
[-] ip-forwarding.nse
[edit]
[-] ncp-serverinfo.nse
[edit]
[-] smb-enum-shares.nse
[edit]
[-] ssh2-enum-algos.nse
[edit]
[-] cvs-brute.nse
[edit]
[-] nat-pmp-info.nse
[edit]
[-] epmd-info.nse
[edit]
[-] bjnp-discover.nse
[edit]
[-] stuxnet-detect.nse
[edit]
[-] ftp-vuln-cve2010-4221.nse
[edit]
[-] http-litespeed-sourcecode-download.nse
[edit]
[-] gpsd-info.nse
[edit]
[-] snmp-ios-config.nse
[edit]
[-] broadcast-igmp-discovery.nse
[edit]
[-] http-robtex-reverse-ip.nse
[edit]
[-] snmp-processes.nse
[edit]
[-] broadcast-sybase-asa-discover.nse
[edit]
[-] wsdd-discover.nse
[edit]
[-] netbus-info.nse
[edit]
[-] broadcast-ripng-discover.nse
[edit]
[-] pop3-brute.nse
[edit]
[-] backorifice-brute.nse
[edit]
[-] domcon-cmd.nse
[edit]
[-] citrix-enum-apps.nse
[edit]
[-] dns-nsec-enum.nse
[edit]
[-] rpcap-brute.nse
[edit]
[-] ftp-bounce.nse
[edit]
[-] stun-info.nse
[edit]
[-] dns-update.nse
[edit]
[-] broadcast-wake-on-lan.nse
[edit]
[-] dns-cache-snoop.nse
[edit]
[-] rsync-list-modules.nse
[edit]
[-] snmp-netstat.nse
[edit]
[-] url-snarf.nse
[edit]
[-] snmp-interfaces.nse
[edit]
[-] cassandra-info.nse
[edit]
[-] http-huawei-hg5xx-vuln.nse
[edit]
[-] memcached-info.nse
[edit]
[-] http-proxy-brute.nse
[edit]
[-] pptp-version.nse
[edit]
[-] broadcast-pppoe-discover.nse
[edit]
[-] dns-random-srcport.nse
[edit]
[-] ip-geolocation-geoplugin.nse
[edit]
[-] smb-security-mode.nse
[edit]
[-] ms-sql-dump-hashes.nse
[edit]
[-] ntp-monlist.nse
[edit]
[-] http-wordpress-enum.nse
[edit]
[-] ike-version.nse
[edit]
[-] broadcast-eigrp-discovery.nse
[edit]
[-] amqp-info.nse
[edit]
[-] iax2-brute.nse
[edit]
[-] mysql-variables.nse
[edit]
[-] ajp-request.nse
[edit]
[-] cccam-version.nse
[edit]
[-] mysql-brute.nse
[edit]
[-] http-malware-host.nse
[edit]
[-] http-domino-enum-passwords.nse
[edit]
[-] vnc-brute.nse
[edit]
[-] duplicates.nse
[edit]
[-] db2-das-info.nse
[edit]
[-] broadcast-dhcp6-discover.nse
[edit]
[-] pop3-capabilities.nse
[edit]
[-] http-form-fuzzer.nse
[edit]
[-] flume-master-info.nse
[edit]
[-] ms-sql-tables.nse
[edit]
[-] broadcast-wsdd-discover.nse
[edit]
[-] jdwp-info.nse
[edit]
[-] mcafee-epo-agent.nse
[edit]
[-] smb-brute.nse
[edit]
[-] irc-sasl-brute.nse
[edit]
[-] http-php-version.nse
[edit]
[-] ms-sql-brute.nse
[edit]
[-] http-form-brute.nse
[edit]
[-] http-cors.nse
[edit]
[-] jdwp-version.nse
[edit]
[-] smbv2-enabled.nse
[edit]
[-] ssl-cert.nse
[edit]
[-] dns-fuzz.nse
[edit]
[-] mysql-enum.nse
[edit]
[-] script.db
[edit]
[-] rlogin-brute.nse
[edit]
[-] ovs-agent-version.nse
[edit]
[-] ntp-info.nse
[edit]
[-] ajp-auth.nse
[edit]
[-] targets-sniffer.nse
[edit]
[-] quake3-master-getservers.nse
[edit]
[-] http-date.nse
[edit]
[-] cups-queue-info.nse
[edit]
[-] rdp-vuln-ms12-020.nse
[edit]
[-] http-tplink-dir-traversal.nse
[edit]
[-] http-robots.txt.nse
[edit]
[-] hadoop-tasktracker-info.nse
[edit]
[-] eap-info.nse
[edit]
[-] ms-sql-xp-cmdshell.nse
[edit]
[-] broadcast-dns-service-discovery.nse
[edit]
[-] sip-methods.nse
[edit]
[-] broadcast-avahi-dos.nse
[edit]
[-] hadoop-secondary-namenode-info.nse
[edit]
[-] db2-discover.nse
[edit]
[-] jdwp-inject.nse
[edit]
[-] servicetags.nse
[edit]
[-] netbus-brute.nse
[edit]
[-] ms-sql-hasdbaccess.nse
[edit]
[-] gopher-ls.nse
[edit]
[-] asn-query.nse
[edit]
[-] firewall-bypass.nse
[edit]
[-] redis-brute.nse
[edit]
[-] dpap-brute.nse
[edit]
[-] imap-capabilities.nse
[edit]
[-] smtp-vuln-cve2010-4344.nse
[edit]
[-] tls-nextprotoneg.nse
[edit]
[-] upnp-info.nse
[edit]
[-] http-icloud-findmyiphone.nse
[edit]
[-] ventrilo-info.nse
[edit]
[-] hostmap-ip2hosts.nse
[edit]
[-] wdb-version.nse
[edit]
[-] http-qnap-nas-info.nse
[edit]
[-] smb-enum-groups.nse
[edit]
[-] address-info.nse
[edit]
[-] smb-mbenum.nse
[edit]
[-] dns-srv-enum.nse
[edit]
[-] http-iis-webdav-vuln.nse
[edit]
[-] broadcast-listener.nse
[edit]
[-] http-default-accounts.nse
[edit]
[-] mysql-audit.nse
[edit]
[-] bittorrent-discovery.nse
[edit]
[-] reverse-index.nse
[edit]
[-] smb-os-discovery.nse
[edit]
[-] smtp-strangeport.nse
[edit]
[-] socks-open-proxy.nse
[edit]
[-] http-vhosts.nse
[edit]
[-] broadcast-upnp-info.nse
[edit]
[-] afp-serverinfo.nse
[edit]
[-] targets-ipv6-multicast-slaac.nse
[edit]
[-] ldap-novell-getpass.nse
[edit]
[-] nfs-showmount.nse
[edit]
[-] http-vuln-cve2012-1823.nse
[edit]
[-] stun-version.nse
[edit]
[-] http-fileupload-exploiter.nse
[edit]
[-] vnc-info.nse
[edit]
[-] http-axis2-dir-traversal.nse
[edit]
[-] ssh-hostkey.nse
[edit]
[-] http-phpmyadmin-dir-traversal.nse
[edit]
[-] hadoop-jobtracker-info.nse
[edit]
[-] http-stored-xss.nse
[edit]
[-] hbase-region-info.nse
[edit]
[-] broadcast-ataoe-discover.nse
[edit]
[-] dns-check-zone.nse
[edit]
[-] rdp-enum-encryption.nse
[edit]
[-] ms-sql-query.nse
[edit]
[-] http-wordpress-plugins.nse
[edit]
[-] irc-info.nse
[edit]
[-] rmi-vuln-classloader.nse
[edit]
[-] ssl-known-key.nse
[edit]
[-] mysql-dump-hashes.nse
[edit]
[-] rexec-brute.nse
[edit]
[-] mmouse-exec.nse
[edit]
[-] vmauthd-brute.nse
[edit]
[-] dns-ip6-arpa-scan.nse
[edit]
[-] smb-system-info.nse
[edit]
[-] irc-brute.nse
[edit]
[-] broadcast-versant-locate.nse
[edit]
[-] xmpp-brute.nse
[edit]
[-] ldap-search.nse
[edit]
[-] http-put.nse
[edit]
[-] banner.nse
[edit]
[-] http-adobe-coldfusion-apsa1301.nse
[edit]
[-] llmnr-resolve.nse
[edit]
[-] domino-enum-users.nse
[edit]
[-] broadcast-ms-sql-discover.nse
[edit]
[-] telnet-brute.nse
[edit]
[-] isns-info.nse
[edit]
[-] http-userdir-enum.nse
[edit]
[-] smb-enum-users.nse
[edit]
[-] dns-nsid.nse
[edit]
[-] ndmp-version.nse
[edit]
[-] voldemort-info.nse
[edit]
[-] sslv2.nse
[edit]
[-] redis-info.nse
[edit]
[-] drda-brute.nse
[edit]
[-] smtp-vuln-cve2011-1720.nse
[edit]
[-] skypev2-version.nse
[edit]
[-] http-open-proxy.nse
[edit]
[-] irc-unrealircd-backdoor.nse
[edit]
[-] ssl-date.nse
[edit]
[-] couchdb-databases.nse
[edit]
[-] snmp-win32-software.nse
[edit]
[-] whois.nse
[edit]
[-] http-email-harvest.nse
[edit]
[-] http-virustotal.nse
[edit]
[-] broadcast-pim-discovery.nse
[edit]
[-] distcc-cve2004-2687.nse
[edit]
[-] http-exif-spider.nse
[edit]
[-] couchdb-stats.nse
[edit]
[-] rpc-grind.nse
[edit]
[-] finger.nse
[edit]
[-] metasploit-msgrpc-brute.nse
[edit]
[-] http-waf-fingerprint.nse
[edit]
[-] http-config-backup.nse
[edit]
[-] http-vuln-cve2010-2861.nse
[edit]
[-] ipv6-ra-flood.nse
[edit]
[-] http-phpself-xss.nse
[edit]
[-] http-sql-injection.nse
[edit]
[-] telnet-encryption.nse
[edit]
[-] jdwp-exec.nse
[edit]
[-] hddtemp-info.nse
[edit]
[-] metasploit-info.nse
[edit]
[-] ipidseq.nse
[edit]
[-] http-auth.nse
[edit]
[-] ncp-enum-users.nse
[edit]
[-] sip-enum-users.nse
[edit]
[-] daap-get-library.nse
[edit]
[-] socks-auth-info.nse
[edit]
[-] broadcast-dhcp-discover.nse
[edit]
[-] http-vuln-cve2009-3960.nse
[edit]
[-] http-coldfusion-subzero.nse
[edit]
[-] mongodb-databases.nse
[edit]
[-] xdmcp-discover.nse
[edit]
[-] http-chrono.nse
[edit]
[-] netbus-auth-bypass.nse
[edit]
[-] drda-info.nse
[edit]
[-] membase-http-info.nse
[edit]
[-] smb-flood.nse
[edit]
[-] dns-zeustracker.nse
[edit]
[-] http-apache-negotiation.nse
[edit]
[-] iscsi-info.nse
[edit]
[-] smb-server-stats.nse
[edit]
[-] mysql-vuln-cve2012-2122.nse
[edit]
[-] dns-service-discovery.nse
[edit]
[-] creds-summary.nse
[edit]
[-] oracle-sid-brute.nse
[edit]
[-] dns-recursion.nse
[edit]
[-] broadcast-pc-anywhere.nse
[edit]
[-] http-slowloris-check.nse
[edit]
[-] snmp-brute.nse
[edit]
[-] ftp-proftpd-backdoor.nse
[edit]
[-] imap-brute.nse
[edit]
[-] gkrellm-info.nse
[edit]
[-] versant-info.nse
[edit]
[-] svn-brute.nse
[edit]
[-] hadoop-datanode-info.nse
[edit]
[-] informix-brute.nse
[edit]
[-] mmouse-brute.nse
[edit]
[-] samba-vuln-cve-2012-1182.nse
[edit]
[-] broadcast-ping.nse
[edit]
[-] unusual-port.nse
[edit]
[-] smtp-brute.nse
[edit]
[-] http-vuln-cve2013-0156.nse
[edit]
[-] http-trace.nse
[edit]
[-] rmi-dumpregistry.nse
[edit]
[-] dns-blacklist.nse
[edit]
[-] ldap-brute.nse
[edit]
[-] pcanywhere-brute.nse
[edit]
[-] dns-client-subnet-scan.nse
[edit]
[-] snmp-win32-shares.nse
[edit]