mirror of
https://github.com/nmap/nmap.git
synced 2025-12-22 15:39:03 +00:00
fixed a statistic bug, cleaned up some code
fixed a setMode bug that wouldn't accept mode 'creds' changed the creds iterator to take a file handle instead of a table [Patrik]
This commit is contained in:
@@ -174,7 +174,9 @@
|
|||||||
-- David's request.
|
-- David's request.
|
||||||
-- Revised 08/30/2010 - v0.6 - added support for custom iterators and did some
|
-- Revised 08/30/2010 - v0.6 - added support for custom iterators and did some
|
||||||
-- needed cleanup.
|
-- needed cleanup.
|
||||||
-- Revised 06/19/2010 - v0.7 - added support for creds library
|
-- Revised 06/19/2011 - v0.7 - added support for creds library [Patrik]
|
||||||
|
-- Revised 07/07/2011 - v0.71- fixed some minor bugs, and changed credential
|
||||||
|
-- iterator to use a file handle instead of table
|
||||||
|
|
||||||
module(... or "brute", package.seeall)
|
module(... or "brute", package.seeall)
|
||||||
require 'unpwdb'
|
require 'unpwdb'
|
||||||
@@ -216,11 +218,18 @@ Options = {
|
|||||||
-- @return status true on success else false
|
-- @return status true on success else false
|
||||||
-- @return err string containing the error message on failure
|
-- @return err string containing the error message on failure
|
||||||
setMode = function( self, mode )
|
setMode = function( self, mode )
|
||||||
if ( mode == "password" or mode == "user" ) then
|
local modes = { "password", "user", "creds" }
|
||||||
self.mode = mode
|
local supported = false
|
||||||
else
|
|
||||||
|
for _, m in ipairs(modes) do
|
||||||
|
if ( mode == m ) then supported = true end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ( not(supported) ) then
|
||||||
stdnse.print_debug("ERROR: brute.options.setMode: mode %s not supported", mode)
|
stdnse.print_debug("ERROR: brute.options.setMode: mode %s not supported", mode)
|
||||||
return false, "Unsupported mode"
|
return false, "Unsupported mode"
|
||||||
|
else
|
||||||
|
self.mode = mode
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
@@ -356,14 +365,6 @@ Engine =
|
|||||||
table.insert( self.iterators, iterator )
|
table.insert( self.iterators, iterator )
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- Sets the engine running mode
|
|
||||||
--
|
|
||||||
-- @param mode string, one of either "user", "creds" or "pass"
|
|
||||||
setMode = function( self, mode )
|
|
||||||
mode = ( mode == "user" or mode == "creds" or mode == "pass" ) and mode or nil
|
|
||||||
assert(mode, ("Unsupported mode: (%s)"):format(mode))
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Limit the number of worker threads
|
--- Limit the number of worker threads
|
||||||
--
|
--
|
||||||
-- @param max number containing the maximum number of allowed threads
|
-- @param max number containing the maximum number of allowed threads
|
||||||
@@ -482,6 +483,9 @@ Engine =
|
|||||||
-- * We've reached the maximum retry attempts
|
-- * We've reached the maximum retry attempts
|
||||||
until( status or ( response and not( response:isRetry() ) ) or retries == 0)
|
until( status or ( response and not( response:isRetry() ) ) or retries == 0)
|
||||||
|
|
||||||
|
-- Increase the amount of total guesses
|
||||||
|
self.counter = self.counter + 1
|
||||||
|
|
||||||
-- did we exhaust all retries, terminate and report?
|
-- did we exhaust all retries, terminate and report?
|
||||||
if ( retries == 0 ) then
|
if ( retries == 0 ) then
|
||||||
Engine.terminate_all = true
|
Engine.terminate_all = true
|
||||||
@@ -522,8 +526,6 @@ Engine =
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Increase the amount of total guesses
|
|
||||||
self.counter = self.counter + 1
|
|
||||||
local timediff = (os.time() - interval_start)
|
local timediff = (os.time() - interval_start)
|
||||||
|
|
||||||
-- This thread made another guess
|
-- This thread made another guess
|
||||||
@@ -549,7 +551,7 @@ Engine =
|
|||||||
-- @return err string containing error message on failure
|
-- @return err string containing error message on failure
|
||||||
start = function(self)
|
start = function(self)
|
||||||
|
|
||||||
local result, cvar, stats = {}, {}, {}
|
local cvar = {}
|
||||||
local condvar = nmap.condvar( cvar )
|
local condvar = nmap.condvar( cvar )
|
||||||
|
|
||||||
assert(self.options.script_name, "SCRIPT_NAME was not set in options.script_name")
|
assert(self.options.script_name, "SCRIPT_NAME was not set in options.script_name")
|
||||||
@@ -570,7 +572,7 @@ Engine =
|
|||||||
local status, passwords = unpwdb.passwords()
|
local status, passwords = unpwdb.passwords()
|
||||||
if ( not(status) ) then return false, "Failed to load passwords" end
|
if ( not(status) ) then return false, "Failed to load passwords" end
|
||||||
|
|
||||||
local mode = stdnse.get_script_args("brute.mode")
|
local mode = self.options.mode or stdnse.get_script_args("brute.mode")
|
||||||
|
|
||||||
-- Are we guessing against a service that has no username (eg. VNC)
|
-- Are we guessing against a service that has no username (eg. VNC)
|
||||||
if ( self.options.passonly ) then
|
if ( self.options.passonly ) then
|
||||||
@@ -582,28 +584,21 @@ Engine =
|
|||||||
elseif ( mode == 'creds' ) then
|
elseif ( mode == 'creds' ) then
|
||||||
local credfile = stdnse.get_script_args("brute.credfile")
|
local credfile = stdnse.get_script_args("brute.credfile")
|
||||||
if ( not(credfile) ) then
|
if ( not(credfile) ) then
|
||||||
return false, "No credential file specified"
|
return false, "No credential file specified (see brute.credfile)"
|
||||||
end
|
end
|
||||||
|
|
||||||
local f = io.open( credfile, "r" )
|
local f = io.open( credfile, "r" )
|
||||||
if ( not(f) ) then
|
if ( not(f) ) then
|
||||||
return false, ("Failed to open credfile (%s)"):format(credfile)
|
return false, ("Failed to open credfile (%s)"):format(credfile)
|
||||||
end
|
end
|
||||||
local c = {}
|
|
||||||
for line in f:lines() do
|
|
||||||
local trim = function(s) return s:match('^()%s*$') and '' or s:match('^%s*(.*%S)') end
|
|
||||||
line = trim(line)
|
|
||||||
local user, pass = line:match("^([^%/]*)%/(.*)$")
|
|
||||||
table.insert(c, { [user]=pass } )
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert( self.iterators, Iterators.credential_iterator( c ) )
|
table.insert( self.iterators, Iterators.credential_iterator( f ) )
|
||||||
elseif ( mode and mode == 'user' ) then
|
elseif ( mode and mode == 'user' ) then
|
||||||
table.insert( self.iterators, Iterators.user_pw_iterator( usernames, passwords ) )
|
table.insert( self.iterators, Iterators.user_pw_iterator( usernames, passwords ) )
|
||||||
elseif( mode and mode == 'pass' ) then
|
elseif( mode and mode == 'pass' ) then
|
||||||
table.insert( self.iterators, Iterators.pw_user_iterator( usernames, passwords ) )
|
table.insert( self.iterators, Iterators.pw_user_iterator( usernames, passwords ) )
|
||||||
elseif ( mode ) then
|
elseif ( mode ) then
|
||||||
return false, ("Unsupported mode: %s"):format(nmap.registry.args['brute.mode'])
|
return false, ("Unsupported mode: %s"):format(mode)
|
||||||
-- Default to the pw_user_iterator in case no iterator was specified
|
-- Default to the pw_user_iterator in case no iterator was specified
|
||||||
elseif ( 0 == #self.iterators ) then
|
elseif ( 0 == #self.iterators ) then
|
||||||
table.insert( self.iterators, Iterators.pw_user_iterator( usernames, passwords ) )
|
table.insert( self.iterators, Iterators.pw_user_iterator( usernames, passwords ) )
|
||||||
@@ -623,6 +618,7 @@ Engine =
|
|||||||
|
|
||||||
local valid_accounts = creds.Credentials:new(self.options.script_name, self.host, self.port):getTable()
|
local valid_accounts = creds.Credentials:new(self.options.script_name, self.host, self.port):getTable()
|
||||||
|
|
||||||
|
local result = {}
|
||||||
-- Did we find any accounts, if so, do formatting
|
-- Did we find any accounts, if so, do formatting
|
||||||
if ( valid_accounts and #valid_accounts > 0 ) then
|
if ( valid_accounts and #valid_accounts > 0 ) then
|
||||||
valid_accounts.name = "Accounts"
|
valid_accounts.name = "Accounts"
|
||||||
@@ -639,6 +635,7 @@ Engine =
|
|||||||
local tps = ( sum == 0 ) and ( self.counter / time_diff ) or ( sum / #self.tps )
|
local tps = ( sum == 0 ) and ( self.counter / time_diff ) or ( sum / #self.tps )
|
||||||
|
|
||||||
-- Add the statistics to the result
|
-- Add the statistics to the result
|
||||||
|
local stats = {}
|
||||||
table.insert(stats, ("Performed %d guesses in %d seconds, average tps: %d"):format( self.counter, time_diff, tps ) )
|
table.insert(stats, ("Performed %d guesses in %d seconds, average tps: %d"):format( self.counter, time_diff, tps ) )
|
||||||
stats.name = "Statistics"
|
stats.name = "Statistics"
|
||||||
table.insert( result, stats )
|
table.insert( result, stats )
|
||||||
@@ -763,17 +760,18 @@ Iterators = {
|
|||||||
|
|
||||||
--- Credential iterator (for default or known user/pass combinations)
|
--- Credential iterator (for default or known user/pass combinations)
|
||||||
--
|
--
|
||||||
-- @param creds table containing username/pass combinations
|
-- @param f file handle to file containing credentials separated by '/'
|
||||||
-- the table should be of the following format
|
|
||||||
-- { ["user"] = "pass", ["user2"] = "pass2" }
|
|
||||||
-- @return function iterator
|
-- @return function iterator
|
||||||
credential_iterator = function( creds )
|
credential_iterator = function( f )
|
||||||
local function next_credential ()
|
local function next_credential ()
|
||||||
for _, item in ipairs(creds) do
|
local c = {}
|
||||||
for user, pass in pairs(item) do
|
for line in f:lines() do
|
||||||
|
local trim = function(s) return s:match('^()%s*$') and '' or s:match('^%s*(.*%S)') end
|
||||||
|
line = trim(line)
|
||||||
|
local user, pass = line:match("^([^%/]*)%/(.*)$")
|
||||||
coroutine.yield( user, pass )
|
coroutine.yield( user, pass )
|
||||||
end
|
end
|
||||||
end
|
f:close()
|
||||||
while true do coroutine.yield( nil, nil ) end
|
while true do coroutine.yield( nil, nil ) end
|
||||||
end
|
end
|
||||||
return coroutine.wrap( next_credential )
|
return coroutine.wrap( next_credential )
|
||||||
|
|||||||
Reference in New Issue
Block a user