1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-10 09:49:05 +00:00

o [NSE] Added new default credential list for Oracle and modified the

oracle-brute script to make use of it. [Patrik]
This commit is contained in:
patrik
2011-09-05 08:13:34 +00:00
parent 4e9265b883
commit ae75aa7fd3
3 changed files with 775 additions and 39 deletions

View File

@@ -1,5 +1,20 @@
description = [[
Performs brute force password auditing against Oracle servers.
Running it in default mode it performs an audit against a list of common
Oracle usernames and passwords. The mode can be changed by supplying the
argument oracle-brute.nodefault at which point the script will use the
username- and password- lists supplied with Nmap. Custom username- and
password- lists may be supplied using the userdb and passdb arguments.
The default credential list can be changed too by using the brute.credfile
argument. In case the userdb or passdb arguments are supplied, the script
assumes that it should run in the nodefault mode.
In modern versions of Oracle password guessing speeds decrease after a few
guesses and remain slow, due to connection throttling.
WARNING: The script makes no attempt to discover the amount of guesses
that can be made before locking an account. Running this script may therefor
result in a large number of accounts being locked out on the database server.
]]
---
@@ -21,15 +36,18 @@ Performs brute force password auditing against Oracle servers.
-- x The Driver class contains the driver implementation used by the brute
-- library
--
-- @args oracle-brute.sid the instance against which to perform password
-- guessing
--
-- @args oracle-brute.sid - the instance against which to perform password
-- guessing
-- @args oracle-brute.nodefault - do not attempt to guess any Oracle default
-- accounts
--
-- Version 0.2
-- Version 0.3
-- Created 07/12/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
-- Revised 07/23/2010 - v0.2 - added script usage and output and
-- - oracle-brute.sid argument
-- Revised 07/25/2011 - v0.3 - added support for guessing default accounts
-- changed code to use ConnectionPool
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
@@ -44,34 +62,37 @@ require 'creds'
portrule = shortport.port_or_service(1521, "oracle-tns", "tcp", "open")
local ConnectionPool = {}
Driver =
{
new = function(self, host, port)
local o = {}
new = function(self, host, port, sid )
local o = { host = host, port = port, sid = sid }
setmetatable(o, self)
self.__index = self
o.host = host
o.port = port
return o
end,
--- Connects performs protocol negotiation
--
-- @return true on success, false on failure
connect = function( self )
local status, data
self.helper = tns.Helper:new( self.host, self.port, nmap.registry.args['oracle-brute.sid'] )
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)
@@ -85,7 +106,11 @@ Driver =
end
tries = tries - 1
stdnse.sleep(1)
until( tries == 0 or data ~= "12520")
until( tries == 0 or data ~= "12520" )
if ( status ) then
ConnectionPool[coroutine.running()] = self.helper
end
return status, data
end,
@@ -101,6 +126,8 @@ Driver =
local status, data = self.helper:Login( username, password )
if ( status ) then
self.helper:Close()
ConnectionPool[coroutine.running()] = nil
return true, brute.Account:new(username, password, creds.State.VALID)
-- Check for account locked message
elseif ( data:match("ORA[-]28000") ) then
@@ -111,6 +138,8 @@ Driver =
return false, brute.Error:new(data)
-- any other errors are likely communication related, attempt to re-try
else
self.helper:Close()
ConnectionPool[coroutine.running()] = nil
local err = brute.Error:new(data)
err:setRetry(true)
return false, err
@@ -122,39 +151,55 @@ Driver =
--- Disconnects and terminates the Oracle TNS communication
disconnect = function( self )
self.helper:Close()
return true
end,
--- Perform a connection with the helper, this makes sure that the Oracle
-- instance is correct.
--
-- @return status true on success false on failure
-- @return err containing the error message on failure
check = function( self )
local helper = tns.Helper:new( self.host, self.port, nmap.registry.args['oracle-brute.sid'] )
local status, err = helper:Connect()
if( status ) then
helper:Close()
return true
end
return false, err
end,
}
action = function(host, port)
local status, result
local engine = brute.Engine:new(Driver, host, port )
engine.options.script_name = SCRIPT_NAME
local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst"
local sid = stdnse.get_script_args('oracle-brute.sid') or
stdnse.get_script_args('tns.sid')
local engine = brute.Engine:new(Driver, host, port, sid)
local mode = "default"
if ( not( nmap.registry.args['oracle-brute.sid'] ) and not( nmap.registry.args['tns.sid'] ) ) then
return "ERROR: Oracle instance not set (see oracle-brute.sid or tns.sid)"
if ( not(sid) ) then
return "\n ERROR: Oracle instance not set (see oracle-brute.sid or tns.sid)"
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()
local f
if ( stdnse.get_script_args('userdb') or
stdnse.get_script_args('passdb') or
stdnse.get_script_args('oracle-brute.nodefault') or
stdnse.get_script_args('brute.credfile') ) then
mode = nil
end
if ( mode == "default" ) then
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:addIterator(brute.Iterators.credential_iterator(f))
end
engine.options.script_name = SCRIPT_NAME
status, result = engine:start()
return result
end