Nmap Development mailing list archives

Ncrack ssh module


From: ithilgore <ithilgore.ryu.l () gmail com>
Date: Mon, 13 Jul 2009 07:24:50 +0300

Hello nmap-dev!
 I am pleased to announce that the ssh module for Ncrack has entered the testing
and refining phase. Currently, it works only with version 2 of SSH, though there
are plans to support v1 as well. As you know, the module was built on top of a
custom-made opensshlib which in turn was based on the original code of OpenSSH.
The library has been tailored according to the needs of Ncrack:

* only supports the password authentication method
* it has been stripped of any unneeded subsystems like sftp or X-forwarding or
other features that have nothing to do with the authentication phase
* it uses a struct (ncrack_ssh_state) which is passed along all library
functions that need to work on one of its members. Normally, the OpenSSH code
uses static/global variables which cannot work in parallel. Thus, the struct is
used so that all of these variables (like the Buffer corresponding to the
incoming packet in process) have a unique instance by each module invocation.

Now here are some interesting points for discussion:


----------- SSH username/password iteration ----------------

SSH unfortunately doesn't allow the authentication of more than one username per
connection. This means that in a given connection we can only test the maximum
allowed passwords for 1 username. If we try to change the username in a
connection, then we get immediately disconnected by the server with reason:
(example when we first tried guest and then root as usernames)

Disconnecting: Change of username or service not allowed: (guest,ssh-connection)
-> (root,ssh-connection)

What does the above entail? Ncrack by default uses an iteration of trying each
password for every username, instead of the usual iteration of trying every
password for each username. This means that given the following lists:

Username list: guest, root
Password list: 12345, test, foo, bar

Ncrack will try them by default with the following order:
guest/12345, root/12345, guest/test, root/test, guest/foo, root/foo, guest/bar,
root/bar

Usually the default for common password crackers is doing the opposite. However,
this is less effective for the reason that password lists are usually sorted by
order of password frequency. This means that by trying the most common passwords
for every username at the beginning of the cracking phase, the odds of success
are increased.
Of course, Ncrack is flexible enough to give you the option to do the opposite
iteration by specifying the option --passwords-first.

As you have already realized by now neither the default nor the opposite
iteration is good enough against SSH targets. Using Ncrack's default iteration
we would only be able to make 1 authentication per connection, since we would
get disconnected when trying to change the username in the same connection.
Using the opposite iteration is still not good enough, because we are are not
able to take advantage of the frequency-sorted password lists.

Consequently, I was thinking of providing a 3rd kind of iteration for Ncrack:
For every service, Ncrack uses a first reconnaissance probe that opens just 1
connection and tries to make as many authentication attempts as the server
allows. By doing this, it can understand the maximum number of allowed
authentication attempts per connection against that specific server and since
there is only 1 connection open at that time, the reliability of the inference
is much higher.
Knowing that, Ncrack in this special mode of iteration will provide each
connection with passwords for the same username. So if a connection started with
the username 'guest' then Ncrack will give the next 'maximum allowed
authentication attempts per connection' passwords for that username. This will
need a separate list of Connection unique ids so that each of them is allocated
the next 'maximum allowed authentication attempts' and Ncrack can remember the
username of each connection and at which password-list iteration it was since
the last time the connection asked for a pair.
The above sounds a bit complicated, so let's see an example to clear things out.

Let's suppose that the SSH server allows 3 attempts per connection and we have
the following lists:

Username list: guest, root
Password list: 12345, test, foo, bar, changeme, lala, keke, 000

Suppose Ncrack opens 4 parallel connections numbered #1-#4.

Connection #1 will first get guest/12345 and will additionally be allocated with
the passwords 'test' and 'foo' for the same username(guest) for the next 2 attempts.

Connection #2 will first get root/12345 and will additionally be allocated with
the passwords 'test' and 'foo' for the same username(root) for the next 2 attempts.

Connection #3 will first get guest/bar and will additionally be allocated with
the passwords 'changeme' and 'lala' for the same username(guest) for the next 2
attempts.

Connection #4 will first get root/bar and will additionally be allocated with
the passwords 'changeme' and 'lala for the same username(root) for the next 2
attempts.

After any of the connection finishes, then the first newly invoked connection #5
will get guest/keke and will then try guest/keke and guest/000 and so on.

By using this mixed mode of iteration we are taking advantage of the
frequency-sorted password lists and the maximum efficiency of using all the
allowed attempts per connection. This kind of iteration could be made the
default for the SSH service and could be provided as option for any other
service that wants this kind of iteration for some strange reason.

The problem gets a bit more complicated though when the pair pool comes into
play. The pair pool is a place where failed credentials are stored in case the
peer closes on us in the middle of authentication (which can happen when strange
network conditions occure for example). Then if the pool is non-empty, Ncrack
will first extract any credential from there and give that to the module instead
of moving on to the next username/password pair of the main lists. By doing that
we increase accuracy to 100% since no credential pair has a chance of never
being tried out.

In our case, the pool would act a bit differently. I am not sure what the best
approach would be here but I am thinking about something like this:
Ncrack will extract pairs from the pool only in case a connection has the same
username belonging to it and will also have to deallocate one pair from the
connection since we are now getting one additional one.
Of course, every deallocation will be 'virtual' using pointers to lists. Ncrack
already does that by using only one username/password list (implemented as an
STL vector) instance and just moving pointers pointing to different vector
positions.

In addition, I was thinking that maybe it would be best to provide these kinds
of options (which of the 3 kinds of iteration) as per-host instead of global
ones like --passwords-first that apply to every service. So a user would be able
to specify something like: ./ncrack 10.0.0.2:22,it=1 10.0.0.10:21,it=2
where 'it' stands for iteration and 1 and 2 stand for numbers corresponding to
each mode of iteration. Something more intuitive could be used there though
(instead of mode numbers).

I am also concerned about some other things but will write about them later. For
now, I would like to hear your opinions on the above matters.
The first alpha version of the module can be downloaded from this Ncrack branch:
svn://svn.insecure.org/nmap-exp/ithilgore/ncrack-ssh

Cheers,
ithilgore



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


Current thread: