mirror of
https://github.com/nmap/nmap.git
synced 2025-12-08 21:51:28 +00:00
Remove more bin.lua packings.
This commit is contained in:
106
nselib/coap.lua
106
nselib/coap.lua
@@ -1,4 +1,3 @@
|
||||
local bin = require "bin"
|
||||
local comm = require "comm"
|
||||
local json = require "json"
|
||||
local lpeg = require "lpeg"
|
||||
@@ -329,22 +328,23 @@ COAP.header.build = function(options)
|
||||
code = COAP.header.codes.build(code)
|
||||
|
||||
-- Build the fixed portion of the header.
|
||||
local pkt = ""
|
||||
|
||||
ver = ver << 6
|
||||
mtype = mtype << 4
|
||||
|
||||
pkt = pkt .. bin.pack("C", ver | mtype | tkl)
|
||||
pkt = pkt .. code
|
||||
pkt = pkt .. bin.pack(">S", id)
|
||||
pkt = pkt .. token
|
||||
local pkt = {
|
||||
string.pack("B", ver | mtype | tkl),
|
||||
code,
|
||||
string.pack(">I2", id),
|
||||
token,
|
||||
}
|
||||
|
||||
-- Include optional portions of the header.
|
||||
if options["options"] then
|
||||
pkt = pkt .. COAP.header.options.build(options.options)
|
||||
pkt[#pkt+1] = COAP.header.options.build(options.options)
|
||||
end
|
||||
|
||||
return pkt
|
||||
return table.concat(pkt)
|
||||
end
|
||||
|
||||
--- Parses a CoAP message header.
|
||||
@@ -361,9 +361,6 @@ end
|
||||
-- string containing the error message on failure.
|
||||
COAP.header.parse = function(buf, pos)
|
||||
assert(type(buf) == "string")
|
||||
if #buf < 4 then
|
||||
return false, "Cannot parse a string of less than four bytes."
|
||||
end
|
||||
|
||||
if not pos or pos == 0 then
|
||||
pos = 1
|
||||
@@ -371,14 +368,11 @@ COAP.header.parse = function(buf, pos)
|
||||
assert(type(pos) == "number")
|
||||
assert(pos <= #buf)
|
||||
|
||||
if pos + 4 - 1 > #buf then
|
||||
if #buf - pos + 1 < 4 then
|
||||
return false, "Fixed header extends past end of buffer."
|
||||
end
|
||||
|
||||
local pos, ver_type_tkl, code, id = bin.unpack("CA>S", buf, pos)
|
||||
if not pos then
|
||||
return false, "Failed to parse fixed header."
|
||||
end
|
||||
local ver_type_tkl, code, id, pos = string.unpack(">Bc1I2", buf, pos)
|
||||
|
||||
-- Parse the fixed header.
|
||||
local hdr = {}
|
||||
@@ -486,7 +480,7 @@ COAP.header.codes.build = function(name)
|
||||
|
||||
class = class << 5
|
||||
|
||||
return bin.pack("C", class | detail)
|
||||
return string.pack("B", class | detail)
|
||||
end
|
||||
|
||||
--- Parses a CoAP request or response code.
|
||||
@@ -511,7 +505,7 @@ COAP.header.codes.parse = function(buf, pos)
|
||||
assert(type(pos) == "number")
|
||||
assert(pos <= #buf)
|
||||
|
||||
local pos, id = bin.unpack("C", buf, pos)
|
||||
local id, pos = string.unpack("B", buf, pos)
|
||||
if not pos then
|
||||
return false, id
|
||||
end
|
||||
@@ -1462,20 +1456,8 @@ COAP.header.options.value.uint.build = function(val)
|
||||
if val == 0 then
|
||||
return ""
|
||||
end
|
||||
|
||||
if val <= 255 then
|
||||
return bin.pack("C", val)
|
||||
end
|
||||
|
||||
if val <= 65535 then
|
||||
return bin.pack(">S", val)
|
||||
end
|
||||
|
||||
if val <= 16777215 then
|
||||
return bin.pack(">I", val):sub(2, 5)
|
||||
end
|
||||
|
||||
return bin.pack(">I", val)
|
||||
-- strip leading null bytes to use smallest space
|
||||
return string.pack(">I16", val):gsub("^\0*","")
|
||||
end
|
||||
|
||||
--- Parses a CoAP message Uint header option value.
|
||||
@@ -1490,25 +1472,15 @@ end
|
||||
COAP.header.options.value.uint.parse = function(buf)
|
||||
assert(type(buf) == "string")
|
||||
assert(#buf >= 0)
|
||||
assert(#buf <= 4)
|
||||
assert(#buf <= 16)
|
||||
|
||||
if #buf == 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
local val, pos
|
||||
if #buf == 1 then
|
||||
pos, val = bin.unpack("C", buf)
|
||||
elseif #buf == 2 then
|
||||
pos, val = bin.unpack(">S", buf)
|
||||
elseif #buf == 3 then
|
||||
pos, val = bin.unpack(">I", string.char(0x00) .. buf)
|
||||
else
|
||||
pos, val = bin.unpack(">I", buf)
|
||||
end
|
||||
local val = string.unpack(">I" .. #buf, buf)
|
||||
|
||||
-- There should be no way for this to fail.
|
||||
assert(pos)
|
||||
assert(val)
|
||||
assert(type(val) == "number")
|
||||
|
||||
@@ -1567,19 +1539,18 @@ COAP.header.options.delta_length.build = function(delta, length)
|
||||
end
|
||||
|
||||
if num <= 268 then
|
||||
return 13, bin.pack("C", num - 13)
|
||||
return 13, string.pack("B", num - 13)
|
||||
end
|
||||
|
||||
return 14, bin.pack(">S", num - 269)
|
||||
return 14, string.pack(">I2", num - 269)
|
||||
end
|
||||
|
||||
local d1, d2 = build(delta)
|
||||
local l1, l2 = build(length)
|
||||
|
||||
d1 = d1 << 4
|
||||
bin.pack("C", d1 | l1)
|
||||
|
||||
return bin.pack("C", d1 | l1) .. d2 .. l2
|
||||
return string.pack("B", d1 | l1) .. d2 .. l2
|
||||
end
|
||||
|
||||
--- Parse the variable-length option delta and length field.
|
||||
@@ -1613,7 +1584,7 @@ COAP.header.options.delta_length.parse = function(buf, pos)
|
||||
assert(type(pos) == "number")
|
||||
assert(pos <= #buf)
|
||||
|
||||
local pos, delta_and_length = bin.unpack("C", buf, pos)
|
||||
local delta_and_length, pos = string.unpack("B", buf, pos)
|
||||
if not pos then
|
||||
return false, nil, nil, delta_and_length
|
||||
end
|
||||
@@ -1636,20 +1607,20 @@ COAP.header.options.delta_length.parse = function(buf, pos)
|
||||
|
||||
if delta == 13 then
|
||||
required_bytes = required_bytes + 1
|
||||
dspec = "C"
|
||||
dspec = "B"
|
||||
elseif delta == 14 then
|
||||
required_bytes = required_bytes + 2
|
||||
delta = 269
|
||||
dspec = ">S"
|
||||
dspec = ">I2"
|
||||
end
|
||||
|
||||
if length == 13 then
|
||||
required_bytes = required_bytes + 1
|
||||
lspec = "C"
|
||||
lspec = "B"
|
||||
elseif length == 14 then
|
||||
required_bytes = required_bytes + 2
|
||||
length = 269
|
||||
lspec = ">S"
|
||||
lspec = ">I2"
|
||||
end
|
||||
|
||||
if pos + required_bytes - 1 > #buf then
|
||||
@@ -1659,7 +1630,7 @@ COAP.header.options.delta_length.parse = function(buf, pos)
|
||||
-- Extract the remaining bytes of each field.
|
||||
if dspec then
|
||||
local num
|
||||
pos, num = bin.unpack(dspec, buf, pos)
|
||||
num, pos = string.unpack(dspec, buf, pos)
|
||||
if not pos then
|
||||
return false, nil, nil, num
|
||||
end
|
||||
@@ -1668,7 +1639,7 @@ COAP.header.options.delta_length.parse = function(buf, pos)
|
||||
|
||||
if lspec then
|
||||
local num
|
||||
pos, num = bin.unpack(lspec, buf, pos)
|
||||
num, pos = string.unpack(lspec, buf, pos)
|
||||
if not pos then
|
||||
return false, nil, nil, num
|
||||
end
|
||||
@@ -2426,7 +2397,7 @@ local tests = {
|
||||
{
|
||||
{["name"] = "etag", ["value"] = "ETAGETAG"},
|
||||
},
|
||||
bin.pack("CA", 0x48, "ETAGETAG")
|
||||
"\x48ETAGETAG"
|
||||
},
|
||||
{
|
||||
-- Before
|
||||
@@ -2450,7 +2421,7 @@ local tests = {
|
||||
{["name"] = "uri_path", ["value"] = "foo"},
|
||||
{["name"] = "max_age", ["value"] = 0},
|
||||
},
|
||||
bin.pack("CAC", 0xB3, "foo", 0x30)
|
||||
"\xB3foo\x30"
|
||||
},
|
||||
{
|
||||
-- Before
|
||||
@@ -2463,7 +2434,7 @@ local tests = {
|
||||
{["name"] = "uri_path", ["value"] = ".well-known"},
|
||||
{["name"] = "uri_path", ["value"] = "core"},
|
||||
},
|
||||
bin.pack("CACA", 0xBB, ".well-known", 0x04, "core")
|
||||
"\xBB.well-known\x04core"
|
||||
},
|
||||
{
|
||||
-- Before
|
||||
@@ -2482,14 +2453,7 @@ local tests = {
|
||||
{["name"] = "uri_path", ["value"] = "core"},
|
||||
{["name"] = "max_age", ["value"] = 0},
|
||||
},
|
||||
bin.pack(
|
||||
"CACCACAC",
|
||||
0x48, "ETAGETAG", -- ID: 4, Delta: 4
|
||||
0x10, -- ID: 5, Delta: 1
|
||||
0x6B, ".well-known", -- ID: 11, Delta: 6
|
||||
0x04, "core", -- ID: 11, Delta: 0
|
||||
0x30 -- ID: 14, Delta: 3
|
||||
)
|
||||
"\x48ETAGETAG\x10\x6B.well-known\x04core\x30"
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2537,15 +2501,7 @@ local tests = {
|
||||
{["name"] = "uri_path", ["value"] = "core"},
|
||||
},
|
||||
},
|
||||
bin.pack(
|
||||
"CC>SACACA",
|
||||
0x48,
|
||||
0x01,
|
||||
0x1234,
|
||||
"nmapcoap",
|
||||
0xBB, ".well-known",
|
||||
0x04, "core"
|
||||
)
|
||||
"\x48\x01\x12\x34nmapcoap\xBB.well-known\x04core"
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
-- o Added possibility to override transaction id
|
||||
-- o Added WPAD action
|
||||
|
||||
local bin = require "bin"
|
||||
local datetime = require "datetime"
|
||||
local ipOps = require "ipOps"
|
||||
local math = require "math"
|
||||
@@ -67,7 +66,7 @@ local function read_ip(data, pos, length)
|
||||
local results = {}
|
||||
for i=1, length, 4 do
|
||||
local value
|
||||
pos, value = bin.unpack(">I", data, pos)
|
||||
value, pos = string.unpack(">I4", data, pos)
|
||||
table.insert(results, ipOps.fromdword(value))
|
||||
end
|
||||
|
||||
@@ -75,7 +74,7 @@ local function read_ip(data, pos, length)
|
||||
end
|
||||
else
|
||||
local value
|
||||
pos, value = bin.unpack(">I", data, pos)
|
||||
value, pos = string.unpack(">I4", data, pos)
|
||||
|
||||
return pos, ipOps.fromdword(value)
|
||||
end
|
||||
@@ -89,7 +88,8 @@ end
|
||||
--@return The new position (will always be pos + length, no matter what we think it should be)
|
||||
--@return The value of the field, or nil if the field length was wrong.
|
||||
local function read_string(data, pos, length)
|
||||
return bin.unpack(string.format("A%d", length), data, pos)
|
||||
local value, pos = string.unpack(("c%d"):format(length), data, pos)
|
||||
return pos, value
|
||||
end
|
||||
|
||||
---Read a single byte. Print an error if the length isn't 1.
|
||||
@@ -105,7 +105,8 @@ local function read_1_byte(data, pos, length)
|
||||
pos = pos + length
|
||||
return pos, nil
|
||||
end
|
||||
return bin.unpack("C", data, pos)
|
||||
local value, pos = string.unpack("B", data, pos)
|
||||
return pos, value
|
||||
end
|
||||
|
||||
---Read a message type. This is a single-byte value that's looked up in the <code>request_types_str</code>
|
||||
@@ -163,7 +164,8 @@ local function read_2_bytes(data, pos, length)
|
||||
pos = pos + length
|
||||
return pos, nil
|
||||
end
|
||||
return bin.unpack(">S", data, pos)
|
||||
local value, pos = string.unpack(">I2", data, pos)
|
||||
return pos, value
|
||||
end
|
||||
|
||||
|
||||
@@ -185,7 +187,7 @@ local function read_2_bytes_list(data, pos, length)
|
||||
local results = {}
|
||||
for i=1, length, 2 do
|
||||
local value
|
||||
pos, value = bin.unpack(">S", data, pos)
|
||||
value, pos = string.unpack(">I2", data, pos)
|
||||
table.insert(results, value)
|
||||
end
|
||||
|
||||
@@ -207,7 +209,8 @@ local function read_4_bytes(data, pos, length)
|
||||
pos = pos + length
|
||||
return pos, nil
|
||||
end
|
||||
return bin.unpack(">I", data, pos)
|
||||
local value, pos = string.unpack(">I4", data, pos)
|
||||
return pos, value
|
||||
end
|
||||
|
||||
---Read a 4-byte unsigned little endian value, and interpret it as a time offset value. Print an
|
||||
@@ -225,7 +228,7 @@ local function read_time(data, pos, length)
|
||||
pos = pos + length
|
||||
return pos, nil
|
||||
end
|
||||
pos, result = bin.unpack(">I", data, pos)
|
||||
result, pos = string.unpack(">I4", data, pos)
|
||||
|
||||
return pos, datetime.format_time(result)
|
||||
end
|
||||
@@ -426,34 +429,32 @@ function dhcp_build(request_type, ip_address, mac_address, options, request_opti
|
||||
end
|
||||
|
||||
-- Header
|
||||
packet = packet .. bin.pack(">CCCC", overrides['op'] or 1, overrides['htype'] or 1, overrides['hlen'] or 6, overrides['hops'] or 0) -- BOOTREQUEST, 10mb ethernet, 6 bytes long, 0 hops
|
||||
packet = packet .. string.pack(">BBBB", overrides['op'] or 1, overrides['htype'] or 1, overrides['hlen'] or 6, overrides['hops'] or 0) -- BOOTREQUEST, 10mb ethernet, 6 bytes long, 0 hops
|
||||
packet = packet .. ( overrides['xid'] or transaction_id ) -- Transaction ID =
|
||||
packet = packet .. bin.pack(">SS", overrides['secs'] or 0, overrides['flags'] or 0x0000) -- Secs, flags
|
||||
packet = packet .. string.pack(">I2I2", overrides['secs'] or 0, overrides['flags'] or 0x0000) -- Secs, flags
|
||||
packet = packet .. ip_address -- Client address
|
||||
packet = packet .. bin.pack("<I", overrides['yiaddr'] or 0) -- yiaddr
|
||||
packet = packet .. bin.pack("<I", overrides['siaddr'] or 0) -- siaddr
|
||||
packet = packet .. bin.pack("<I", overrides['giaddr'] or 0) -- giaddr
|
||||
packet = packet .. string.pack("<I4I4I4", overrides['yiaddr'] or 0,
|
||||
overrides['siaddr'] or 0,
|
||||
overrides['giaddr'] or 0)
|
||||
packet = packet .. mac_address .. string.rep('\0', 16 - #mac_address) -- chaddr (MAC address)
|
||||
packet = packet .. (overrides['sname'] or string.rep('\0', 64)) -- sname
|
||||
packet = packet .. (overrides['file'] or string.rep('\0', 128)) -- file
|
||||
packet = packet .. bin.pack(">I", overrides['cookie'] or 0x63825363) -- Magic cookie
|
||||
packet = packet .. string.pack(">I4", overrides['cookie'] or 0x63825363) -- Magic cookie
|
||||
|
||||
-- Options
|
||||
packet = packet .. bin.pack(">CCC", 0x35, 1, request_type) -- Request type
|
||||
packet = packet .. string.pack(">BBB", 0x35, 1, request_type) -- Request type
|
||||
|
||||
for _, option in ipairs(options or {}) do
|
||||
packet = packet .. bin.pack(">C", option.number)
|
||||
if ( "string" == option.type ) then
|
||||
packet = packet .. bin.pack("p", option.value)
|
||||
elseif( "ip" == option.type ) then
|
||||
packet = packet .. bin.pack(">CI", 4, option.value)
|
||||
packet = packet .. string.pack(">B", option.number)
|
||||
if ( "string" == option.type or "ip" == option.type ) then
|
||||
packet = packet .. string.pack("s1", option.value)
|
||||
end
|
||||
end
|
||||
|
||||
packet = packet .. bin.pack(">CCA", 0x37, #request_options, request_options) -- Request options
|
||||
packet = packet .. bin.pack(">CCI", 0x33, 4, lease_time or 1) -- Lease time
|
||||
packet = packet .. string.pack(">Bs1", 0x37, request_options) -- Request options
|
||||
packet = packet .. string.pack(">BBI4", 0x33, 4, lease_time or 1) -- Lease time
|
||||
|
||||
packet = packet .. bin.pack(">C", 0xFF) -- Termination
|
||||
packet = packet .. "\xFF" -- Termination
|
||||
|
||||
return true, strbuf.dump(packet)
|
||||
end
|
||||
@@ -473,26 +474,26 @@ function dhcp_parse(data, transaction_id)
|
||||
local result = {}
|
||||
|
||||
-- Receive the first bit and make sure we got the correct operation back
|
||||
pos, result['op'], result['htype'], result['hlen'], result['hops'] = bin.unpack(">CCCC", data, pos)
|
||||
result.op, result.htype, result.hlen, result.hops, pos = string.unpack(">BBBB", data, pos)
|
||||
if(result['op'] ~= 2) then
|
||||
return false, string.format("DHCP server returned invalid reply ('op' wasn't BOOTREPLY (it was 0x%02x))", result['op'])
|
||||
end
|
||||
|
||||
-- Confirm the transaction id
|
||||
pos, result['xid'] = bin.unpack("A4", data, pos)
|
||||
result.xid, pos = string.unpack("c4", data, pos)
|
||||
if(result['xid'] ~= transaction_id) then
|
||||
return false, string.format("DHCP server returned invalid reply (transaction id didn't match (%s != %s))", result['xid'], transaction_id)
|
||||
end
|
||||
|
||||
-- Unpack the secs, flags, addresses, sname, and file
|
||||
pos, result['secs'], result['flags'] = bin.unpack(">SS", data, pos)
|
||||
pos, result['ciaddr'] = bin.unpack(">I", data, pos)
|
||||
pos, result['yiaddr'] = bin.unpack(">I", data, pos)
|
||||
pos, result['siaddr'] = bin.unpack(">I", data, pos)
|
||||
pos, result['giaddr'] = bin.unpack(">I", data, pos)
|
||||
pos, result['chaddr'] = bin.unpack("A16", data, pos)
|
||||
pos, result['sname'] = bin.unpack("A64", data, pos)
|
||||
pos, result['file'] = bin.unpack("A128", data, pos)
|
||||
result.secs, result.flags,
|
||||
result.ciaddr,
|
||||
result.yiaddr,
|
||||
result.siaddr,
|
||||
result.giaddr,
|
||||
result.chaddr,
|
||||
result.sname,
|
||||
result.file, pos = string.unpack(">I2I2 I4I4I4I4 c16 c64 c128", data, pos)
|
||||
|
||||
-- Convert the addresses to strings
|
||||
result['ciaddr_str'] = ipOps.fromdword(result['ciaddr'])
|
||||
@@ -501,7 +502,7 @@ function dhcp_parse(data, transaction_id)
|
||||
result['giaddr_str'] = ipOps.fromdword(result['giaddr'])
|
||||
|
||||
-- Confirm the cookie
|
||||
pos, result['cookie'] = bin.unpack(">I", data, pos)
|
||||
result.cookie, pos = string.unpack(">I4", data, pos)
|
||||
if(result['cookie'] ~= 0x63825363) then
|
||||
return false, "DHCP server returned invalid reply (the magic cookie was invalid)"
|
||||
end
|
||||
@@ -515,7 +516,7 @@ function dhcp_parse(data, transaction_id)
|
||||
end
|
||||
|
||||
local option, length
|
||||
pos, option, length = bin.unpack(">CC", data, pos)
|
||||
option, length, pos = string.unpack(">BB", data, pos)
|
||||
|
||||
-- Check for termination condition
|
||||
if(option == 0xFF) then
|
||||
@@ -611,10 +612,10 @@ end
|
||||
--@return The parsed response, as a table.
|
||||
function make_request(target, request_type, ip_address, mac_address, options, request_options, overrides, lease_time)
|
||||
-- A unique id that identifies this particular session (and lets us filter out what we don't want to see)
|
||||
local transaction_id = overrides and overrides['xid'] or bin.pack("<I", math.random(0, 0x7FFFFFFF))
|
||||
local transaction_id = overrides and overrides['xid'] or string.pack("<I4", math.random(0, 0x7FFFFFFF))
|
||||
|
||||
-- Generate the packet
|
||||
local status, packet = dhcp_build(request_type, bin.pack(">I", ipOps.todword(ip_address)), mac_address, options, request_options, overrides, lease_time, transaction_id)
|
||||
local status, packet = dhcp_build(request_type, ipOps.ip_to_str(ip_address), mac_address, options, request_options, overrides, lease_time, transaction_id)
|
||||
if(not(status)) then
|
||||
stdnse.debug1("dhcp: Couldn't build packet: " .. packet)
|
||||
return false, "Couldn't build packet: " .. packet
|
||||
|
||||
@@ -920,7 +920,8 @@ MQTT.utf8_parse = function(buf, pos)
|
||||
return false, ("Buffer at position %d has no space for a %d-byte UTF-8 string."):format(pos, str_length)
|
||||
end
|
||||
|
||||
return string.unpack(">s2", buf, pos)
|
||||
local value, pos = string.unpack(">s2", buf, pos)
|
||||
return pos, value
|
||||
end
|
||||
|
||||
--- Prefix the body of an MQTT packet with a fixed header.
|
||||
|
||||
114
nselib/mysql.lua
114
nselib/mysql.lua
@@ -7,7 +7,6 @@
|
||||
--
|
||||
-- @author Patrik Karlsson <patrik@cqure.net>
|
||||
|
||||
local bin = require "bin"
|
||||
local nmap = require "nmap"
|
||||
local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
@@ -91,7 +90,7 @@ local function decodeHeader( data, pos )
|
||||
local response = {}
|
||||
local pos, tmp = pos or 1, 0
|
||||
|
||||
pos, tmp = bin.unpack( "<I", data, pos )
|
||||
tmp, pos = string.unpack( "<I4", data, pos )
|
||||
response.len = ( tmp & 255 )
|
||||
response.number = ( tmp >> 24 )
|
||||
|
||||
@@ -121,42 +120,38 @@ function receiveGreeting( socket )
|
||||
end
|
||||
|
||||
local is_error
|
||||
pos, is_error = bin.unpack( "C", data, pos )
|
||||
is_error, pos = string.unpack("B", data, pos)
|
||||
|
||||
if ( is_error == 0xff ) then
|
||||
pos, response.errorcode = bin.unpack( "<S", data, pos )
|
||||
pos, response.errormsg = bin.unpack("A" .. (#data - pos + 1), data, pos )
|
||||
response.errorcode, pos = string.unpack( "<I2", data, pos )
|
||||
response.errormsg = data:sub(pos)
|
||||
|
||||
return false, response.errormsg
|
||||
end
|
||||
|
||||
response.proto = is_error
|
||||
pos, response.version = bin.unpack( "z", data, pos )
|
||||
pos, response.threadid = bin.unpack( "<I", data, pos )
|
||||
response.version, response.threadid, pos = string.unpack( "<zI4", data, pos )
|
||||
|
||||
if response.proto == 10 then
|
||||
pos, response.salt, _ = bin.unpack( "A8C", data, pos )
|
||||
pos, response.capabilities = bin.unpack( "<S", data, pos )
|
||||
if pos < #data then
|
||||
pos, response.charset = bin.unpack( "C", data, pos )
|
||||
pos, response.status = bin.unpack( "<S", data, pos )
|
||||
pos, response.extcapabilities = bin.unpack( "<S", data, pos) -- capabilities, upper 2 bytes
|
||||
response.salt, response.capabilities, pos = string.unpack("<c8xI2", data, pos)
|
||||
local auth_plugin_len
|
||||
pos, auth_plugin_len = bin.unpack("C", data, pos)
|
||||
pos, tmp = bin.unpack( "A10", data, pos )
|
||||
if pos < #data then
|
||||
response.charset, response.status,
|
||||
response.extcapabilities, -- capabilities, upper 2 bytes
|
||||
auth_plugin_len, tmp, pos = string.unpack( "<BI2 I2 Bc10", data, pos )
|
||||
if tmp ~= "\0\0\0\0\0\0\0\0\0\0" then
|
||||
stdnse.debug2("reserved bytes are not nulls")
|
||||
end
|
||||
if response.capabilities & Capabilities.Support41Auth > 0 then
|
||||
pos, tmp, _ = bin.unpack("A" .. (math.max(13, auth_plugin_len - 8) - 1) .. "x", data, pos)
|
||||
tmp, pos = string.unpack("c" .. (math.max(13, auth_plugin_len - 8) - 1) .. "x", data, pos)
|
||||
response.salt = response.salt .. tmp
|
||||
end
|
||||
if response.extcapabilities & ExtCapabilities.SupportsAuthPlugins > 0 then
|
||||
response.auth_plugin_name = bin.unpack("z", data, pos)
|
||||
response.auth_plugin_name = string.unpack("z", data, pos)
|
||||
end
|
||||
end
|
||||
elseif response.proto == 9 then
|
||||
pos, response.auth_plugin_data = bin.unpack( "z", data, pos )
|
||||
response.auth_plugin_data, pos = string.unpack( "z", data, pos )
|
||||
else
|
||||
stdnse.debug2("Unknown MySQL protocol version: %d", response.proto)
|
||||
end
|
||||
@@ -189,8 +184,8 @@ local function createLoginHash(pass, salt)
|
||||
hash_stage3 = openssl.sha1( salt .. hash_stage2 )
|
||||
|
||||
for pos=1, hash_stage1:len() do
|
||||
_, b1 = bin.unpack( "C", hash_stage1, pos )
|
||||
_, b2 = bin.unpack( "C", hash_stage3, pos )
|
||||
b1 = string.unpack( "B", hash_stage1, pos )
|
||||
b2 = string.unpack( "B", hash_stage3, pos )
|
||||
|
||||
reply[pos] = string.char( b2 ~ b1 )
|
||||
end
|
||||
@@ -244,7 +239,7 @@ function loginRequest( socket, params, username, password, salt )
|
||||
hash = createLoginHash( password, salt )
|
||||
end
|
||||
|
||||
local packet = bin.pack( "<SSICAzp",
|
||||
local packet = string.pack( "<I2I2I4B c23 zs1",
|
||||
clicap,
|
||||
extcapabilities,
|
||||
MAXPACKET,
|
||||
@@ -256,7 +251,7 @@ function loginRequest( socket, params, username, password, salt )
|
||||
|
||||
local tmp = packet:len() + ( packetno << 24 )
|
||||
|
||||
packet = bin.pack( "<I", tmp ) .. packet
|
||||
packet = string.pack( "<I4", tmp ) .. packet
|
||||
|
||||
try( socket:send(packet) )
|
||||
packet = try( socket:receive_bytes(HEADER_SIZE) )
|
||||
@@ -270,26 +265,24 @@ function loginRequest( socket, params, username, password, salt )
|
||||
|
||||
local is_error
|
||||
|
||||
pos, is_error = bin.unpack( "C", packet, pos )
|
||||
is_error, pos = string.unpack( "B", packet, pos )
|
||||
|
||||
if is_error > 0 then
|
||||
pos, response.errorcode = bin.unpack( "<S", packet, pos )
|
||||
|
||||
local has_sqlstate
|
||||
pos, has_sqlstate = bin.unpack( "C", packet, pos )
|
||||
response.errorcode, has_sqlstate, pos = string.unpack( "<I2B", packet, pos )
|
||||
|
||||
if has_sqlstate == 35 then
|
||||
pos, response.sqlstate = bin.unpack( "A5", packet, pos )
|
||||
response.sqlstate, pos = string.unpack( "c5", packet, pos )
|
||||
end
|
||||
|
||||
pos, response.errormessage = bin.unpack( "z", packet, pos )
|
||||
response.errormessage, pos = string.unpack( "z", packet, pos )
|
||||
|
||||
return false, response.errormessage
|
||||
else
|
||||
response.errorcode = 0
|
||||
pos, response.affectedrows = bin.unpack( "C", packet, pos )
|
||||
pos, response.serverstatus = bin.unpack( "<S", packet, pos )
|
||||
pos, response.warnings = bin.unpack( "<S", packet, pos )
|
||||
response.affectedrows,
|
||||
response.serverstatus,
|
||||
response.warnings, pos = string.unpack( "<BI2I2", packet, pos )
|
||||
end
|
||||
|
||||
return true, response
|
||||
@@ -309,36 +302,19 @@ end
|
||||
-- <code>length</code> and <code>type</code>
|
||||
function decodeField( data, pos )
|
||||
|
||||
local header, len
|
||||
local def, _
|
||||
local _
|
||||
local field = {}
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.catalog = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.database = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.table = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.orig_table = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.name = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
pos, len = bin.unpack( "C", data, pos )
|
||||
pos, field.orig_name = bin.unpack( "A" .. len, data, pos )
|
||||
|
||||
-- should be 0x0C
|
||||
pos, _ = bin.unpack( "C", data, pos )
|
||||
|
||||
-- charset, in my case 0x0800
|
||||
pos, _ = bin.unpack( "<S", data, pos )
|
||||
|
||||
pos, field.length = bin.unpack( "<I", data, pos )
|
||||
pos, field.type = bin.unpack( "A6", data, pos )
|
||||
field.catalog,
|
||||
field.database,
|
||||
field.table,
|
||||
field.orig_table,
|
||||
field.name,
|
||||
field.orig_name,
|
||||
_, -- should be 0x0C
|
||||
_, -- charset, in my case 0x0800
|
||||
field.length,
|
||||
field.type, pos = string.unpack( "<s1s1s1s1s1s1BI2I4c6", data, pos )
|
||||
|
||||
return pos, field
|
||||
|
||||
@@ -403,7 +379,7 @@ function decodeQueryResponse( socket )
|
||||
end
|
||||
|
||||
if header.len > 0 then
|
||||
local _, b = bin.unpack("C", data, pos )
|
||||
local b = string.unpack("B", data, pos )
|
||||
|
||||
-- Is this the EOF packet?
|
||||
if b == EOF_MARKER then
|
||||
@@ -465,13 +441,11 @@ end
|
||||
-- @return number containing the amount of fields
|
||||
function decodeResultSetHeader( data )
|
||||
|
||||
local _, fields
|
||||
|
||||
if data:len() ~= HEADER_SIZE + 1 then
|
||||
return false, "Result set header was incorrect"
|
||||
end
|
||||
|
||||
_, fields = bin.unpack( "C", data, HEADER_SIZE + 1 )
|
||||
local fields = string.unpack( "B", data, HEADER_SIZE + 1 )
|
||||
|
||||
return true, fields
|
||||
end
|
||||
@@ -486,16 +460,16 @@ end
|
||||
-- @return rows table containing row tables
|
||||
function decodeDataPackets( data, count )
|
||||
|
||||
local len, pos = 0, 1, 1
|
||||
local header, row, rows = {}, {}, {}
|
||||
local pos = 1
|
||||
local rows = {}
|
||||
|
||||
while pos < data:len() do
|
||||
row = {}
|
||||
while pos <= data:len() do
|
||||
local row = {}
|
||||
local header
|
||||
pos, header = decodeHeader( data, pos )
|
||||
|
||||
for i=1, count do
|
||||
pos, len = bin.unpack("C", data, pos )
|
||||
pos, row[i] = bin.unpack("A" .. len, data, pos)
|
||||
row[i], pos = string.unpack("s1", data, pos)
|
||||
end
|
||||
|
||||
table.insert( rows, row )
|
||||
@@ -521,7 +495,7 @@ function sqlQuery( socket, query )
|
||||
local packet, packet_len, pos, header
|
||||
local status, fields, field_count, rows, rs
|
||||
|
||||
packet = bin.pack("<ICA", querylen, Command.Query, query )
|
||||
packet = string.pack("<I4B", querylen, Command.Query) .. query
|
||||
|
||||
--
|
||||
-- http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Result_Set_Header_Packet
|
||||
|
||||
Reference in New Issue
Block a user