Nmap Development mailing list archives
Re: [NSE] SMB authentication patch
From: Ron <ron () skullsecurity net>
Date: Mon, 13 Oct 2008 22:30:14 -0500
Hi David, David Fifield wrote:
On Fri, Oct 10, 2008 at 07:14:47PM -0500, Ron wrote: I'll send you a separate message with a pcap log and the user2sid results.
Good find on that one. It turns out I was handling aliases incorrectly, so all the users ended up numbered incorrectly, which caused them to over-write each other. I was able to replicate it on my system, and it's now fixed.
I tried that and got Host script results: |_ MSRPC: NetSessEnum(): ERROR: Read off the end of the packet
I managed to replicate/fix that, as well, but it stems from a deeper problem, which I'm not so sure about. Looking at the logs, it seems that you're automatically being logged in as "GUEST". Normally that happens if your username wasn't found, which is strange. Is there anything weird about your user accounts, or are you part of a domain, or something like that? Can you try adding a smbdomain argument, and try setting it to "MSHOME" or "MAC-MINI"? (those are the two domains I've seen in your packet caps), and running smb-enumusers.nse? If you're logged in properly, it should display more information about the accounts (descriptions, full names, etc). Maybe try disabling the 'GUEST' account on your system, see if that makes a difference. If not, we need to figure out why it's forcing you to GUEST instead of a full user -- can you try mounting a share on that machine remotely, and getting a packet cap? On the plus side, this unintentionally made me realize that I wasn't testing GUEST access, so I've added a GUEST account to my testing. The other funny thing is that the information being returned is 100% stuff that could be recovered without a user account. Scary, eh?
I'll send you a pcap log of that too.
Thanks, it was helpful
David Fifield
I've attached an updated patch as well as the new module (which gives far more information to you, even as a GUEST, now). I'm also version controlling my stuff in my own svn repository -- would that be easier for your testing than using attachments? Ron
---Currently enumerates the active sessions on a system, where a session is defined as a connection to -- a share. It does this using the srvsvc.netsessenum() function. \n --\n --The future direction for this will be to enumerate users logged into the server as well (the same way --the psloggedin.exe tool does), but that's the future. -- --@usage -- nmap --script smb-enumsessions.nse -p445 <host>\n -- sudo nmap -sU -sS --script smb-enumsessions.nse -p U:137,T:139 <host>\n -- --@output -- Host script results: -- | MSRPC: NetSessEnum(): -- | User ADMINISTRATOR logged on from 192.168.1.44 for 00m18s, idle for 00m18s -- | User RON logged on from 192.168.1.42 for 00m05s, idle for 00m02s -- |_ User ADMINISTRATOR logged on from 192.168.1.3 for [just logged in, it's probably you], idle for [not idle] -- --@args smbusername The SMB username to log in with. The form DOMAIN\username and username@DOMAIN -- are NOT understood. To set a domain, use the smbdomain argument. --@args smbdomain The domain to log in with. If you aren't in a domained environment, then anything -- will (should?) be accepted by the server. --@args smbpassword The password to connect with. Be cautious with this, since some servers will lock -- accounts if the incorrect password is given (although it's rare for the -- 'administrator' account to be lockoutable, in the off chance that it is, you could -- get yourself in trouble). --@args smbhash A password hash to use when logging in. This is given as a single hex string (32 -- characters) or a pair of hex strings (2 x 32 characters, optionally separated by a -- single character). These hashes are the Lanman or NTLM hash of the user's password, -- and are stored by systems, on the harddrive or memory. They can be retrived from memory -- using the fgdump or pwdump tools. --@args smbguest If this is set to 'true' or '1', a 'guest' login will be attempted if the normal one -- fails. This should be harmless, but I thought I would disable it by default anyway -- because I'm not entirely sure of any possible consequences. --@args smbtype The type of SMB authentication to use. By default, NTLMv1 is used, which is a pretty -- decent compromise between security and compatibility. If you are paranoid, you might -- want to use 'v2' or 'lmv2' for this (actually, if you're paranoid, you should be -- avoiding this protocol altogether :P). If you're using an extremely old system, you -- might need to set this to 'v1' or 'lm', which are less secure but more compatible. \n --\n -- If you want finer grained control, these are the possible options:\n -- <ul> -- <li>v1 -- Sends LMv1 and NTLMv1</li> -- <li>LMv1 -- Sends LMv1 only</li> -- <li>NTLMv1 -- Sends NTLMv1 only (default)</li> -- <li>v2 -- Sends LMv2 and NTLMv2</li> -- <li>LMv2 -- Sends LMv2 only</li> -- </ul> -- ----------------------------------------------------------------------- id = "MSRPC: NetSessEnum()" description = "Tries calling the NetSessEnum() RPC function to get a list of active sessions" author = "Ron Bowes" copyright = "Ron Bowes" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"discovery","intrusive"} require 'msrpc' require 'smb' require 'stdnse' hostrule = function(host) local port = smb.get_port(host) if(port == nil) then return false else return true end end ---Attempts to enumerate the shares on a remote system using MSRPC calls. This will likely fail -- against a modern system, but will succeed against Windows 2000. -- --@param host The host object. --@return (status, result) If status is false, result is an error string. Otherwise, result is -- a list of all shares on a system. local function srvsvc_enum_sessions(host) local i local status, smbstate local bind_result, netsessenum_result -- Create the SMB session status, smbstate = msrpc.start_smb(host, msrpc.SRVSVC_PATH) if(status == false) then return false, smbstate end -- Bind to SRVSVC service status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil) if(status == false) then msrpc.stop_smb(smbstate) return false, bind_result end -- Call netsessenum status, netsessenum_result = msrpc.srvsvc_netsessenum(smbstate, host.ip) if(status == false) then msrpc.stop_smb(smbstate) return false, netsessenum_result end -- Stop the SMB session msrpc.stop_smb(smbstate) return true, netsessenum_result['sessions'] end -- TODO: Comment local function winreg_enum_rids(host) local i, j local elements = {} -- Create the SMB session status, smbstate = msrpc.start_smb(host, msrpc.WINREG_PATH) if(status == false) then return false, smbstate end -- Bind to WINREG service status, bind_result = msrpc.bind(smbstate, msrpc.WINREG_UUID, msrpc.WINREG_VERSION, nil) if(status == false) then msrpc.stop_smb(smbstate) return false, bind_result end status, openhku_result = msrpc.winreg_openhku(smbstate) if(status == false) then msrpc.stop_smb(smbstate) return false, openhku_result end -- Loop through the keys under HKEY_USERS and grab the names i = 0 repeat status, enumkey_result = msrpc.winreg_enumkey(smbstate, openhku_result['handle'], i) if(status == true) then local element = {} element['name'] = enumkey_result['name'] element['sid'] = msrpc.string_to_sid(enumkey_result['name']) element['changed_date'] = enumkey_result['changed_date'] elements[#elements + 1] = element end i = i + 1 until status ~= true --TODO: Close the key msrpc.stop_smb(smbstate) -- Start a new SMB session status, smbstate = msrpc.start_smb(host, msrpc.LSA_PATH) if(status == false) then return false, smbstate end -- Bind to LSA service status, bind_result = msrpc.bind(smbstate, msrpc.LSA_UUID, msrpc.LSA_VERSION, nil) if(status == false) then msrpc.stop_smb(smbstate) return false, bind_result end -- Get a policy handle status, openpolicy2_result = msrpc.lsa_openpolicy2(smbstate, host.ip) if(status == false) then msrpc.stop_smb(smbstate) return false, openpolicy2_result end -- Convert the RIDs to names local results = {} stdnse.print_debug(3, "MSRPC: Found %d SIDs that might be logged in", #elements) for i = 1, #elements, 1 do if(elements[i]['sid'] ~= nil) then -- The RID is the last subauthority local rid = elements[i]['sid']['subauthorities'][elements[i]['sid']['count']] stdnse.print_debug(3, "MSRPC: Found an actual RID: %d", rid) -- The server is the rest of the SID, so remove the last subauthority elements[i]['sid']['subauthorities'][elements[i]['sid']['count']] = nil elements[i]['sid']['count'] = elements[i]['sid']['count'] - 1 -- Look up the RID stdnse.print_debug(3, "MSRPC: Looking up RID %s in SID %s", rid, msrpc.sid_to_string(elements[i]['sid'])) status, lookupsids2_result = msrpc.lsa_lookupsids2(smbstate, openpolicy2_result['policy_handle'], elements[i]['sid'], {rid}) if(status == false) then -- It may not succeed, if it doesn't that's ok stdnse.print_debug(3, "MSRPC: Lookup failed") else -- Create the result array local result = {} result['rid'] = rid result['changed_date'] = elements[i]['changed_date'] -- TODO: How can I find the domain here? -- Fill in the result from the response if(lookupsids2_result['details'][1] == nil) then result['name'] = "<unknown>" result['domain'] = "" else result['name'] = lookupsids2_result['details'][1]['name'] result['type'] = lookupsids2_result['details'][1]['type'] result['domain'] = lookupsids2_result['domains'][1]['name'] end if(result['type'] ~= 5) then -- Don't show "well known" accounts -- Add it to the results results[#results + 1] = result end end end end -- Close the policy msrpc.lsa_close(smbstate, openpolicy2_result['policy_handle']) -- Stop the session msrpc.stop_smb(smbstate) return true, results end action = function(host) local status, sessions local response = " \n" -- Enumerate the logged in users status, users = winreg_enum_rids(host) if(status == false) then response = response .. "ERROR: Couldn't enumerate login sessions: " .. users .. "\n" else response = response .. "Users logged in:\n" if(#users == 0) then response = response .. "|_ <nobody>\n" else for i = 1, #users, 1 do response = response .. string.format("|_ %s\\%s, logged in since %s [testing -- may not be accurate]\n", users[i]['domain'], users[i]['name'], users[i]['changed_date']) end end end -- Get the connected sessions status, sessions = srvsvc_enum_sessions(host) if(status == false) then response = response .. "ERROR: Couldn't enumerate network sessions: " .. sessions .. "\n" else response = response .. "Active SMB Sessions:\n" if(#sessions == 0) then response = response .. "|_ <none>\n" else -- Format the result for i = 1, #sessions, 1 do local active = sessions[i]['active'] if(active == 0) then active = "[just logged in, it's probably you]" elseif(active > 60 * 60 * 24) then active = string.format("%dd%dh%02dm%02ds", active / (60*60*24), (active % (60*60*24)) / 3600, (active % 3600) / 60, active % 60) elseif(active > 60 * 60) then active = string.format("%dh%02dm%02ds", active / 3600, (active % 3600) / 60, active % 60) else active = string.format("%02dm%02ds", active / 60, active % 60) end local idle = sessions[i]['idle'] if(idle == 0) then idle = "[not idle]" elseif(idle > 60 * 60 * 24) then idle = string.format("%dd%dh%02dm%02ds", idle / (60*60*24), (idle % (60*60*24)) / 3600, (idle % 3600) / 60, idle % 60) elseif(idle > 60 * 60) then idle = string.format("%dh%02dm%02ds", idle / 3600, (idle % 3600) / 60, idle % 60) else idle = string.format("%02dm%02ds", idle / 60, idle % 60) end response = response .. string.format("|_ %s is connected from %s for %s, idle for %s\n", sessions[i]['user'], sessions[i]['client'], active, idle) end end end return response end
Attachment:
smb_updates-20081013.diff.gz
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- Re: [NSE] SMB authentication patch, (continued)
- Re: [NSE] SMB authentication patch David Fifield (Oct 10)
- Re: [NSE] SMB authentication patch Ron (Oct 10)
- Re: [NSE] SMB authentication patch David Fifield (Oct 10)
- Re: [NSE] SMB authentication patch Ron (Oct 10)
- Re: [NSE] SMB authentication patch David Fifield (Oct 13)
- Re: [NSE] SMB authentication patch Ron (Oct 13)
- Re: [NSE] SMB authentication patch David Fifield (Oct 13)
- Re: [NSE] SMB authentication patch Ron (Oct 10)
- Re: [NSE] SMB authentication patch David Fifield (Oct 10)
- Re: [NSE] SMB authentication patch Ron (Oct 10)
- Re: [NSE] SMB authentication patch Ron (Oct 10)
- Re: [NSE] SMB authentication patch David Fifield (Oct 13)
- Re: [NSE] SMB authentication patch Ron (Oct 13)
- Re: [NSE] SMB authentication patch David Fifield (Oct 13)