home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / nselib / unpwdb.lua < prev    next >
Text File  |  2009-07-06  |  4KB  |  162 lines

  1. --- Username/password database library.
  2. --
  3. -- The <code>usernames</code> and <code>passwords</code> functions return
  4. -- multiple values for use with exception handling via
  5. -- <code>nmap.new_try</code>. The first value is the Boolean success
  6. -- indicator, the second value is the closure.
  7. --
  8. -- The closures can take an argument of <code>"reset"</code> to rewind the list
  9. -- to the beginning.
  10. --
  11. -- You can select your own username and/or password database to read from with
  12. -- the script arguments <code>userdb</code> and <code>passdb</code>,
  13. -- respectively.  Comments are allowed in these files, prefixed with
  14. -- <code>"#!comment:"</code>.  Comments cannot be on the same line as a
  15. -- username or password because this leaves too much ambiguity, e.g. does the
  16. -- password in <code>"mypass  #!comment: blah"</code> contain a space, two
  17. -- spaces, or do they just separate the password from the comment?
  18. --
  19. -- @args userdb The filename of an alternate username database.
  20. -- @args passdb The filename of an alternate password database.
  21. -- @author Kris Katterjohn 06/2008
  22. -- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  23.  
  24. module(... or "unpwdb", package.seeall)
  25.  
  26. local usertable = {}
  27. local passtable = {}
  28.  
  29. local customdata = false
  30.  
  31. -- So I don't have to type as much :)
  32. local args = nmap.registry.args
  33.  
  34. local userfile = function()
  35.     if args.userdb then
  36.         customdata = true
  37.         return args.userdb
  38.     end
  39.  
  40.     return nmap.fetchfile("nselib/data/usernames.lst")
  41. end
  42.  
  43. local passfile = function()
  44.     if args.passdb then
  45.         customdata = true
  46.         return args.passdb
  47.     end
  48.  
  49.     return nmap.fetchfile("nselib/data/passwords.lst")
  50. end
  51.  
  52. local filltable = function(filename, table)
  53.     if #table ~= 0 then
  54.         return true
  55.     end
  56.  
  57.     local file = io.open(filename, "r")
  58.  
  59.     if not file then
  60.         return false
  61.     end
  62.  
  63.     while true do
  64.         local l = file:read()
  65.  
  66.         if not l then
  67.             break
  68.         end
  69.  
  70.         -- Comments takes up a whole line
  71.         if not l:match("#!comment:") then
  72.             table[#table + 1] = l
  73.         end
  74.     end
  75.  
  76.     file:close()
  77.  
  78.     return true
  79. end
  80.  
  81. local closure = function(table)
  82.     local i = 1
  83.  
  84.     return function(cmd)
  85.         if cmd == "reset" then
  86.             i = 1
  87.             return
  88.         end
  89.         local elem = table[i]
  90.         if elem then i = i + 1 end
  91.         return elem
  92.     end
  93. end
  94.  
  95. --- Returns the suggested number of seconds to attempt a brute force attack,
  96. -- based on Nmap's timing values (<code>-T4</code> etc.) and whether or not a
  97. -- user-defined list is used.
  98. --
  99. -- You can use the script argument <code>notimelimit</code> to make this
  100. -- function return <code>nil</code>, which means the brute-force should run
  101. -- until the list is empty. If <code>notimelimit</code> is not used, be sure to
  102. -- still check for <code>nil</code> return values on the above two functions in
  103. -- case you finish before the time limit is up.
  104. timelimit = function()
  105.    -- If we're reading from a user-defined username or password list,
  106.    -- we'll give them a timeout 1.5x the default.  If the "notimelimit"
  107.    -- script argument is used, we return nil.
  108.     local t = nmap.timing_level()
  109.  
  110.     -- Easy enough
  111.     if args.notimelimit then
  112.         return nil
  113.     end
  114.  
  115.     if t <= 3 then
  116.         return (customdata and 900) or 600
  117.     elseif t == 4 then
  118.         return (customdata and 450) or 300
  119.     elseif t == 5 then
  120.         return (customdata and 270) or 180
  121.     end
  122. end
  123.  
  124. --- Returns a function closure which returns a new username with every call
  125. -- until the username list is exhausted (in which case it returns
  126. -- <code>nil</code>).
  127. -- @return boolean Status.
  128. -- @return function The usernames iterator.
  129. usernames = function()
  130.     local path = userfile()
  131.  
  132.     if not path then
  133.         return false, "Cannot find username list"
  134.     end
  135.  
  136.     if not filltable(path, usertable) then
  137.         return false, "Error parsing username list"
  138.     end
  139.  
  140.     return true, closure(usertable)
  141. end
  142.  
  143. --- Returns a function closure which returns a new password with every call
  144. -- until the password list is exhausted (in which case it returns
  145. -- <code>nil</code>).
  146. -- @return boolean Status.
  147. -- @return function The passwords iterator.
  148. passwords = function()
  149.     local path = passfile()
  150.  
  151.     if not path then
  152.         return false, "Cannot find password list"
  153.     end
  154.  
  155.     if not filltable(path, passtable) then
  156.         return false, "Error parsing password list"
  157.     end
  158.  
  159.     return true, closure(passtable)
  160. end
  161.  
  162.