From 2a11de56e44157e2eb5267b76ee4d911bf30afb9 Mon Sep 17 00:00:00 2001 From: dmiller Date: Sun, 16 Sep 2018 04:28:25 +0000 Subject: [PATCH] Remove more bin.lua packing, including the last 'binary string' packing --- nselib/dhcp6.lua | 75 ++++++++++++++++++++++++------------------------ nselib/dns.lua | 1 - nselib/isns.lua | 52 ++++++++++++++------------------- nselib/pppoe.lua | 3 +- nselib/rpcap.lua | 34 +++++++++------------- 5 files changed, 76 insertions(+), 89 deletions(-) diff --git a/nselib/dhcp6.lua b/nselib/dhcp6.lua index 71b77671c..26f833059 100644 --- a/nselib/dhcp6.lua +++ b/nselib/dhcp6.lua @@ -21,13 +21,13 @@ -- @author Patrik Karlsson -- -local bin = require "bin" local datetime = require "datetime" local ipOps = require "ipOps" local math = require "math" local nmap = require "nmap" local os = require "os" local stdnse = require "stdnse" +local string = require "string" local table = require "table" _ENV = stdnse.module("dhcp6", stdnse.seeall) @@ -88,11 +88,11 @@ DHCP6.Option = { __tostring = function(self) local data if ( self.time ) then - data = bin.pack(">S", self.time) + data = string.pack(">I2", self.time) else - data = bin.pack(">S", (os.time() - self.created) * 1000) + data = string.pack(">I2", (os.time() - self.created) * 1000) end - return bin.pack(">SP", self.type, data) + return string.pack(">I2s2", self.type, data) end, }, @@ -124,12 +124,13 @@ DHCP6.Option = { parse = function(data) local opt = DHCP6.Option[DHCP6.OptionTypes.OPTION_CLIENTID]:new() local pos - pos, opt.duid = bin.unpack(">S", data, pos) + opt.duid, pos = string.unpack(">I2", data, pos) if ( 1 ~= opt.duid ) then stdnse.debug1("Unexpected DUID type (%d)", opt.duid) return end - pos, opt.hwtype, opt.time, opt.mac = bin.unpack(">SIA" .. (#data - pos - 4 - 2 + 1), data, pos) + opt.hwtype, opt.time = string.unpack(">I2I4", data, pos) + opt.mac = data:sub(pos) opt.time = opt.time + os.time({year=2000, day=1, month=1, hour=0, min=0, sec=0}) return opt end, @@ -137,8 +138,8 @@ DHCP6.Option = { -- Converts option to a string -- @return str string containing the class instance as string __tostring = function(self) - local data = bin.pack(">SSIA", self.duid, self.hwtype, self.time, self.mac) - return bin.pack(">SP", self.type, data) + local data = string.pack(">I2I2I4", self.duid, self.hwtype, self.time) .. self.mac + return string.pack(">I2s2", self.type, data) end, }, @@ -183,9 +184,11 @@ DHCP6.Option = { -- @return opt new instance of option parse = function(data) local opt = DHCP6.Option[DHCP6.OptionTypes.OPTION_STATUS_CODE]:new() - local pos - pos, opt.code, opt.msg = bin.unpack(">SA" .. (#data - 2), data) + local pos + opt.code, pos = string.unpack(">I2", data) + opt.msg = data:sub(pos) + return opt end, @@ -215,7 +218,7 @@ DHCP6.Option = { for i=1,count do local srv - pos, srv = bin.unpack(">B16", data, pos) + srv, pos = string.unpack(">c16", data, pos) table.insert(opt.servers, srv) end return opt @@ -224,12 +227,12 @@ DHCP6.Option = { -- Converts option to a string -- @return str string containing the class instance as string __tostring = function(self) - local len = #self.servers * 16 - local data= bin.pack(">SS", self.type, self.len) + local data = {} for _, ipv6 in ipairs(self.servers) do - data = data .. ipOps.ip_to_str(ipv6) + data[#data+1] = ipOps.ip_to_str(ipv6) end - return data + data = table.concat(data) + return string.pack(">I2s2", self.type, data) end }, @@ -259,7 +262,7 @@ DHCP6.Option = { local domain = {} repeat local part - pos, part = bin.unpack("p", data, pos) + part, pos = string.unpack("s1", data, pos) if ( part ~= "" ) then table.insert(domain, part) end @@ -296,8 +299,8 @@ DHCP6.Option = { -- Converts option to a string -- @return str string containing the class instance as string __tostring = function(self) - local data = bin.pack(">IIIA", self.iaid, self.t1, self.t2, self.options) - return bin.pack(">SP", self.type, data) + local data = string.pack(">I4I4I4", self.iaid, self.t1, self.t2) .. self.options + return string.pack(">I2s2", self.type, data) end, }, @@ -330,16 +333,16 @@ DHCP6.Option = { local opt = DHCP6.Option[DHCP6.OptionTypes.OPTION_IA_NA]:new() local pos - pos, opt.iaid, opt.t1, opt.t2 = bin.unpack(">III", data) + opt.iaid, opt.t1, opt.t2, pos = string.unpack(">I4I4I4", data) -- do we have any options while ( pos < #data ) do local typ, len, ipv6, pref_lt, valid_lt, options - pos, typ, len = bin.unpack(">SS", data, pos) + typ, len, pos = string.unpack(">I2I2", data, pos) if ( 5 == DHCP6.OptionTypes.OPTION_IAADDR ) then local addr = { type = DHCP6.OptionTypes.OPTION_IAADDR } - pos, addr.ipv6, addr.pref_lt, addr.valid_lt = bin.unpack(">A16II", data, pos) + addr.ipv6, addr.pref_lt, addr.valid_lt, pos = string.unpack(">c16I4I4", data, pos) table.insert(opt.options, addr) else pos = pos + len @@ -351,10 +354,10 @@ DHCP6.Option = { -- Converts option to a string -- @return str string containing the class instance as string __tostring = function(self) - local data = bin.pack(">III", self.iaid, self.t1, self.t2) + local data = string.pack(">I4I4I4", self.iaid, self.t1, self.t2) -- TODO: we don't cover self.options here, we should probably add that - return bin.pack(">SP", self.type, data) + return string.pack(">I2s2", self.type, data) end, }, @@ -378,11 +381,11 @@ DHCP6.Option = { -- @return opt new instance of option parse = function(data) local opt = DHCP6.Option[DHCP6.OptionTypes.OPTION_SNTP_SERVERS]:new() - local pos, server = 1 + local pos, server repeat - pos, server = bin.unpack(">B16", data, pos) - table.insert( opt.servers, ipOps.bin_to_ip(server) ) + server, pos = string.unpack(">c16", data, pos) + table.insert( opt.servers, ipOps.str_to_ip(server) ) until( pos > #data ) return opt end, @@ -413,7 +416,7 @@ DHCP6.Option = { repeat local tmp - pos, tmp = bin.unpack("p", data, pos) + tmp, pos = string.unpack("s1", data, pos) table.insert(pieces, tmp) until(pos >= #data) opt.fqdn = stdnse.strjoin(".", pieces) @@ -453,12 +456,12 @@ DHCP6.Request = { -- @return str string containing the class instance as string __tostring = function(self) local tmp = (self.type << 24) + self.xid - local data = "" + local data = {} for _, opt in ipairs(self.opts) do - data = data .. tostring(opt) + data[#data+1] = tostring(opt) end - return bin.pack(">IA", tmp, data) + return string.pack(">I4", tmp) .. table.concat(data) end, } @@ -485,14 +488,14 @@ DHCP6.Response = { -- @return opt new instance of option parse = function(data) local resp = DHCP6.Response:new() - local pos, tmp = bin.unpack(">I", data) + local tmp, pos = string.unpack(">I4", data) resp.msgtype = (tmp & 0xFF000000) resp.msgtype = (resp.msgtype >> 24) resp.xid = (tmp & 0x00FFFFFF) while( pos < #data ) do local opt = {} - pos, opt.type, opt.data = bin.unpack(">SP", data, pos) + opt.type, opt.data, pos = string.unpack(">I2s2", data, pos) if ( DHCP6.Option[opt.type] and DHCP6.Option[opt.type].parse ) then local opt_parsed = DHCP6.Option[opt.type].parse(opt.data) if ( not(opt_parsed) ) then @@ -535,9 +538,7 @@ OptionToString = { [DHCP6.OptionTypes.OPTION_IA_NA] = function(opt) if ( opt.options and 1 == #opt.options ) then - local ipv6 = opt.options[1].ipv6 - ipv6 = select(2, bin.unpack("B" .. #ipv6, ipv6)) - ipv6 = ipOps.bin_to_ip(ipv6) + local ipv6 = ipOps.str_to_ip(opt.options[1].ipv6) return "Non-temporary Address", ipv6 end end, @@ -545,7 +546,7 @@ OptionToString = { [DHCP6.OptionTypes.OPTION_DNS_SERVERS] = function(opt) local servers = {} for _, srv in ipairs(opt.servers) do - local ipv6 = ipOps.bin_to_ip(srv) + local ipv6 = ipOps.str_to_ip(srv) table.insert(servers, ipv6) end return "DNS Servers", stdnse.strjoin(",", servers) @@ -603,7 +604,7 @@ Helper = { req:addOption(option[DHCP6.OptionTypes.OPTION_ELAPSED_TIME]:new()) req:addOption(option[DHCP6.OptionTypes.OPTION_CLIENTID]:new(self.mac)) - local iaid = select(2, bin.unpack(">I", self.mac:sub(3))) + local iaid = string.unpack(">I4", self.mac:sub(3)) req:addOption(option[DHCP6.OptionTypes.OPTION_IA_NA]:new(iaid, 3600, 5400)) self.host, self.port = { ip = "ff02::1:2" }, { number = 547, protocol = "udp"} diff --git a/nselib/dns.lua b/nselib/dns.lua index b988d622f..8ae3edc66 100644 --- a/nselib/dns.lua +++ b/nselib/dns.lua @@ -30,7 +30,6 @@ -- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html -local bin = require "bin" local coroutine = require "coroutine" local ipOps = require "ipOps" local nmap = require "nmap" diff --git a/nselib/isns.lua b/nselib/isns.lua index 7f4948a7c..4b7531a5d 100644 --- a/nselib/isns.lua +++ b/nselib/isns.lua @@ -4,11 +4,11 @@ -- @author Patrik Karlsson -- -local bin = require('bin') local ipOps = require('ipOps') local match = require('match') local nmap = require('nmap') local stdnse = require('stdnse') +local string = require "string" local table = require('table') _ENV = stdnse.module("isns", stdnse.seeall); @@ -57,10 +57,9 @@ Header = { -- @return hdr new instance of Header parse = function(data) local hdr = Header:new() - local pos - pos, hdr.ver, hdr.func_id, hdr.pdu_len, hdr.flags, hdr.trans_id, - hdr.seq_id = bin.unpack(">SSSSSS", data) + hdr.ver, hdr.func_id, hdr.pdu_len, hdr.flags, hdr.trans_id, + hdr.seq_id = string.unpack(">I2I2I2I2I2I2", data) return hdr end, @@ -69,7 +68,7 @@ Header = { -- Converts the instance to an opaque string -- @return str containing an opaque string __tostring = function(self) - return bin.pack(">SSSSSS", self.ver, self.func_id, + return string.pack(">I2I2I2I2I2I2", self.ver, self.func_id, self.pdu_len, self.flags, self.trans_id, self.seq_id ) end @@ -168,10 +167,9 @@ Attribute = { -- -- @param tag number containing the tag number -- @param val string containing the tag value - -- @param len number containing the tag length -- @return o new Attribute instance - new = function(self, tag, val, len) - local o = { tag = tag, len = ( len or (val and #val or 0) ), val = val or "" } + new = function(self, tag, val) + local o = { tag = tag, val = val or "" } setmetatable(o, self) self.__index = self return o @@ -184,10 +182,8 @@ Attribute = { -- @return attr new instance of Attribute parse = function(data) local attr = Attribute:new() - local pos - pos, attr.tag, attr.len = bin.unpack(">II", data) - pos, attr.val = bin.unpack(">A" .. attr.len, pos) + attr.tag, attr.val = string.unpack(">I4s4", data) return attr end, @@ -196,7 +192,7 @@ Attribute = { -- Converts the instance to an opaque string -- @return str containing an opaque string __tostring = function(self) - return bin.pack(">IIA", self.tag, self.len, self.val) + return string.pack(">I4s4", self.tag, self.val) end, } @@ -217,9 +213,8 @@ Attributes = { -- Adds a new Attribute to the table -- @param tag number containing the tag number -- @param val string containing the tag value - -- @param len number containing the tag length - add = function(self, tag, val, len) - table.insert(self, Attribute:new(tag, val, len)) + add = function(self, tag, val) + table.insert(self, Attribute:new(tag, val)) end, -- @@ -333,16 +328,15 @@ Response = { local pos = #(tostring(hdr)) + 1 local resp = Response:new() - pos, resp.error = bin.unpack(">I", data, pos) + resp.error, pos = string.unpack(">I4", data, pos) if ( resp.error ~= 0 ) then return resp end while( pos < #data ) do - local tag, len, val - pos, tag, len = bin.unpack(">II", data, pos) - pos, val = bin.unpack("A" .. len, data, pos) - resp.attrs:add( tag, val, len ) + local tag, val + tag, val, pos = string.unpack(">I4s4", data, pos) + resp.attrs:add(tag, val) end return resp end, @@ -478,17 +472,15 @@ Helper = { for _, attr in ipairs(resp.attrs) do if ( attr.tag == Attribute.Tag.ISNS_TAG_PORTAL_IP_ADDRESS ) then addr = attr.val - local pos, is_ipv4 = bin.unpack("A12", addr) + local is_ipv4 = string.unpack("c12", addr) if ( is_ipv4 == "\0\0\0\0\0\0\0\0\0\0\xFF\xFF" ) then - local pos, bin_ip = bin.unpack("B4", addr, 13) - addr = ipOps.bin_to_ip(bin_ip) + addr = ipOps.str_to_ip(addr:sub(13, 16)) else - local pos, bin_ip = bin.unpack("B16", addr) - addr = ipOps.bin_to_ip(bin_ip) + addr = ipOps.str_to_ip(addr:sub(1,16)) end elseif ( attr.tag == Attribute.Tag.ISNS_TAG_PORTAL_TCP_UDP_PORT ) then - local pos, s1 - pos, s1, port = bin.unpack(">SS", attr.val) + local s1 + s1, port = string.unpack(">I2I2", attr.val) if ( s1 == 1 ) then proto = "udp" @@ -534,9 +526,9 @@ Helper = { local results = {} for _, attr in ipairs(resp.attrs) do if ( attr.tag == Attribute.Tag.ISNS_TAG_ISCSI_NAME ) then - name = attr.val + name = string.unpack("z", attr.val) elseif( attr.tag == Attribute.Tag.ISNS_TAG_ISCSI_NODE_TYPE ) then - local _, val = bin.unpack(">I", attr.val) + local val = string.unpack(">I4", attr.val) if ( val == iSCSI.NodeType.CONTROL ) then ntype = "Control" elseif ( val == iSCSI.NodeType.INITIATOR ) then @@ -548,7 +540,7 @@ Helper = { end end if ( name and ntype ) then - table.insert(results, { name = name:match("^([^\0]*)"), type = ntype }) + table.insert(results, { name = name, type = ntype }) name, ntype = nil, nil end end diff --git a/nselib/pppoe.lua b/nselib/pppoe.lua index 7365885ae..b092781e9 100644 --- a/nselib/pppoe.lua +++ b/nselib/pppoe.lua @@ -25,6 +25,7 @@ local rand = require "rand" local nmap = require "nmap" local packet = require "packet" local stdnse = require "stdnse" +local string = require "string" local table = require "table" _ENV = stdnse.module("pppoe", stdnse.seeall) @@ -484,7 +485,7 @@ PPPoE = { pado.data = data:sub(pos) repeat - local tag, raw + local tag, decoded, raw tag, raw, pos = string.unpack(">I2s2", pos) if ( PPPoE.TagDecoder[tag] ) then decoded = PPPoE.TagDecoder[tag](raw) diff --git a/nselib/rpcap.lua b/nselib/rpcap.lua index 869ce8ebf..e524461f5 100644 --- a/nselib/rpcap.lua +++ b/nselib/rpcap.lua @@ -25,11 +25,11 @@ -- @author Patrik Karlsson -local bin = require "bin" local ipOps = require "ipOps" local match = require "match" local nmap = require "nmap" local stdnse = require "stdnse" +local string = require "string" local table = require "table" _ENV = stdnse.module("rpcap", stdnse.seeall) @@ -59,7 +59,7 @@ RPCAP = { __tostring = function(self) local DUMMY = 0 - return bin.pack(">SSSSAA", self.type, DUMMY, #self.username, #self.password, self.username, self.password) + return string.pack(">I2I2I2I2", self.type, DUMMY, #self.username, #self.password) .. self.username .. self.password end, }, @@ -77,7 +77,7 @@ RPCAP = { __tostring = function(self) local DUMMY = 0 - return bin.pack(">SSSS", self.type, DUMMY, 0, 0) + return string.pack(">I2I2I2I2", self.type, DUMMY, 0, 0) end, } @@ -101,13 +101,12 @@ RPCAP = { parse = function(data) local header = RPCAP.Header:new() - local pos - pos, header.version, header.type, header.value, header.length = bin.unpack(">CCSI", data) + header.version, header.type, header.value, header.length = string.unpack(">BBI2I4", data) return header end, __tostring = function(self) - return bin.pack(">CCSI", self.version, self.type, self.value, self.length) + return string.pack(">BBI2I4", self.version, self.type, self.value, self.length) end, }, @@ -184,7 +183,7 @@ RPCAP = { local err = RPCAP.Response.Error:new() local pos = RPCAP.Header.size + 1 err.header = RPCAP.Header.parse(data) - pos, err.error = bin.unpack("A" .. err.header.length, data, pos) + err.error, pos = string.unpack("c" .. err.header.length, data, pos) return err end @@ -207,19 +206,17 @@ RPCAP = { local function parseField(data, pos) local offset = pos local family, port - pos, family, port = bin.unpack(">SS", data, pos) + family, port, pos = string.unpack(">I2I2", data, pos) if ( family == 0x0017 ) then -- not sure why... pos = pos + 4 - local ipv6 - pos, ipv6 = bin.unpack("B16", data, pos) - return offset + 128, ipOps.bin_to_ip(ipv6) + local ipv6 = ipOps.str_to_ip(data:sub(pos, pos + 16 - 1)) + return offset + 128, ipv6 elseif ( family == 0x0002 ) then - local ipv4 - pos, ipv4 = bin.unpack("B4", data, pos) - return offset + 128, ipOps.bin_to_ip(ipv4) + local ipv4 = ipOps.str_to_ip(data:sub(pos, pos + 4 - 1)) + return offset + 128, ipv4 end return offset + 128, nil @@ -244,10 +241,10 @@ RPCAP = { for i=1, resp.header.value do local name_len, desc_len, iface_flags, addr_count, dummy - pos, name_len, desc_len, iface_flags, addr_count, dummy = bin.unpack(">SSISS", data, pos) + name_len, desc_len, iface_flags, addr_count, dummy, pos = string.unpack(">I2I2I4I2I2", data, pos) local name, desc - pos, name, desc = bin.unpack("A" .. name_len .. "A" .. desc_len, data, pos) + name, desc, pos = string.unpack("c" .. name_len .. "c" .. desc_len, data, pos) local addrs = {} for j=1, addr_count do @@ -255,10 +252,7 @@ RPCAP = { pos, addr = parseAddress(data, pos) local cidr if ( addr.netmask ) then - local bits = ipOps.ip_to_bin(addr.netmask) - local ones = bits:match("^(1*)") - cidr = #ones - table.insert(addrs, ("%s/%d"):format(addr.ip,cidr)) + table.insert(addrs, addr.ip .. ipOps.subnet_to_cidr(addr.netmask)) else table.insert(addrs, addr.ip) end