Nmap Development mailing list archives
Re: [nmap-svn] r16159 - nmap/nselib
From: Ron <ron () skullsecurity net>
Date: Fri, 20 Nov 2009 11:06:55 -0600
Sorry, I committed some extra code in this one that I didn't mean to (should have 'svn diff'ed.. oops).
The code is simply functions that aren't called from anywhere (yet), so, unless somebody minds, I'm just going to leave it.
commit-mailer () insecure org wrote:
Author: ron Date: Fri Nov 20 09:00:55 2009 New Revision: 16159 Log: Reduced the number of connections/traffic used by smb-enum-shares.nse by half. I was checking a random share to see if the right error is returned for every share, when it only actually had to be done once. Modified: nmap/nselib/msrpc.lua nmap/nselib/smb.lua Modified: nmap/nselib/msrpc.lua ============================================================================== --- nmap/nselib/msrpc.lua (original) +++ nmap/nselib/msrpc.lua Fri Nov 20 09:00:55 2009 @@ -395,6 +395,65 @@ return true, result end+---LANMAN API calls use different conventions than everything else, so make a separate function for them. +function call_lanmanapi(smbstate, opnum, server_type)+ local status, result + local parameters = "" + local data + local convert, entry_count, available_entries + local entries = {} + local pos ++ parameters = bin.pack("<SzzSSI", + opnum, + "WrLehDO", -- Parameter Descriptor+ "B16", -- Return Descriptor + 0, -- Detail level + 14724, -- Return buffer size + server_type -- Server type + ) + + stdnse.print_debug(1, "MSRPC: Sending Browser Service request") + status, result = smb.send_transaction_named_pipe(smbstate, parameters, nil, "\\PIPE\\LANMAN", true) + if(not(status)) then + return false, "Couldn't call LANMAN API: " .. result + end + + parameters = result.parameters + data = result.data + + stdnse.print_debug(1, "MSRPC: Parsing Browser Service response") + pos, status, convert, entry_count, available_entries = bin.unpack("<SSSS", parameters) + if(status ~= 0) then + return false, string.format("Call to Browser Service failed with status = %d", status) + end + + stdnse.print_debug(1, "MSRPC: Browser service returned %d entries", entry_count) + + local pos = 1 + local entry + for i = 1, entry_count, 1 do + -- Read the string + pos, entry = bin.unpack("<z", data, pos) + stdnse.print_debug(1, "MSRPC: Found name: %s", entry) + + -- pos needs to be rounded to the next even multiple of 16 + while(((pos - 1) % 16) ~= 0) do + pos = pos + 1 + end + + -- Make sure we didn't hit the end of the packet + if(not(entry)) then + return false, "Call to browser service didn't receive enough data" + end + + -- Insert the result + table.insert(entries, entry) + end + + return true, entries +end +---A proxy to a <code>msrpctypes</code> function that converts a ShareType to an english string. -- I implemented this as a proxy so scripts don't have to make direct calls to <code>msrpctypes</code>-- functions. Modified: nmap/nselib/smb.lua ============================================================================== --- nmap/nselib/smb.lua (original) +++ nmap/nselib/smb.lua Fri Nov 20 09:00:55 2009 @@ -1972,18 +1972,23 @@-- It is probably best to think of this as another protocol layer. This function will wrap SMB stuff around a -- MSRPC call, make the call, then unwrap the SMB stuff from it before returning. -----@param smb The SMB object associated with the connection ---@param function_parameters The parameter data to pass to the function. This is untested, since none of the--- transactions I've done have required parameters. ---@param function_data The data to send with the packet. This is basically the next protocol layer ---@param pipe [optional] The pipe to transact on. Default: "\PIPE\". +--@param smb The SMB object associated with the connection+--@param function_parameters The parameter data to pass to the function. This is untested, since none of the+-- transactions I've done have required parameters. +--@param function_data The data to send with the packet. This is basically the next protocol layer +--@param pipe [optional] The pipe to transact on. Default: "\PIPE\". +--@param no_setup [optional] If set, the 'setup' is set to 0 and some parameters are left off. This occurs while +-- using the LANMAN Remote API. Default: false. --@return (status, result) If status is false, result is an error message. Otherwise, result is a table -- containing 'parameters' and 'data', representing the parameters and data returned by the server. -function send_transaction_named_pipe(smb, function_parameters, function_data, pipe)+function send_transaction_named_pipe(smb, function_parameters, function_data, pipe, no_setup)local header1, header2, header3, header4, command, status, flags, flags2, pid_high, signature, unused, pid, mid local header, parameters, data- local parameters_offset, data_offset - local total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2 + local parameter_offset = 0 + local parameter_size = 0 + local data_offset = 0 + local data_size = 0 + local total_word_count, total_data_count, reserved1, parameter_count, parameter_displacement, data_count, data_displacement, setup_count, reserved2 local response = {}if(pipe == nil) then@@ -1994,34 +1999,52 @@ header = smb_encode_header(smb, command_codes['SMB_COM_TRANSACTION']) -- 0x25 = SMB_COM_TRANSACTION-- 0x20 for SMB header, 0x01 for parameters header, 0x20 for parameters length, 0x02 for data header, 0x07 for "\PIPE\"- parameters_offset = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1) - data_offset = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1) + string.len(function_parameters) + if(function_parameters) then + parameter_offset = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1) + parameter_size = #function_parameters + end + + if(function_data) then + data_offset = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1) + parameter_size + data_size = #function_data + end-- Parameters are 0x20 bytes long. - parameters = bin.pack("<SSSSCCSISSSSSCCSS", - string.len(function_parameters), -- Total parameter count. - string.len(function_data), -- Total data count. - 0x000, -- Max parameter count.- 0x400, -- Max data count. + parameters = bin.pack("<SSSSCCSISSSSS",+ parameter_size, -- Total parameter count. + data_size, -- Total data count. + 0x0008, -- Max parameter count.+ 0x3984, -- Max data count. 0x00, -- Max setup count. 0x00, -- Reserved. 0x0000, -- Flags (0x0000 = 2-way transaction, don't disconnect TIDs). - 0x00000000, -- Timeout (0x00000000 = return immediately). + 0x00001388, -- Timeout (0x00000000 = return immediately). 0x0000, -- Reserved. - string.len(function_parameters), -- Parameter bytes. - parameters_offset, -- Parameter offset. - string.len(function_data), -- Data bytes. - data_offset, -- Data offset. - 0x02, -- Number of 'setup' words (only ever seen '2'). - 0x00, -- Reserved. - 0x0026, -- Function to call. - smb['fid'] -- Handle to open file - ) + parameter_size, -- Parameter bytes. + parameter_offset, -- Parameter offset. + data_size, -- Data bytes. + data_offset -- Data offset. + ) + + if(no_setup) then+ parameters = parameters .. bin.pack("<CC", + 0x00, -- Number of 'setup' words (none)+ 0x00 -- Reserved. + ) + else + parameters = parameters .. bin.pack("<CCSS", + 0x02, -- Number of 'setup' words + 0x00, -- Reserved. + 0x0026, -- Function to call. + smb['fid'] -- Handle to open file + ) + end- -- \PIPE\ is 0x07 bytes long. - data = bin.pack("<z", pipe);- data = data .. function_parameters; - data = data .. function_data + data = bin.pack("<z", pipe) + data = data .. bin.pack("<I", 0) -- Padding + + data = data .. (function_parameters or '') + data = data .. (function_data or '')-- Send the transaction requeststdnse.print_debug(2, "SMB: Sending SMB_COM_TRANSACTION") @@ -2075,7 +2098,7 @@ function send_transaction_waitnamedpipe(smb, priority, pipe)local header1, header2, header3, header4, command, status, flags, flags2, pid_high, signature, unused, pid, mid local header, parameters, data- local parameters_offset, data_offset + local parameter_offset, data_offset local total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2 local response = {} local padding = "" @@ -2643,15 +2666,6 @@ -- Save the name details['name'] = share- -- Ensure that the server returns the proper error message- status, result = share_host_returns_proper_error(host) - if(status == false) then - return false, result - end - if(status == true and result == false) then - return false, "Server doesn't return proper value for non-existent shares" - end - -- Check if the current user can read the share stdnse.print_debug(1, "SMB: Checking if share %s can be read by the current user", share) status, result = share_user_can_read(host, share) @@ -2702,7 +2716,7 @@ else -- Process the result a bit result = result['info'] - if(result['max_users'] == 4294967295) then + if(result['max_users'] == 0xFFFFFFFF) then result['max_users'] = "<unlimited>" end details['details'] = result @@ -2723,6 +2737,7 @@-- detail as we could get. If extra isn't nil, it is set to extra information that should be displayed (such as a warning). function share_get_list(host) + local status, resultlocal enum_status local extra = "" local shares = {} @@ -2753,6 +2768,15 @@ -- Sort the shares table.sort(shares)+ -- Ensure that the server returns the proper error message+ status, result = share_host_returns_proper_error(host) + if(status == false) then + return false, result + end + if(status == true and result == false) then + return false, "Server doesn't return proper value for non-existent shares; can't enumerate shares" + end + -- Get more information on each share for i = 1, #shares, 1 do local status, result _______________________________________________ Sent through the nmap-svn mailing list http://cgi.insecure.org/mailman/listinfo/nmap-svn
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Re: [nmap-svn] r16159 - nmap/nselib Ron (Nov 20)
