From 10dce0382cc807c5f8fcb1ae90f3e5de0e1cb3f3 Mon Sep 17 00:00:00 2001 From: dmiller Date: Wed, 25 Feb 2015 19:58:42 +0000 Subject: [PATCH] Clean up string concatenations Building a string with var = var .. "something" has miserable time complexities. This commit cleans up a lot of that in scripts, focusing on packing of data with bin.pack and concatenations within loops. Additionally, a few instances were replaced with string.rep --- scripts/broadcast-igmp-discovery.nse | 35 ++++++++++------------ scripts/broadcast-pim-discovery.nse | 25 +++++++--------- scripts/broadcast-ripng-discover.nse | 6 ++-- scripts/broadcast-wake-on-lan.nse | 7 ++--- scripts/broadcast-wpad-discover.nse | 8 ++--- scripts/citrix-brute-xml.nse | 9 +++--- scripts/db2-das-info.nse | 2 +- scripts/dns-fuzz.nse | 43 ++++++++++++++------------- scripts/http-awstatstotals-exec.nse | 10 +++---- scripts/http-fileupload-exploiter.nse | 7 +++-- scripts/http-git.nse | 6 +--- scripts/http-open-proxy.nse | 38 +++++++++++------------ scripts/http-passwd.nse | 6 +--- scripts/krb5-enum-users.nse | 14 ++++----- scripts/llmnr-resolve.nse | 20 ++++++------- scripts/mrinfo.nse | 22 ++++++-------- scripts/mtrace.nse | 20 +++++++------ scripts/nfs-showmount.nse | 3 +- scripts/nrpe-enum.nse | 23 ++++++-------- scripts/oracle-sid-brute.nse | 8 ++--- scripts/p2p-conficker.nse | 6 ++-- scripts/smtp-vuln-cve2011-1720.nse | 16 +++++----- scripts/smtp-vuln-cve2011-1764.nse | 27 ++++++++--------- scripts/sniffer-detect.nse | 6 ++-- scripts/ssh-hostkey.nse | 6 ++-- scripts/traceroute-geolocation.nse | 6 ++-- 26 files changed, 174 insertions(+), 205 deletions(-) diff --git a/scripts/broadcast-igmp-discovery.nse b/scripts/broadcast-igmp-discovery.nse index 4544146aa..65936fcf6 100644 --- a/scripts/broadcast-igmp-discovery.nse +++ b/scripts/broadcast-igmp-discovery.nse @@ -214,28 +214,23 @@ local igmpRaw = function(interface, version) end -- Let's craft an IGMP Membership Query - local igmp_raw = bin.pack(">C", 0x11) -- Membership Query, same for all versions - if version == 1 then - igmp_raw = igmp_raw .. bin.pack(">C", 0x00) -- Unused, 0x00 for version 1 only - else - igmp_raw = igmp_raw .. bin.pack(">C", 0x16) -- Max response time: 10 Seconds, for version 2 and 3 - end - - igmp_raw = igmp_raw .. bin.pack(">S", 0x00) -- Checksum, calculated later - igmp_raw = igmp_raw .. bin.pack(">I", 0x00) -- Multicast Address: 0.0.0.0 + local igmp_raw = bin.pack(">CCSI", + 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 + 0 -- Multicast Address: 0.0.0.0 + ) if version == 3 then - -- Reserved = 4 bits (Should be zeroed) - -- Supress Flag = 1 bit - -- QRV (Querier's Robustness Variable) = 3 bits - -- all are set to 0 - igmp_raw = igmp_raw .. bin.pack(">C", 0x00) - -- QQIC (Querier's Query Interval Code) in seconds = Set to 0 to get insta replies. - igmp_raw = igmp_raw .. bin.pack(">C", 0x10) - -- Number of sources (in the next arrays) = 1 ( Our IP only) - igmp_raw = igmp_raw .. bin.pack(">S", 0x01) - -- Source = Our IP address - igmp_raw = igmp_raw .. bin.pack(">I", ipOps.todword(interface.address)) + igmp_raw = bin.pack(">ACCSI", igmp_raw, + 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 + ) end igmp_raw = igmp_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(igmp_raw)) .. igmp_raw:sub(5) diff --git a/scripts/broadcast-pim-discovery.nse b/scripts/broadcast-pim-discovery.nse index 1e779db7c..816cd295b 100644 --- a/scripts/broadcast-pim-discovery.nse +++ b/scripts/broadcast-pim-discovery.nse @@ -55,21 +55,16 @@ end -- Generates a raw PIM Hello message. --@return hello Raw PIM Hello message local helloRaw = function() - -- Version: 2, Type: Hello (0) - local hello_raw = bin.pack(">C", 0x20) - -- Reserved - hello_raw = hello_raw.. bin.pack(">C", 0x00) - -- Checksum: Calculated later - hello_raw = hello_raw.. bin.pack(">S", 0x0000) - -- Options (TLVs) - -- Hold time 1 second - hello_raw = hello_raw.. bin.pack(">SSS", 0x01, 0x02, 0x01) - -- Generation ID: Random - hello_raw = hello_raw.. bin.pack(">SSI", 0x14, 0x04, math.random(23456)) - -- DR Priority: 1 - hello_raw = hello_raw.. bin.pack(">SSI", 0x13, 0x04, 0x01) - -- State fresh capable: Version = 1, interval = 0, Reserved - hello_raw = hello_raw.. bin.pack(">SSCCS", 0x15, 0x04, 0x01, 0x00, 0x00) + local hello_raw = bin.pack(">CCSAAAA", + 0x20, -- Version: 2, Type: Hello (0) + 0x00, -- Reserved + 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 + ) -- Calculate checksum hello_raw = hello_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(hello_raw)) .. hello_raw:sub(5) diff --git a/scripts/broadcast-ripng-discover.nse b/scripts/broadcast-ripng-discover.nse index d172db653..9ca99dcdf 100644 --- a/scripts/broadcast-ripng-discover.nse +++ b/scripts/broadcast-ripng-discover.nse @@ -107,11 +107,11 @@ 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 = {bin.pack(">CCS", self.command, self.version, RESERVED)} for _, rte in ipairs(self.entries) do - str = str .. tostring(rte) + str[#str+1] = tostring(rte) end - return str + return table.concat(str) end, }, diff --git a/scripts/broadcast-wake-on-lan.nse b/scripts/broadcast-wake-on-lan.nse index a2687e694..1c39d06af 100644 --- a/scripts/broadcast-wake-on-lan.nse +++ b/scripts/broadcast-wake-on-lan.nse @@ -1,6 +1,7 @@ local bin = require "bin" local nmap = require "nmap" local stdnse = require "stdnse" +local string = require "string" description = [[ Wakes a remote system up from sleep by sending a Wake-On-Lan packet. @@ -35,11 +36,7 @@ end -- @param mac string containing the MAC without delimiters -- @return packet string containing the raw packet local function createWOLPacket(mac) - local packet = bin.pack("H", "FFFFFFFFFFFF") - for i=1, 16 do - packet = packet .. bin.pack("H", mac) - end - return packet + return "\xff\xff\xff\xff\xff\xff" .. string.rep(bin.pack("H", mac), 16) end diff --git a/scripts/broadcast-wpad-discover.nse b/scripts/broadcast-wpad-discover.nse index d9e81fd68..b6c68af18 100644 --- a/scripts/broadcast-wpad-discover.nse +++ b/scripts/broadcast-wpad-discover.nse @@ -44,11 +44,11 @@ local arg_nodhcp = stdnse.get_script_args(SCRIPT_NAME .. ".nodhcp") local arg_getwpad= stdnse.get_script_args(SCRIPT_NAME .. ".getwpad") local function createRequestList(req_list) - local output = "" - for _, v in ipairs(req_list) do - output = output .. string.char(v) + local output = {} + for i, v in ipairs(req_list) do + output[i] = string.char(v) end - return output + return table.concat(output) end diff --git a/scripts/citrix-brute-xml.nse b/scripts/citrix-brute-xml.nse index c187f875f..42b40c8f4 100644 --- a/scripts/citrix-brute-xml.nse +++ b/scripts/citrix-brute-xml.nse @@ -96,14 +96,13 @@ end -- @param accounts table containing accounts (tables) -- @return string containing the result function create_result_from_table(accounts) + local result = {} - local result = "" - - for _, account in ipairs(accounts) do - result = result .. " " .. account.username .. ":" .. account.password .. " => " .. account.message .. "\n" + for i, account in ipairs(accounts) do + result[i] = ("\n %s:%s => %s"):format(account.username, account.password, account.message) end - return "\n" .. result + return table.concat(result) end action = function(host, port) diff --git a/scripts/db2-das-info.nse b/scripts/db2-das-info.nse index b159b0c26..2cc6f7f72 100644 --- a/scripts/db2-das-info.nse +++ b/scripts/db2-das-info.nse @@ -417,7 +417,7 @@ action = function(host, port) if (db2profile ~= nil ) then result = "DB2 Administration Server Settings\r\n" - result = result .. extract_server_profile( db2response.info ) + .. extract_server_profile( db2response.info ) -- Set port information port.version.name = "ibm-db2" diff --git a/scripts/dns-fuzz.nse b/scripts/dns-fuzz.nse index e4074d86e..0a1f32048 100644 --- a/scripts/dns-fuzz.nse +++ b/scripts/dns-fuzz.nse @@ -6,6 +6,7 @@ local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" +local table = require "table" description = [[ Launches a DNS fuzzing attack against DNS servers. @@ -100,12 +101,12 @@ end -- @return Random string of lowercase characters function makeWord () local len = math.random(3,7) - local name = string.char(len) + local name = {string.char(len)} for i = 1, len do -- this next line assumes ascii - name = name .. string.char(math.random(string.byte("a"),string.byte("z"))) + name[i+1] = string.char(math.random(string.byte("a"),string.byte("z"))) end - return name + return table.concat(name) end --- @@ -117,14 +118,14 @@ end function makeHost (compressed) -- randomly choose between 2 to 4 levels in this domain local levels = math.random(2,4) - local name = "" + local name = {} for i = 1, levels do - name = name .. makeWord () + name[#name+1] = makeWord () end if compressed then - name = name .. string.char(0xC0) .. string.char(0x0C) + name[#name+1] = "\xc0\x0c" else - name = name .. string.char(0x00) + name[#name+1] = "\x00" end return name @@ -167,18 +168,18 @@ end -- @param dnsPacket A packet, generated by makePacket() -- @return The same packet, but with bit flip errors function nudgePacket (dnsPacket) - local newPacket = "" + local newPacket = {} -- Iterate over every byte in the packet dnsPacket:gsub(".", function(c) -- Induce bit errors at a rate of 1/50. if math.random(50) == 25 then -- Bitflip algorithm: c ^ 1<<(rand()%7) - newPacket = newPacket .. string.char( bit.bxor(c:byte(), bit.lshift(1, math.random(0,7))) ) + newPacket[#newPacket+1] = string.char( bit.bxor(c:byte(), bit.lshift(1, math.random(0,7))) ) else - newPacket = newPacket .. c + newPacket[#newPacket+1] = c end end) - return newPacket + return table.concat(newPacket) end --- @@ -186,17 +187,17 @@ end -- @param dnsPacket A packet, generated by makePacket() -- @return The same packet, but with a single byte missing function dropByte (dnsPacket) - local newPacket = "" + local newPacket = {} local byteToDrop = math.random(dnsPacket:len())-1 local i = 0 -- Iterate over every byte in the packet dnsPacket:gsub(".", function(c) i=i+1 if not i==byteToDrop then - newPacket = newPacket .. c + newPacket[#newPacket+1] = c end end) - return newPacket + return table.concat(newPacket) end --- @@ -204,18 +205,18 @@ end -- @param dnsPacket A packet, generated by makePacket() -- @return The same packet, but with a single byte missing function injectByte (dnsPacket) - local newPacket = "" + local newPacket = {} local byteToInject = math.random(dnsPacket:len())-1 local i = 0 -- Iterate over every byte in the packet dnsPacket:gsub(".", function(c) i=i+1 if i==byteToInject then - newPacket = newPacket .. string.char(math.random(0,255)) + newPacket[#newPacket+1] = string.char(math.random(0,255)) end - newPacket = newPacket .. c + newPacket[#newPacket+1] = c end) - return newPacket + return table.concat(newPacket) end --- @@ -223,7 +224,7 @@ end -- @param dnsPacket A packet, generated by makePacket() -- @return The same packet, but with a single byte missing function truncatePacket (dnsPacket) - local newPacket = "" + local newPacket = {} -- at least 12 bytes to make sure the packet isn't dropped as a tinygram local eatPacketPos = math.random(12,dnsPacket:len())-1 local i = 0 @@ -233,9 +234,9 @@ function truncatePacket (dnsPacket) if i==eatPacketPos then return end - newPacket = newPacket .. c + newPacket[#newPacket+1] = c end) - return newPacket + return table.concat(newPacket) end --- diff --git a/scripts/http-awstatstotals-exec.nse b/scripts/http-awstatstotals-exec.nse index 5dfd7aa0a..764ab1f92 100644 --- a/scripts/http-awstatstotals-exec.nse +++ b/scripts/http-awstatstotals-exec.nse @@ -4,6 +4,7 @@ local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" +local table = require "table" description = [[ Exploits a remote code execution vulnerability in Awstats Totals 1.0 up to 1.14 and possibly other products based on it (CVE: 2008-3922). @@ -99,12 +100,9 @@ action = function(host, port) end --Encode payload using PHP's chr() - local encoded_payload = "" - cmd:gsub(".", function(c) encoded_payload = encoded_payload .."chr("..string.byte(c)..")." end) - if string.sub(encoded_payload, #encoded_payload) == "." then - encoded_payload = string.sub(encoded_payload, 1, #encoded_payload-1) - end - local stealth_payload = "?sort={%24{passthru%28"..encoded_payload.."%29}}{%24{exit%28%29}}" + local encoded_payload = {} + cmd:gsub(".", function(c) encoded_payload[#encoded_payload+1] = ("chr(%s)"):format(string.byte(c)) end) + local stealth_payload = "?sort={%24{passthru%28"..table.concat(encoded_payload,'.').."%29}}{%24{exit%28%29}}" --set payload and send request local req = http.get(host, port, uri .. stealth_payload) diff --git a/scripts/http-fileupload-exploiter.nse b/scripts/http-fileupload-exploiter.nse index 04ff62e65..7b53c543b 100644 --- a/scripts/http-fileupload-exploiter.nse +++ b/scripts/http-fileupload-exploiter.nse @@ -177,11 +177,12 @@ end local prepareRequest = function(fields, fieldvalues) local filefield = 0 - local req = "" + local req = {} local value for _, field in ipairs(fields) do if field["type"] == "file" then + -- FIXME: What if there is more than one ? filefield = field elseif field["type"] == "text" or field["type"] == "textarea" or field["type"] == "radio" or field["type"] == "checkbox" then if fieldvalues[field["name"]] ~= nil then @@ -189,11 +190,11 @@ local prepareRequest = function(fields, fieldvalues) else value = "SampleData0" end - req = req .. '--AaB03x\nContent-Disposition: form-data; name="' .. field["name"] .. '";\n\n' .. value .. '\n' + req[#req+1] = ('--AaB03x\nContent-Disposition: form-data; name="%s";\n\n%s\n'):format(field["name"], value) end end - return req, filefield + return table.concat(req), filefield end diff --git a/scripts/http-git.nse b/scripts/http-git.nse index 02fadc086..d4dfc015a 100644 --- a/scripts/http-git.nse +++ b/scripts/http-git.nse @@ -271,11 +271,7 @@ function action(host, port) -- Show what patterns matched what files for name, matches in pairs(info["interesting-matches"] or {}) do - local temp = name .. " matched patterns" - for _, matched in ipairs(matches) do - temp = temp .. " '" .. matched .. "'" - end - table.insert(new, temp) + table.insert(new, ("%s matched patterns '%s'"):format(name, table.concat(matches, "' '"))) end if info["repository-description"] then diff --git a/scripts/http-open-proxy.nse b/scripts/http-open-proxy.nse index 0c265bb29..38d83baff 100644 --- a/scripts/http-open-proxy.nse +++ b/scripts/http-open-proxy.nse @@ -2,6 +2,7 @@ local proxy = require "proxy" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" +local table = require "table" local url = require "url" description=[[ @@ -53,7 +54,7 @@ categories = {"default", "discovery", "external", "safe"} -- @return response String with supported methods function custom_test(host, port, test_url, pattern) local lstatus = false - local response = "" + local response = {} -- if pattern is not used, result for test is code check result. -- otherwise it is pattern check result. @@ -70,17 +71,17 @@ function custom_test(host, port, test_url, pattern) local conn_status = proxy.test_connect(host, port, "http", hostname) if get_status then lstatus = true - response = response .. " GET" + response[#response+1] = "GET" end if head_status then lstatus = true - response = response .. " HEAD" + response[#response+1] = "HEAD" end if conn_status then lstatus = true - response = response .. " CONNECTION" + response[#response+1] = "CONNECTION" end - if lstatus then response = "Methods supported: " .. response end + if lstatus then response = "Methods supported: " .. table.concat(response, " ") end return lstatus, response end @@ -101,7 +102,6 @@ end function default_test(host, port) local fstatus = false local cstatus = false - local response = "" local get_status, head_status, conn_status local get_r1, get_r2, get_r3 local get_cstatus, head_cstatus @@ -123,13 +123,13 @@ function default_test(host, port) -- pattern. -- if it was using the same flag, program could return without testing GET/HEAD -- once more before returning - - if get_status then fstatus = true; response = response .. " GET" end - if head_status then fstatus = true; response = response .. " HEAD" end - if conn_status then cstatus = true; response = response .. " CONNECTION" end + local response = {} + if get_status then fstatus = true; response[#response+1] = "GET" end + if head_status then fstatus = true; response[#response+1] = "HEAD" end + if conn_status then cstatus = true; response[#response+1] = "CONNECTION" end -- if proxy is open, return it! - if fstatus then return fstatus, "Methods supported: " .. response end + if fstatus then return fstatus, "Methods supported: " .. table.concat(response, " ") end -- if we receive a invalid response, but with a valid -- response code, we should make a next attempt. @@ -145,14 +145,14 @@ function default_test(host, port) head_status, _, head_cstatus = proxy.test_head(host, port, "http", test_url, hostname, pattern) conn_status = proxy.test_connect(host, port, "http", hostname) - if get_status then fstatus = true; response = response .. " GET" end - if head_status then fstatus = true; response = response .. " HEAD" end + if get_status then fstatus = true; response[#response+1] = "GET" end + if head_status then fstatus = true; response[#response+1] = "HEAD" end if conn_status then - if not cstatus then response = response .. " CONNECTION" end + if not cstatus then response[#response+1] = "CONNECTION" end cstatus = true end - if fstatus then return fstatus, "Methods supported: " .. response end + if fstatus then return fstatus, "Methods supported: " .. table.concat(response, " ") end -- same valid code checking as above if not (get_cstatus or head_cstatus or conn_status) then return false, nil end @@ -164,13 +164,13 @@ function default_test(host, port) get_status, get_r3, get_cstatus = proxy.test_get(host, port, "http", test_url, hostname, pattern) conn_status = proxy.test_connect(host, port, "http", hostname) - if get_status then fstatus = true; response = response .. " GET" end + if get_status then fstatus = true; response[#response+1] = "GET" end if conn_status then - if not cstatus then response = response .. " CONNECTION" end + if not cstatus then response[#response+1] = "CONNECTION" end cstatus = true end - if fstatus then return fstatus, "Methods supported:" .. response end + if fstatus then return fstatus, "Methods supported:" .. table.concat(response, " ") end if not get_cstatus then stdnse.debug1("Test 3 - Computer History\nReceived valid status codes, but pattern does not match") end @@ -181,7 +181,7 @@ function default_test(host, port) end -- Check if at least CONNECTION worked - if cstatus then return true, "Methods supported:" .. response end + if cstatus then return true, "Methods supported:" .. table.concat(response, " ") end -- Nothing works... return false, nil diff --git a/scripts/http-passwd.nse b/scripts/http-passwd.nse index 716e80fc8..73efd377d 100644 --- a/scripts/http-passwd.nse +++ b/scripts/http-passwd.nse @@ -113,11 +113,7 @@ end --@return String description for output local output = function(passwd, dir) local trunc, len = truncatePasswd(passwd) - local out = "" - out = out .. "Directory traversal found.\nPayload: \"" .. dir .. "\"\n" - out = out .. "Printing first " .. len .. " bytes:\n" - out = out .. trunc - return out + return ('Directory traversal found.\nPayload: "%s"\nPrinting first %d bytes:\n%s'):format(dir, len, trunc) end portrule = shortport.http diff --git a/scripts/krb5-enum-users.nse b/scripts/krb5-enum-users.nse index 097e9be6c..17000f69d 100644 --- a/scripts/krb5-enum-users.nse +++ b/scripts/krb5-enum-users.nse @@ -163,13 +163,13 @@ KRB5 = { -- @param names table containing a list of names to encode -- @return princ string containing an encoded principal encodePrincipal = function(self, encoder, name_type, names ) - local princ = "" + local princ = {} - for _, n in ipairs(names) do - princ = princ .. encoder:encode( { _type = 'GeneralString', n } ) + for i, n in ipairs(names) do + princ[i] = encoder:encode( { _type = 'GeneralString', n } ) end - princ = self:encodeSequence(encoder, 0x30, princ) + princ = self:encodeSequence(encoder, 0x30, table.concat(princ)) princ = self:encodeSequence(encoder, 0xa1, princ) princ = encoder:encode( name_type ) .. princ @@ -193,16 +193,16 @@ KRB5 = { local encoder = asn1.ASN1Encoder:new() encoder:registerTagEncoders(KRB5.tagEncoder) - local data = "" + local data = {} -- encode encryption types for _,enctype in ipairs(KRB5.EncryptionTypes) do for k, v in pairs( enctype ) do - data = data .. encoder:encode(v) + data[#data+1] = encoder:encode(v) end end - data = self:encodeSequence(encoder, 0x30, data ) + data = self:encodeSequence(encoder, 0x30, table.concat(data) ) data = self:encodeSequence(encoder, 0xA8, data ) -- encode nonce diff --git a/scripts/llmnr-resolve.nse b/scripts/llmnr-resolve.nse index 7eb300755..8486a442f 100644 --- a/scripts/llmnr-resolve.nse +++ b/scripts/llmnr-resolve.nse @@ -55,16 +55,16 @@ categories = {"discovery", "safe", "broadcast"} -- @param hostname Hostname to query for. -- @return query Raw llmnr query. local llmnrQuery = function(hostname) - local query = bin.pack(">S", math.random(0,65535)) -- transaction ID - query = query .. bin.pack(">S", 0x0000) -- Flags: Standard Query - query = query .. bin.pack(">S", 0x0001) -- Questions = 1 - query = query .. bin.pack(">S", 0x0000) -- Answer RRs = 0 - query = query .. bin.pack(">S", 0x0000) -- Authority RRs = 0 - query = query .. bin.pack(">S", 0x0000) -- Additional RRs = 0 - query = query .. bin.pack(">CAC", #hostname, hostname, 0x00) -- Hostname - query = query .. bin.pack(">S", 0x0001) -- Type: Host Address - query = query .. bin.pack(">S", 0x0001) -- Class: IN - return query + return bin.pack(">S6pCS2", + math.random(0,65535), -- transaction ID + 0x0000, -- Flags: Standard Query + 0x0001, -- Questions = 1 + 0x0000, -- Answer RRs = 0 + 0x0000, -- Authority RRs = 0 + 0x0000, -- Additional RRs = 0 + hostname, 0x00, -- Hostname + 0x0001, -- Type: Host Address + 0x0001) -- Class: IN end --- Sends a llmnr query. diff --git a/scripts/mrinfo.nse b/scripts/mrinfo.nse index 9037b211f..a28c73e63 100644 --- a/scripts/mrinfo.nse +++ b/scripts/mrinfo.nse @@ -166,19 +166,15 @@ end -- Function that generates a raw DVMRP Ask Neighbors 2 request. local mrinfoRaw = function() - -- Type: DVMRP - local mrinfo_raw = bin.pack(">C", 0x13) - -- Code: Ask Neighbor v2 - mrinfo_raw = mrinfo_raw.. bin.pack(">C", 0x05) - -- Checksum: Calculated later - mrinfo_raw = mrinfo_raw.. bin.pack(">S", 0x0000) - -- Reserved - mrinfo_raw = mrinfo_raw.. bin.pack(">S", 0x000a) - -- Version == Cisco IOS 12.4 - -- Minor version: 4 - mrinfo_raw = mrinfo_raw.. bin.pack(">C", 0x04) - -- Major version: 12 - mrinfo_raw = mrinfo_raw.. bin.pack(">C", 0x0c) + local mrinfo_raw = bin.pack(">CCSSCC", + 0x13, -- Type: DVMRP + 0x05, -- Code: Ask Neighbor v2 + 0x0000, -- Checksum: Calculated later + 0x000a, -- Reserved + -- Version == Cisco IOS 12.4 + 0x04, -- Minor version: 4 + 0x0c) -- Major version: 12 + -- Calculate checksum mrinfo_raw = mrinfo_raw:sub(1,2) .. bin.pack(">S", packet.in_cksum(mrinfo_raw)) .. mrinfo_raw:sub(5) diff --git a/scripts/mtrace.nse b/scripts/mtrace.nse index 5a74613eb..5b6f5f3d7 100644 --- a/scripts/mtrace.nse +++ b/scripts/mtrace.nse @@ -119,15 +119,17 @@ end --@param receiver Receiver of the response. --@return data Raw Traceroute Query. local traceRaw = function(fromip, toip, group, receiver) - local data = bin.pack(">C", 0x1f) -- Type: Traceroute Query - local data = data .. bin.pack(">C", 0x20) -- Hops: 32 - local data = data .. bin.pack(">S", 0x0000) -- Checksum: To be set later - local data = data .. bin.pack(">I", ipOps.todword(group)) -- Multicast group - local data = data .. bin.pack(">I", ipOps.todword(fromip)) -- Source - local data = data .. bin.pack(">I", ipOps.todword(toip)) -- Destination - local data = data .. bin.pack(">I", ipOps.todword(receiver)) -- Receiver - local data = data .. bin.pack(">C", 0x40) -- TTL - local data = data .. bin.pack(">CS", 0x00, math.random(123456)) -- Query ID + local data = bin.pack(">CCSIIIICCS", + 0x1f, -- Type: Traceroute Query + 0x20, -- Hops: 32 + 0x0000, -- Checksum: To be set later + ipOps.todword(group), -- Multicast group + ipOps.todword(fromip), -- Source + ipOps.todword(toip), -- Destination + ipOps.todword(receiver), -- Receiver + 0x40, -- TTL + 0x00, math.random(123456) -- Query ID + ) -- We calculate checksum data = data:sub(1,2) .. bin.pack(">S", packet.in_cksum(data)) .. data:sub(5) diff --git a/scripts/nfs-showmount.nse b/scripts/nfs-showmount.nse index edab6f84e..e6891c510 100644 --- a/scripts/nfs-showmount.nse +++ b/scripts/nfs-showmount.nse @@ -84,8 +84,7 @@ action = function(host, port) end for _, v in ipairs( mounts ) do - local entry = v.name - entry = entry .. " " .. stdnse.strjoin(" ", v) + local entry = v.name .. " " .. stdnse.strjoin(" ", v) table.insert( result, entry ) end diff --git a/scripts/nrpe-enum.nse b/scripts/nrpe-enum.nse index 499f792e2..3713e23af 100644 --- a/scripts/nrpe-enum.nse +++ b/scripts/nrpe-enum.nse @@ -139,22 +139,17 @@ end local nrpe_write = function(cmd) -- Create request packet, before checksum. - local pkt = "" - pkt = pkt .. bin.pack(">S", 2) - pkt = pkt .. bin.pack(">S", 1) - pkt = pkt .. bin.pack(">I", 0) - pkt = pkt .. bin.pack(">S", 0) - pkt = pkt .. bin.pack("A", cmd) - pkt = pkt .. string.char(0x00):rep(1024 - #cmd) - pkt = pkt .. bin.pack(">S", 0) + local pkt = bin.pack(">SSISAAS", + 2, + 1, + 0, + 0, + cmd, + string.rep("\0", 1024 - #cmd), + 0) -- Calculate the checksum, and insert it into the packet. - pkt = bin.pack( - "A>IA", - string.char(pkt:byte(1, 4)), - crc32(pkt), - string.char(pkt:byte(9, #pkt)) - ) + pkt = pkt:sub(1,4) .. bin.pack(">I", crc32(pkt)) .. pkt:sub(9) return pkt end diff --git a/scripts/oracle-sid-brute.nse b/scripts/oracle-sid-brute.nse index 700f41cb9..c6f537da9 100644 --- a/scripts/oracle-sid-brute.nse +++ b/scripts/oracle-sid-brute.nse @@ -3,6 +3,7 @@ local io = require "io" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" +local string = require "string" local table = require "table" description = [[ @@ -77,10 +78,9 @@ end -- local function create_connect_packet( host_ip, port_no, sid ) - local connect_data = "(DESCRIPTION=(CONNECT_DATA=(SID=" .. sid .. ")" - connect_data = connect_data .. "(CID=(PROGRAM=)(HOST=__jdbc__)(USER=)))" - connect_data = connect_data .. "(ADDRESS=(PROTOCOL=tcp)(HOST=" .. host_ip .. ")" - connect_data = connect_data .. "(PORT=" .. port_no .. ")))" + local connect_data = string.format( + "(DESCRIPTION=(CONNECT_DATA=(SID=%s)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=)))\z + (ADDRESS=(PROTOCOL=tcp)(HOST=%s)(PORT=%d)))", sid, host_ip, port_no) local data = bin.pack(">SSSSSSSSSSICCA", 308, -- Version diff --git a/scripts/p2p-conficker.nse b/scripts/p2p-conficker.nse index b8fc8b4fa..e1358a845 100644 --- a/scripts/p2p-conficker.nse +++ b/scripts/p2p-conficker.nse @@ -457,9 +457,7 @@ local function p2p_create_packet(protocol, do_encryption) end -- Add the key and flags that are always present (and skip over the boring stuff) - local packet = "" - packet = packet .. bin.pack(" %s)", mech, mkill)) return smtp_finish(nil, true) @@ -242,8 +242,8 @@ local function check_smtpd(smtp_opts) end end - table.insert(vuln.check_results, string.format("AUTH tests:%s", - auth_tests)) + table.insert(vuln.check_results, string.format("AUTH tests: %s", + table.concat(auth_tests, " "))) end else stdnse.debug2("Authentication is not available") diff --git a/scripts/smtp-vuln-cve2011-1764.nse b/scripts/smtp-vuln-cve2011-1764.nse index b60d1b0c1..a27c2de93 100644 --- a/scripts/smtp-vuln-cve2011-1764.nse +++ b/scripts/smtp-vuln-cve2011-1764.nse @@ -101,20 +101,19 @@ local function check_dkim(socket, smtp_opts) return status, response end - local message = "MIME-Version: 1.0\r\n" - message = message..string.format("From: <%s>\r\nTo: <%s>\r\n", - smtp_opts.mailfrom, - smtp_opts.mailto) - message = message.."Subject: Nmap Exim DKIM Format String check\r\n" - - -- use a fake DKIM-Signature header. - message = message.."DKIM-Signature: v=1; a=%s%s%s%s;" - message = message.." c=%s%s%s%s; q=dns/txt;\r\n" - message = message.." d=%s%s%s%s; s=%s%s%s%s;\r\n" - message = message.." h=mime-version:from:to:subject;\r\n" - message = message.." bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;\r\n" - message = message.." b=DyE0uKynaea3Y66zkrnMaBqtYPYVXhazCKGBiZKMNywclgbj0MkREPH3t2EWByev9g=" - status, response = socket:send(message.."\r\n") + local message = ( + string.format( "MIME-Version: 1.0\r\nFrom: <%s>\r\nTo: <%s>\r\n", + smtp_opts.mailfrom, smtp_opts.mailto) + .."Subject: Nmap Exim DKIM Format String check\r\n" + -- use a fake DKIM-Signature header. + .."DKIM-Signature: v=1; a=%s%s%s%s;" + .." c=%s%s%s%s; q=dns/txt;\r\n" + .." d=%s%s%s%s; s=%s%s%s%s;\r\n" + .." h=mime-version:from:to:subject;\r\n" + .." bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;\r\n" + .." b=DyE0uKynaea3Y66zkrnMaBqtYPYVXhazCKGBiZKMNywclgbj0MkREPH3t2EWByev9g=\r\n" + ) + status, response = socket:send(message) if not status then return status, "failed to send the message." end diff --git a/scripts/sniffer-detect.nse b/scripts/sniffer-detect.nse index d6a229b9b..5910b698a 100644 --- a/scripts/sniffer-detect.nse +++ b/scripts/sniffer-detect.nse @@ -1,6 +1,7 @@ local nmap = require "nmap" local stdnse = require "stdnse" local string = require "string" +local table = require "table" description = [[ Checks if a target on a local Ethernet has its network card in promiscuous mode. @@ -117,10 +118,11 @@ action = function(host) "\x01\x00\x5e\x00\x00\x03", -- M3 } local v - local out = "" + local out = {} for _, v in ipairs(t) do - out = out .. do_test(dnet, pcap, host, v .. test_static) + out[#out+1] = do_test(dnet, pcap, host, v .. test_static) end + out = table.concat(out) dnet:ethernet_close() pcap:pcap_close() diff --git a/scripts/ssh-hostkey.nse b/scripts/ssh-hostkey.nse index 5a9d3119e..ef4fcc3db 100644 --- a/scripts/ssh-hostkey.nse +++ b/scripts/ssh-hostkey.nse @@ -375,13 +375,13 @@ local function postaction() for key, hosts in pairs(hostkeys) do if #hostkeys[key] > 1 then table.sort(hostkeys[key], function(a, b) return ipOps.compare_ip(a, "lt", b) end) - local str = 'Key ' .. key .. ' used by:' + local str = {'Key ' .. key .. ' used by:'} local tab = {key=revmap[key], hosts={}} for _, host in ipairs(hostkeys[key]) do - str = str .. '\n ' .. host + str[#str+1] = host table.insert(tab.hosts, host) end - table.insert(output, str) + table.insert(output, table.concat(str, "\n ")) table.insert(output_tab, tab) end end diff --git a/scripts/traceroute-geolocation.nse b/scripts/traceroute-geolocation.nse index 7e0eed329..9719d3fa1 100644 --- a/scripts/traceroute-geolocation.nse +++ b/scripts/traceroute-geolocation.nse @@ -94,16 +94,16 @@ local function createKMLFile(filename, coords) local header = '\r\n' local footer = '' - local output = "" + local output = {} for _, coord in ipairs(coords) do - output = output .. ("%s,%s, 0.\r\n"):format(coord.lon, coord.lat) + output[#output+1] = ("%s,%s, 0.\r\n"):format(coord.lon, coord.lat) end local f = io.open(filename, "w") if ( not(f) ) then return false, "Failed to create KML file" end - f:write(header .. output .. footer) + f:write(header .. table.concat(output) .. footer) f:close() return true