Nmap Development mailing list archives

Re: using the credentials database


From: Patrik Karlsson <patrik () cqure net>
Date: Tue, 5 Jul 2011 19:17:51 +0200

Hi Toni,

Have a look at the following patch and see if it fits your needs.
I've added support for feeding the library with credentials from the command line.
The attached patch does not store these credentials in any way. Instead it fetches them from the command line, when 
getCredentials is called.

The patch makes the following changes:
- The State supplied to getCredentials is now a bit mask instead which allows you to supply multiple states (see 
example below)
- Credentials may now be "added" using the command line. The following arguments are supported:
        o creds.global - adds credentials that will always be returned, regardless of service
        o creds.<service> - eg. creds.http adds credentials that will be used when 'http' is set in port.service
- The command line supplied credentials are returned after any discovered credentials for the specific service
- Credentials should be added as user pass pairs (eg. user:pass,user2:pass2). Empty passwords are supported by leaving 
out the ':' eg. (user,user2,user3)

Here's an example on how I've tested this:
./nmap --script creds-test,creds-test4 -d 127.0.0.1 -p 22 --script-args 
"creds.global='foo:bar',creds.http='httpuser:httppass,httpuser2,httppass2',creds.ftp='anonymous:a () a se'"

The creds-test script adds a bunch of "discovered" credentials to different services.
The creds-test4 script depends on creds-test and fetches any discovered credentials and prints them out, using the 
following code:

        local http_creds = creds.Credentials:new(creds.ALL_DATA, host, { number=80, service="http" })
        local state = creds.State.VALID + creds.State.PARAM + creds.State.LOCKED
        for _, cred in pairs(http_creds:getCredentials(state)) do
                print(cred.host.ip, cred.user, cred.pass, creds.StateMsg[cred.state])
        end

The results from creds-test4 look like this:
127.0.0.1       patrik  secret  Account is valid
127.0.0.1       fritz   charles Account is valid
127.0.0.1       jack    harley  Account is locked
127.0.0.1       httpuser        httppass        nil
127.0.0.1       httpuser2       nil     nil
127.0.0.1       httppass2       nil     nil
127.0.0.1       foo     bar     nil

The three leading credentials were discovered by the creds-test script and the last four were supplied on the command 
line.
It makes sense to me, what do you think?

Also, I would appreciate if someone could at least skim through the code to make sure it looks sane.
I would like to avoid a "WTF was he thinking?"-moment when we discover something major foobar and have tons of scripts 
relying on the library.

Attachment: creds-cli-add.patch
Description:



//Patrik 

On Jul 5, 2011, at 2:17 PM, Toni Ruottu wrote:

I made some tests with an info script I have been working on. I ended
up doing the following.

action = function(host, port)
       local response = {}
       local c = creds.Credentials:new(creds.ALL_DATA, host, port)
       for _, cred in pairs(c:getCredentials(creds.State.VALID)) do
               local info = getinfo(host, port, cred.user, cred.pass)
               table.insert(response, info)
       end
       return stdnse.format_output(true, response)
end

This is roughly how it goes for services where different users have
different data. How would this code change if we had the command line
creds support in place? Another getCredentials call for the command
line creds? A combiner for combining VALID with PARAM?


On Thu, Jun 30, 2011 at 10:12 AM, Patrik Karlsson <patrik () cqure net> wrote:

At this point I think it shouldn't be a problem, technically, to add
credentials from the command line.
Before I (or someone else) does so, I think we need to consider the
following:
1. I've been working with the following (most common) account states:
LOCKED, VALID, DISABLED and CHANGEPW
  We probably need to add a new state for the credentials added on
command line
2. The library structures credentials around hosts and ports.
  Adding "global" credentials will need some kind of work-around.
  The easiest way is probably adding a host eg. 0.0.0.0 and port 0 that
would keep track of these credentials
  This way, it should be straight forward to allow adding service
specific credentials from the command line too.
3. The command line added credentials need to be handled differently in
output
  I propose that the 0.0.0.0 host is filtered from all output.
  If the global credentials are discovered for some service they will be
added to the respective host and service.
4. When a script queries all credentials discovered for a host and port we
need to consider how to handle global credentials
  Should they be returned first or last in the table?
  Should they be returned at all if there were other credentials
discovered for that host & port combination?
5. There are currently very few scripts that make use of the library for
storing credentials.
  There are none that make use of reading from the database.
  This will of course hopefully change over time.
  Until then the documentation regarding global credentials needs to be
very clear so that users don't mistakenly think they can use it.

Those are some of my thoughts. Comments?

//Patrik

What I'd like to see next, is support for feeding credentials into the
database from command line. I am sure this could be made into a really
hard design task, but maybe we do not need to support very complex use
cases. We could just support global credentials that would match all
services. How about --script-args creds.global=joe:secret,admin:123456

On Tue, Jun 28, 2011 at 12:04 AM, Patrik Karlsson <patrik () cqure net>
wrote:

On Jun 27, 2011, at 4:25 PM, Toni Ruottu wrote:

Do we have examples for using the credentials stored in the database?
Do I need to use the credentials explicitly when I am developing http
info scripts, or does the http library just log in for me if
authorization is required?

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


Hi Toni,

I've added some documentation and a new function called getCredentials
that will hopefully get you what you need.
Let me know if there's anything else you find missing :)

In regards to the http library, you need to se the credentials
explicitly. Check out the http-brute script for an example.

//Patrik
--
Patrik Karlsson
http://www.cqure.net
http://www.twitter.com/nevdull77

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




--
Patrik Karlsson
http://www.cqure.net
http://www.twitter.com/nevdull77






--
Patrik Karlsson
http://www.cqure.net
http://www.twitter.com/nevdull77

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

Current thread: