home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / nselib / netbios.lua < prev    next >
Text File  |  2009-07-06  |  12KB  |  403 lines

  1. --- Creates and parses NetBIOS traffic. The primary use for this is to send
  2. --  NetBIOS name requests. 
  3. --
  4. --@author Ron Bowes <ron@skullsecurity.net>
  5. --@copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  6. -----------------------------------------------------------------------
  7.  
  8. module(... or "netbios", package.seeall)
  9.  
  10. require 'bit'
  11. require 'bin'
  12. require 'stdnse'
  13.  
  14. --- Encode a NetBIOS name for transport. Most packets that use the NetBIOS name
  15. --  require this encoding to happen first. It takes a name containing any possible
  16. --  character, and converted it to all uppercase characters (so it can, for example,
  17. --  pass case-sensitive data in a case-insensitive way)
  18. --
  19. -- There are two levels of encoding performed:
  20. -- * L1: Pad the string to 16 characters withs spaces (or NULLs if it's the 
  21. --     wildcard "*") and replace each byte with two bytes representing each
  22. --     of its nibbles, plus 0x41. 
  23. -- * L2: Prepend the length to the string, and to each substring in the scope
  24. --     (separated by periods). 
  25. --@param name The name that will be encoded (eg. "TEST1"). 
  26. --@param scope [optional] The scope to encode it with. I've never seen scopes used
  27. --       in the real world (eg, "insecure.org"). 
  28. --@return The L2-encoded name and scope 
  29. --        (eg. "\x20FEEFFDFEDBCACACACACACACACACAAA\x08insecure\x03org")
  30. function name_encode(name, scope)
  31.  
  32.     stdnse.print_debug(3, "Encoding name '%s'", name)
  33.     -- Truncate or pad the string to 16 bytes
  34.     if(string.len(name) >= 16) then
  35.         name = string.sub(name, 1, 16)
  36.     else
  37.         local padding = " "
  38.         if name == "*" then
  39.             padding = "\0"
  40.         end
  41.  
  42.         repeat
  43.             name = name .. padding
  44.         until string.len(name) == 16
  45.     end
  46.  
  47.     -- Convert to uppercase
  48.     name = string.upper(name)
  49.  
  50.     -- Do the L1 encoding
  51.     local L1_encoded = ""
  52.     for i=1, string.len(name), 1 do
  53.         local b = string.byte(name, i)
  54.         L1_encoded = L1_encoded .. string.char(bit.rshift(bit.band(b, 0xF0), 4) + 0x41)
  55.         L1_encoded = L1_encoded .. string.char(bit.rshift(bit.band(b, 0x0F), 0) + 0x41)
  56.     end
  57.  
  58.     -- Do the L2 encoding 
  59.     local L2_encoded = string.char(32) .. L1_encoded
  60.  
  61.     if scope ~= nil then
  62.         -- Split the scope at its periods
  63.         local piece
  64.         for piece in string.gmatch(scope, "[^.]+") do
  65.             L2_encoded = L2_encoded .. string.char(string.len(piece)) .. piece
  66.         end
  67.     end
  68.  
  69.     stdnse.print_debug(3, "=> '%s'", L2_encoded)
  70.     return L2_encoded
  71. end
  72.  
  73.  
  74.  
  75. --- Does the exact opposite of name_encode. Converts an encoded name to
  76. --  the string representation. If the encoding is invalid, it will still attempt
  77. --  to decode the string as best as possible. 
  78. --@param encoded_name The L2-encoded name
  79. --@return the decoded name and the scope. The name will still be padded, and the
  80. --         scope will never be nil (empty string is returned if no scope is present)
  81. function name_decode(encoded_name)
  82.     local name = ""
  83.     local scope = ""
  84.  
  85.     local len = string.byte(encoded_name, 1)
  86.     local i
  87.  
  88.     stdnse.print_debug(3, "Decoding name '%s'", encoded_name)
  89.  
  90.     for i = 2, len + 1, 2 do
  91.         local ch = 0
  92.         ch = bit.bor(ch, bit.lshift(string.byte(encoded_name, i)     - 0x41, 4))
  93.         ch = bit.bor(ch, bit.lshift(string.byte(encoded_name, i + 1) - 0x41, 0))
  94.  
  95.         name = name .. string.char(ch)
  96.     end
  97.  
  98.     -- Decode the scope
  99.     local pos = 34
  100.     while string.len(encoded_name) > pos do
  101.         local len = string.byte(encoded_name, pos)
  102.         scope = scope .. string.sub(encoded_name, pos + 1, pos + len) .. "."
  103.         pos = pos + 1 + len
  104.     end
  105.  
  106.     -- If there was a scope, remove the trailing period
  107.     if(string.len(scope) > 0) then
  108.         scope = string.sub(scope, 1, string.len(scope) - 1)
  109.     end
  110.  
  111.     stdnse.print_debug(3, "=> '%s'", name)
  112.  
  113.     return name, scope
  114. end
  115.  
  116. --- Sends out a UDP probe on port 137 to get a human-readable list of names the
  117. --  the system is using. 
  118. --@param host The IP or hostname to check. 
  119. --@param prefix [optional] The prefix to put on each line when it's returned. 
  120. --@return (status, result) If status is true, the result is a human-readable 
  121. --        list of names. Otherwise, result is an error message. 
  122. function get_names(host, prefix)
  123.  
  124.     local status, names, statistics = do_nbstat(host)
  125.  
  126.     if(prefix == nil) then
  127.         prefix = ""
  128.     end
  129.  
  130.  
  131.     if(status) then
  132.         local result = ""
  133.         for i = 1, #names, 1 do
  134.             result = result .. string.format("%s%s<%02x>\n", prefix, names[i]['name'], names[i]['prefix'])
  135.         end
  136.  
  137.         return true, result
  138.     else
  139.         return false, names
  140.     end
  141. end
  142.  
  143. --- Sends out a UDP probe on port 137 to get the server's name (that is, the
  144. --  entry in its NBSTAT table with a 0x20 suffix). 
  145. --@param host The IP or hostname of the server. 
  146. --@param names [optional] The names to use, from <code>do_nbstat</code>. 
  147. --@return (status, result) If status is true, the result is the NetBIOS name. 
  148. --        otherwise, result is an error message. 
  149. function get_server_name(host, names)
  150.  
  151.     local status
  152.     local i
  153.  
  154.     if names == nil then
  155.         status, names = do_nbstat(host)
  156.     
  157.         if(status == false) then
  158.             return false, names
  159.         end
  160.     end
  161.  
  162.     for i = 1, #names, 1 do
  163.         if names[i]['suffix'] == 0x20 then
  164.             return true, names[i]['name']
  165.         end
  166.     end
  167.  
  168.     return false, "Couldn't find NetBIOS server name"
  169. end
  170.  
  171. --- Sends out a UDP probe on port 137 to get the user's name (that is, the 
  172. --  entry in its NBSTAT table with a 0x03 suffix, that isn't the same as
  173. --  the server's name. If the username can't be determined, which is frequently
  174. --  the case, nil is returned. 
  175. --@param host The IP or hostname of the server. 
  176. --@param names [optional] The names to use, from <code>do_nbstat</code>. 
  177. --@return (status, result) If status is true, the result is the NetBIOS name or nil. 
  178. --        otherwise, result is an error message.
  179. function get_user_name(host, names)
  180.  
  181.     local status, server_name = get_server_name(host, names)
  182.  
  183.     if(status == false) then
  184.         return false, server_name
  185.     end
  186.  
  187.     if(names == nil) then
  188.         status, names = do_nbstat(host)
  189.     
  190.         if(status == false) then
  191.             return false, names
  192.         end
  193.     end
  194.  
  195.     for i = 1, #names, 1 do
  196.         if names[i]['suffix'] == 0x03 and names[i]['name'] ~= server_name then
  197.             return true, names[i]['name']
  198.         end
  199.     end
  200.     
  201.     return true, nil
  202.     
  203. end
  204.  
  205.  
  206. --- This is the function that actually handles the UDP query to retrieve
  207. --  the NBSTAT information. We make use of the Nmap registry here, so if another
  208. --  script has already performed a nbstat query, the result can be re-used. 
  209. --
  210. -- The NetBIOS request's header looks like this:
  211. --<code>
  212. --  --------------------------------------------------
  213. --  |  15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0 |
  214. --  |                  NAME_TRN_ID                    |
  215. --  | R |   OPCODE  |      NM_FLAGS      |   RCODE    | (FLAGS)
  216. --  |                    QDCOUNT                      |
  217. --  |                    ANCOUNT                      |
  218. --  |                    NSCOUNT                      |
  219. --  |                    ARCOUNT                      |
  220. --  --------------------------------------------------
  221. --</code>
  222. --
  223. -- In this case, the TRN_ID is a constant (0x1337, what else?), the flags
  224. -- are 0, and we have one question. All fields are network byte order. 
  225. --
  226. -- The body of the packet is a list of names to check for in the following
  227. -- format:
  228. -- * (ntstring) encoded name
  229. -- * (2 bytes)  query type (0x0021 = NBSTAT)
  230. -- * (2 bytes)  query class (0x0001 = IN)
  231. --
  232. -- The response header is the exact same, except it'll have some flags set
  233. -- (0x8000 for sure, since it's a response), and ANCOUNT will be 1. The format
  234. -- of the answer is:
  235. --
  236. -- * (ntstring) requested name
  237. -- * (2 bytes)  query type
  238. -- * (2 bytes)  query class
  239. -- * (2 bytes)  time to live
  240. -- * (2 bytes)  record length
  241. -- * (1 byte)   number of names
  242. -- * [for each name]
  243. -- *  (16 bytes) padded name, with a 1-byte suffix
  244. -- *  (2 bytes)  flags
  245. -- * (variable) statistics (usually mac address)
  246. --
  247. --@param host The IP or hostname of the system. 
  248. --@return (status, names, statistics) If status is true, then the servers names are
  249. --        returned as a table containing 'name', 'suffix', and 'flags'. 
  250. --        Otherwise, names is an error message and statistics is undefined. 
  251. function do_nbstat(host)
  252.  
  253.     local status, err
  254.     local socket = nmap.new_socket()
  255.     local encoded_name = name_encode("*")
  256.     local statistics
  257.  
  258.     stdnse.print_debug(3, "Performing nbstat on host '%s'", host)
  259.     -- Check if it's cased in the registry for this host
  260.     if(nmap.registry["nbstat_names_" .. host] ~= nil) then
  261.         stdnse.print_debug(3, " |_ [using cached value]")
  262.         return true, nmap.registry["nbstat_names_" .. host], nmap.registry["nbstat_statistics_" .. host]
  263.     end
  264.  
  265.     -- Create the query header
  266.     local query = bin.pack(">SSSSSS", 
  267.             0x1337,  -- Transaction id
  268.             0x0000,  -- Flags
  269.             1,       -- Questions
  270.             0,       -- Answers
  271.             0,       -- Authority
  272.             0        -- Extra
  273.         )
  274.  
  275.     query = query .. bin.pack(">zSS", 
  276.             encoded_name, -- Encoded name
  277.             0x0021,       -- Query type (0x21 = NBSTAT)
  278.             0x0001        -- Class = IN
  279.         )
  280.     status, err = socket:connect(host, 137, "udp")
  281.     if(status == false) then
  282.         return false, err
  283.     end
  284.  
  285.     status, err = socket:send(query)
  286.     if(status == false) then
  287.         return false, err
  288.     end
  289.  
  290.     socket:set_timeout(1000)
  291.  
  292.     status, result = socket:receive_bytes(1)
  293.     if(status == false) then
  294.         return false, result
  295.     end
  296.  
  297.     close_status, err = socket:close()
  298.     if(close_status == false) then
  299.         return false, err
  300.     end
  301.  
  302.     if(status) then
  303.         local pos, TRN_ID, FLAGS, QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT, rr_name, rr_type, rr_class, rr_ttl
  304.         local rrlength, name_count
  305.  
  306.         pos, TRN_ID, FLAGS, QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT = bin.unpack(">SSSSSS", result)
  307.  
  308.         -- Sanity check the result (has to have the same TRN_ID, 1 answer, and proper flags)
  309.         if(TRN_ID ~= 0x1337) then
  310.             return false, string.format("Invalid transaction ID returned: 0x%04x", TRN_ID)
  311.         end
  312.         if(ANCOUNT ~= 1) then
  313.             return false, "Server returned an invalid number of answers"
  314.         end
  315.         if(bit.band(FLAGS, 0x8000) == 0) then
  316.             return false, "Server's flags didn't indicate a response"
  317.         end
  318.         if(bit.band(FLAGS, 0x0007) ~= 0) then
  319.             return false, string.format("Server returned a NetBIOS error: 0x%02x", bit.band(FLAGS, 0x0007))
  320.         end
  321.  
  322.         -- Start parsing the answer field
  323.         pos, rr_name, rr_type, rr_class, rr_ttl = bin.unpack(">zSSI", result, pos)
  324.  
  325.         -- More sanity checks
  326.         if(rr_name ~= encoded_name) then
  327.             return false, "Server returned incorrect name"
  328.         end
  329.         if(rr_class ~= 0x0001) then
  330.             return false, "Server returned incorrect class"
  331.         end
  332.         if(rr_type ~= 0x0021) then
  333.             return false, "Server returned incorrect query type"
  334.         end
  335.  
  336.         pos, rrlength, name_count = bin.unpack(">SC", result, pos)
  337.  
  338.         local names = {}
  339.         for i = 1, name_count do
  340.             local name, suffix, flags
  341.  
  342.             -- Instead of reading the 16-byte name and pulling off the suffix, 
  343.             -- we read the first 15 bytes and then the 1-byte suffix. 
  344.             pos, name, suffix, flags = bin.unpack(">A15CS", result, pos)
  345.             name = string.gsub(name, "[ ]*$", "")
  346.  
  347.             names[i] = {}
  348.             names[i]['name']   = name
  349.             names[i]['suffix'] = suffix
  350.             names[i]['flags']  = flags
  351.  
  352.             -- Decrement the length
  353.             rrlength = rrlength - 18
  354.         end
  355.  
  356.         if(rrlength > 0) then
  357.             rrlength = rrlength - 1
  358.         end
  359.         pos, statistics = bin.unpack(string.format(">A%d", rrlength), result, pos)
  360.  
  361.         -- Put it in the registry, in case anybody else needs it
  362.         nmap.registry["nbstat_names_"      .. host] = names
  363.         nmap.registry["nbstat_statistics_" .. host] = statistics
  364.  
  365.         return true, names, statistics
  366.  
  367.     else
  368.         return false, "Name query failed: " .. result
  369.     end
  370. end
  371.  
  372. ---Convert the 16-bit flags field to a string. 
  373. --@param flags The 16-bit flags field
  374. --@return A string representing the flags
  375. function flags_to_string(flags)
  376.     local result = ""
  377.  
  378.     if(bit.band(flags, 0x8000) ~= 0) then
  379.         result = result .. "<group>"
  380.     else
  381.         result = result .. "<unique>"
  382.     end
  383.  
  384.     if(bit.band(flags, 0x1000) ~= 0) then
  385.         result = result .. "<deregister>"
  386.     end
  387.  
  388.     if(bit.band(flags, 0x0800) ~= 0) then
  389.         result = result .. "<conflict>"
  390.     end
  391.  
  392.     if(bit.band(flags, 0x0400) ~= 0) then
  393.         result = result .. "<active>"
  394.     end
  395.  
  396.     if(bit.band(flags, 0x0200) ~= 0) then
  397.         result = result .. "<permanent>"
  398.     end
  399.  
  400.     return result
  401. end
  402.  
  403.