Nmap Development mailing list archives

Re: Ncrack ssh module


From: ithilgore <ithilgore.ryu.l () gmail com>
Date: Tue, 14 Jul 2009 14:51:13 +0300

David Fifield wrote:
On Mon, Jul 13, 2009 at 07:24:50AM +0300, ithilgore wrote:
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.

As you have already realized by now neither the default nor the
opposite iteration is good enough against SSH targets.

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.

This is an excellent idea. Based on what you say, this should definitely
be the default mode of operation for SSH.

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.

I don't see the need for a reconnaissance probe, unless the architecture
of Ncrack requires each connection to know the credentials it will try
in advance. Instead, think of it this way: There is a globally optimum
next pair to try, but each connection has its own locally optimum next
pair that may be different. In the example above, after guest/12345 has
been tried, the next best pair globally is root/12345, because that is
the next most likely to succeed. But for the connection that tried
guest/12345, that's not optimum, because it would have to restart the
connection. Instead, its local optimum is guest/test.

The reconnaissance probe is being sent out on all occasions against every
service for the following reasons:

* It is used to gather timing information like how much time the server delays
between sending him our credentials and showing us the results of the
authentication attempt. This will be used by the Ncrack dynamic engine to infer
whether it will be faster to later open even more connections instead of trying
to wait for a possibly long time between each auth-attempt of the same
connection. This happens when the sum of the 3way handshake time and the time of
the pre-authentication protocol exchange is less than the time of the delay
imposed by the server when showing the results of an auth-attempt. In
particular, it will be even more important for services that impose an
exponential increase for each attempt in the same connection (e.g 1 sec in the
first attempt, 5 secs in the second and 15 in the 3rd)

* It is sent in the beginning when no other connection has been opened against
that particular service, so that makes it reliable enough. We haven't started
hitting the server with a load of connections yet and thus we are more certain
that we won't be disconnected in the middle of the authentication (which tends
to happen even in a local network when the number of connections increases
dramatically)

* It isn't really time-consuming since it only happens for one time in the
beginning of each service cracking.

* There are services out there that require you to try N+1 times to authenticate
 before they disconnect you and then you realize that only N attempts are
allowed. In these cases, sending out the +1 packet *for each* connection is a
total waste of bandwidth. Examples of these services that I have encountered so
far are many telnet daemons.


So when a new connection is started, it grabs the next global optimum.
But while a connection exists, it grabs its next best local optimum each
time, until the connection ends.

I can see the avlue of a reconnaissance probe if you have to attempt a
fourth authentication to find that only three are allowed. But if the
server disconnects you automatically after three failed authentications,
you can use that as the signal to end the connection. Then the software
will gracefully cope in case the limit changes dynamically or something.

I haven't really seen any service that dynamically changes the limit. That would
be a challenging problem to solve if we happen to encounter it. Usually,
firewalls do the dynamic part but mostly by decreasing the number of connections
allowed, something which is (not good enough yet)/will be handled by the Ncrack
dynamic engine.



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).

These options seem pretty obscure. You can add them but I don't see them
being used much. Picking the best default for each protocol is what's
most important.

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

Please provide instructions for checking out, compiling, and testing it
against an SSH server. I'm sure there are people (like me) who would be
happy to test it but need some more guidance. In particular, I would
like a little HOWTO on setting up an sshd locally with a custom passwd
file, if that's possible. It's best if people can test this without
creating new users with insecure passwords on their own systems.

Instructions follow:

I have already merged the ssh-module branch into the main Ncrack trunk so you
had better download it from there now:

$ svn co --username "guest" --password ""
svn://svn.insecure.org/nmap-exp/ithilgore/ncrack
$ cd ncrack
$ ./configure
$ make

If everything goes well, the ncrack binary will be ready to deploy.
Now for setting the sshd locally, the only thing you have to do is edit the
sshd_config file usually located at /etc/ssh/sshd_config and change the line:

ListenAddress 0.0.0.0

to

ListenAddress 127.0.0.1

Then start/restart sshd - usually /etc/rc.d/sshd start or /etc/init.d/sshd start
As for the test password file, you would need to create some test users with
adduser or useradd and then invoking passwd for each of them. Alternatively you
can just append these 2 usernames/passwords to the end of /etc/passwd and
/etc/shadow accordingly (this will only work in Linux since *BSD use other kinds
of database files)

/etc/passwd
guest:x:1003:100::/home/guest:/bin/bash
admin:x:1004:100::/home/admin:/bin/bash

/etc/shadow
guest:$1$FN1MKPRK$/HkayeFu9kKJShsGBhdVN/:14439:0:99999:7:::
admin:$1$CxND5UQ6$tlSFZ1iBJvTf4eY5nhqsq1:14439:0:99999:7:::

the hashes correspond to 12345 for guest and hello1 for admin
The home directories don't need to be created.

After you are ready with the above invoke ncrack like this:
./ncrack 127.0.0.1:22 -d10 --passwords-first
(-d10 is maximum debugging output)
OR
./ncrack 127.0.0.1:22
OR
./ncrack 127.0.0.1:22 --passwords-first

--passwords-first isn't required but will increase performance for now (in
addition if you don't specify it, ncrack will wrongfully report that the maximum
auth attempts are 2 instead of 1 - which is the case when trying to change the
username in the same connection) This will be fixed soon. I will probably start
implementing the special kind of username/password iteration in a while.

Regards,
ithilgore

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


Current thread: