Nmap Development mailing list archives

Re: [RFC] Username/Password NSE library


From: Kris Katterjohn <katterjohn () gmail com>
Date: Mon, 23 Jun 2008 02:24:12 -0500

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hey everyone,

I've attached my username/password database NSElib, which is named "unpwdb".
While I like this name because it's short and sweet, I don't think everybody
will, so any suggestions for a better name are certainly welcome :)

Along with the library, I've also attached a verbose script for testing.  Just
put your username list in nselib/usernames.lst and your password list in
nselib/passwords.lst, then run the script on localhost (or whatever).

- From unpwdb.lua:

usernames() - Returns a closure which returns a new username with every call
until the username list is exhausted (in which case it returns nil)

passwords() - Returns a closure which returns a new password with every call
until the password list is exhausted (in which case it returns nil)

These 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, and the last value is a boolean value indicating
whether or not the list read from is user-defined (true) or not (false).

You can select your own username and/or password database to read from with
the script arguments userdb and passdb, respectively.  The databases are
read line-by-line and recorded verbatim, so no comments are allowed (this
could get confused with a real username or password).


I wrote:
OK, guys, poll time: should we use the stock, ordered password file from John
the Ripper with ~3100 entries, a different password file obtained from
elsewhere, or generate our own list (e.g. from honeypot data per Brandon's
suggestion)?  I don't see how to use two separate lists from different sources
together.

The ordered list that comes with a password cracker listed #10 overall on
SecTools lends credence to one of these options :)

However, the list with John isn't huge (e.g. tens of thousands of entries) and
can't expanded on-the-fly.  But if 3107 sounds like a good number of entries,
then it makes for a really good candidate.

Of course, if we decide on the list from John, or wherever, we can always
create our own list later if we decide we want more entries or whathaveyou.


Assuming nobody runs into any problems with my attached library, the only
thing remaining is finding a username and password list.  I'm for the password
list that comes with John, but I can't find a good username list.

Maybe we should generate our own username list?

Thanks,
Kris Katterjohn


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIVAwUBSF9Pk/9K37xXYl36AQJQDQ/9FMO8noact/8YO/Mwd2t9UVpcH5c8DREK
DaDeTMylBxS00cu6UVeQxj0fZe8Nsx++dIOoVEEljS1Io6I42u11TJ1f17wi8LMz
tXaDf3xy7vMj8e1fB7OLwjtw7beFdoSf21E7du4vDCBcSEgad+I/4S3YmIoZcTqX
kQy0oG8JNXr8EMjhhPtSj68uPrx1tWQRWlF9wyjrp1ZvsW+mQzB1zwnZIarXCFs4
uAnpnaZM3aynepRn4bDO0GCHz99Bj5eeGszonGMhvRv0VrNEeMgmETq4Kz/yFqSZ
6vcWAhX8ROBUF2mwJqPI7ukmX+PfL+P5u4xFdw2X69i4Kbrrd18j3L+QCkLvv7oe
rLSzVzTm2bp24mXEkYWRgCx+jFNgoQFQmXfzn+HNQdZV5VFdkbUi0MhkfoGM49nL
6X8xyo0hCqLq0P+BDNtSDAHOi8d5buOtnCU0aciGE5xswlkvHkKvpTi075m1PPCz
vnlwcGMtKU5X4No8GRUj4FZIzQulDYgnllwBmGKOBBp4c+wj7LvISK89phyxpmWS
uiZuTY5V8Gp6Yooh/v06I1hR2hqpMqvWRNgd/U2oB0qVdrBhO0hDNEf7wc87h2DA
O0PtJ4UBt8BqFkBIzdLSxybn83xVPfLVz19JOR5GLEZV6oI5q3AMRuaIHHFUplG3
3O16GPSi7D0=
=XAjz
-----END PGP SIGNATURE-----
-- Kris Katterjohn 06/2008

module(..., package.seeall)

---- Username/Password DB Library
--
-- usernames() - Returns a closure which returns a new username with every call
-- until the username list is exhausted (in which case it returns nil)
--
-- passwords() - Returns a closure which returns a new password with every call
-- until the password list is exhausted (in which case it returns nil)
--
-- These 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, and the last value is a boolean value indicating
-- whether or not the list read from is user-defined (true) or not (false).
--
-- You can select your own username and/or password database to read from with
-- the script arguments userdb and passdb, respectively.  The databases are
-- read line-by-line and recorded verbatim, so no comments are allowed (this
-- could get confused with a real username or password).
--
----

local usertable = {}
local passtable = {}

local userfile = function()
        if nmap.registry.args.userdb then
                return true, nmap.registry.args.userdb
        end

        return false, nmap.fetchfile("nselib/usernames.lst")
end

local passfile = function()
        if nmap.registry.args.passdb then
                return true, nmap.registry.args.passdb
        end

        return false, nmap.fetchfile("nselib/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

                table[#table + 1] = l
        end

        file:close()

        return true
end

local closure = function(table)
        local i = 1

        return function()
                local elem = table[i]
                if elem then i = i + 1 end
                return elem
        end
end

usernames = function()
        local custom, path = userfile()

        if not path then
                return false, "Cannot find username list", custom
        end

        if not filltable(path, usertable) then
                return false, "Error parsing username list", custom
        end

        return true, closure(usertable), custom
end

passwords = function()
        local custom, path = passfile()

        if not path then
                return false, "Cannot find password list", custom
        end

        if not filltable(path, passtable) then
                return false, "Error parsing password list", custom
        end

        return true, closure(passtable), custom
end

id = "unpwdb-test"
description = "testing unpwdb nselib"
author = "kris katterjohn"
license = "same as nmap"
categories = {"default"}

require "unpwdb"

hostrule = function() return true end

action = function()
        local status, user, pass, custom

        status, user, custom = unpwdb.usernames()

        if not status then
                return "bad user"
        end

        if custom then
                print("user-defined username db")
        else
                print("default username db")
        end

        status, pass, custom = unpwdb.passwords()

        if not status then
                return "bad pass"
        end

        if custom then
                print("user-defined password db")
        else
                print("default password db")
        end

        local result = " \n***usernames***\n"

        while true do
                local username = user()
                if not username then break end
                result = result .. username .. "\n"
        end

        result = result .. "***passwords***\n"

        while true do
                local password = pass()
                if not password then break end
                result = result .. password .. "\n"
        end

        return result
end


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: