Nmap Development mailing list archives

Re: NSE script for OS identification / clarification using Netbios/SMB


From: Brandon Enright <bmenrigh () ucsd edu>
Date: Fri, 30 Nov 2007 04:25:50 +0000

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

On Thu, 29 Nov 2007 16:29:53 -0800
Fyodor <fyodor () insecure org> wrote:

On Thu, Nov 29, 2007 at 01:47:01AM +0000, Brandon Enright wrote:

Cool.  This script is a prime candidate for replacing my nbstat.nse
script.  It would be nice to get all of the NetBIOS and SMB functions
all in one place (a library?) so that scripts like this or mine are as
simple and calling functions to generate the packet, send, and parse it.

Both Nessus and Metasploit have libraries like this that make writing
arbitrary Windows scripts much easier.

Hi Brandon.  Such a library would likely be valuable.  It could be
written as a Lua module or in C.

I'm not very familiar with NetBIOS/SMB.  Do you thin we should keep
both scripts (e.g. they each provide some unique functionality) or
only have one of them (e.g. the functionality is redundant)?  And if
only one, which do you thin should be kept?

Cheers,
-F


For the short term I don't think anything needs to happen.  In the not too
long term though, more generic NetBIOS packet constructing and parsing
functions should be made and the nbstat functionality should be rolled into
osversion.  We could call the union of these two netbiosinfo.nse or
something like that.  I'm perfectly happy to do what I can to this end in
the coming days/weeks.

As far as I'm concerned, NetBIOS/SMB is black magic.  My work on nbstat was
10% insight, 89% brute-force, and 1% luck.  My understanding of these
protocols is limited to broad generalities only.

The reason I suggested that the scripts either be combined or a library
made is due to their similarity (and the relative lack of quality of nbstat
versus osversion).

Take for example the similarity in UDP packet construction (ignore
difference in base):

osversion:
string.char(0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 
            0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
            0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 
            0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 0x00, 0x00)

nbstat:
status, result = socket:send(
        "\003\097\000\016\000\001\000\000" ..
        "\000\000\000\000\032\067\075\065" ..
        "\065\065\065\065\065\065\065\065" ..
        "\065\065\065\065\065\065\065\065" ..
        "\065\065\065\065\065\065\065\065" ..
        "\065\065\065\065\065\000\000\033" ..
        "\000\001")

It would  be really nice to have a rather generic
construct_netbios_payload(...) library function where the packet payload
can be put together as fields rather than one large string.  A function
like that would be able to construct either of these payloads and the
(few) differences between theme would be much more apparent.

Also take the OSVersion detction versus name types code in the two scripts:

osversion:
ntgeneric = string.find(nametype, 0x44,0x00) 
ntvista = string.find(nametype, 0x04, 0x00)
ntunix = string.find(nametype, 0x64, 0x00)

nbstat:
if (nameflags == "\003\068\000" or
    nameflags == "\003\004\000") then

It would be nice to have a more generic NetBIOS response parser to return
all of this junk in a generic data structure.  Parsing these packets is so
bug-prone and hard to follow it should be outlawed.

OSVersion provide the incredibly useful name encoder

- -- This function encodes the workstation share name returned from the
- -- UDP wildcard NetBIOS query. Each character from the NetBIOS share
- -- name is encoded/mangled using a special algorithm.
...snip...
encode = function(name)
...snip...


In the long term, setting aside political, technical or licensing issues, we
should look at Metasploit and Nessus's NetBIOS/SMB libraries to see if we
can either port or reproduce them.

Back in August of 2006 Fyodor asked someone to look into writing a MS06-040
check (http://seclists.org/nmap-dev/2006/q3/0203.html).  I immediately
thought to myself "oh, I should be able to do this" and started looking at
the Metasploit code that does it
(http://metasploit.com/projects/Framework/modules/exploits/netapi_ms06_040.pm).
Amazingly, the Metasploit module does almost no work at all.  Most of the
heavy lifting is done with Pex::DCERPC like so:

my $dce = Pex::DCERPC->new(
        'handle'      => $handle,
        'username'    => $self->GetVar('SMBUSER'),
        'password'    => $self->GetVar('SMBPASS'),
        'domain'      => $self->GetVar('SMBDOM'),
        'fragsize'    => $self->GetVar('FragSize'),
        'bindevasion' => $self->GetVar('BindEvasion'),
        'directsmb'   => $self->GetVar('DirectSMB'),
);

Needless to say, the Pex::DCERPC implementation is complicated.  I soon
realized that the amount of work required to implement a check for MS06-040
was beyond what I could do in a few days.  I suspect others realized the
same thing since a check was not written.

If we do end up getting a library of NetBIOS and SMB functions written the
floodgates to cool Windows scripts will be wide open.

Brandon

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQFHT5DOqaGPzAsl94IRAssLAKClQMLOGJziFCpcHkhniOanOyNTCACfW4Md
IQMvEYm+yrZQK8gmGOdf7BY=
=6U2i
-----END PGP SIGNATURE-----

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


Current thread: