1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 22:21:29 +00:00
Files
nmap/nselib/unpwdb.lua

155 lines
3.7 KiB
Lua

--- Username/password database library.
-- \n\n
-- The usernames and passwords functions return multiple values for use
-- with exception handling via nmap.new_try().
-- The first value is the boolean success indicator, the second value is
-- the closure.
-- \n\n
-- The closures can take a parameter of "reset" to rewind the list to the
-- beginning.
-- \n\n
-- You can select your own username and/or password database to read from with
-- the script arguments userdb and passdb, respectively. Comments are allowed
-- in these files, prefixed with "#!comment:". Comments cannot be on the same
-- line as a username or password because this leaves too much ambiguity, e.g.
-- does the password in "mypass #!comment: blah" contain a space, two spaces,
-- or do they just separate the password from the comment?
--
-- @author Kris Katterjohn 06/2008
module(... or "unpwdb", package.seeall)
local usertable = {}
local passtable = {}
local customdata = false
-- So I don't have to type as much :)
local args = nmap.registry.args
local userfile = function()
if args.userdb then
customdata = true
return args.userdb
end
return nmap.fetchfile("nselib/data/usernames.lst")
end
local passfile = function()
if args.passdb then
customdata = true
return args.passdb
end
return nmap.fetchfile("nselib/data/passwords.lst")
end
local filltable = function(filename, table)
if #table ~= 0 then
return true
end
local file = io.open(filename, "r")
if not file then
return false
end
while true do
local l = file:read()
if not l then
break
end
-- Comments takes up a whole line
if not l:match("#!comment:") then
table[#table + 1] = l
end
end
file:close()
return true
end
local closure = function(table)
local i = 1
return function(cmd)
if cmd == "reset" then
i = 1
return
end
local elem = table[i]
if elem then i = i + 1 end
return elem
end
end
--- Returns the suggested number of seconds to attempt a brute
-- force attack, based on Nmap's timing values (-T4, etc) and whether or not a
-- user-defined list is used.
-- \n\n
-- You can use the script argument "notimelimit" to make this function return
-- nil, which means the brute-force should run until the list is empty. If
-- "notimelimit" is not used, be sure to still check for nil return values on
-- the above two functions in case you finish before the time limit is up.
timelimit = function()
-- If we're reading from a user-defined username or password list,
-- we'll give them a timeout 1.5x the default. If the "notimelimit"
-- script argument is used, we return nil.
local t = nmap.timing_level()
-- Easy enough
if args.notimelimit then
return nil
end
if t <= 3 then
return (customdata and 900) or 600
elseif t == 4 then
return (customdata and 450) or 300
elseif t == 5 then
return (customdata and 270) or 180
end
end
--- Returns a function closure which returns a new username with every call
-- until the username list is exhausted (in which case it returns nil).
-- @return boolean Status.
-- @return function The usernames iterator.
usernames = function()
local path = userfile()
if not path then
return false, "Cannot find username list"
end
if not filltable(path, usertable) then
return false, "Error parsing username list"
end
return true, closure(usertable)
end
--- Returns a function closure which returns a new password with every call
-- until the password list is exhausted (in which case it returns nil).
-- @return boolean Status.
-- @return function The passwords iterator.
passwords = function()
local path = passfile()
if not path then
return false, "Cannot find password list"
end
if not filltable(path, passtable) then
return false, "Error parsing password list"
end
return true, closure(passtable)
end