1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-26 09:29:01 +00:00

Allow encoding OID component greater than 127 in snmp.lua. Previously

the code just took each value mod 256 and stored it as a single byte.
The OID 1.3.1000.5 would encode as follows

tag len 1.3 1000%256  5
 06  03  2b       e8 05

What you're supposed to do is break each value into 7-bit chunks, and
set the high bit in every octet but the last. Now it is correctly
encoded as

tag len 1.3 1000  5
 06  04  2b 8768 05

The length also would not have been correct for lengths over 127, and
that is fixed also.
This commit is contained in:
david
2009-12-14 00:55:05 +00:00
parent ee0fee26c0
commit 3f7be738ad
2 changed files with 42 additions and 3 deletions

View File

@@ -16,6 +16,10 @@ o Added new NSE scripts:
system, server build date, and upstream time server IP address.
[Richard Sammet]
o Removed a limitation of snmp.lua that only allowed it to properly
encode OID component values up to 127. The bug was reported by
Victor Rudnev. [David]
Nmap 5.10BETA1 [2009-11-23]
o Added 14 new NSE scripts for a grand total of 72! You can learn

View File

@@ -8,6 +8,8 @@
module(... or "snmp",package.seeall)
require("bit")
---
-- Encodes an Integer according to ASN.1 basic encoding rules.
-- @param val Value to be encoded.
@@ -66,6 +68,39 @@ local function encodeLength(val)
end
local function encode_length_primitive(len)
if len < 128 then
return string.char(len)
else
local parts = {}
while len > 0 do
table.insert(parts, 1, string.char(bit.mod(len, 256)))
len = bit.rshift(len, 8)
end
assert(#parts < 128)
table.insert(parts, 1, string.char(#parts + 0x80))
return table.concat(parts)
end
end
-- Encode one component of an OID as a byte string. 7 bits of the component are
-- stored in each octet, most significant first, with the eigth bit set in all
-- octets but the last. These encoding rules come from
-- http://luca.ntop.org/Teaching/Appunti/asn1.html, section 5.9 OBJECT
-- IDENTIFIER.
local function encode_oid_component(n)
local parts = {}
table.insert(parts, 1, string.char(bit.mod(n, 128)))
while n >= 128 do
n = bit.rshift(n, 7)
table.insert(parts, 1, string.char(bit.mod(n, 128) + 0x80))
end
return table.concat(parts)
end
---
-- Encodes a given value according to ASN.1 basic encoding rules for SNMP
-- packet creation.
@@ -87,11 +122,11 @@ function encode(val)
end
if (vtype == 'table') then -- complex data types
if val._snmp == '06' then -- OID
local oidStr = bin.pack("C", val[1]*40 + val[2])
local oidStr = string.char(val[1]*40 + val[2])
for i = 3, #val do
oidStr = oidStr .. bin.pack("C", val[i])
oidStr = oidStr .. encode_oid_component(val[i])
end
return bin.pack("HCA", '06', #val - 1, oidStr)
return bin.pack("HAA", '06', encode_length_primitive(#oidStr), oidStr)
elseif (val._snmp == '40') then -- ipAddress
return bin.pack("HC4", '40 04', unpack(val))
elseif (val._snmp == '41') then -- counter