diff --git a/nselib/data/packetdecoders.lua b/nselib/data/packetdecoders.lua index 5fd8144a8..3e3a5a091 100644 --- a/nselib/data/packetdecoders.lua +++ b/nselib/data/packetdecoders.lua @@ -197,6 +197,7 @@ Decoders = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end -- EIGRP is IP protocol 88 (0x58), so verify this if ( p.ip_p ~= 88 ) then return end @@ -250,6 +251,7 @@ Decoders = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end -- EIGRP is IP protocol 88 (0x58), so verify this if ( p.ip_p ~= 88 ) then return end @@ -294,6 +296,7 @@ Decoders = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end -- IP Protocol is 89 for OSPF if p.ip_p ~= 89 then return end @@ -368,6 +371,7 @@ udp = { process = function(self, layer3) local dhcp = require("dhcp") local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) -- the dhcp.parse function isn't optimal for doing @@ -421,6 +425,7 @@ udp = { local netbios = require('netbios') local tab = require('tab') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local dresp = dns.decode(data) @@ -472,6 +477,7 @@ udp = { process = function(self, layer3) local netbios = require('netbios') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local ip, src, dst = string.unpack(">c4 xxxxxx c34 c34", data, 5) @@ -508,6 +514,7 @@ udp = { process = function(self, layer3) local tab = require('tab') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local dhcp6 = require("dhcp6") @@ -544,6 +551,7 @@ udp = { process = function(self, layer3) local tab = require('tab') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local function split(str) @@ -596,6 +604,7 @@ udp = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local headers = stringaux.strsplit("\r\n", data) @@ -631,6 +640,7 @@ udp = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local State = { @@ -682,6 +692,7 @@ udp = { process = function(self, layer3) local json = require("json") local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local status, info = json.parse(data) if ( not(status) ) then @@ -738,6 +749,7 @@ udp = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) if ( data:match("^eIPAD") ) then @@ -776,6 +788,7 @@ udp = { process = function(self, layer3) local dns = require('dns') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local dresp = dns.decode(data) local name @@ -878,6 +891,7 @@ udp = { local tab = require('tab') local dns = require('dns') local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) local resp = dns.decode(data) @@ -911,6 +925,7 @@ udp = { process = function(self, layer3) local p = packet.Packet:new( layer3, #layer3 ) + if not p then return end local data = layer3:sub(p.udp_offset + 9) if ( data:match("^SpotUdp") ) then diff --git a/nselib/multicast.lua b/nselib/multicast.lua index ccdb72a32..62e189286 100644 --- a/nselib/multicast.lua +++ b/nselib/multicast.lua @@ -109,8 +109,7 @@ mld_query = function( if_nfo, arg_timeout ) if status then local l2reply = packet.Frame:new(layer2) local l3reply = packet.Packet:new(layer3, length, true) - local target_ip = l3reply.ip_src - if l3reply.ip6_nhdr == packet.MLD_LISTENER_REPORT or l3reply.ip6_nhdr == packet.MLDV2_LISTENER_REPORT then + if l3reply and (l3reply.ip6_nhdr == packet.MLD_LISTENER_REPORT or l3reply.ip6_nhdr == packet.MLDV2_LISTENER_REPORT) then table.insert( nmap.registry[reg_entry], { if_nfo.device, l2reply, l3reply } diff --git a/scripts/broadcast-eigrp-discovery.nse b/scripts/broadcast-eigrp-discovery.nse index 442e9f1f0..c74a5326e 100644 --- a/scripts/broadcast-eigrp-discovery.nse +++ b/scripts/broadcast-eigrp-discovery.nse @@ -132,23 +132,25 @@ local eigrpListener = function(interface, timeout, responses) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - eigrp_raw = string.sub(l3data, p.ip_hl*4 + 1) - -- Check if it is an EIGRPv2 Update - if eigrp_raw:byte(1) == 0x02 and eigrp_raw:byte(2) == 0x01 then - -- Skip if did get the info from this router before - if not routers[p.ip_src] then - -- Parse header - response = eigrp.EIGRP.parse(eigrp_raw) - response.src = p.ip_src - response.interface = interface.shortname - end - if response then - -- See, if it has routing information - for _,tlv in pairs(response.tlvs) do - if eigrp.EIGRP.isRoutingTLV(tlv.type) then - routers[p.ip_src] = true - table.insert(responses, response) - break + if p then + eigrp_raw = string.sub(l3data, p.ip_hl*4 + 1) + -- Check if it is an EIGRPv2 Update + if eigrp_raw:byte(1) == 0x02 and eigrp_raw:byte(2) == 0x01 then + -- Skip if did get the info from this router before + if not routers[p.ip_src] then + -- Parse header + response = eigrp.EIGRP.parse(eigrp_raw) + response.src = p.ip_src + response.interface = interface.shortname + end + if response then + -- See, if it has routing information + for _,tlv in pairs(response.tlvs) do + if eigrp.EIGRP.isRoutingTLV(tlv.type) then + routers[p.ip_src] = true + table.insert(responses, response) + break + end end end end @@ -178,13 +180,15 @@ local asListener = function(interface, timeout, astab) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - eigrp_raw = string.sub(l3data, p.ip_hl*4 + 1) - -- Listen for EIGRPv2 Hello packets - if eigrp_raw:byte(1) == 0x02 and eigrp_raw:byte(2) == 0x05 then - eigrp_hello = eigrp.EIGRP.parse(eigrp_raw) - if eigrp_hello and eigrp_hello.as then - table.insert(astab, eigrp_hello.as) - break + if p then + eigrp_raw = string.sub(l3data, p.ip_hl*4 + 1) + -- Listen for EIGRPv2 Hello packets + if eigrp_raw:byte(1) == 0x02 and eigrp_raw:byte(2) == 0x05 then + eigrp_hello = eigrp.EIGRP.parse(eigrp_raw) + if eigrp_hello and eigrp_hello.as then + table.insert(astab, eigrp_hello.as) + break + end end end end diff --git a/scripts/broadcast-igmp-discovery.nse b/scripts/broadcast-igmp-discovery.nse index 415c782a2..16267f109 100644 --- a/scripts/broadcast-igmp-discovery.nse +++ b/scripts/broadcast-igmp-discovery.nse @@ -164,23 +164,25 @@ local igmpListener = function(interface, timeout, responses) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - igmp_raw = string.sub(l3data, p.ip_hl*4 + 1) if p then - -- check the first byte before sending to the parser - -- response 0x12 == Membership Response version 1 - -- response 0x16 == Membership Response version 2 - -- response 0x22 == Membership Response version 3 - local igmptype = igmp_raw:byte(1) - if igmptype == 0x12 or igmptype == 0x16 or igmptype == 0x22 then - response = igmpParse(igmp_raw) - if response then - response.src = p.ip_src - response.interface = interface.shortname - -- Many hosts return more than one same response message - -- this is to not output duplicates - if not devices[response.src..response.type..(response.group or response.ngroups)] then - devices[response.src..response.type..(response.group or response.ngroups)] = true - table.insert(responses, response) + igmp_raw = string.sub(l3data, p.ip_hl*4 + 1) + if p then + -- check the first byte before sending to the parser + -- response 0x12 == Membership Response version 1 + -- response 0x16 == Membership Response version 2 + -- response 0x22 == Membership Response version 3 + local igmptype = igmp_raw:byte(1) + if igmptype == 0x12 or igmptype == 0x16 or igmptype == 0x22 then + response = igmpParse(igmp_raw) + if response then + response.src = p.ip_src + response.interface = interface.shortname + -- Many hosts return more than one same response message + -- this is to not output duplicates + if not devices[response.src..response.type..(response.group or response.ngroups)] then + devices[response.src..response.type..(response.group or response.ngroups)] = true + table.insert(responses, response) + end end end end diff --git a/scripts/broadcast-ospf2-discover.nse b/scripts/broadcast-ospf2-discover.nse index 20c5bf0fa..12fe9eda4 100644 --- a/scripts/broadcast-ospf2-discover.nse +++ b/scripts/broadcast-ospf2-discover.nse @@ -316,73 +316,75 @@ local ospfListen = function(interface, timeout) if status then stdnse.print_debug(2, "Packet received on interface %s.", interface.shortname) local p = packet.Packet:new(l3_data, #l3_data) - local ospf_raw = string.sub(l3_data, p.ip_hl * 4 + 1) - if ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_HELLO then - stdnse.print_debug(2, "OSPFv2 Hello packet detected.") + if p then + local ospf_raw = string.sub(l3_data, p.ip_hl * 4 + 1) + if ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_HELLO then + stdnse.print_debug(2, "OSPFv2 Hello packet detected.") - local ospf_hello = ospf.OSPF.Hello.parse(ospf_raw) - stdnse.print_debug(2, "Captured OSPFv2 Hello packet with the following parameters:") - ospfDumpHello(ospf_hello) + local ospf_hello = ospf.OSPF.Hello.parse(ospf_raw) + stdnse.print_debug(2, "Captured OSPFv2 Hello packet with the following parameters:") + ospfDumpHello(ospf_hello) - -- Additional checks required for message digest authentication - if ospf_hello.header.auth_type == 0x02 then - if not md5_key then - return fail("Argument md5_key must be present when message digest authentication is disclosed.") - elseif not have_ssl then - return fail("Cannot handle message digest authentication unless openssl is compiled in.") + -- Additional checks required for message digest authentication + if ospf_hello.header.auth_type == 0x02 then + if not md5_key then + return fail("Argument md5_key must be present when message digest authentication is disclosed.") + elseif not have_ssl then + return fail("Cannot handle message digest authentication unless openssl is compiled in.") + end end - end - ospfReplyHello(interface, ospf_hello) - start = nmap.clock_ms() - elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_DBDESC then - stdnse.print_debug(2, "OSPFv2 Database Description packet detected.") + ospfReplyHello(interface, ospf_hello) + start = nmap.clock_ms() + elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_DBDESC then + stdnse.print_debug(2, "OSPFv2 Database Description packet detected.") - local ospf_db_desc = ospf.OSPF.DBDescription.parse(ospf_raw) - stdnse.print_debug(2, "Captured OSPFv2 Database Description packet with the following parameters:") - ospfDumpDBDesc(ospf_db_desc) + local ospf_db_desc = ospf.OSPF.DBDescription.parse(ospf_raw) + stdnse.print_debug(2, "Captured OSPFv2 Database Description packet with the following parameters:") + ospfDumpDBDesc(ospf_db_desc) - if not ospfReplyDBDesc(interface, string.sub(l2_data, 7, 12), ospf_db_desc) then - return - end - elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_LSUPD then - stdnse.print_debug(2, "OSPFv2 LS Update packet detected.") + if not ospfReplyDBDesc(interface, string.sub(l2_data, 7, 12), ospf_db_desc) then + return + end + elseif ospf_raw:byte(1) == 0x02 and ospf_raw:byte(2) == OSPF_MSG_LSUPD then + stdnse.print_debug(2, "OSPFv2 LS Update packet detected.") - local ospf_ls_upd = ospf.OSPF.LSUpdate.parse(ospf_raw) - stdnse.print_debug(2, "Captured OSPFv2 LS Update packet with the following parameters:") - ospfDumpLSUpdate(ospf_ls_upd) + local ospf_ls_upd = ospf.OSPF.LSUpdate.parse(ospf_raw) + stdnse.print_debug(2, "Captured OSPFv2 LS Update packet with the following parameters:") + ospfDumpLSUpdate(ospf_ls_upd) - local targets = {} - for i, lsa in ipairs(ospf_ls_upd.lsas) do - -- Only Type 1 (Router-LSA) and Type 5 (AS-External-LSA) are supported at the moment - if lsa.header.type == 1 then - for j, link in ipairs(lsa.links) do - if link.type == 3 then - local target = link.id .. ipOps.subnet_to_cidr(link.data) - targets[target] = 1 + local targets = {} + for i, lsa in ipairs(ospf_ls_upd.lsas) do + -- Only Type 1 (Router-LSA) and Type 5 (AS-External-LSA) are supported at the moment + if lsa.header.type == 1 then + for j, link in ipairs(lsa.links) do + if link.type == 3 then + local target = link.id .. ipOps.subnet_to_cidr(link.data) + targets[target] = 1 + end + end + elseif lsa.header.type == 5 then + local target = lsa.header.id .. ipOps.subnet_to_cidr(lsa.netmask) + targets[target] = 1 + end + end + local output = stdnse.output_table() + if next(targets) then + local out_links = {} + output["Area ID"] = ipOps.fromdword(ospf_ls_upd.header.area_id) + output["External Routes"] = out_links + for t, _ in pairs(targets) do + table.insert(out_links, t) + if target.ALLOW_NEW_TARGETS then + target.add(t) end end - elseif lsa.header.type == 5 then - local target = lsa.header.id .. ipOps.subnet_to_cidr(lsa.netmask) - targets[target] = 1 - end - end - local output = stdnse.output_table() - if next(targets) then - local out_links = {} - output["Area ID"] = ipOps.fromdword(ospf_ls_upd.header.area_id) - output["External Routes"] = out_links - for t, _ in pairs(targets) do - table.insert(out_links, t) - if target.ALLOW_NEW_TARGETS then - target.add(t) + if not target.ALLOW_NEW_TARGETS then + stdnse.verbose("Use the newtargets script-arg to add the results as targets") end end - if not target.ALLOW_NEW_TARGETS then - stdnse.verbose("Use the newtargets script-arg to add the results as targets") - end + return output end - return output end end end diff --git a/scripts/broadcast-pim-discovery.nse b/scripts/broadcast-pim-discovery.nse index 6af27fcee..69067cb6b 100644 --- a/scripts/broadcast-pim-discovery.nse +++ b/scripts/broadcast-pim-discovery.nse @@ -111,10 +111,12 @@ local helloListen = function(interface, timeout, responses) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - hello_raw = string.sub(l3data, p.ip_hl*4 + 1) - -- Check that PIM Type is Hello - if p and hello_raw:byte(1) == 0x20 then - table.insert(responses, p.ip_src) + if p then + hello_raw = string.sub(l3data, p.ip_hl*4 + 1) + -- Check that PIM Type is Hello + if p and hello_raw:byte(1) == 0x20 then + table.insert(responses, p.ip_src) + end end end end diff --git a/scripts/broadcast-ping.nse b/scripts/broadcast-ping.nse index a22a6322e..40aa3b629 100644 --- a/scripts/broadcast-ping.nse +++ b/scripts/broadcast-ping.nse @@ -193,14 +193,18 @@ local broadcast_if = function(if_table,icmp_responders) -- Do stuff with packet local icmpreply = packet.Packet:new(l3data,plen,false) - -- We check whether the packet is parsed ok, and whether the ICMP ID of the sent packet - -- is the same with the ICMP ID of the received packet. We don't want ping probes interfering - local icmp_id = icmpreply:raw(icmpreply.icmp_offset+4,2) - if icmpreply:ip_parse() and icmp_ids[icmp_id] then - if not icmp_responders[icmpreply.ip_src] then - -- [key = IP]=MAC - local mac_pretty = stdnse.format_mac(l2:sub(7,12)) - icmp_responders[icmpreply.ip_src] = mac_pretty + if icmpreply then + -- We check whether the packet is parsed ok, and whether the ICMP ID of the sent packet + -- is the same with the ICMP ID of the received packet. We don't want ping probes interfering + local icmp_id = icmpreply:raw(icmpreply.icmp_offset+4,2) + if icmpreply:ip_parse() and icmp_ids[icmp_id] then + if not icmp_responders[icmpreply.ip_src] then + -- [key = IP]=MAC + local mac_pretty = stdnse.format_mac(l2:sub(7,12)) + icmp_responders[icmpreply.ip_src] = mac_pretty + end + else + stdnse.debug1("Erroneous ICMP packet received; Cannot parse IP header.") end else stdnse.debug1("Erroneous ICMP packet received; Cannot parse IP header.") diff --git a/scripts/firewalk.nse b/scripts/firewalk.nse index 31b4d31eb..f4ba444b2 100644 --- a/scripts/firewalk.nse +++ b/scripts/firewalk.nse @@ -456,7 +456,7 @@ local Firewalk_v4 = { -- @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 + return ip and ip.ip_bin_dst == src and ip.ip_p == packet.IPPROTO_ICMP and ip.icmp_type == ICMP_TIME_EXCEEDEDv4 end, @@ -467,7 +467,7 @@ local Firewalk_v4 = { 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 + if not ip or ip.ip_p ~= packet.IPPROTO_ICMP or ip.icmp_type ~= ICMP_TIME_EXCEEDEDv4 then return end @@ -475,7 +475,7 @@ local Firewalk_v4 = { local ip2 = packet.Packet:new(is, is:len(), true) -- check ICMP payload - if ip2.ip_bin_src == scanner.target.bin_ip_src and + if ip2 and ip2.ip_bin_src == scanner.target.bin_ip_src and ip2.ip_bin_dst == scanner.target.bin_ip then -- layer 4 checks @@ -522,7 +522,7 @@ local Firewalk_v6 = { -- @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 + return ip and ip.ip_bin_dst == src and ip.ip_p == packet.IPPROTO_ICMPV6 and ip.icmpv6_type == ICMP_TIME_EXCEEDEDv6 end, @@ -533,7 +533,7 @@ local Firewalk_v6 = { 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 + if not ip or ip.ip_p ~= packet.IPPROTO_ICMPV6 or ip.icmpv6_type ~= ICMP_TIME_EXCEEDEDv6 then return end @@ -541,7 +541,7 @@ local Firewalk_v6 = { local ip2 = packet.Packet:new(is) -- check ICMP payload - if ip2.ip_bin_src == scanner.target.bin_ip_src and + if ip2 and ip2.ip_bin_src == scanner.target.bin_ip_src and ip2.ip_bin_dst == scanner.target.bin_ip then -- layer 4 checks diff --git a/scripts/firewall-bypass.nse b/scripts/firewall-bypass.nse index b2e75a49a..4b67f2063 100644 --- a/scripts/firewall-bypass.nse +++ b/scripts/firewall-bypass.nse @@ -115,20 +115,11 @@ ftp_helper = { local f = packet.Frame:new(l2data) local p = packet.Packet:new(l3data, #l3data) - if isIp4 then - if not p:ip_parse() then - -- An error happened - stdnse.debug1("Couldn't parse IPv4 sniffed packet.") - sniffer:pcap_close() - return false - end - else - if not p:ip6_parse() then - -- An error happened - stdnse.debug1("Couldn't parse IPv6 sniffed packet.") - sniffer:pcap_close() - return false - end + if not p or (isIp4 and not p:ip_parse()) or (not isIp4 and not p:ip6_parse()) then + -- An error happened + stdnse.debug1("Couldn't parse sniffed packet.") + sniffer:pcap_close() + return false end -- Spoof packet diff --git a/scripts/ipv6-node-info.nse b/scripts/ipv6-node-info.nse index 56f280aa0..485484d0d 100644 --- a/scripts/ipv6-node-info.nse +++ b/scripts/ipv6-node-info.nse @@ -247,7 +247,7 @@ local function handle_received_packet(buf) local text local p = packet.Packet:new(buf) - if p.icmpv6_type ~= ICMPv6_NODEINFORESP then + if not p or p.icmpv6_type ~= ICMPv6_NODEINFORESP then return end local qtype, flags, pos = string.unpack(">I2I2", p.buf, p.icmpv6_offset + 4) diff --git a/scripts/knx-gateway-discover.nse b/scripts/knx-gateway-discover.nse index 4559c2b61..4f480d349 100644 --- a/scripts/knx-gateway-discover.nse +++ b/scripts/knx-gateway-discover.nse @@ -194,10 +194,12 @@ local knxListen = function(interface, timeout, ips, results) status, _, _, l3data = listener:pcap_receive() if status then local p = packet.Packet:new(l3data, #l3data) - -- Skip IP and UDP headers - local knxMessage = string.sub(l3data, p.ip_hl*4 + 8 + 1) - local co = stdnse.new_thread(knxParseSearchResponse, ips, results, knxMessage) - threads[co] = true; + if p then + -- Skip IP and UDP headers + local knxMessage = string.sub(l3data, p.ip_hl*4 + 8 + 1) + local co = stdnse.new_thread(knxParseSearchResponse, ips, results, knxMessage) + threads[co] = true; + end end end diff --git a/scripts/llmnr-resolve.nse b/scripts/llmnr-resolve.nse index 2d56f34fb..a1b14b3e6 100644 --- a/scripts/llmnr-resolve.nse +++ b/scripts/llmnr-resolve.nse @@ -98,34 +98,36 @@ local llmnrListen = function(interface, timeout, result) status, _, _, l3data = listener:pcap_receive() if status then local p = packet.Packet:new(l3data, #l3data) - -- Skip IP and UDP headers - local llmnr = string.sub(l3data, p.ip_hl*4 + 8 + 1) - -- Flags - local trans, flags, questions = string.unpack(">I2 I2 I2", llmnr) + if p then + -- Skip IP and UDP headers + local llmnr = string.sub(l3data, p.ip_hl*4 + 8 + 1) + -- Flags + local trans, flags, questions = string.unpack(">I2 I2 I2", llmnr) - -- Make verifications - -- Message == Response bit - -- and 1 Question (hostname we requested) and - if ((flags >> 15) == 1) and questions == 0x01 then - stdnse.debug1("got response from %s", p.ip_src) - -- Skip header's 12 bytes - -- extract host length - local qlen, index = string.unpack(">B", llmnr, 13) - -- Skip hostname, null byte, type field and class field - index = index + qlen + 1 + 2 + 2 + -- Make verifications + -- Message == Response bit + -- and 1 Question (hostname we requested) and + if ((flags >> 15) == 1) and questions == 0x01 then + stdnse.debug1("got response from %s", p.ip_src) + -- Skip header's 12 bytes + -- extract host length + local qlen, index = string.unpack(">B", llmnr, 13) + -- Skip hostname, null byte, type field and class field + index = index + qlen + 1 + 2 + 2 - -- Now, answer record - local response, alen = {} - -- Extract hostname with the correct case sensitivity. - response.hostname, index = string.unpack(">s1x", llmnr, index) + -- Now, answer record + local response, alen = {} + -- Extract hostname with the correct case sensitivity. + response.hostname, index = string.unpack(">s1x", llmnr, index) - -- skip type, class, ttl, dlen - index = index + 2 + 2 + 4 + 2 - response.address, index = string.unpack(">c4", llmnr, index) - response.address = ipOps.str_to_ip(response.address) - table.insert(result, response) - else - stdnse.debug1("skipped llmnr response.") + -- skip type, class, ttl, dlen + index = index + 2 + 2 + 4 + 2 + response.address, index = string.unpack(">c4", llmnr, index) + response.address = ipOps.str_to_ip(response.address) + table.insert(result, response) + else + stdnse.debug1("skipped llmnr response.") + end end end end diff --git a/scripts/mrinfo.nse b/scripts/mrinfo.nse index 3df9aae36..3bf6a8fe0 100644 --- a/scripts/mrinfo.nse +++ b/scripts/mrinfo.nse @@ -147,8 +147,8 @@ local mrinfoListen = function(interface, timeout, responses) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - mrinfo_raw = string.sub(l3data, p.ip_hl*4 + 1) if p then + mrinfo_raw = string.sub(l3data, p.ip_hl*4 + 1) -- Check that IGMP Type == DVMRP (0x13) and DVMRP code == Neighbor 2 (0x06) if mrinfo_raw:byte(1) == 0x13 and mrinfo_raw:byte(2) == 0x06 then response = mrinfoParse(mrinfo_raw) diff --git a/scripts/mtrace.nse b/scripts/mtrace.nse index e899226ba..1817feed9 100644 --- a/scripts/mtrace.nse +++ b/scripts/mtrace.nse @@ -264,8 +264,8 @@ local traceListener = function(interface, timeout, responses) status, _, _, l3data = listener:pcap_receive() if status then p = packet.Packet:new(l3data, #l3data) - trace_raw = string.sub(l3data, p.ip_hl*4 + 1) if p then + trace_raw = string.sub(l3data, p.ip_hl*4 + 1) -- Check that IGMP Type == 0x1e (Traceroute Response) if trace_raw:byte(1) == 0x1e then response = traceParse(trace_raw) diff --git a/scripts/path-mtu.nse b/scripts/path-mtu.nse index 6dc441c43..f41d11c28 100644 --- a/scripts/path-mtu.nse +++ b/scripts/path-mtu.nse @@ -106,6 +106,9 @@ end -- Checks how we should react to this packet local checkpkt = function(reply, orig) local ip = packet.Packet:new(reply, reply:len()) + if not ip then + return "recap" + end if ip.ip_p == IPPROTO_ICMP then if ip.icmp_type ~= 3 then @@ -117,7 +120,7 @@ local checkpkt = function(reply, orig) local ip2 = packet.Packet:new(is, is:len()) -- Check sent packet against ICMP payload - if ip2.ip_p ~= IPPROTO_UDP or + if not ip2 or ip2.ip_p ~= IPPROTO_UDP or ip2.ip_p ~= orig.ip_p or ip2.ip_bin_src ~= orig.ip_bin_src or ip2.ip_bin_dst ~= orig.ip_bin_dst or @@ -151,7 +154,7 @@ end -- different hosts local check = function(layer3) local ip = packet.Packet:new(layer3, layer3:len()) - return ip.ip_bin_dst + return ip and ip.ip_bin_dst end -- Updates a packet's info and calculates checksum diff --git a/scripts/qscan.nse b/scripts/qscan.nse index 2228adf65..a7b496572 100644 --- a/scripts/qscan.nse +++ b/scripts/qscan.nse @@ -178,6 +178,7 @@ end -- @return Destination and source IP addresses and TCP ports local check = function(layer3) local ip = packet.Packet:new(layer3, layer3:len()) + if not ip then return nil end return string.pack('>c4c4I2I2', ip.ip_bin_dst, ip.ip_bin_src, ip.tcp_dport, ip.tcp_sport) end diff --git a/scripts/snmp-brute.nse b/scripts/snmp-brute.nse index a284dbc96..03ff4a00e 100644 --- a/scripts/snmp-brute.nse +++ b/scripts/snmp-brute.nse @@ -190,7 +190,7 @@ local sniff_snmp_responses = function(host, port, lport, result) if status then local p = packet.Packet:new(l3,#l3) - if not p:udp_parse() then + if not p or not p:udp_parse() then --shouldn't happen result.status = false result.msg = "Wrong type of packet received" diff --git a/scripts/targets-ipv6-multicast-invalid-dst.nse b/scripts/targets-ipv6-multicast-invalid-dst.nse index e4c4323b4..84f8d304b 100644 --- a/scripts/targets-ipv6-multicast-invalid-dst.nse +++ b/scripts/targets-ipv6-multicast-invalid-dst.nse @@ -123,13 +123,15 @@ local function single_interface_broadcast(if_nfo, results) local l2reply = packet.Frame:new(layer2) if l2reply.mac_dst == src_mac then local reply = packet.Packet:new(layer3) - local target_str = reply.ip_src - if not results[target_str] then - if target.ALLOW_NEW_TARGETS then - target.add(target_str) + if reply then + local target_str = reply.ip_src + if not results[target_str] then + if target.ALLOW_NEW_TARGETS then + target.add(target_str) + end + results[#results + 1] = { address = target_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device } + results[target_str] = true end - results[#results + 1] = { address = target_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device } - results[target_str] = true end end end diff --git a/scripts/targets-ipv6-multicast-slaac.nse b/scripts/targets-ipv6-multicast-slaac.nse index e683d5fed..d79010ca0 100644 --- a/scripts/targets-ipv6-multicast-slaac.nse +++ b/scripts/targets-ipv6-multicast-slaac.nse @@ -170,7 +170,7 @@ local function single_interface_broadcast(if_nfo, results) local l2reply = packet.Frame:new(layer2) if string.sub(l2reply.mac_dst, 1, 3) == string.sub(expected_mac_dst_prefix, 1, 3) then local reply = packet.Packet:new(layer3) - if reply.ip_bin_src == expected_ip6_src and + if reply and reply.ip_bin_src == expected_ip6_src and string.sub(expected_ip6_dst_prefix,1,12) == string.sub(reply.ip_bin_dst,1,12) then local ula_target_addr_str = ipOps.str_to_ip(reply.ns_target) local identifier = get_identifier(reply.ns_target) diff --git a/scripts/targets-sniffer.nse b/scripts/targets-sniffer.nse index 4bb616261..7037469c3 100644 --- a/scripts/targets-sniffer.nse +++ b/scripts/targets-sniffer.nse @@ -61,6 +61,7 @@ end -- Returns an array of address strings. local function get_ip_addresses(layer3) local ip = packet.Packet:new(layer3, layer3:len()) + if not ip then return {} end return { ipOps.str_to_ip(ip.ip_bin_src), ipOps.str_to_ip(ip.ip_bin_dst) } end diff --git a/scripts/url-snarf.nse b/scripts/url-snarf.nse index 05da22c4d..fd5c05b3f 100644 --- a/scripts/url-snarf.nse +++ b/scripts/url-snarf.nse @@ -127,17 +127,19 @@ action = function() local status, len, _, l3 = socket:pcap_receive() if ( status ) then local p = packet.Packet:new( l3, #l3 ) - local pos = p.tcp_data_offset + 1 - local http_data = p.buf:sub(pos) + if p then + local pos = p.tcp_data_offset + 1 + local http_data = p.buf:sub(pos) - local url = get_url(http_data) - if ( url ) then - counter = counter + 1 - if ( not(arg_nostdout) ) then - print(p.ip_src, url) - end - if ( arg_outfile ) then - log_entry(p.ip_src, url) + local url = get_url(http_data) + if ( url ) then + counter = counter + 1 + if ( not(arg_nostdout) ) then + print(p.ip_src, url) + end + if ( arg_outfile ) then + log_entry(p.ip_src, url) + end end end end