1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-20 22:49:01 +00:00

Whitespace in ike.lua.

This commit is contained in:
david
2013-06-18 03:44:32 +00:00
parent 1614b7f594
commit af5f103b5f

View File

@@ -15,14 +15,14 @@ The current funcionality includes:
1. Generating a Main or Aggressive Mode IKE request packet with a variable amount of transforms and a vpn group. 1. Generating a Main or Aggressive Mode IKE request packet with a variable amount of transforms and a vpn group.
2. Sending a packet 2. Sending a packet
3. Receiving the response 3. Receiving the response
4. Parsing the response for VIDs 4. Parsing the response for VIDs
5. Searching for the VIDs in 'ike-fingerprints.lua' 5. Searching for the VIDs in 'ike-fingerprints.lua'
6. returning a parsed info table 6. returning a parsed info table
This library is meant for extension, which could include: This library is meant for extension, which could include:
1. complete parsing of the response packet (might allow for better fingerprinting) 1. complete parsing of the response packet (might allow for better fingerprinting)
2. adding more options to the request packet 2. adding more options to the request packet
vendor field (might give better fingerprinting of services, e.g. Checkpoint) vendor field (might give better fingerprinting of services, e.g. Checkpoint)
3. backoff pattern analyses 3. backoff pattern analyses
... ...
@@ -36,28 +36,47 @@ author = "Jesper Kueckelhahn"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html" license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"} categories = {"discovery", "safe"}
local enc_methods = { local enc_methods = {
["des"] = 0x80010001, ["des"] = 0x80010001,
["3des"] = 0x80010005, ["3des"] = 0x80010005,
["aes/128"]= { 0x80010007, 0x800E0080 }, ["aes/128"] = { 0x80010007, 0x800E0080 },
["aes/192"]= { 0x80010007, 0x800E00C0 }, ["aes/192"] = { 0x80010007, 0x800E00C0 },
["aes/256"]= { 0x80010007, 0x800E0100 } ["aes/256"] = { 0x80010007, 0x800E0100 },
} }
local authentication= {
["psk"] = 0x80030001,
["rsa"] = 0x80030003,
["Hybrid"] = 0x8003FADD,
["XAUTH"] = 0x8003FDE9,
}
local authentication= { ["psk"] = 0x80030001, ["rsa"] = 0x80030003, ["Hybrid"] = 0x8003FADD, ["XAUTH"] = 0x8003FDE9} local hash_algo = {
["md5"] = 0x80020001,
["sha1"] = 0x80020002,
}
local hash_algo = { ["md5"] = 0x80020001, ["sha1"] = 0x80020002} local group_desc = {
local group_desc = { ["768"] = 0x80040001, ["1024"] = 0x80040002, ["1536"]= 0x80040005} ["768"] = 0x80040001,
local exchange_mode = { ["Main"] = 0x02, ["Aggressive"]= 0x04} ["1024"] = 0x80040002,
local protocol_ids = { ["tcp"] = "06", ["udp"]= "11"} ["1536"] = 0x80040005,
}
local exchange_mode = {
["Main"] = 0x02,
["Aggressive"] = 0x04,
}
local protocol_ids = {
["tcp"] = "06",
["udp"] = "11",
}
-- Response packet types -- Response packet types
local response_exchange_type = { local response_exchange_type = {
["02"] = "Main", ["02"] = "Main",
["04"] = "Aggressive", ["04"] = "Aggressive",
["05"] = "Informational" ["05"] = "Informational",
} }
-- Payload names -- Payload names
@@ -69,7 +88,7 @@ local payloads = {
["05"] = "ID", ["05"] = "ID",
["08"] = "Hash", ["08"] = "Hash",
["0A"] = "Nonce", ["0A"] = "Nonce",
["0D"] = "VID" ["0D"] = "VID",
} }
@@ -113,8 +132,8 @@ end
-- --
local function generate_random(length) local function generate_random(length)
local rnd = "" local rnd = ""
for i=1, length do for i=1, length do
rnd = rnd .. string.format("%.2X", math.random(255)) rnd = rnd .. string.format("%.2X", math.random(255))
end end
return rnd return rnd
@@ -125,9 +144,8 @@ end
-- --
local function convert_to_hex(id) local function convert_to_hex(id)
local hex_str = "" local hex_str = ""
for c in string.gmatch(id, ".") do
for c in string.gmatch(id, ".") do hex_str = hex_str .. string.format("%X", c:byte())
hex_str = hex_str .. string.format("%X", c:byte())
end end
return hex_str return hex_str
end end
@@ -135,13 +153,13 @@ end
-- Extract Payloads -- Extract Payloads
local function extract_payloads(packet) local function extract_payloads(packet)
-- packet only contains HDR -- packet only contains HDR
if packet:len() < 61 then return {} end if packet:len() < 61 then return {} end
local np = packet:sub(33,34) -- next payload local np = packet:sub(33,34) -- next payload
local index = 61 -- starting point for search local index = 61 -- starting point for search
local ike_headers = {} -- ike headers local ike_headers = {} -- ike headers
local payload = '' local payload = ''
-- loop over packet -- loop over packet
@@ -169,7 +187,7 @@ local function extract_payloads(packet)
-- jump to the next payload -- jump to the next payload
index = index + payload_length index = index + payload_length
end end
return ike_headers return ike_headers
end end
@@ -183,8 +201,8 @@ end
-- --
-- NOTE: the second step currently only has support for CISCO devices -- NOTE: the second step currently only has support for CISCO devices
-- --
-- Input is a table of collected vendor-ids, output is a table -- Input is a table of collected vendor-ids, output is a table
-- with fields: -- with fields:
-- vendor, version, name, attributes (table), guess (table), os -- vendor, version, name, attributes (table), guess (table), os
local function lookup(vendor_ids) local function lookup(vendor_ids)
if vendor_ids == {} or vendor_ids == nil then return {} end if vendor_ids == {} or vendor_ids == nil then return {} end
@@ -206,35 +224,34 @@ local function lookup(vendor_ids)
-- loop over the vendor_ids returned in ike request -- loop over the vendor_ids returned in ike request
for _,vendor_id in pairs(vendor_ids) do for _,vendor_id in pairs(vendor_ids) do
-- loop over the fingerprints found in database -- loop over the fingerprints found in database
for _,row in pairs(fingerprints) do for _,row in pairs(fingerprints) do
if vendor_id:find(row.fingerprint) then if vendor_id:find(row.fingerprint) then
-- if a match is found, check if it's a version detection or attribute -- if a match is found, check if it's a version detection or attribute
if row.category == 'vendor' then if row.category == 'vendor' then
-- Only store the first match -- Only store the first match
if info.vendor == nil then if info.vendor == nil then
-- the fingerprint contains information about the VID -- the fingerprint contains information about the VID
info.vendor = row info.vendor = row
local debug_string = '' local debug_string = ''
if row.vendor ~= nil then debug_string = debug_string .. row.vendor .. ' ' end if row.vendor ~= nil then debug_string = debug_string .. row.vendor .. ' ' end
if row.version ~= nil then debug_string = debug_string .. row.version end if row.version ~= nil then debug_string = debug_string .. row.version end
stdnse.print_debug(2, "IKE: Fingerprint: %s matches %s", vendor_id, debug_string) stdnse.print_debug(2, "IKE: Fingerprint: %s matches %s", vendor_id, debug_string)
end end
elseif row.category == 'attribute' then elseif row.category == 'attribute' then
info.attribs[ #info.attribs + 1] = row info.attribs[ #info.attribs + 1] = row
stdnse.print_debug(2, "IKE: Attribute: %s matches %s", vendor_id, row.text) stdnse.print_debug(2, "IKE: Attribute: %s matches %s", vendor_id, row.text)
break break
end end
end end
end end
end end
end end
@@ -243,36 +260,36 @@ local function lookup(vendor_ids)
-- Search for the order of the vids -- Search for the order of the vids
-- Uses category 'vid_ordering' -- Uses category 'vid_ordering'
--- ---
-- search in the 'vid_ordering' category -- search in the 'vid_ordering' category
local debug_string = '' local debug_string = ''
for _,row in pairs(fingerprints) do for _,row in pairs(fingerprints) do
if row.category == 'vid_ordering' and all_vids:find(row.fingerprint) then if row.category == 'vid_ordering' and all_vids:find(row.fingerprint) then
-- Use ordering information if there where no vendor matches from prevoius step -- Use ordering information if there where no vendor matches from prevoius step
if info.vendor == nil then if info.vendor == nil then
info.vendor = row info.vendor = row
-- Debugging info -- Debugging info
debug_string = '' debug_string = ''
if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' ' end if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' ' end
if info.vendor.version ~= nil then debug_string = debug_string .. info.vendor.version .. ' ' end if info.vendor.version ~= nil then debug_string = debug_string .. info.vendor.version .. ' ' end
if info.vendor.ostype ~= nil then debug_string = debug_string .. info.vendor.ostype end if info.vendor.ostype ~= nil then debug_string = debug_string .. info.vendor.ostype end
stdnse.print_debug(2, 'IKE: No vendor match, but ordering match found: %s', debug_string) stdnse.print_debug(2, 'IKE: No vendor match, but ordering match found: %s', debug_string)
return info return info
-- Update OS based on ordering -- Update OS based on ordering
elseif info.vendor.vendor == row.vendor then elseif info.vendor.vendor == row.vendor then
info.vendor.ostype = row.ostype info.vendor.ostype = row.ostype
-- Debugging info -- Debugging info
debug_string = '' debug_string = ''
if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' to ' end if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' to ' end
if row.ostype ~= nil then debug_string = debug_string .. row.ostype end if row.ostype ~= nil then debug_string = debug_string .. row.ostype end
stdnse.print_debug(2, 'IKE: Vendor and ordering match. OS updated: %s', debug_string) stdnse.print_debug(2, 'IKE: Vendor and ordering match. OS updated: %s', debug_string)
return info return info
-- Only print debugging information if conflicting information is detected -- Only print debugging information if conflicting information is detected
@@ -282,7 +299,7 @@ local function lookup(vendor_ids)
if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' vs ' end if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' vs ' end
if row.vendor ~= nil then debug_string = debug_string .. row.vendor end if row.vendor ~= nil then debug_string = debug_string .. row.vendor end
stdnse.print_debug(2, 'IKE: Found an ordering match, but vendors do not match. %s', debug_string) stdnse.print_debug(2, 'IKE: Found an ordering match, but vendors do not match. %s', debug_string)
end end
end end
end end
@@ -294,8 +311,8 @@ end
-- Handle a response packet -- Handle a response packet
-- A very limited response parser -- A very limited response parser
-- Currently only the VIDs are extracted -- Currently only the VIDs are extracted
-- This could be made more advanced to -- This could be made more advanced to
-- allow for fingerprinting via the order -- allow for fingerprinting via the order
-- of the returned headers -- of the returned headers
--- ---
function response(packet) function response(packet)
@@ -308,7 +325,7 @@ function response(packet)
local ike_headers = {} local ike_headers = {}
-- simple check that the type is something other than 'Informational' -- simple check that the type is something other than 'Informational'
-- as this type does not include VIDs -- as this type does not include VIDs
if resp_type ~= "Informational" then if resp_type ~= "Informational" then
resp["mode"] = resp_type resp["mode"] = resp_type
@@ -334,7 +351,7 @@ end
-- and is a hex string -- and is a hex string
-- --
function send_request( host, port, packet ) function send_request( host, port, packet )
local socket = nmap.new_socket() local socket = nmap.new_socket()
local s_status, r_status, data, i, hexstring, _ local s_status, r_status, data, i, hexstring, _
@@ -345,13 +362,13 @@ function send_request( host, port, packet )
s_status,_ = socket:send(packet) s_status,_ = socket:send(packet)
-- receive answer -- receive answer
if s_status then if s_status then
r_status, data = socket:receive_lines(1) r_status, data = socket:receive_lines(1)
if r_status then if r_status then
i, hexstring = bin.unpack("H" .. data:len(), data) i, hexstring = bin.unpack("H" .. data:len(), data)
socket:close() socket:close()
return response(hexstring) return response(hexstring)
else else
socket:close() socket:close()
end end
@@ -363,7 +380,7 @@ function send_request( host, port, packet )
end end
-- Create the aggressive part of a packet -- Create the aggressive part of a packet
-- Aggressive mode includes the user-id, so the -- Aggressive mode includes the user-id, so the
-- length of this has to be taken into account -- length of this has to be taken into account
-- --
local function generate_aggressive(port, protocol, id, diffie) local function generate_aggressive(port, protocol, id, diffie)
@@ -377,39 +394,38 @@ local function generate_aggressive(port, protocol, id, diffie)
key_length = 96 key_length = 96
elseif diffie == 2 then elseif diffie == 2 then
key_length = 128 key_length = 128
end end
return bin.pack(">SHHSSHSHCHHH", return bin.pack(">SHHSSHSHCHHH",
-- Key Exchange -- Key Exchange
0x0a00 , -- Next payload (Nonce) 0x0a00 , -- Next payload (Nonce)
string.format("%04X", key_length+4) , -- Length (132-bit) string.format("%04X", key_length+4) , -- Length (132-bit)
generate_random(key_length) , -- Random key data generate_random(key_length) , -- Random key data
-- Nonce -- Nonce
0x0500 , -- Next payload (Identification) 0x0500 , -- Next payload (Identification)
0x0018 , -- Length (24) 0x0018 , -- Length (24)
generate_random(20) , -- Nonce data generate_random(20) , -- Nonce data
-- Identification -- Identification
0x0000 , -- Next Payload (None) 0x0000 , -- Next Payload (None)
id_len , -- Payload length (id + 8) id_len , -- Payload length (id + 8)
0x03 , -- ID Type (USER_FQDN) 0x03 , -- ID Type (USER_FQDN)
hex_prot , -- Protocol ID (UDP) hex_prot , -- Protocol ID (UDP)
hex_port , -- Port (500) hex_port , -- Port (500)
convert_to_hex(id) -- Id Data (as hex) convert_to_hex(id) -- Id Data (as hex)
) )
end end
-- Create the transform -- Create the transform
-- AES encryption needs an extra value to define the key length -- AES encryption needs an extra value to define the key length
-- Currently only DES, 3DES and AES encryption is supported -- Currently only DES, 3DES and AES encryption is supported
-- --
local function generate_transform(auth, encryption, hash, group, number, total) local function generate_transform(auth, encryption, hash, group, number, total)
local key_length, trans_length, aes_enc, sep, enc local key_length, trans_length, aes_enc, sep, enc
local next_payload, payload_number local next_payload, payload_number
-- handle special case of aes -- handle special case of aes
if encryption:sub(1,3) == "aes" then if encryption:sub(1,3) == "aes" then
trans_length = 0x0028 trans_length = 0x0028
@@ -431,25 +447,25 @@ local function generate_transform(auth, encryption, hash, group, number, total)
-- set the payload number -- set the payload number
payload_number = string.format("%.2X", number) payload_number = string.format("%.2X", number)
local trans = bin.pack(">SSHCSIIII", local trans = bin.pack(">SSHCSIIII",
next_payload , -- Next payload next_payload , -- Next payload
trans_length , -- Transform length trans_length , -- Transform length
payload_number , -- Transform number payload_number , -- Transform number
0x01 , -- Transform ID (IKE) 0x01 , -- Transform ID (IKE)
0x0000 , -- spacers ? 0x0000 , -- spacers ?
enc , -- Encryption algorithm enc , -- Encryption algorithm
hash_algo[hash] , -- Hash algorithm hash_algo[hash] , -- Hash algorithm
authentication[auth], -- Authentication method authentication[auth] , -- Authentication method
group_desc[group] -- Group Description group_desc[group] -- Group Description
) )
if key_length ~= nil then if key_length ~= nil then
trans = trans .. bin.pack(">I", key_length) -- only set for aes trans = trans .. bin.pack(">I", key_length) -- only set for aes
end end
trans = trans .. bin.pack(">IL", trans = trans .. bin.pack(">IL",
0x800b0001 , -- Life type (seconds) 0x800b0001 , -- Life type (seconds)
0x000c000400007080 -- Life duration (28800) 0x000c000400007080 -- Life duration (28800)
) )
return trans return trans
@@ -457,7 +473,7 @@ end
-- Generate multiple transforms -- Generate multiple transforms
-- Input nust be a table of complete transforms -- Input nust be a table of complete transforms
-- --
local function generate_transforms(transform_table) local function generate_transforms(transform_table)
local transforms = '' local transforms = ''
@@ -481,9 +497,9 @@ function request(port, proto, mode, transforms, diffie, id)
transform_string = generate_transforms(transforms) transform_string = generate_transforms(transforms)
number_transforms = string.format("%.2X", #transforms) number_transforms = string.format("%.2X", #transforms)
-- check for aggressive vs Main mode -- check for aggressive vs Main mode
if mode == "Aggressive" then if mode == "Aggressive" then
str_aggressive = generate_aggressive(port, proto, id, diffie) str_aggressive = generate_aggressive(port, proto, id, diffie)
payload_after_sa = 0x0400 payload_after_sa = 0x0400
else else
str_aggressive = "" str_aggressive = ""
@@ -497,29 +513,29 @@ function request(port, proto, mode, transforms, diffie, id)
l_pro = string.format("%.4X", 8 + transform_string:len()) l_pro = string.format("%.4X", 8 + transform_string:len())
-- Build the packet -- Build the packet
local packet = bin.pack(">HLCCCCIHSHIISHCCCH", local packet = bin.pack(">HLCCCCIHSHIISHCCCH",
generate_random(8) , -- Initiator cookie generate_random(8) , -- Initiator cookie
0x0000000000000000 , -- Responder cookie 0x0000000000000000 , -- Responder cookie
0x01 , -- Next payload (SA) 0x01 , -- Next payload (SA)
0x10 , -- Version 0x10 , -- Version
exchange_mode[mode] , -- Exchange type exchange_mode[mode] , -- Exchange type
0x00 , -- Flags 0x00 , -- Flags
0x00000000 , -- Message id 0x00000000 , -- Message id
l , -- packet length l , -- packet length
--# Security Association -- Security Association
payload_after_sa , -- Next payload (Key exchange, if aggressive mode) payload_after_sa , -- Next payload (Key exchange, if aggressive mode)
l_sa , -- Length l_sa , -- Length
0x00000001 , -- IPSEC 0x00000001 , -- IPSEC
0x00000001 , -- Situation 0x00000001 , -- Situation
--## Proposal --## Proposal
0x0000 , -- Next payload (None) 0x0000 , -- Next payload (None)
l_pro , -- Payload length l_pro , -- Payload length
0x01 , -- Proposal number 0x01 , -- Proposal number
0x01 , -- Protocol ID (ISAKMP) 0x01 , -- Protocol ID (ISAKMP)
0x00 , -- SPI Size 0x00 , -- SPI Size
number_transforms -- Proposal transforms number_transforms -- Proposal transforms
) )
@@ -533,4 +549,4 @@ function request(port, proto, mode, transforms, diffie, id)
end end
return _ENV return _ENV