diff --git a/scripts/broadcast-igmp-discovery.nse b/scripts/broadcast-igmp-discovery.nse index 59deb3ad2..26b23afcf 100644 --- a/scripts/broadcast-igmp-discovery.nse +++ b/scripts/broadcast-igmp-discovery.nse @@ -1,7 +1,6 @@ local nmap = require "nmap" local stdnse = require "stdnse" local table = require "table" -local bin = require "bin" local packet = require "packet" local ipOps = require "ipOps" local target = require "target" @@ -113,42 +112,30 @@ local igmpParse = function(data) local response = {} local group, source -- Report type (0x12 == v1, 0x16 == v2, 0x22 == v3) - index, response.type = bin.unpack(">C", data, index) + response.type, index = string.unpack(">B", data, index) if response.type == 0x12 or response.type == 0x16 then - -- Max response time - index, response.maxrt = bin.unpack(">C", data, index) - -- Checksum - index, response.checksum = bin.unpack(">S", data, index) - -- Multicast group - index, response.group = bin.unpack(">I", data, index) - response.group = ipOps.fromdword(response.group) + -- Max response time, Checksum, Multicast group + response.maxrt, response.checksum, response.group, index = string.unpack(">B I2 c4", data, index) + response.group = ipOps.str_to_ip(response.group) return response elseif response.type == 0x22 and #data >= 12 then - -- Skip reserved byte - index = index + 1 - -- Checksum - index, response.checksum = bin.unpack(">S", data, index) - -- Skip reserved byte - index = index + 2 - -- Number of groups - index, response.ngroups = bin.unpack(">S", data, index) + -- Skip reserved byte, Checksum, Skip reserved bytes, Number of groups + response.checksum, response.ngroups, index = string.unpack(">x I2 xx I2", data, index) response.groups = {} for i=1,response.ngroups do group = {} -- Mode is either INCLUDE or EXCLUDE - index, group.mode = bin.unpack(">C", data, index) + group.mode, -- Auxiliary data length in the group record (in 32bits units) - index, group.auxdlen = bin.unpack(">C", data, index) + group.auxdlen, -- Number of source addresses - index, group.nsrc = bin.unpack(">S", data, index) - index, group.address = bin.unpack(">I", data, index) - group.address = ipOps.fromdword(group.address) + group.nsrc, + group.address, index = string.unpack(">BB I2 c4", data, index) + group.address = ipOps.str_to_ip(group.address) group.src = {} - if group.nsrc > 0 then - for i=1,group.nsrc do - index, source = bin.unpack(">I", data, index) - table.insert(group.src, ipOps.fromdword(source)) - end + for i=1,group.nsrc do + source, index = string.unpack(">c4", data, index) + table.insert(group.src, ipOps.str_to_ip(source)) end -- Skip auxiliary data index = index + group.auxdlen @@ -214,7 +201,7 @@ local igmpRaw = function(interface, version) end -- Let's craft an IGMP Membership Query - local igmp_raw = bin.pack(">CCSI", + local igmp_raw = string.pack(">BB I2 I4", 0x11, -- Membership Query, same for all versions version == 1 and 0 or 0x16, -- Max response time: 10 Seconds, for version 2 and 3 0, -- Checksum, calculated later @@ -222,18 +209,18 @@ local igmpRaw = function(interface, version) ) if version == 3 then - igmp_raw = bin.pack(">ACCSI", igmp_raw, + igmp_raw = igmp_raw .. string.pack(">BB I2", 0, -- Reserved = 4 bits (Should be zeroed) -- Supress Flag = 1 bit -- QRV (Querier's Robustness Variable) = 3 bits -- all are set to 0 0x10, -- QQIC (Querier's Query Interval Code) in seconds = Set to 0 to get insta replies. - 0x0001, -- Number of sources (in the next arrays) = 1 ( Our IP only) - ipOps.todword(interface.address) -- Source = Our IP address + 0x0001 -- Number of sources (in the next arrays) = 1 ( Our IP only) ) + .. ipOps.ip_to_str(interface.address) -- Source = Our IP address end - igmp_raw = igmp_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(igmp_raw)) .. igmp_raw:sub(5) + igmp_raw = igmp_raw:sub(1,2) .. string.pack(">I2", packet.in_cksum(igmp_raw)) .. igmp_raw:sub(5) return igmp_raw end @@ -267,7 +254,7 @@ igmpQuery = function(interface, version) sock:ethernet_open(interface.device) -- Ethernet IPv4 multicast, our ethernet address and type IP - local eth_hdr = bin.pack("HAH", "01 00 5e 00 00 01", interface.mac, "08 00") + local eth_hdr = "\x01\x00\x5e\x00\x00\x01" .. interface.mac .. "\x08\x00" sock:ethernet_send(eth_hdr .. igmp_packet.buf) sock:ethernet_close() end diff --git a/scripts/broadcast-pim-discovery.nse b/scripts/broadcast-pim-discovery.nse index 08adcf1bf..c14289156 100644 --- a/scripts/broadcast-pim-discovery.nse +++ b/scripts/broadcast-pim-discovery.nse @@ -1,7 +1,6 @@ local nmap = require "nmap" local packet = require "packet" local ipOps = require "ipOps" -local bin = require "bin" local stdnse = require "stdnse" local target = require "target" local table = require "table" @@ -55,18 +54,17 @@ end -- Generates a raw PIM Hello message. --@return hello Raw PIM Hello message local helloRaw = function() - local hello_raw = bin.pack(">CCSAAAA", + local hello_raw = string.pack(">BB I2", 0x20, -- Version: 2, Type: Hello (0) 0x00, -- Reserved - 0x0000, -- Checksum: Calculated later + 0x0000) -- Checksum: Calculated later -- Options (TLVs) - bin.pack(">SSS", 0x01, 0x02, 0x01), -- Hold time 1 second - bin.pack(">SSI", 0x14, 0x04, math.random(23456)), -- Generation ID: Random - bin.pack(">SSI", 0x13, 0x04, 0x01), -- DR Priority: 1 - bin.pack(">SSCCS", 0x15, 0x04, 0x01, 0x00, 0x00) -- State fresh capable: Version = 1, interval = 0, Reserved - ) + .. string.pack(">I2I2 I2", 0x01, 0x02, 0x01) -- Hold time 1 second + .. string.pack(">I2I2 I4", 0x14, 0x04, math.random(23456)) -- Generation ID: Random + .. string.pack(">I2I2 I4", 0x13, 0x04, 0x01) -- DR Priority: 1 + .. string.pack(">I2I2 BBI2", 0x15, 0x04, 0x01, 0x00, 0x00) -- State fresh capable: Version = 1, interval = 0, Reserved -- Calculate checksum - hello_raw = hello_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(hello_raw)) .. hello_raw:sub(5) + hello_raw = hello_raw:sub(1,2) .. string.pack(">I2", packet.in_cksum(hello_raw)) .. hello_raw:sub(5) return hello_raw end @@ -88,7 +86,7 @@ local helloQuery = function(interface, dstip) sock = nmap.new_dnet() sock:ethernet_open(interface.device) -- Ethernet multicast for PIM, our ethernet address and packet type IP - eth_hdr = bin.pack(">HAS", "01 00 5e 00 00 0d", interface.mac, 0x0800) + eth_hdr = "\x01\x00\x5e\x00\x00\x0d" .. interface.mac .. "\x08\x00" sock:ethernet_send(eth_hdr .. hello_packet.buf) sock:ethernet_close() end diff --git a/scripts/broadcast-ripng-discover.nse b/scripts/broadcast-ripng-discover.nse index 9087d004f..82f90dd08 100644 --- a/scripts/broadcast-ripng-discover.nse +++ b/scripts/broadcast-ripng-discover.nse @@ -1,7 +1,7 @@ -local bin = require "bin" local ipOps = require "ipOps" local nmap = require "nmap" local stdnse = require "stdnse" +local string = require "string" local tab = require "tab" local table = require "table" @@ -69,9 +69,8 @@ RIPng = { local rte = RIPng.RTE:new() local pos, ip - pos, ip, rte.tag, rte.prefix_len, rte.metric = bin.unpack(">A16SCC", data) - ip = select(2, bin.unpack("B" .. #ip, ip)) - rte.prefix = ipOps.bin_to_ip(ip) + ip, rte.tag, rte.prefix_len, rte.metric, pos = string.unpack(">c16 I2 BB", data) + rte.prefix = ipOps.str_to_ip(ip, 'inet6') return rte end, @@ -80,7 +79,7 @@ RIPng = { __tostring = function(self) local ipstr = ipOps.ip_to_str(self.prefix) assert(16 == #ipstr, "Invalid IPv6 address encountered") - return bin.pack(">ASCC", ipstr, self.tag, self.prefix_len, self.metric) + return ipstr .. string.pack(">I2 BB", self.tag, self.prefix_len, self.metric) end, @@ -107,7 +106,7 @@ RIPng = { -- Converts the whole request to a string __tostring = function(self) local RESERVED = 0 - local str = {bin.pack(">CCS", self.command, self.version, RESERVED)} + local str = {string.pack(">BB I2", self.command, self.version, RESERVED)} for _, rte in ipairs(self.entries) do str[#str+1] = tostring(rte) end @@ -134,7 +133,7 @@ RIPng = { local resp = RIPng.Response:new() local pos, _ - pos, resp.command, resp.version, _ = bin.unpack(">CCS", data) + resp.command, resp.version, _, pos = string.unpack(">BB I2", data) resp.entries = {} while( pos < #data ) do local e = RIPng.RTE.parse(data:sub(pos)) diff --git a/scripts/broadcast-sybase-asa-discover.nse b/scripts/broadcast-sybase-asa-discover.nse index 277816764..cbea5ea3f 100644 --- a/scripts/broadcast-sybase-asa-discover.nse +++ b/scripts/broadcast-sybase-asa-discover.nse @@ -1,7 +1,7 @@ -local bin = require "bin" local nmap = require "nmap" local os = require "os" local stdnse = require "stdnse" +local string = require "string" local table = require "table" description = [[ @@ -44,8 +44,9 @@ Ping = { -- returns the ping request as a string __tostring = function(self) - return bin.pack("HAH", "1b00003d0000000012", "CONNECTIONLESS_TDS", - "000000010000040005000500000102000003010104080000000000000000070204b1") + return stdnse.fromhex("1b00003d0000000012") + .. "CONNECTIONLESS_TDS" + .. stdnse.fromhex("000000010000040005000500000102000003010104080000000000000000070204b1") end }, @@ -68,7 +69,7 @@ Ping = { -- dbinstance.name and dbinstance.port fields parse = function(self) -- do a very basic length check - local pos, len = bin.unpack(">I", self.data) + local len, pos = string.unpack(">I4", self.data) len = len & 0x0000FFFF if ( len ~= #self.data ) then @@ -77,16 +78,16 @@ Ping = { end local connectionless_tds - pos, connectionless_tds = bin.unpack("p", self.data, 9) + connectionless_tds, pos = string.unpack("s1", self.data, 9) if ( connectionless_tds ~= "CONNECTIONLESS_TDS" ) then stdnse.debug2("Did not find the expected CONNECTIONLESS_TDS header") return end self.dbinstance = {} - pos, self.dbinstance.name = bin.unpack("p", self.data, 40) + self.dbinstance.name, pos = string.unpack("s1", self.data, 40) pos = pos + 2 - pos, self.dbinstance.port = bin.unpack(">S", self.data, pos) + self.dbinstance.port, pos = string.unpack(">I2", self.data, pos) end, } diff --git a/scripts/daap-get-library.nse b/scripts/daap-get-library.nse index 23351d223..a39fca41a 100644 --- a/scripts/daap-get-library.nse +++ b/scripts/daap-get-library.nse @@ -1,4 +1,3 @@ -local bin = require "bin" local http = require "http" local nmap = require "nmap" local shortport = require "shortport" @@ -57,7 +56,7 @@ portrule = shortport.port_or_service(3689, "daap") -- @param port table containing number and protocol fields. -- @return string containing the name of the library function getLibraryName( host, port ) - local _, libname, pos + local libname, pos local url = "daap://" .. host.ip .. "/server-info" local response = http.get( host, port, url, nil, nil, nil) @@ -68,10 +67,8 @@ function getLibraryName( host, port ) pos = string.find(response.body, "minm") if pos > 0 then - local len pos = pos + 4 - pos, len = bin.unpack( ">I", response.body, pos ) - pos, libname = bin.unpack( "A" .. len, response.body, pos ) + libname, pos = string.unpack( ">s4", response.body, pos ) end return libname @@ -90,14 +87,14 @@ local function getAttributeAsInt( data, name ) if pos and pos > 0 then pos = pos + 4 local len - pos, len = bin.unpack( ">I", data, pos ) + len, pos = string.unpack( ">I4", data, pos ) if ( len ~= 4 ) then stdnse.debug1("Unexpected length returned: %d", len ) return end - pos, attrib = bin.unpack( ">I", data, pos ) + attrib, pos = string.unpack( ">I4", data, pos ) end return attrib @@ -111,7 +108,7 @@ end -- @return number containing the session identity received from the server function getSessionId( host, port ) - local _, sessionid + local sessionid local response = http.get( host, port, "/login", nil, nil, nil ) if response ~= nil then @@ -129,7 +126,7 @@ end -- @return number containing the revision number for the library function getRevisionNumber( host, port, sessionid ) local url = "/update?session-id=" .. sessionid .. "&revision-number=1" - local _, revision + local revision local response = http.get( host, port, url, nil, nil, nil ) if response ~= nil then @@ -164,14 +161,8 @@ end -- @return pos number containing new position after reading string -- @return value string containing the string item that was read local function getStringItem( data, pos ) - local len - - pos, len = bin.unpack(">I", data, pos) - - if ( len > 0 ) then - return bin.unpack( "A"..len, data, pos ) - end - + local item, pos = string.unpack(">s4", data, pos) + return pos, item end local itemFetcher = {} @@ -194,7 +185,7 @@ parseItem = function( data, len ) local item = {} while( len - pos > 0 ) do - pos, name = bin.unpack( "A4", data, pos ) + name, pos = string.unpack( "c4", data, pos ) if itemFetcher[name] then pos, item[name] = itemFetcher[name](data, pos ) @@ -239,10 +230,10 @@ function getItems( host, port, sessionid, revid, dbid, limit ) pos = string.find(response.body, "mlit", pos) pos = pos + 4 - pos, len = bin.unpack( ">I", response.body, pos ) + len, pos = string.unpack( ">I4", response.body, pos ) if ( pos < response.body:len() and pos + len < response.body:len() ) then - pos, data = bin.unpack( "A" .. len, response.body, pos ) + data, pos = string.unpack( "c" .. len, response.body, pos ) else break end diff --git a/scripts/db2-das-info.nse b/scripts/db2-das-info.nse index 4e89dd089..22b305f25 100644 --- a/scripts/db2-das-info.nse +++ b/scripts/db2-das-info.nse @@ -1,4 +1,3 @@ -local bin = require "bin" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" @@ -134,8 +133,8 @@ function parse_db2_packet(packet) return end - local _, len = bin.unpack(">S", packet.data:sub(info_length_offset, info_length_offset + 1)) - _, response.version = bin.unpack("z", packet.data:sub(version_offset) ) + local len = string.unpack(">I2", packet.data, info_length_offset) + response.version = string.unpack("z", packet.data, version_offset) response.info_length = len - 4 response.info = packet.data:sub(info_offset, info_offset + response.info_length - (info_offset-info_length_offset)) @@ -187,12 +186,12 @@ function read_db2_packet(socket) stdnse.debug1("Got DB2DAS packet") - local _, endian = bin.unpack( "A2", packet.header.raw, ENDIANESS_OFFSET ) + local endian = string.unpack( "c2", packet.header.raw, ENDIANESS_OFFSET ) if endian == "9z" then - _, packet.header.data_len = bin.unpack("I", packet.header.raw, DATA_LENGTH_OFFSET ) + packet.header.data_len = string.unpack(">I4", packet.header.raw, DATA_LENGTH_OFFSET ) end total_len = header_len + packet.header.data_len @@ -269,8 +268,7 @@ function create_das_packet( magic, data ) packet.header.raw = "\x00\x00\x00\x00\x44\x42\x32\x44\x41\x53\x20\x20\x20\x20\x20\x20" .. "\x01\x04\x00\x00\x00\x10\x39\x7a\x00\x05\x00\x00\x00\x00\x00\x00" .. "\x00\x00\x00\x00" - .. bin.pack("C", magic) - .. bin.pack("s2", data, offset - 2) return offset, ("0x%s"):format(stdnse.tohex(field)) end, ["NSAP-PTR"] = parse_domain, @@ -373,7 +369,7 @@ local RD = { vp = string.byte(data, offset+3) vp = (vp >> 4) * 10 ^ (vp & 0x0f) / 100 offset = offset + 4 - offset, lat, lon, alt = bin.unpack(">III", data, offset) + lat, lon, alt, offset = string.unpack(">I4I4I4", data, offset) lat = (lat-2^31)/3600000 --degrees local latd = 'N' if lat < 0 then @@ -393,7 +389,7 @@ local RD = { --EID NIMLOC --related to Nimrod DARPA project (Patton1995) SRV = function(data, offset) local priority, weight, port, info - offset, priority, weight, port = bin.unpack(">SSS", data, offset) + priority, weight, port, offset = string.unpack(">I2I2I2", data, offset) offset, info = parse_domain(data, offset) return offset, string.format("%d %d %d %s", priority, weight, port, info) end, @@ -425,11 +421,11 @@ local RD = { return offset, string.format("%d %s %s", prefix, addr, name) end, DNAME = parse_domain, - SINK = function(data, offset) -- http://bgp.potaroo.net/ietf/all-ids/draft-eastlake-kitchen-sink-02.txt + SINK = function(data, offset) -- https://tools.ietf.org/html/draft-eastlake-kitchen-sink-02 local coding, subcoding, field coding = string.byte(data, offset) subcoding = string.byte(data, offset+1) - offset, field = bin.unpack("A" .. (bto16(data, offset-2)-2), data, offset+2) + field, offset = string.unpack("c" .. (bto16(data, offset-2)-2), data, offset+2) return offset, string.format("%d %d %s", coding, subcoding, stdnse.tohex(field)) end, --OPT APL DS @@ -467,7 +463,7 @@ function get_rdata(data, offset, ttype) return RD[typetab[ttype]](data, offset) else local field - offset, field = bin.unpack("A" .. bto16(data, offset-2), data, offset) + field, offset = string.unpack(">s2", data, offset - 2) return offset, ("hex: %s"):format(stdnse.tohex(field)) end end diff --git a/scripts/enip-info.nse b/scripts/enip-info.nse index 9d8423a44..591645efc 100644 --- a/scripts/enip-info.nse +++ b/scripts/enip-info.nse @@ -1,4 +1,3 @@ -local bin = require "bin" local ipOps = require "ipOps" local nmap = require "nmap" local shortport = require "shortport" @@ -1666,41 +1665,35 @@ action = function(host,port) return false, response end -- unpack the response command - local pos, command = bin.unpack("C", response, 1) + local command = string.byte(response, 1) -- unpack the response type id - local typeid - pos, typeid = bin.unpack("C", response, 27) + local typeid = string.byte(response, 27) -- if command is 0x63 if ( command == 0x63) then -- if typeid == 0x0c (req ident) if( typeid == 0x0c) then -- vendor number - local vennum - pos, vennum = bin.unpack("I", response, 37) - output["Device IP"] = ipOps.fromdword(dword) + local ip = string.unpack("c4", response, 37) + output["Device IP"] = ipOps.str_to_ip(ip) -- set Nmap output set_nmap(host, port) -- close socket diff --git a/scripts/http-exif-spider.nse b/scripts/http-exif-spider.nse index dc8465527..ab6a12a3c 100644 --- a/scripts/http-exif-spider.nse +++ b/scripts/http-exif-spider.nse @@ -30,7 +30,6 @@ local shortport = require 'shortport' local stdnse = require 'stdnse' local httpspider = require 'httpspider' local string = require 'string' -local bin = require 'bin' local table = require 'table' -- These definitions are copied/pasted/reformatted from the jhead-2.96 sourcecode @@ -338,7 +337,7 @@ portrule = shortport.http --@return the new position, and the value. local function unpack_rational(endian, data, pos) local v1, v2 - pos, v1, v2 = bin.unpack(endian .. "II", data, pos) + v1, v2, pos = string.unpack(endian .. "I4I4", data, pos) return pos, v1 / v2 end @@ -347,7 +346,7 @@ local function process_gps(data, pos, endian, result) local latitude, latitude_ref, longitude, longitude_ref -- The first entry in the gps section is a 16-bit size - pos, num_entries = bin.unpack(endian .. "S", data, pos) + num_entries, pos = string.unpack(endian .. "I2", data, pos) -- Loop through the entries to find the fun stuff for i=1, num_entries do @@ -403,8 +402,8 @@ local function parse_exif(exif_data) result = {} -- Read the verify the EXIF header - local pos, header1, header2, endian = bin.unpack(">ISS", exif_data, 1) - if(header1 ~= 0x45786966 or header2 ~= 0x0000) then + local header, endian, pos = string.unpack(">c6 I2", exif_data, 1) + if(header ~= "Exif\0\0") then return false, "Invalid EXIF header" end @@ -419,7 +418,7 @@ local function parse_exif(exif_data) end -- Read the first tiff header and the offset to the first data entry (should be 8) - pos, tiff_header_1, first_offset = bin.unpack(endian .. "SI", exif_data, pos) + tiff_header_1, first_offset, pos = string.unpack(endian .. "I2 I4", exif_data, pos) if(tiff_header_1 ~= 0x002A or first_offset ~= 0x00000008) then return false, "Invalid tiff header" end @@ -428,12 +427,12 @@ local function parse_exif(exif_data) pos = first_offset + 8 - 1 -- The first 16-bit value is the number of entries - local pos, num_entries = bin.unpack(endian .. "S", exif_data, pos) + local num_entries, pos = string.unpack(endian .. "I2", exif_data, pos) -- Loop through the entries for i=1,num_entries do -- Read the entry's header - pos, tag, format, components, value = bin.unpack(endian .. "SSII", exif_data, pos) + tag, format, components, value, pos = string.unpack(endian .. "I2 I2 I4 I4", exif_data, pos) -- Look at the tags we care about if(tag == TAG_GPSINFO) then @@ -442,15 +441,15 @@ local function parse_exif(exif_data) if(not(status)) then return false, result end - elseif(tag == TAG_MAKE) then - dummy, value = bin.unpack("z", exif_data, value + 8 - 1) - table.insert(result, string.format("Make: %s", value)) - elseif(tag == TAG_MODEL) then - dummy, value = bin.unpack("z", exif_data, value + 8 - 1) - table.insert(result, string.format("Model: %s", value)) - elseif(tag == TAG_DATETIME) then - dummy, value = bin.unpack("z", exif_data, value + 8 - 1) - table.insert(result, string.format("Date: %s", value)) + else + value = string.unpack("z", exif_data, value + 8 - 1) + if (tag == TAG_MAKE) then + table.insert(result, string.format("Make: %s", value)) + elseif(tag == TAG_MODEL) then + table.insert(result, string.format("Model: %s", value)) + elseif(tag == TAG_DATETIME) then + table.insert(result, string.format("Date: %s", value)) + end end end @@ -462,14 +461,14 @@ local function parse_jpeg(s) local pos, sig, marker, size, exif_data -- Parse the jpeg header, make sure it's valid (we expect 0xFFD8) - pos, sig = bin.unpack(">S", s, pos) + sig, pos = string.unpack(">I2", s, pos) if(sig ~= 0xFFD8) then return false, "Unexpected signature" end -- Parse the sections to find the exif marker (0xffe1) while(true) do - pos, marker, size = bin.unpack(">SS", s, pos) + marker, size, pos = string.unpack(">I2I2", s, pos) -- Check if we found the exif metadata section, break if we did if(marker == 0xffe1) then @@ -483,7 +482,7 @@ local function parse_jpeg(s) pos = pos + size - 2 end - pos, exif_data = bin.unpack(string.format(">A%d", size), s, pos) + exif_data, pos = string.unpack(string.format(">c%d", size), s, pos) return parse_exif(exif_data) end