1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Use byte values instead of hex strings for ASN.1 types, avoiding upper/lower case mixups

This commit is contained in:
dmiller
2017-03-29 20:41:57 +00:00
parent 49231a2782
commit 85e10c6b2b
4 changed files with 81 additions and 80 deletions

View File

@@ -60,34 +60,34 @@ ASN1Decoder = {
self.decoder = {} self.decoder = {}
-- Boolean -- Boolean
self.decoder["01"] = function( self, encStr, elen, pos ) self.decoder["\x01"] = function( self, encStr, elen, pos )
local val = string.byte(encStr, pos) local val = string.byte(encStr, pos)
return pos + 1, val ~= 0xFF return pos + 1, val ~= 0xFF
end end
-- Integer -- Integer
self.decoder["02"] = function( self, encStr, elen, pos ) self.decoder["\x02"] = function( self, encStr, elen, pos )
return self.decodeInt(encStr, elen, pos) return self.decodeInt(encStr, elen, pos)
end end
-- Octet String -- Octet String
self.decoder["04"] = function( self, encStr, elen, pos ) self.decoder["\x04"] = function( self, encStr, elen, pos )
return bin.unpack("A" .. elen, encStr, pos) return bin.unpack("A" .. elen, encStr, pos)
end end
-- Null -- Null
self.decoder["05"] = function( self, encStr, elen, pos ) self.decoder["\x05"] = function( self, encStr, elen, pos )
return pos, false return pos, false
end end
-- Object Identifier -- Object Identifier
self.decoder["06"] = function( self, encStr, elen, pos ) self.decoder["\x06"] = function( self, encStr, elen, pos )
return self:decodeOID( encStr, elen, pos ) return self:decodeOID( encStr, elen, pos )
end end
-- Context specific tags -- Context specific tags
-- --
self.decoder["30"] = function( self, encStr, elen, pos ) self.decoder["\x30"] = function( self, encStr, elen, pos )
return self:decodeSeq(encStr, elen, pos) return self:decodeSeq(encStr, elen, pos)
end end
end, end,
@@ -133,7 +133,6 @@ ASN1Decoder = {
local newpos = pos local newpos = pos
etype, newpos = string.unpack("c1", encStr, newpos) etype, newpos = string.unpack("c1", encStr, newpos)
etype = stdnse.tohex(etype)
newpos, elen = self.decodeLength(encStr, newpos) newpos, elen = self.decodeLength(encStr, newpos)
if self.decoder[etype] then if self.decoder[etype] then
@@ -222,7 +221,7 @@ ASN1Decoder = {
last = pos + len - 1 last = pos + len - 1
if pos <= last then if pos <= last then
oid._snmp = '06' oid._snmp = '\x06'
pos, octet = bin.unpack("C", encStr, pos) pos, octet = bin.unpack("C", encStr, pos)
oid[2] = math.fmod(octet, 40) oid[2] = math.fmod(octet, 40)
octet = octet - oid[2] octet = octet - oid[2]

View File

@@ -91,7 +91,7 @@ DEREFPOLICY = {
local tagEncoder = {} local tagEncoder = {}
tagEncoder['table'] = function(self, val) tagEncoder['table'] = function(self, val)
if (val._ldap == '0A') then if (val._ldap == '\x0A') then
local ival = self.encodeInt(val[1]) local ival = self.encodeInt(val[1])
local len = self.encodeLength(#ival) local len = self.encodeLength(#ival)
return bin.pack('HAA', '0A', len, ival) return bin.pack('HAA', '0A', len, ival)
@@ -110,10 +110,7 @@ tagEncoder['table'] = function(self, val)
for _, v in ipairs(val) do for _, v in ipairs(val) do
encVal = encVal .. encode(v) -- todo: buffer? encVal = encVal .. encode(v) -- todo: buffer?
end end
local tableType = "\x30" local tableType = val._snmp or "\x30"
if (val["_snmp"]) then
tableType = bin.pack("H", val["_snmp"])
end
return bin.pack('AAA', tableType, self.encodeLength(#encVal), encVal) return bin.pack('AAA', tableType, self.encodeLength(#encVal), encVal)
end end
@@ -142,16 +139,16 @@ end
-- LDAP specific tag decoders -- LDAP specific tag decoders
local tagDecoder = {} local tagDecoder = {}
tagDecoder["0A"] = function( self, encStr, elen, pos ) tagDecoder["\x0A"] = function( self, encStr, elen, pos )
return self.decodeInt(encStr, elen, pos) return self.decodeInt(encStr, elen, pos)
end end
tagDecoder["8A"] = function( self, encStr, elen, pos ) tagDecoder["\x8A"] = function( self, encStr, elen, pos )
return bin.unpack("A" .. elen, encStr, pos) return bin.unpack("A" .. elen, encStr, pos)
end end
-- null decoder -- null decoder
tagDecoder["31"] = function( self, encStr, elen, pos ) tagDecoder["\x31"] = function( self, encStr, elen, pos )
return pos, nil return pos, nil
end end
@@ -241,8 +238,8 @@ function searchRequest( socket, params )
encoder:registerTagEncoders(tagEncoder) encoder:registerTagEncoders(tagEncoder)
decoder:registerTagDecoders(tagDecoder) decoder:registerTagDecoders(tagDecoder)
request = request .. encode( { _ldap='0A', params.scope } )--scope request = request .. encode( { _ldap='\x0A', params.scope } )--scope
request = request .. encode( { _ldap='0A', params.derefPolicy } )--derefpolicy request = request .. encode( { _ldap='\x0A', params.derefPolicy } )--derefpolicy
request = request .. encode( params.sizeLimit or 0)--sizelimit request = request .. encode( params.sizeLimit or 0)--sizelimit
request = request .. encode( params.timeLimit or 0)--timelimit request = request .. encode( params.timeLimit or 0)--timelimit
request = request .. encode( params.typesOnly or false)--TypesOnly request = request .. encode( params.typesOnly or false)--TypesOnly
@@ -370,8 +367,8 @@ function udpSearchRequest( host, port, params )
encoder:registerTagEncoders(tagEncoder) encoder:registerTagEncoders(tagEncoder)
decoder:registerTagDecoders(tagDecoder) decoder:registerTagDecoders(tagDecoder)
request = request .. encode( { _ldap='0A', params.scope } )--scope request = request .. encode( { _ldap='\x0A', params.scope } )--scope
request = request .. encode( { _ldap='0A', params.derefPolicy } )--derefpolicy request = request .. encode( { _ldap='\x0A', params.derefPolicy } )--derefpolicy
request = request .. encode( params.sizeLimit or 0)--sizelimit request = request .. encode( params.sizeLimit or 0)--sizelimit
request = request .. encode( params.timeLimit or 0)--timelimit request = request .. encode( params.timeLimit or 0)--timelimit
request = request .. encode( params.typesOnly or false)--TypesOnly request = request .. encode( params.typesOnly or false)--TypesOnly
@@ -464,7 +461,7 @@ function bindRequest( socket, params )
local catch = function() socket:close() stdnse.debug1("bindRequest failed") end local catch = function() socket:close() stdnse.debug1("bindRequest failed") end
local try = nmap.new_try(catch) local try = nmap.new_try(catch)
local ldapAuth = encode( { _ldaptype = 80, params.password } ) local ldapAuth = encode( { _ldaptype = '80', params.password } )
local bindReq = encode( params.version ) .. encode( params.username ) .. ldapAuth local bindReq = encode( params.version ) .. encode( params.username ) .. ldapAuth
local ldapMsg = encode(ldapMessageId) .. encodeLDAPOp( APPNO.BindRequest, true, bindReq ) local ldapMsg = encode(ldapMessageId) .. encodeLDAPOp( APPNO.BindRequest, true, bindReq )
local packet local packet

View File

@@ -28,20 +28,20 @@ end
-- Complex tag encoders -- Complex tag encoders
tagEncoder['table'] = function(self, val) tagEncoder['table'] = function(self, val)
if val._snmp == '06' then -- OID if val._snmp == '\x06' then -- OID
local oidStr = string.char(val[1]*40 + val[2]) local oidStr = string.char(val[1]*40 + val[2])
for i = 3, #val do for i = 3, #val do
oidStr = oidStr .. self.encode_oid_component(val[i]) oidStr = oidStr .. self.encode_oid_component(val[i])
end end
return bin.pack("HAA", '06', self.encodeLength(#oidStr), oidStr) return bin.pack("HAA", '06', self.encodeLength(#oidStr), oidStr)
elseif (val._snmp == '40') then -- ipAddress elseif (val._snmp == '\x40') then -- ipAddress
return bin.pack("HC4", '40 04', table.unpack(val)) return bin.pack("HC4", '40 04', table.unpack(val))
-- counter or gauge or timeticks or opaque -- counter or gauge or timeticks or opaque
elseif (val._snmp == '41' or val._snmp == '42' or val._snmp == '43' or val._snmp == '44') then elseif (val._snmp == '\x41' or val._snmp == '\x42' or val._snmp == '\x43' or val._snmp == '\x44') then
local val = self:encodeInt(val[1]) local val = self:encodeInt(val[1])
return bin.pack("HAA", val._snmp, self.encodeLength(#val), val) return bin.pack("AAA", val._snmp, self.encodeLength(#val), val)
end end
local encVal = "" local encVal = ""
@@ -49,10 +49,7 @@ tagEncoder['table'] = function(self, val)
encVal = encVal .. self:encode(v) -- todo: buffer? encVal = encVal .. self:encode(v) -- todo: buffer?
end end
local tableType = "\x30" local tableType = val._snmp or "\x30"
if (val["_snmp"]) then
tableType = bin.pack("H", val["_snmp"])
end
return bin.pack('AAA', tableType, self.encodeLength(#encVal), encVal) return bin.pack('AAA', tableType, self.encodeLength(#encVal), encVal)
end end
@@ -85,18 +82,18 @@ local tagDecoder = {}
-- Response-PDU -- Response-PDU
-- TOOD: Figure out how to remove these dependencies -- TOOD: Figure out how to remove these dependencies
tagDecoder["a2"] = function( self, encStr, elen, pos ) tagDecoder["\xa2"] = function( self, encStr, elen, pos )
local seq = {} local seq = {}
pos, seq = self:decodeSeq(encStr, elen, pos) pos, seq = self:decodeSeq(encStr, elen, pos)
seq._snmp = "a2" seq._snmp = "\xa2"
return pos, seq return pos, seq
end end
tagDecoder["40"] = function( self, encStr, elen, pos ) tagDecoder["\x40"] = function( self, encStr, elen, pos )
local ip = {} local ip = {}
pos, ip[1], ip[2], ip[3], ip[4] = bin.unpack("C4", encStr, pos) pos, ip[1], ip[2], ip[3], ip[4] = bin.unpack("C4", encStr, pos)
ip._snmp = '40' ip._snmp = '\x40'
return pos, ip return pos, ip
end end
@@ -114,23 +111,23 @@ function decode(encStr, pos)
decoder:registerBaseDecoders() decoder:registerBaseDecoders()
-- Application specific tags -- Application specific tags
-- tagDecoder["40"] = decoder.decoder["06"] -- IP Address; same as OID -- tagDecoder["40"] = decoder.decoder["06"] -- IP Address; same as OID
tagDecoder["41"] = decoder.decoder["02"] -- Counter; same as Integer tagDecoder["\x41"] = decoder.decoder["\x02"] -- Counter; same as Integer
tagDecoder["42"] = decoder.decoder["02"] -- Gauge tagDecoder["\x42"] = decoder.decoder["\x02"] -- Gauge
tagDecoder["43"] = decoder.decoder["02"] -- TimeTicks tagDecoder["\x43"] = decoder.decoder["\x02"] -- TimeTicks
tagDecoder["44"] = decoder.decoder["04"] -- Opaque; same as Octet String tagDecoder["\x44"] = decoder.decoder["\x04"] -- Opaque; same as Octet String
tagDecoder["45"] = decoder.decoder["06"] -- NsapAddress tagDecoder["\x45"] = decoder.decoder["\x06"] -- NsapAddress
tagDecoder["46"] = decoder.decoder["02"] -- Counter64 tagDecoder["\x46"] = decoder.decoder["\x02"] -- Counter64
tagDecoder["47"] = decoder.decoder["02"] -- UInteger32 tagDecoder["\x47"] = decoder.decoder["\x02"] -- UInteger32
-- Context specific tags -- Context specific tags
tagDecoder["a0"] = decoder.decoder["30"] -- GetRequest-PDU tagDecoder["\xa0"] = decoder.decoder["\x30"] -- GetRequest-PDU
tagDecoder["a1"] = decoder.decoder["30"] -- GetNextRequest-PDU tagDecoder["\xa1"] = decoder.decoder["\x30"] -- GetNextRequest-PDU
--tagDecoder["a2"] = decoder.decoder["30"] -- Response-PDU --tagDecoder["\xa2"] = decoder.decoder["\x30"] -- Response-PDU
tagDecoder["a3"] = decoder.decoder["30"] -- SetRequest-PDU tagDecoder["\xa3"] = decoder.decoder["\x30"] -- SetRequest-PDU
tagDecoder["a4"] = decoder.decoder["30"] -- Trap-PDU tagDecoder["\xa4"] = decoder.decoder["\x30"] -- Trap-PDU
tagDecoder["a5"] = decoder.decoder["30"] -- GetBulkRequest-PDU tagDecoder["\xa5"] = decoder.decoder["\x30"] -- GetBulkRequest-PDU
tagDecoder["a6"] = decoder.decoder["30"] -- InformRequest-PDU (not implemented here yet) tagDecoder["\xa6"] = decoder.decoder["\x30"] -- InformRequest-PDU (not implemented here yet)
tagDecoder["a7"] = decoder.decoder["30"] -- SNMPv2-Trap-PDU (not implemented here yet) tagDecoder["\xa7"] = decoder.decoder["\x30"] -- SNMPv2-Trap-PDU (not implemented here yet)
end end
@@ -174,7 +171,7 @@ function buildGetRequest(options, ...)
if not options.errIdx then options.errIdx = 0 end if not options.errIdx then options.errIdx = 0 end
local req = {} local req = {}
req._snmp = 'a0' req._snmp = '\xa0'
req[1] = options.reqId req[1] = options.reqId
req[2] = options.err req[2] = options.err
req[3] = options.errIdx req[3] = options.errIdx
@@ -206,7 +203,7 @@ function buildGetNextRequest(options, ...)
options.errIdx = options.errIdx or 0 options.errIdx = options.errIdx or 0
local req = {} local req = {}
req._snmp = 'a1' req._snmp = '\xa1'
req[1] = options.reqId req[1] = options.reqId
req[2] = options.err req[2] = options.err
req[3] = options.errIdx req[3] = options.errIdx
@@ -242,7 +239,7 @@ function buildSetRequest(options, oid, value)
if not options.errIdx then options.errIdx = 0 end if not options.errIdx then options.errIdx = 0 end
local req = {} local req = {}
req._snmp = 'a3' req._snmp = '\xa3'
req[1] = options.reqId req[1] = options.reqId
req[2] = options.err req[2] = options.err
req[3] = options.errIdx req[3] = options.errIdx
@@ -268,14 +265,14 @@ end
-- @return Table representing PDU -- @return Table representing PDU
function buildTrap(enterpriseOid, agentIp, genTrap, specTrap, timeStamp) function buildTrap(enterpriseOid, agentIp, genTrap, specTrap, timeStamp)
local req = {} local req = {}
req._snmp = 'a4' req._snmp = '\xa4'
if (type(enterpriseOid) == "string") then if (type(enterpriseOid) == "string") then
req[1] = str2oid(enterpriseOid) req[1] = str2oid(enterpriseOid)
else else
req[1] = enterpriseOid req[1] = enterpriseOid
end end
req[2] = {} req[2] = {}
req[2]._snmp = '40' req[2]._snmp = '\x40'
for n in string.gmatch(agentIp, "%d+") do for n in string.gmatch(agentIp, "%d+") do
table.insert(req[2], tonumber(n)) table.insert(req[2], tonumber(n))
end end
@@ -283,7 +280,7 @@ function buildTrap(enterpriseOid, agentIp, genTrap, specTrap, timeStamp)
req[4] = specTrap req[4] = specTrap
req[5] = {} req[5] = {}
req[5]._snmp = '43' req[5]._snmp = '\x43'
req[5][1] = timeStamp req[5][1] = timeStamp
req[6] = {} req[6] = {}
@@ -309,7 +306,7 @@ function buildGetResponse(options, oid, value)
if not options.errIdx then options.errIdx = 0 end if not options.errIdx then options.errIdx = 0 end
local resp = {} local resp = {}
resp._snmp = 'a2' resp._snmp = '\xa2'
resp[1] = options.reqId resp[1] = options.reqId
resp[2] = options.err resp[2] = options.err
resp[3] = options.errIdx resp[3] = options.errIdx
@@ -341,7 +338,7 @@ function str2oid(oidStr)
for n in string.gmatch(oidStr, "%d+") do for n in string.gmatch(oidStr, "%d+") do
table.insert(oid, tonumber(n)) table.insert(oid, tonumber(n))
end end
oid._snmp = '06' oid._snmp = '\x06'
return oid return oid
end end
@@ -373,7 +370,7 @@ function str2ip(ipStr)
for n in string.gmatch(ipStr, "%d+") do for n in string.gmatch(ipStr, "%d+") do
table.insert(ip, tonumber(n)) table.insert(ip, tonumber(n))
end end
ip._snmp = '40' ip._snmp = '\x40'
return ip return ip
end end
@@ -384,8 +381,10 @@ end
-- @return Table with all decoded responses and their OIDs. -- @return Table with all decoded responses and their OIDs.
function fetchResponseValues(resp) function fetchResponseValues(resp)
if (type(resp) == "string") then if (type(resp) == "string") then
local nsedebug = require "nsedebug"
local _ local _
_, resp = decode(resp) _, resp = decode(resp)
stdnse.debug1("Decoded: >>>%s<<<", nsedebug.tostr(resp))
end end
if (type(resp) ~= "table") then if (type(resp) ~= "table") then
@@ -393,9 +392,9 @@ function fetchResponseValues(resp)
end end
local varBind local varBind
if (resp._snmp and resp._snmp == 'a2') then if (resp._snmp and resp._snmp == '\xa2') then
varBind = resp[4] varBind = resp[4]
elseif (resp[3] and resp[3]._snmp and resp[3]._snmp == 'a2') then elseif (resp[3] and resp[3]._snmp and resp[3]._snmp == '\xa2') then
varBind = resp[3][4] varBind = resp[3][4]
end end
@@ -404,15 +403,15 @@ function fetchResponseValues(resp)
for k, v in ipairs(varBind) do for k, v in ipairs(varBind) do
local val = v[2] local val = v[2]
if (type(v[2]) == "table") then if (type(v[2]) == "table") then
if (v[2]._snmp == '40') then if (v[2]._snmp == '\x40') then
val = v[2][1] .. '.' .. v[2][2] .. '.' .. v[2][3] .. '.' .. v[2][4] val = v[2][1] .. '.' .. v[2][2] .. '.' .. v[2][3] .. '.' .. v[2][4]
elseif (v[2]._snmp == '41') then elseif (v[2]._snmp == '\x41') then
val = v[2][1] val = v[2][1]
elseif (v[2]._snmp == '42') then elseif (v[2]._snmp == '\x42') then
val = v[2][1] val = v[2][1]
elseif (v[2]._snmp == '43') then elseif (v[2]._snmp == '\x43') then
val = v[2][1] val = v[2][1]
elseif (v[2]._snmp == '44') then elseif (v[2]._snmp == '\x44') then
val = v[2][1] val = v[2][1]
end end
end end
@@ -554,15 +553,21 @@ Helper = {
local oid = base_oid local oid = base_oid
local options = {} local options = {}
local nsedebug = require "nsedebug"
local status, snmpdata = self:getnext(options, oid) local status, snmpdata = self:getnext(options, oid)
stdnse.debug1("got data: >>>%s<<<", nsedebug.tostr(snmpdata))
while ( snmpdata and snmpdata[1] and snmpdata[1][1] and snmpdata[1][2] ) do while ( snmpdata and snmpdata[1] and snmpdata[1][1] and snmpdata[1][2] ) do
oid = snmpdata[1][2] oid = snmpdata[1][2]
stdnse.debug1("Comparing %s to %s", oid, base_oid)
if not oid:match(base_oid) or base_oid == oid then break end if not oid:match(base_oid) or base_oid == oid then break end
stdnse.debug1("matched %s", base_oid)
table.insert(snmp_table, { oid = oid, value = snmpdata[1][1] }) table.insert(snmp_table, { oid = oid, value = snmpdata[1][1] })
local _ -- NSE don't want you to use global even if it is _ local _ -- NSE don't want you to use global even if it is _
_, snmpdata = self:getnext(options, oid) _, snmpdata = self:getnext(options, oid)
stdnse.debug1("got data: >>>%s<<<", nsedebug.tostr(snmpdata))
end end
stdnse.debug1("done")
return status, snmp_table return status, snmp_table
end end

View File

@@ -99,32 +99,32 @@ KRB5 = {
-- A number of custom ASN1 decoders needed to decode the response -- A number of custom ASN1 decoders needed to decode the response
tagDecoder = { tagDecoder = {
["18"] = function( self, encStr, elen, pos ) ["\x18"] = function( self, encStr, elen, pos )
return bin.unpack("A" .. elen, encStr, pos) return bin.unpack("A" .. elen, encStr, pos)
end, end,
["1B"] = function( ... ) return KRB5.tagDecoder["18"](...) end, ["\x1B"] = function( ... ) return KRB5.tagDecoder["\x18"](...) end,
["6B"] = function( self, encStr, elen, pos ) ["\x6B"] = function( self, encStr, elen, pos )
local seq local seq
pos, seq = self:decodeSeq(encStr, elen, pos) pos, seq = self:decodeSeq(encStr, elen, pos)
return pos, seq return pos, seq
end, end,
-- Not really sure what these are, but they all decode sequences -- Not really sure what these are, but they all decode sequences
["7E"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\x7E"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A0"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA0"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A1"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA1"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A2"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA2"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A3"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA3"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A4"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA4"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A5"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA5"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A6"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA6"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A7"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA7"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A8"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA8"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["A9"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xA9"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["AA"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xAA"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
["AC"] = function( ... ) return KRB5.tagDecoder["6B"](...) end, ["\xAC"] = function( ... ) return KRB5.tagDecoder["\x6B"](...) end,
}, },