Difference between revisions of "Nbquery"

From SkullSecurity
Jump to: navigation, search
(New page: Command for sending out NetBIOS queries. There are a number of query types available in NetBIOS, and this program is capable of sending any of them. The response (or lack thereof) will gi...)
 
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
Command for sending out NetBIOS queries.
+
==Intro==
 +
[[nbquery]] is capable of sending out any type of NetBIOS request. These
 +
request types include:
 +
* NB
 +
* NBSTAT
 +
* Register
 +
* Refresh
 +
* Release
 +
* Conflict
 +
* Demand
  
There are a number of query types available in NetBIOS, and this program is
+
More on what each of them do below.
capable of sending any of them. The response (or lack thereof) will give you
+
information about the Windows-based or Samba systems in the area.
+
  
 
One thing worth noting about the NetBIOS protocol is that it is nearly
 
One thing worth noting about the NetBIOS protocol is that it is nearly
Line 9: Line 16:
 
library to * build requests. The primary differences between NetBIOS and DNS
 
library to * build requests. The primary differences between NetBIOS and DNS
 
are:
 
are:
- How names are encoded (NetBIOS names are encoded before being sent),
+
* How names are encoded (NetBIOS names are encoded before being sent),
- How the flags are used (NetBIOS has a different set of flags), and
+
* How the flags are used (NetBIOS has a different set of flags), and
- How requests are sent (NetBIOS is capable of broadcasting requests
+
* How requests are sent (NetBIOS is capable of broadcasting requests
  
The DNS library is more than capable of dealing with these differences.
+
The 'dns' library I wrote can easily deal with these differences, so it is
 +
used for building dns queries.
  
Now, without further ado, let's take a look at the query types available:
+
==Usage==
 +
<pre>
 +
Usage: ./nbquery [options] <action>
 +
-h --help
 +
    Help (this screen).
 +
-t --target <targetip>
 +
    The address to send the request. For simple NB requests to the local
 +
    network, the default (broadcast; '255.255.255.255') works. If you want to
 +
    get full information (-t NBSTAT) or get information for a non-local network,
 +
    this should be set to the target address.
 +
-s --source <sourceip>
 +
-p --port <port>
 +
    Choose a port besides the default (137). Not generally useful, since Windows
 +
    runs NetBIOS Name Service on UDP/137.
 +
-w --wait <ms>
 +
    The amount of time, in milliseconds, to wait for repsonses. Default: 500ms.
 +
-V --version
 +
    Print version and exit.
 +
Actions (must choose exactly one):
 +
--nb [name[:<suffix>]]
 +
    Query for a NetBIOS name. Queries for any name by default ('*'). If you're
 +
    looking for a specific server, say, 'TEST01', set the name to that to that
 +
    name. You can optionally add the one-byte suffix after the name, such as
 +
    'TEST01:03', but that isn't too common
 +
--nbstat [name[:<suffix>]]
 +
    Query for a NetBIOS status. Format is the same as --nb.
 +
--register <name>
 +
    Send out a notice that you're going to be using the given name.
 +
    If any systems are already using the name, they will respond with a
 +
    conflict.
 +
--refresh <name>
 +
    Send out a notice that you're refreshing your use of a name. I haven't seen
 +
    this provoke a response before, so it might be useless.
 +
--release <name>
 +
    Send a notice that you're done using a name. If somebody else owns that
 +
    name, they will generally return an error.
 +
--conflict <name>
 +
    Sent immediately after somebody else registers, this informs the system
 +
    that they aren't the rightful owner of a name and they should not use it.
 +
    To automate this, see the 'nbsniff' tool with --poison.
 +
--demand <name>
 +
    Demands that another system releases the name. Typically isn't implemented
 +
    for security reasons. Again, see 'nbsniff --poison'.
 +
</pre>
  
NB (--nb)
+
==NB==
    An NB query will broadcast a request for a certain name (or the wildcard)
+
A standard NB (NetBIOS) query, sent when --nb is passed can do several
    to the target (UDP/137 to, typically, the broadcast address). Any hosts
+
things:
    on that network with matching names will respond.
+
# Ask who owns a particular name
 +
# Ask who is on the local segment (doesn't work against all hosts)
 +
# Ask if a particular system has a name
  
    --nb requests are the target of [[nbsniff]]'s --poison attack, so sending
+
The first two points require a broadcast -- by default, we broadcast to the
    out --nb queries is a great way to test nbsniff.
+
global broadcast address, 255.255.255.255, but I noticed that that doesn't
 +
always work, so you may need to pass your local broadcast address,
 +
"-t x.x.x.255" (where "x.x.x" is the start of your address).
  
NBSTAT (--nbstat)
+
Asking who owns a particular name is a technique used by Windows when it
    An NBSTAT query is a request to a single host for its status. It returns
+
fails to find a host in DNS. This allows it to find hosts on the local
    all names it has registered, as well as some other targeted information
+
network with a given name. Broadcasting for a name is obviously a bad idea;
    (such as, on Windows, its MAC address).
+
more on that in [[nbsniff]].
  
Register, Renew, Release (--register, --renew, --release)
+
Here's how it looks on nbquery:
    These are queries typically used by systems when they are starting up
+
<pre>
    or shutting down. If you try to register or release an address that's
+
$ ./nbquery --nb=WINDOWSXP
    already in use, the host using it will respond with "error: active".
+
Creating a UDP socket.
    I haven't seen --renew evoke a response.
+
Sending query.
 +
ANSWER query: (NB:WINDOWSXP      <00|workstation>): success, IP: 192.168.1.106, TTL: 300000s
  
    One of the most useful purposes of these commands is actually to test
+
$ ./nbquery --nb=VISTA -t 192.168.1.255
    [[nbsniff]]'s --conflict command. When using --conflict, nbsniff will
+
Creating a UDP socket.
    send "error: active" responses to any number of names.
+
Sending query.
 +
ANSWER query: (NB:VISTA          <00|workstation>): success, IP: 192.168.1.102, TTL: 300000s
 +
</pre>
  
Conflict, Demand (--conflict, --demand)
+
('WINDOWSXP' and 'VISTA' are what I named my test systems)
    Conflict and demand are ways of asking other hosts to relinquish a
+
 
    NetBIOS name. As far as I know, no modern implementation will honour
+
The second use is asking who is on a local network. I've found that this only
    them.
+
works against certain systems; mostly Windows 2000. But here's how it's
 +
done:
 +
<pre>
 +
$ ./nbquery --nb
 +
Creating a UDP socket.
 +
Sending query.
 +
ANSWER query: (NB:*<00|workstation>): success, IP: 192.168.1.109, TTL: 300000s
 +
</pre>
 +
 
 +
Finally, asking if somebody owns a name is silly, but it can be done using
 +
the -t argument:
 +
<pre>
 +
$ ./nbquery --nb=WINDOWSXP -t 192.168.1.106
 +
Creating a UDP socket.
 +
Sending query.
 +
ANSWER query: (NB:WINDOWSXP      <00|workstation>): success, IP: 192.168.1.106, TTL: 300000s
 +
</pre>
 +
 
 +
==NBSTAT==
 +
NBSTAT goes further than NetBIOS. It is targeted against a specific host
 +
and asks that host for a list of all names it thinks it owns. The Windows
 +
program nbtstat does this, as well as the opensource nbtscan program.
 +
 
 +
This usage is pretty simple:
 +
<pre>
 +
$ ./nbquery --nbstat -t 192.168.1.106
 +
Creating a UDP socket.
 +
Sending query.
 +
NBSTAT response: Received 4 names; success (MAC: 00:0c:29:07:69:b0)
 +
ANSWER: (NBSTAT:*<00|workstation>): WINDOWSXP<00> <unique><active> (0x0400)
 +
ANSWER: (NBSTAT:*<00|workstation>): WINDOWSXP<20> <unique><active> (0x0400)
 +
ANSWER: (NBSTAT:*<00|workstation>): WORKGROUP<00> <group><active> (0x8400)
 +
ANSWER: (NBSTAT:*<00|workstation>): WORKGROUP<1e> <group><active> (0x8400)
 +
 
 +
ron@ankh:~/tools/nbtool$ ./nbquery --nbstat -t 192.168.1.109
 +
Creating a UDP socket.
 +
Sending query.
 +
NBSTAT response: Received 6 names; success (MAC: 00:0c:29:f5:81:bd)
 +
ANSWER: (NBSTAT:*<00|workstation>): WINDOWS2000<00> <unique><active> (0x0400)
 +
ANSWER: (NBSTAT:*<00|workstation>): WINDOWS2000<03> <unique><active> (0x0400)
 +
ANSWER: (NBSTAT:*<00|workstation>): SKULLSECURITY<00> <group><active> (0x8400)
 +
ANSWER: (NBSTAT:*<00|workstation>): RON<03> <unique><active> (0x0400)
 +
ANSWER: (NBSTAT:*<00|workstation>): SKULLSECURITY<1e> <group><active> (0x8400)
 +
</pre>
 +
 
 +
==Register, Renew, Release==
 +
The register, renew, and release queries are all very similar -- they're
 +
designed to emulate the actions that Windows itself takes while booting
 +
and shutting down.
 +
 
 +
When a Windows computer boots, the first thing it does is send out a
 +
'register' request for its own name. It does this to let the other systems
 +
know that it intends to use that name. If another system already has that
 +
name, it sends back a conflict and the new system will give it up until
 +
the next boot. More on conflicts in [[nbsniff]].
 +
 
 +
The register and release commands (activated by --register and --release)
 +
will generally provoke a response if a system is already using a name,
 +
whereas renew, in my experience, has never provokes a response.
 +
 
 +
Here is an example of the three of them, in the typical order that Windows
 +
would send them:
 +
<pre>
 +
$ ./nbquery --register=WINDOWS2000
 +
Creating a UDP socket.
 +
Sending query.
 +
ANSWER query: (NB:WINDOWS2000    <00|workstation>): error: active, IP: 192.168.1.109, TTL: 0s
 +
 
 +
ron@ankh:~/tools/nbtool$ ./nbquery --refresh=WINDOWSXP
 +
Creating a UDP socket.
 +
Sending query.
 +
Wait time has elapsed.
 +
 
 +
ron@ankh:~/tools/nbtool$ ./nbquery --release=VISTA
 +
Creating a UDP socket.
 +
Sending query.
 +
ANSWER query: (NB:VISTA          <00|workstation>): error: name not found, IP: 0.0.0.0, TTL: 0s
 +
</pre>
 +
 
 +
Note that the --register provoked "error: active", whereas --release
 +
provoked "error: name not found".
 +
 
 +
As before, WINDOWS2000, WINDOWSXP, and VISTA are the namef of my test
 +
systems.
 +
 
 +
One of those best uses of these programs is to test [[nbsniff]].
 +
 
 +
==Conflict, Demand==
 +
Conflict and demand (activated with --conflict and --demand) are ways of
 +
asking hosts to relinquish their name. Neither are supported by any modern
 +
NetBIOS implementation, though; I added them for completeness.
 +
 
 +
--demand is actually the same as --release, except that --demand expects
 +
to be unicast and --release expects to be broadcast.

Latest revision as of 16:02, 21 February 2010

Intro

nbquery is capable of sending out any type of NetBIOS request. These request types include:

  • NB
  • NBSTAT
  • Register
  • Refresh
  • Release
  • Conflict
  • Demand

More on what each of them do below.

One thing worth noting about the NetBIOS protocol is that it is nearly identical to DNS. In fact, it's close enough that this script uses the DNS library to * build requests. The primary differences between NetBIOS and DNS are:

  • How names are encoded (NetBIOS names are encoded before being sent),
  • How the flags are used (NetBIOS has a different set of flags), and
  • How requests are sent (NetBIOS is capable of broadcasting requests

The 'dns' library I wrote can easily deal with these differences, so it is used for building dns queries.

Usage

Usage: ./nbquery [options] <action>
 -h --help
    Help (this screen).
 -t --target <targetip>
    The address to send the request. For simple NB requests to the local
    network, the default (broadcast; '255.255.255.255') works. If you want to
    get full information (-t NBSTAT) or get information for a non-local network,
    this should be set to the target address.
 -s --source <sourceip>
 -p --port <port>
    Choose a port besides the default (137). Not generally useful, since Windows
    runs NetBIOS Name Service on UDP/137.
 -w --wait <ms>
    The amount of time, in milliseconds, to wait for repsonses. Default: 500ms.
 -V --version
    Print version and exit.
Actions (must choose exactly one):
 --nb [name[:<suffix>]]
    Query for a NetBIOS name. Queries for any name by default ('*'). If you're
    looking for a specific server, say, 'TEST01', set the name to that to that
    name. You can optionally add the one-byte suffix after the name, such as
    'TEST01:03', but that isn't too common
 --nbstat [name[:<suffix>]]
    Query for a NetBIOS status. Format is the same as --nb.
 --register <name>
    Send out a notice that you're going to be using the given name.
    If any systems are already using the name, they will respond with a
    conflict.
 --refresh <name>
    Send out a notice that you're refreshing your use of a name. I haven't seen
    this provoke a response before, so it might be useless.
 --release <name>
    Send a notice that you're done using a name. If somebody else owns that
    name, they will generally return an error.
 --conflict <name>
    Sent immediately after somebody else registers, this informs the system
    that they aren't the rightful owner of a name and they should not use it.
    To automate this, see the 'nbsniff' tool with --poison.
 --demand <name>
    Demands that another system releases the name. Typically isn't implemented
    for security reasons. Again, see 'nbsniff --poison'.

NB

A standard NB (NetBIOS) query, sent when --nb is passed can do several things:

  1. Ask who owns a particular name
  2. Ask who is on the local segment (doesn't work against all hosts)
  3. Ask if a particular system has a name

The first two points require a broadcast -- by default, we broadcast to the global broadcast address, 255.255.255.255, but I noticed that that doesn't always work, so you may need to pass your local broadcast address, "-t x.x.x.255" (where "x.x.x" is the start of your address).

Asking who owns a particular name is a technique used by Windows when it fails to find a host in DNS. This allows it to find hosts on the local network with a given name. Broadcasting for a name is obviously a bad idea; more on that in nbsniff.

Here's how it looks on nbquery:

$ ./nbquery --nb=WINDOWSXP
Creating a UDP socket.
Sending query.
ANSWER query: (NB:WINDOWSXP      <00|workstation>): success, IP: 192.168.1.106, TTL: 300000s

$ ./nbquery --nb=VISTA -t 192.168.1.255
Creating a UDP socket.
Sending query.
ANSWER query: (NB:VISTA          <00|workstation>): success, IP: 192.168.1.102, TTL: 300000s

('WINDOWSXP' and 'VISTA' are what I named my test systems)

The second use is asking who is on a local network. I've found that this only works against certain systems; mostly Windows 2000. But here's how it's done:

$ ./nbquery --nb
Creating a UDP socket.
Sending query.
ANSWER query: (NB:*<00|workstation>): success, IP: 192.168.1.109, TTL: 300000s

Finally, asking if somebody owns a name is silly, but it can be done using the -t argument:

$ ./nbquery --nb=WINDOWSXP -t 192.168.1.106
Creating a UDP socket.
Sending query.
ANSWER query: (NB:WINDOWSXP      <00|workstation>): success, IP: 192.168.1.106, TTL: 300000s

NBSTAT

NBSTAT goes further than NetBIOS. It is targeted against a specific host and asks that host for a list of all names it thinks it owns. The Windows program nbtstat does this, as well as the opensource nbtscan program.

This usage is pretty simple:

$ ./nbquery --nbstat -t 192.168.1.106
Creating a UDP socket.
Sending query.
NBSTAT response: Received 4 names; success (MAC: 00:0c:29:07:69:b0)
ANSWER: (NBSTAT:*<00|workstation>): WINDOWSXP<00> <unique><active> (0x0400)
ANSWER: (NBSTAT:*<00|workstation>): WINDOWSXP<20> <unique><active> (0x0400)
ANSWER: (NBSTAT:*<00|workstation>): WORKGROUP<00> <group><active> (0x8400)
ANSWER: (NBSTAT:*<00|workstation>): WORKGROUP<1e> <group><active> (0x8400)

ron@ankh:~/tools/nbtool$ ./nbquery --nbstat -t 192.168.1.109
Creating a UDP socket.
Sending query.
NBSTAT response: Received 6 names; success (MAC: 00:0c:29:f5:81:bd)
ANSWER: (NBSTAT:*<00|workstation>): WINDOWS2000<00> <unique><active> (0x0400)
ANSWER: (NBSTAT:*<00|workstation>): WINDOWS2000<03> <unique><active> (0x0400)
ANSWER: (NBSTAT:*<00|workstation>): SKULLSECURITY<00> <group><active> (0x8400)
ANSWER: (NBSTAT:*<00|workstation>): RON<03> <unique><active> (0x0400)
ANSWER: (NBSTAT:*<00|workstation>): SKULLSECURITY<1e> <group><active> (0x8400)

Register, Renew, Release

The register, renew, and release queries are all very similar -- they're designed to emulate the actions that Windows itself takes while booting and shutting down.

When a Windows computer boots, the first thing it does is send out a 'register' request for its own name. It does this to let the other systems know that it intends to use that name. If another system already has that name, it sends back a conflict and the new system will give it up until the next boot. More on conflicts in nbsniff.

The register and release commands (activated by --register and --release) will generally provoke a response if a system is already using a name, whereas renew, in my experience, has never provokes a response.

Here is an example of the three of them, in the typical order that Windows would send them:

$ ./nbquery --register=WINDOWS2000
Creating a UDP socket.
Sending query.
ANSWER query: (NB:WINDOWS2000    <00|workstation>): error: active, IP: 192.168.1.109, TTL: 0s

ron@ankh:~/tools/nbtool$ ./nbquery --refresh=WINDOWSXP
Creating a UDP socket.
Sending query.
Wait time has elapsed.

ron@ankh:~/tools/nbtool$ ./nbquery --release=VISTA
Creating a UDP socket.
Sending query.
ANSWER query: (NB:VISTA          <00|workstation>): error: name not found, IP: 0.0.0.0, TTL: 0s

Note that the --register provoked "error: active", whereas --release provoked "error: name not found".

As before, WINDOWS2000, WINDOWSXP, and VISTA are the namef of my test systems.

One of those best uses of these programs is to test nbsniff.

Conflict, Demand

Conflict and demand (activated with --conflict and --demand) are ways of asking hosts to relinquish their name. Neither are supported by any modern NetBIOS implementation, though; I added them for completeness.

--demand is actually the same as --release, except that --demand expects to be unicast and --release expects to be broadcast.