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

Changed smb-enum-shares to detect a host that returns the incorrect value for unknown shares (happened against what appears to be a EMC SANS). Also added a check to stdnse.strjoin() to ensure that the first parameter is either nil or a string, I got the parameters wrong and spent awhile trying to figure otu why.

This commit is contained in:
ron
2008-12-08 03:33:25 +00:00
parent da4a8ef302
commit 86de493a3e
2 changed files with 56 additions and 20 deletions

View File

@@ -127,9 +127,9 @@ end
--@return List of shares that exist but are denied to us.
function check_shares(host, shares)
local smbstate
local i
local allowed_shares = {}
local denied_shares = {}
local i
local allowed_shares = {}
local denied_shares = {}
-- Begin the SMB session
status, smbstate = smb.start(host)
@@ -151,32 +151,55 @@ function check_shares(host, shares)
return false, err
end
-- Check for hosts that accept any share by generating a totally random name (we don't use a set
-- name because then hosts could potentially fool us. Perhaps I'm in a paranoid mood today)
local set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
local share = ""
math.randomseed(os.time())
for i = 1, 16, 1 do
local random = math.random(#set)
share = share .. string.sub(set, random, random)
end
share = string.format("\\\\%s\\%s", host.ip, share)
stdnse.print_debug(2, "EnumShares: Trying a random share to see if server responds properly: %s", share)
status, err = smb.tree_connect(smbstate, share)
if(status == false) then
if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
return false, "Server doesn't return proper value for non-existent shares (returns ACCESS_DENIED)"
end
else
-- If we were actually able to connect to this share, then there's probably a serious issue
smb.tree_disconnect(smbstate)
return false, "Server doesn't return proper value for non-existent shares (accepts the connection)"
end
-- Connect to the shares
stdnse.print_debug(2, "EnumShares: Testing %d shares", #shares)
for i = 1, #shares, 1 do
for i = 1, #shares, 1 do
-- Change the share to the '\\ip\share' format
local share = string.format("\\\\%s\\%s", host.ip, shares[i])
local share = string.format("\\\\%s\\%s", host.ip, shares[i])
-- Try connecting to the tree
stdnse.print_debug(3, "EnumShares: Testing share %s", share)
status, err = smb.tree_connect(smbstate, share)
status, err = smb.tree_connect(smbstate, share)
-- If it fails, checkwhy
if(status == false) then
if(status == false) then
-- If the result was ACCESS_DENIED, record it
if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
stdnse.print_debug(3, "EnumShares: Access was denied")
denied_shares[#denied_shares + 1] = shares[i]
denied_shares[#denied_shares + 1] = shares[i]
else
stdnse.print_debug(3, "ERROR: EnumShares: Share didn't pan out: %s", err)
end
else
end
else
-- Add it to allowed shares
stdnse.print_debug(3, "EnumShares: Access was granted")
allowed_shares[#allowed_shares + 1] = shares[i]
smb.tree_disconnect(smbstate)
end
end
allowed_shares[#allowed_shares + 1] = shares[i]
smb.tree_disconnect(smbstate)
end
end
-- Log off the user
smb.stop(smbstate)
@@ -221,17 +244,18 @@ local function get_share_info(host, name)
end
action = function(host)
local enum_result
local result, shared
local response = " \n"
local shares = {}
local allowed, denied
-- Try and do this the good way, make a MSRPC call to get the shares
result, shares = samr_enum_shares(host)
enum_result, shares = samr_enum_shares(host)
-- If that failed, try doing it with brute force. This almost certainly won't find everything, but it's the
-- best we can do.
if(result == false) then
if(enum_result == false) then
if(nmap.debugging() > 0) then
response = response .. string.format("ERROR: Couldn't enum all shares, checking for common ones (%s)\n", shares)
end
@@ -250,10 +274,20 @@ action = function(host)
status, allowed, denied = check_shares(host, shares)
if(status == false) then
if(nmap.debugging() > 0) then
return "ERROR: " .. allowed
if(enum_result == false) then
-- At this point, we have nothing
if(nmap.debugging() > 0) then
return "ERROR: " .. allowed
else
return nil
end
else
return nil
-- If we're here, we have a valid list of shares, but couldn't check them
if(nmap.debugging() > 0) then
return "ERROR: " .. allowed .. "\nShares found: " .. stdnse.strjoin(", ", shares)
else
return stdnse.strjoin(", ", shares)
end
end
end