mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
o [NSE] Added credential storage library (creds.lua) and modified the brute
library and scripts to make use of it. [Patrik]
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [NSE] Added credential storage library (creds.lua) and modified the brute
|
||||
library and scripts to make use of it. [Patrik]
|
||||
|
||||
o [NSE] Added a MySQL audit script and a rulebase that supports auditing a
|
||||
subset of the MySQL CIS 1.0.2 Benchmark. [Patrik]
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
-- by '/'
|
||||
|
||||
--
|
||||
-- Version 0.6
|
||||
-- Version 0.7
|
||||
-- Created 06/12/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 07/13/2010 - v0.2 - added connect, disconnect methods to Driver
|
||||
-- <patrik@cqure.net>
|
||||
@@ -176,10 +176,12 @@
|
||||
-- David's request.
|
||||
-- Revised 08/30/2010 - v0.6 - added support for custom iterators and did some
|
||||
-- needed cleanup.
|
||||
-- Revised 06/19/2010 - v0.7 - added support for creds library
|
||||
|
||||
module(... or "brute", package.seeall)
|
||||
require 'unpwdb'
|
||||
require 'datafiles'
|
||||
require 'creds'
|
||||
|
||||
-- Options that can be set through --script-args
|
||||
Options = {
|
||||
@@ -244,12 +246,9 @@ Account =
|
||||
-- following <code>OPEN</code>, <code>LOCKED</code>,
|
||||
-- <code>DISABLED</code>.
|
||||
new = function(self, username, password, state)
|
||||
local o = {}
|
||||
local o = { username = username, password = password, state = state }
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.username = username
|
||||
o.password = password
|
||||
o.state = state
|
||||
return o
|
||||
end,
|
||||
|
||||
@@ -258,27 +257,12 @@ Account =
|
||||
-- @return string representation of object
|
||||
toString = function( self )
|
||||
local creds
|
||||
|
||||
if ( #self.username > 0 ) then
|
||||
creds = ("%s:%s"):format( self.username, #self.password > 0 and self.password or "<empty>" )
|
||||
else
|
||||
creds = ("%s"):format( ( self.password and #self.password > 0 ) and self.password or "<empty>" )
|
||||
end
|
||||
|
||||
-- An account have the following states
|
||||
--
|
||||
-- OPEN - Login was successful
|
||||
-- LOCKED - The account was locked
|
||||
-- DISABLED - The account was disabled
|
||||
if ( self.state == "OPEN" ) then
|
||||
return ("%s => Login correct"):format( creds )
|
||||
elseif ( self.state == "LOCKED" ) then
|
||||
return ("%s => Account locked"):format( creds )
|
||||
elseif ( self.state == "DISABLED" ) then
|
||||
return ("%s => Account disabled"):format( creds )
|
||||
else
|
||||
return ("%s => Account has unknown state (%s)"):format( creds, self.state )
|
||||
end
|
||||
return ( "%s => %s"):format(creds, self.state.msg )
|
||||
end,
|
||||
|
||||
}
|
||||
@@ -290,11 +274,9 @@ Error =
|
||||
retry = false,
|
||||
|
||||
new = function(self, msg)
|
||||
local o = {}
|
||||
local o = { msg = msg, done = false }
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.msg = msg
|
||||
o.done = false
|
||||
return o
|
||||
end,
|
||||
|
||||
@@ -340,7 +322,6 @@ Error =
|
||||
Engine =
|
||||
{
|
||||
STAT_INTERVAL = 20,
|
||||
terminate_all = false,
|
||||
|
||||
--- Creates a new Engine instance
|
||||
--
|
||||
@@ -350,21 +331,23 @@ Engine =
|
||||
-- @param options table containing any script specific options
|
||||
-- @return o new Engine instance
|
||||
new = function(self, driver, host, port, options)
|
||||
local o = {}
|
||||
local o = {
|
||||
driver = driver,
|
||||
host = host,
|
||||
port = port,
|
||||
driver_options = options,
|
||||
terminate_all = false,
|
||||
error = nil,
|
||||
counter = 0,
|
||||
threads = {},
|
||||
tps = {},
|
||||
iterators = {},
|
||||
found_accounts = {},
|
||||
options = Options:new(),
|
||||
}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.driver = driver
|
||||
o.driver_options = options
|
||||
o.host = host
|
||||
o.port = port
|
||||
o.options = Options:new()
|
||||
o.found_accounts = {}
|
||||
o.threads = {}
|
||||
o.counter = 0
|
||||
o.max_threads = tonumber(nmap.registry.args["brute.threads"]) or 10
|
||||
o.iterators = {}
|
||||
o.error = nil
|
||||
o.tps = {}
|
||||
o.max_threads = stdnse.get_script_args("brute.threads") or 10
|
||||
return o
|
||||
end,
|
||||
|
||||
@@ -509,31 +492,31 @@ Engine =
|
||||
return status, response
|
||||
end,
|
||||
|
||||
login = function(self, valid_accounts )
|
||||
|
||||
local condvar = nmap.condvar( valid_accounts )
|
||||
login = function(self, cvar )
|
||||
local condvar = nmap.condvar( cvar )
|
||||
local thread_data = self.threads[coroutine.running()]
|
||||
local interval_start = os.time()
|
||||
|
||||
while( true ) do
|
||||
-- Should we terminate all threads?
|
||||
if ( Engine.terminate_all or thread_data.terminate ) then break end
|
||||
if ( self.terminate_all or thread_data.terminate ) then break end
|
||||
|
||||
local status, response = self:doAuthenticate()
|
||||
|
||||
if ( status ) then
|
||||
-- Prevent locked accounts from appearing several times
|
||||
if ( not(self.found_accounts) or self.found_accounts[response.username] == nil ) then
|
||||
creds.Credentials:new( self.options.script_name, self.host, self.port ):add(response.username, response.password, response.state )
|
||||
|
||||
stdnse.print_debug("Discovered account: %s", response:toString())
|
||||
table.insert( valid_accounts, response:toString() )
|
||||
self.found_accounts[response.username] = true
|
||||
|
||||
-- Check if firstonly option was set, if so abort all threads
|
||||
if ( self.options.firstonly ) then Engine.terminate_all = true end
|
||||
if ( self.options.firstonly ) then self.terminate_all = true end
|
||||
end
|
||||
else
|
||||
if ( response and response:isAbort() ) then
|
||||
Engine.terminate_all = true
|
||||
self.terminate_all = true
|
||||
self.error = response:getMessage()
|
||||
break
|
||||
elseif( response and response:isDone() ) then
|
||||
@@ -559,7 +542,7 @@ Engine =
|
||||
-- if delay was speciefied, do sleep
|
||||
if ( self.options.delay > 0 ) then stdnse.sleep( self.options.delay ) end
|
||||
end
|
||||
condvar("broadcast")
|
||||
condvar "broadcast"
|
||||
end,
|
||||
|
||||
--- Starts the brute-force
|
||||
@@ -568,8 +551,11 @@ Engine =
|
||||
-- @return err string containing error message on failure
|
||||
start = function(self)
|
||||
|
||||
local result, valid_accounts, stats = {}, {}, {}
|
||||
local condvar = nmap.condvar( valid_accounts )
|
||||
local result, cvar, stats = {}, {}, {}
|
||||
local condvar = nmap.condvar( cvar )
|
||||
|
||||
assert(self.options.script_name, "SCRIPT_NAME was not set in options.script_name")
|
||||
assert(self.port.number and self.port.protocol and self.port.service, "Invalid port table detected")
|
||||
|
||||
-- Only run the check method if it exist. We should phase this out
|
||||
-- in favor of a check in the action function of the script
|
||||
@@ -629,16 +615,18 @@ Engine =
|
||||
|
||||
-- Startup all worker threads
|
||||
for i=1, self.max_threads do
|
||||
local co = stdnse.new_thread( self.login, self, valid_accounts )
|
||||
local co = stdnse.new_thread( self.login, self, cvar )
|
||||
self.threads[co] = {}
|
||||
self.threads[co].running = true
|
||||
end
|
||||
|
||||
-- wait for all threads to finnish running
|
||||
while self:threadCount()>0 do condvar("wait") end
|
||||
while self:threadCount()>0 do condvar "wait" end
|
||||
|
||||
local valid_accounts = creds.Credentials:new(self.options.script_name, self.host, self.port):getTable()
|
||||
|
||||
-- Did we find any accounts, if so, do formatting
|
||||
if ( #valid_accounts > 0 ) then
|
||||
if ( valid_accounts and #valid_accounts > 0 ) then
|
||||
valid_accounts.name = "Accounts"
|
||||
table.insert( result, valid_accounts )
|
||||
else
|
||||
@@ -661,7 +649,7 @@ Engine =
|
||||
|
||||
-- Did any error occure? If so add this to the result.
|
||||
if ( self.error ) then
|
||||
result = result .. (" \n\n ERROR: %s"):format( self.error )
|
||||
result = result .. (" \n ERROR: %s"):format( self.error )
|
||||
return false, result
|
||||
end
|
||||
return true, result
|
||||
|
||||
210
nselib/creds.lua
Normal file
210
nselib/creds.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
--- The credential class stores found credentials in the Nmap registry
|
||||
--
|
||||
--
|
||||
-- @author "Patrik Karlsson <patrik@cqure.net>"
|
||||
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
|
||||
|
||||
-- Version 0.1
|
||||
-- Created 2011/02/06 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
module(... or "creds", package.seeall)
|
||||
|
||||
require('ipOps')
|
||||
|
||||
-- Table containing the different account states
|
||||
State = {
|
||||
LOCKED = { msg = 'Account is locked' },
|
||||
VALID = { msg = 'Account is valid' },
|
||||
DISABLED = { msg = 'Account is disabled' },
|
||||
CHANGEPW = { msg = 'Password needs to be changed at next logon' },
|
||||
}
|
||||
|
||||
ALL_DATA = "all_script_data"
|
||||
|
||||
-- The RegStorage class
|
||||
RegStorage = {
|
||||
|
||||
--- Creates a new RegStorage instance
|
||||
--
|
||||
-- @return a new instance
|
||||
new = function(self)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.filter = {}
|
||||
return o
|
||||
end,
|
||||
|
||||
--- Add credentials to storage
|
||||
--
|
||||
-- @param scriptname the name of the script adding the credentials
|
||||
-- @param host host table, name or ip
|
||||
-- @param port number containing the port of the service
|
||||
-- @param service the name of the service
|
||||
-- @param user the name of the user
|
||||
-- @param pass the password of the user
|
||||
-- @param state of the account
|
||||
add = function( self, scriptname, host, port, service, user, pass, state )
|
||||
local cred = {
|
||||
scriptname = scriptname,
|
||||
host = host,
|
||||
port = port,
|
||||
service = service,
|
||||
user = user,
|
||||
pass = pass,
|
||||
state = state
|
||||
}
|
||||
nmap.registry.creds = nmap.registry.creds or {}
|
||||
table.insert( nmap.registry.creds, cred )
|
||||
end,
|
||||
|
||||
--- Sets the storage filter
|
||||
--
|
||||
-- @param host table containing the host
|
||||
-- @param port table containign the port
|
||||
setFilter = function( self, host, port )
|
||||
self.filter.host = host
|
||||
self.filter.port = port
|
||||
end,
|
||||
|
||||
--- Retrieves the table containing all credential records
|
||||
--
|
||||
-- @return table containing all credential records
|
||||
getAll = function( self )
|
||||
local tbl = nmap.registry.creds
|
||||
local new_tbl = {}
|
||||
local host, port = self.filter.host, self.filter.port
|
||||
|
||||
if ( not(tbl) ) then return end
|
||||
|
||||
for _, v in pairs(tbl) do
|
||||
local h = ( v.host.ip or v.host )
|
||||
if ( not(host) and not(port) ) then
|
||||
table.insert(new_tbl, v)
|
||||
elseif ( not(host) and ( port == v.port ) ) then
|
||||
table.insert(new_tbl, v)
|
||||
elseif ( ( host and ( h == host or h == host.ip ) ) and not(port) ) then
|
||||
table.insert(new_tbl, v)
|
||||
elseif ( ( host and ( h == host or h == host.ip ) ) and port.number == v.port ) then
|
||||
table.insert(new_tbl, v)
|
||||
end
|
||||
end
|
||||
return new_tbl
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
-- The credentials class
|
||||
Credentials = {
|
||||
|
||||
--- Creates a new instance of the Credentials class
|
||||
-- @param scriptname string containing the name of the script
|
||||
-- @param host table as received by the scripts action method
|
||||
-- @param port table as received by the scripts action method
|
||||
new = function(self, scriptname, host, port)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.storage = RegStorage:new()
|
||||
o.storage:setFilter(host, port)
|
||||
o.host = host
|
||||
o.port = ( port and port.number ) and port.number
|
||||
o.service = ( port and port.service ) and port.service
|
||||
o.scriptname = scriptname
|
||||
return o
|
||||
end,
|
||||
|
||||
--- Add a discovered credential
|
||||
--
|
||||
-- @param host host table, name or ip
|
||||
-- @param port number containing the port of the service
|
||||
-- @param service the name of the service
|
||||
-- @param user the name of the user
|
||||
-- @param pass the password of the user
|
||||
-- @param state of the account
|
||||
add = function( self, user, pass, state )
|
||||
local pass = ( pass and #pass > 0 ) and pass or "<empty>"
|
||||
assert( self.host, "No host supplied" )
|
||||
assert( self.port, "No port supplied" )
|
||||
assert( state, "No state supplied")
|
||||
assert( self.scriptname, "No scriptname supplied")
|
||||
|
||||
-- there are cases where we will only get a user or password
|
||||
-- so as long we have one of them, we're good
|
||||
if ( user or pass ) then
|
||||
self.storage:add( self.scriptname, self.host, self.port, self.service, user, pass, state )
|
||||
end
|
||||
end,
|
||||
|
||||
--- Returns a table of credentials
|
||||
--
|
||||
-- @return tbl table containing the discovered credentials
|
||||
getTable = function(self)
|
||||
local result = {}
|
||||
local all = self.storage:getAll()
|
||||
|
||||
if ( not(all) ) then return end
|
||||
|
||||
for _, v in pairs(self.storage:getAll()) do
|
||||
local h = ( v.host.ip or v.host )
|
||||
local svc = ("%s/%s"):format(v.port,v.service)
|
||||
local c
|
||||
if ( v.user and #v.user > 0 ) then
|
||||
c = ("%s:%s - %s"):format(v.user, v.pass, v.state.msg)
|
||||
else
|
||||
c = ("%s - %s"):format(v.pass, v.state.msg)
|
||||
end
|
||||
local script = v.scriptname
|
||||
assert(type(h)=="string", "Could not determine a valid host")
|
||||
|
||||
if ( script == self.scriptname or self.scriptname == ALL_DATA ) then
|
||||
result[h] = result[h] or {}
|
||||
result[h][svc] = result[h][svc] or {}
|
||||
table.insert( result[h][svc], c )
|
||||
end
|
||||
end
|
||||
|
||||
local output = {}
|
||||
for hostname, host in pairs(result) do
|
||||
local host_tbl = { name = hostname }
|
||||
for svcname, service in pairs(host) do
|
||||
local svc_tbl = { name = svcname }
|
||||
for _, account in ipairs(service) do
|
||||
table.insert(svc_tbl, account)
|
||||
end
|
||||
-- sort the accounts
|
||||
table.sort( svc_tbl, function(a,b) return a<b end)
|
||||
table.insert( host_tbl, svc_tbl )
|
||||
end
|
||||
-- sort the services
|
||||
table.sort( host_tbl,
|
||||
function(a,b)
|
||||
return tonumber(a.name:match("^(%d+)")) < tonumber(b.name:match("^(%d+)"))
|
||||
end
|
||||
)
|
||||
table.insert( output, host_tbl )
|
||||
end
|
||||
|
||||
-- sort the IP addresses
|
||||
table.sort( output, function(a, b) return ipOps.compare_ip(a.name, "le", b.name) end )
|
||||
if ( self.host and self.port and #output > 0 ) then
|
||||
output = output[1][1]
|
||||
output.name = nil
|
||||
elseif ( self.host and #output > 0 ) then
|
||||
output = output[1]
|
||||
output.name = nil
|
||||
end
|
||||
return output
|
||||
end,
|
||||
|
||||
--- Get credentials with optional host and port filter
|
||||
-- If no filters are supplied all records are returned
|
||||
--
|
||||
-- @param host table or string containing the host to filter
|
||||
-- @param port number containing the port to filter
|
||||
-- @return table suitable from <code>stdnse.format_output</code>
|
||||
__tostring = function(self)
|
||||
local all = self:getTable()
|
||||
if ( all ) then return stdnse.format_output(true, all) end
|
||||
end,
|
||||
|
||||
}
|
||||
@@ -262,7 +262,7 @@ local Driver =
|
||||
nmap.registry.credentials['backorifice'] = {}
|
||||
end
|
||||
table.insert( nmap.registry.credentials.backorifice, { password = password } )
|
||||
return true, brute.Account:new("", password, "OPEN")
|
||||
return true, brute.Account:new("", password, creds.State.VALID)
|
||||
else
|
||||
-- The only indication that the password is incorrect is a timeout
|
||||
local err = brute.Error:new( "Incorrect password" )
|
||||
@@ -271,9 +271,6 @@ local Driver =
|
||||
end
|
||||
end,
|
||||
|
||||
check = function( self )
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
action = function( host, port )
|
||||
@@ -283,6 +280,7 @@ action = function( host, port )
|
||||
|
||||
engine.options.firstonly = true
|
||||
engine.options.passonly = true
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ Driver =
|
||||
if ( status and data:match("NOT_REG_ADMIN") ) then
|
||||
not_admins[username] = true
|
||||
elseif( status and data:match("VALID_USER") ) then
|
||||
return true, brute.Account:new( username, password, "OPEN")
|
||||
return true, brute.Account:new( username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
@@ -147,10 +147,6 @@ Driver =
|
||||
self.sockpool:releaseSocket( self.socket )
|
||||
end,
|
||||
|
||||
check = function( self )
|
||||
return true
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +155,7 @@ action = function(host, port)
|
||||
local pool = SocketPool:new(10)
|
||||
local engine = brute.Engine:new(Driver, host, port, pool )
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
status, result = engine:start()
|
||||
pool:shutdown()
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ Driver = {
|
||||
"Client-DPAP-Version: 1.1\r\n" ..
|
||||
"\r\n\r\n"
|
||||
|
||||
local creds = base64.enc("nmap:" .. password)
|
||||
data = data:format( self.host.ip, self.port.number, self.host.ip, creds )
|
||||
local c = base64.enc("nmap:" .. password)
|
||||
data = data:format( self.host.ip, self.port.number, self.host.ip, c )
|
||||
|
||||
local status = self.socket:send( data )
|
||||
if ( not(status) ) then
|
||||
@@ -73,7 +73,7 @@ Driver = {
|
||||
end
|
||||
|
||||
if ( data:match("^HTTP/1.1 200 OK") ) then
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
@@ -111,6 +111,7 @@ action = function(host, port)
|
||||
|
||||
engine.options.firstonly = true
|
||||
engine.options:setOption( "passonly", true )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ Driver = {
|
||||
nmap.registry.credentials['http'] = {}
|
||||
end
|
||||
table.insert( nmap.registry.credentials.http, { username = username, password = password } )
|
||||
return true, brute.Account:new( username, password, "OPEN")
|
||||
return true, brute.Account:new( username, password, creds.State.VALID)
|
||||
end
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end,
|
||||
@@ -105,6 +105,7 @@ action = function( host, port )
|
||||
local path = nmap.registry.args['http-brute.path']
|
||||
local method = string.upper(nmap.registry.args['http-brute.method'] or "GET")
|
||||
local engine = brute.Engine:new(Driver, host, port, method )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
if ( not(path) ) then
|
||||
return " \n ERROR: No path was specified (see http-brute.path)"
|
||||
|
||||
@@ -135,7 +135,7 @@ Driver = {
|
||||
nmap.registry['credentials'] = nmap.registry['credentials'] or {}
|
||||
nmap.registry.credentials['http'] = nmap.registry.credentials['http'] or {}
|
||||
table.insert( nmap.registry.credentials.http, { username = username, password = password } )
|
||||
return true, brute.Account:new( username, password, "OPEN")
|
||||
return true, brute.Account:new( username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
@@ -235,6 +235,8 @@ action = function( host, port )
|
||||
-- there's a bug in http.lua that does not allow it to be called by
|
||||
-- multiple threads
|
||||
engine:setMaxThreads(1)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
if ( not(uservar) ) then
|
||||
engine.options:setOption( "passonly", true )
|
||||
end
|
||||
|
||||
@@ -78,10 +78,10 @@ Driver =
|
||||
nmap.registry['informix-brute'] = {}
|
||||
end
|
||||
table.insert( nmap.registry['informix-brute'], { ["username"] = username, ["password"] = password } )
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
-- Check for account locked message
|
||||
elseif ( data:match("INFORMIXSERVER does not match either DBSERVERNAME or DBSERVERALIASES") ) then
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
return false, brute.Error:new( data )
|
||||
@@ -93,21 +93,13 @@ Driver =
|
||||
self.helper:Close()
|
||||
end,
|
||||
|
||||
--- Perform a connection with the helper, this makes sure that the Informix
|
||||
-- instance is correct.
|
||||
--
|
||||
-- @return status true on success false on failure
|
||||
-- @return err containing the error message on failure
|
||||
check = function( self )
|
||||
return true
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
status, result = engine:start()
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Driver = {
|
||||
local status = self.helper:login( self.target, username, password, "CHAP")
|
||||
|
||||
if ( status ) then
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end
|
||||
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
@@ -78,7 +78,10 @@ action = function( host, port )
|
||||
if ( status ) then return "No authentication required" end
|
||||
|
||||
local accounts
|
||||
status, accounts = brute.Engine:new(Driver, host, port):start()
|
||||
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
status, accounts = engine:start()
|
||||
|
||||
if ( status ) then return accounts end
|
||||
end
|
||||
@@ -165,7 +165,7 @@ Driver =
|
||||
|
||||
login = function(self, _, password)
|
||||
if self:testpass(password) then
|
||||
return true, brute.Account:new("", password, "OPEN")
|
||||
return true, brute.Account:new("", password, creds.State.VALID)
|
||||
end
|
||||
return false, brute.Error:new("Incorrect password")
|
||||
end,
|
||||
@@ -173,16 +173,13 @@ Driver =
|
||||
disconnect = function(self)
|
||||
return self.socket:close()
|
||||
end,
|
||||
|
||||
check = function(self) --deprecated
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
action = function(host, port)
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
engine.options.firstonly = true
|
||||
engine.options:setOption("passonly", true)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
local status, result = engine:start()
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -64,20 +64,18 @@ Driver = {
|
||||
if self.session:authenticate(username, password) then
|
||||
-- store the account for possible future use
|
||||
omp2.add_account(self.host, username, password)
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
else
|
||||
return false, brute.Error:new("login failed")
|
||||
end
|
||||
end,
|
||||
|
||||
--- Deprecated
|
||||
check = function(self)
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
action = function(host, port)
|
||||
local status, result = brute.Engine:new(Driver, host, port):start()
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
local status, result = engine:start()
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
@@ -100,10 +100,10 @@ Driver =
|
||||
local status, data = self.helper:Login( username, password )
|
||||
|
||||
if ( status ) then
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
-- Check for account locked message
|
||||
elseif ( data:match("ORA[-]28000") ) then
|
||||
return true, brute.Account:new(username, password, "LOCKED")
|
||||
return true, brute.Account:new(username, password, creds.State.LOCKED)
|
||||
-- check for any other message
|
||||
elseif ( data:match("ORA[-]%d+")) then
|
||||
stdnse.print_debug(3, "username: %s, password: %s, error: %s", username, password, data )
|
||||
@@ -147,6 +147,7 @@ Driver =
|
||||
action = function(host, port)
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
|
||||
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)"
|
||||
|
||||
@@ -61,7 +61,7 @@ Driver = {
|
||||
end
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
end,
|
||||
|
||||
disconnect = function(self) return self.helper:close() end,
|
||||
@@ -100,6 +100,7 @@ action = function(host, port)
|
||||
end
|
||||
end
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
local status, result = engine:start()
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -207,7 +207,7 @@ Driver =
|
||||
self.invalid_users[username] = true
|
||||
return false, brute.Error:new("Username not found")
|
||||
elseif ( status and msg:match("success") ) then
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
return true, brute.Account:new(username, password, creds.State.VALID)
|
||||
else
|
||||
return false, brute.Error:new( "Incorrect password" )
|
||||
end
|
||||
@@ -250,12 +250,14 @@ action = function(host, port)
|
||||
return " \n Anonymous SVN detected, no authentication needed"
|
||||
end
|
||||
|
||||
if ( not( svn.auth_mech["CRAM-MD5"] ) ) then
|
||||
if ( not(svn.auth_mech) or not( svn.auth_mech["CRAM-MD5"] ) ) then
|
||||
return " \n No supported authentication mechanisms detected"
|
||||
end
|
||||
|
||||
local invalid_users = {}
|
||||
status, accounts = brute.Engine:new(Driver, host, port, invalid_users):start()
|
||||
local engine = brute.Engine:new(Driver, host, port, invalid_users)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
status, accounts = engine:start()
|
||||
if( not(status) ) then
|
||||
return accounts
|
||||
end
|
||||
|
||||
@@ -69,7 +69,8 @@ Driver =
|
||||
login = function( self, username, password )
|
||||
|
||||
local status, data = self.vnc:handshake()
|
||||
if ( not(status) and data:match("Too many authentication failures") ) then
|
||||
if ( not(status) and ( data:match("Too many authentication failures") or
|
||||
data:match("Your connection has been rejected.") ) ) then
|
||||
local err = brute.Error:new( data )
|
||||
err:setAbort( true )
|
||||
return false, err
|
||||
@@ -83,7 +84,7 @@ Driver =
|
||||
status, data = self.vnc:login( nil, password )
|
||||
|
||||
if ( status ) then
|
||||
return true, brute.Account:new("", password, "OPEN")
|
||||
return true, brute.Account:new("", password, creds.State.VALID)
|
||||
elseif ( not( data:match("Authentication failed") ) ) then
|
||||
local err = brute.Error:new( data )
|
||||
-- This might be temporary, set the retry flag
|
||||
@@ -132,6 +133,7 @@ action = function(host, port)
|
||||
local status, result
|
||||
local engine = brute.Engine:new(Driver, host, port )
|
||||
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
engine.options.firstonly = true
|
||||
engine.options:setOption( "passonly", true )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user