Nmap Development mailing list archives

Re: [NSE] NTP Peer Listing


From: David Fifield <david () bamsoftware com>
Date: Thu, 20 May 2010 12:58:07 -0600

On Wed, May 19, 2010 at 11:55:36PM +0100, jah wrote:
On 15/05/2010 03:50, David Fifield wrote:

PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response
| ntp-monlist: discovered internal addresses:
| 127/8 (1)
| and discovered 1 alternative address for the target:
| 192.168.0.21
| and collected 4 IPv4 addresses:
|_66.79.152.35    69.36.241.112   169.229.70.64   208.77.19.5
| ntp-peers:
|   Private Peers (1)
|     127.0.0.1:56189
|   Public Peers (4)
|     66.79.152.35:123
|     69.36.241.112:123
|     169.229.70.64:123
|_    208.77.19.5:123

I like how both scripts separate out the private and public addresses. I
really like the bit "discovered 1 alternative address for the target" in
ntp-monlist. Do you get the netmask back from the NTP server in "127/8"
or is that inferred?

We don't get the netmask back; "127/8" is just shorthand for 127.0.0.0/8
loopback assignment and is one of the strings returned as the second
value from ipOps.isPrivate when the first return value is true. The
'internal address' summary was intended to summarise the different
private (or special use) addresses revealed by the monlist data and thus
avoid printing them out - my reasoning was that these addresses are only
slightly interesting when the target is somewhere across the internet. 
I wasn't really thinking about scanning your internal ntp servers where
this information might be more useful longhand and I think I
underestimated the interestingness of private addresses for a target
across the internet.  So this summary would be better replaced with the
full listing of private and special use addresses as in Mak's script output.

I agree, sounds good.

Here's the result from running against the first of the public peers
above (the only one that produced any output). I also included the
output of the Metasploit script.

PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response
| ntp-monlist: collected 600 IPv4 addresses:
| 4.78.155.130    66.151.63.26    72.184.160.70   140.182.214.208
| 12.21.127.78    66.152.137.15   72.203.133.69   141.156.191.175
... 146 lines ...
| 66.151.63.14    72.159.219.194  137.113.118.26  217.114.222.89
|_66.151.63.17    72.169.122.140  137.113.118.28  222.66.126.163
| ntp-peers:
|   Private Peers (0)
|   Public Peers (474)
|     4.78.155.130:11308
|     12.21.127.78:123
... 470 lines ...
|     217.114.222.89:123
|_    222.66.126.163:60514

msf auxiliary(ntp_monlist) > set RHOSTS 66.79.152.35
RHOSTS => 66.79.152.35
msf auxiliary(ntp_monlist) > run
[*] Sending probes to 66.79.152.35->66.79.152.35 (1 hosts)
[*] 66.79.152.35:123 96.245.144.224:123 (66.79.152.35)
[*] 66.79.152.35:123 66.83.13.6:123 (66.79.152.35)
... 596 lines ...
[*] 66.79.152.35:123 206.169.68.114:62582 (66.79.152.35)
[*] 66.79.152.35:123 69.7.96.116:6634 (66.79.152.35)
[*] Scanned 1 of 1 hosts (100% complete)

The first thing I see is that ntp-peers gets less than 600 records. This
is reproducible. But when I run it by itself, it gets the maximum of 600.

About the source port numbers: is it possible that these distinguish
between downstream (port 123) and upstream servers (not 123)?
  
I've been looking into host classification because monlist records also
contain the NTP mode and version fields from datagrams received. I
thought it might be possible to classify discovered hosts into clients,
peers and servers and that this might be useful information.  Here's the
information we can infer about a discovered host from the ntp mode field:

Mode 1 - Host is associated with the target as a symmetric active Peer.
Mode 2 - Host is associated with the target as a symmetric passive Peer.
Mode 3 - Host is a Client of the target.
Mode 4 - Host is a Server for the target (the target is configured to
poll the host in client mode).
Mode 5 - Broadcast/Multicast - the value of the source address field of
Mode 5 records is the broad/multicasting interface of the host and the
value of the destination address field is the broadcast address from
which the target accepts broad/multicasted messages.
Mode 6 - Host has sent requests to the target in Control Mode (e.g. ntpq
-np <our_target> )
Mode 7 - Host has sent requests to the target in Private Mode (e.g.
ntpdc -n -c monlist <our_target>)

To muddy the waters a little, the windows time service (W32Time) (by
default on stand-alone workstations and servers) syncs with configured
time servers in symmetric active mode (i.e. NTP Mode 1) in exactly the
same way as Peers.  This prevents us from assuming that discovered hosts
who sent a Mode 1 packet to the target are all Peers.  We could request
a peer list from the target at this point; the peer list contains
records of configured ntp associations (which excluded clients) and this
would allow us to distinguish between Peers and Clients.

The value of the version field tells us the version of the last NTP
message sent by a host to our target.  I don't think this is important
information.

The source port isn't greatly interesting either: messages with a source
port of 123 could be from a client, server or peer; messages with a
source port of something other than 123 are very often clients sending
Mode 3 to the target (perhaps ntpd started with --unprivileged), but
also the target could have been queried (locally or remotely) using
tools such as ntpq and ntpdc.

There's one other vaguely interesting field in the monlist records:
flags - which shows whether a host sent a message to the target Unicast,
Broadcast or Multicast.  This allows us to distinguish between Mode 5
broadcast and Mode 5 multicast associations and to interpret the
destination address as either a broadcast or multicast address to which
the target listens.

To summarise then:

By sending a monlist request and parsing the response we can classify
hosts associated with the target into 4 groups which can be divided into
public and private hosts:
Servers
Peers or Clients
Clients
Others (possibly administrative hosts and probably including the
external address of the Nmap user)
We can also discover alternative addresses for the target (other
interfaces - be they public or private), broadcast and multicast
addresses the target listens to.

By sending an additional peerlist request and parsing the response we
can divide the 'Peers or Clients' group into Peers and Clients.  We can
also discover which of the peers or servers the target was synchronised
to at the time the peer list response was generated.

The question is how to organise this information and I'm leaning toward
something like the following:

PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response
| ntp-monlist:
|   Target is Synchronised with:
|     72.159.219.194
|   Alternative Target Interfaces (2)
|     192.168.0.21
|     2e0e::1
|   Private Servers (0)
|   Public Servers (4)
|     66.151.63.14    72*159*219*194  137.113.118.26  217.114.222.89
|   Private Peers or Clients(1)
|     10.0.0.1
|   Public Peers or Clients(4)
|     4.78.155.130    66.151.63.26    72.184.160.70   140.182.214.208
|   Private Clients (1)
|     127.0.0.1
|   Public Clients (590)
|     66.79.152.35    69.36.241.112   169.229.70.64   208.77.19.5
... more lines ...
|     66.151.63.17    72.169.122.140  137.113.118.28  222.66.126.163
|     2e0f::1 2e0f:76af:f0c3:2e0f:76af:f0c3:2e0f:76af 2e10::1
|_    2e10:76af:f0c3:2e0f:76af:f0c3:2e0f:76af

which is the output seen if we didn't follow-up with a peers list
request - the following is with the peer list information:

PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response
| ntp-monlist:
|   Target is Synchronised with:
|     72.159.219.194
|   Alternative Target Interfaces (2)
|     192.168.0.21
|     2e0e::1
|   Target listens to Broadcast Addresses (1)
|     192.168.0.255
|   Private Servers (0)
|   Public Servers (4)
|     66.151.63.14    72.159.219.194  137.113.118.26  217.114.222.89
|   Private Peers (1)
|     10.0.0.1
|   Public Peers (0)
|   Private Clients (1)
|     127.0.0.1
|   Public Clients (594)
|     66.79.152.35    69.36.241.112   169.229.70.64   208.77.19.5
... more lines ...
|     66.151.63.17    72.169.122.140  207.113.118.28  222.66.126.163
|     2e0f::1 2e0f:76af:f0c3:2e0f:76af:f0c3:2e0f:76af 2e10::1
|_    2e10:76af:f0c3:2e0f:76af:f0c3:2e0f:76af

This output is outstanding. I think I understand the distinctions you've
outlined. I'd be very happy with either of these examples.

Is "72*159*219*194" with the *s supposed to mean something?

I prefer that the first commit of this script not write to a file. With
four addresses per row, we're looking at about 150 lines of output max,
which is big not but not that big.

Do you mean we should omit write-to-file functionality even as currently
implemented in ntp-monlist (as an option requiring a script arg)?

Yes. I kind of want to see that as a separate commit, even if it's right
away. The reason being that we might want to do this sort of thing with
other scripts and I want to see how much code it is.

Overall I prefer the clarity of ntp-peers over ntp-monlist, but I much
appreciate the protocol documentation in ntp-monlist.

I think the proposal (above) for output addresses output clarity?

No, I mean in the source code. 200 lines versus 500 lines matter, and I
find ntp-peers easier to understand than ntp-monlist. This is another
reason I want the file output left out of the initial commit and for you
to check out the pcap issue, to better compare these in terms of similar
features.

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


Current thread: