Home page logo

nmap-dev logo Nmap Development mailing list archives

Re: Status Report #7 of 17
From: ithilgore <ithilgore.ryu.l () gmail com>
Date: Tue, 09 Jun 2009 03:04:15 +0300

----------- Accomplishments -------------

* Handled case when failing to connect to a host at first try (either by timeout
or RST or no route to host): service will move to services_finished list.

* Changed parsing according to last discussion with Fyodor: removed the need for
'?' to specify host arguments (now it is only done with commas ',') Also, user
can now specify only the port like and the default service name
corresponding to that port will be assigned to it (the equivalent also happens
when user has only specified service name in url-like notation)

* Added timing rate meters using Nmap's timing.[cc,h] classes.

* Ncrack now automatically selects current directory's username.lst and/or
password.lst if options -L and/or -P are not specified by the user.

* ServiceGroup got its own separate file now.

* Ncrack will now check if the connection has been closed by the peer before
trying out a new authentication attempt within that connection. It does that
by issuing a read call (through nsock) with a tiny timeout. If nsock returns
NSE_STATUS_TIMEOUT instead of an NSE_STATUS_EOF, then our connection hasn't
been closed yet by the peer. Of course we check that by using an additional
boolean variable so as to differentiate between normal timeouts and this
particular one. There is not really any other *portable* way to check if our
connection is in CLOSE_WAIT state (e.g Linux netstat just parses /proc and *BSD
use fcntl et al)

* Solved the next login pair problem:

Problem: each service that needs to be cracked holds a pointer to the loaded
username list and password list (they are vector objects). Each time a new
connection is made or a new authentication attempt is going to be tried in the
current connection then we need to call NextPair() which gives us the next login
username and password pair. The normal way to do that would be to just move the
password list iterator each time, and the username list iterator once the
password list iterator has finished one full iteration. However, by using this
crude approach arises the following problem:

-- What happens when a connection is prematurely closed by the peer for one
reason or another (before the current login pair is actually tested)? --

It is obvious that the iterator approach would never really try out that pair,
because it would just forget about the unfinished authentication attempt and
move on giving the next (always unique) pair.

Solution: (still needs to be more tested for some end-cases)

Each time a connection is prematurely closed by the peer, which essentially
means that our current authentication attempt was not completed, then we throw
the current pair inside the service's login-pair pool (which is a stl list). The
next time we are going to ask for a pair from NextPair(), if the pair_pool
is not empty, then it will return us one element from that, giving us the
opportunity to retry that pair once again. The element is removed from the pool
when we extract it from NextPair() and if the authentication doesn't finish this
time either, then we move it back to the list so it can be reused later once
again (and this will go on happening until the authentication finishes all steps
for that pair or any other pair in that situation).

The problem, however, is a little more complex than it first seems:

-- What happens if the username list iteration finishes while we have pending
authentication attempts taking place but the pairs for these attempts had been
extracted from the pair_pool? --

Normally, since the pair_pool has its elements removed and would be
empty at the time the username list iteration finishes, then there is no
way to actually know if the service needs to be moved to the services_finished
list (which should be moved there only after *ever* pair has been tested out,
including everything from the pair_pool).
To be able to account for that, we keep a separate mirror_pair_pool which holds
copies of the current pairs being tested out from the main pair_pool. Each time
a pair has been tested out fully, then we can remove that element from the
mirror_pair_pool (remember that the element from the pair_pool had already been
removed at the time it was returned from NextPair()). If it fails being tested,
then we move back that pair to the pair_pool list only (we already have a copy
at the mirror_pair_pool).
Note down, that all this happens to take care of a highly improbable case, but
which however just *might* happen one day. Also, note that every list involved
in the solution is usually really small so any iterations are not

* Fixed some bugs and end-cases.

* Began building dynamic timing engine.

* Tested ftp-module more thoroughly with multiple hosts.

* Compiled successfully ncrack under FreeBSD-7.2

--------- Priorities -------------

* Continue implementing dynamic timing engine. (this will probably be the most
complex and important part of the whole project)

* Perhaps start building smtp-module to begin seeing how differently each
protocol needs to be handled as far as timing is concerned.

* Document timing engine's internals (made it imperative this time)

-- ithilgore

Sent through the nmap-dev mailing list
Archived at http://SecLists.Org

  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]