[ntp:security] [Bug 3113] test #1

bugzilla-daemon at ntp.org bugzilla-daemon at ntp.org
Tue Sep 13 04:52:27 UTC 2016


http://bugs.ntp.org/show_bug.cgi?id=3113

Harlan Stenn <stenn at ntp.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P5                          |P2
              Group|                            |Security
                 CC|                            |mvangund at cisco.com
              Flags|                            |blocking4.2.8+
           Severity|enhancement                 |critical

--- Comment #1 from Harlan Stenn <stenn at ntp.org> 2016-09-13 04:52:27 UTC ---
TALOS-CAN-0130
CVE-YYYY-NNNN

Network Time Protocol Broadcast Mode Poll Interval Enforcement Denial of
Service Vulnerability


:: Summary

An exploitable denial of service vulnerability exists in the
broadcast mode poll interval enforcement functionality of ntpd.  To
limit abuse, ntpd restricts the rate at which each broadcast
association will process incoming packets.  ntpd will reject
broadcast mode packets that arrive before the poll interval
specified in the preceding broadcast packet expires.  A
vulnerability exists which allows remote unauthenticated attackers
to send specially crafted broadcast mode NTP packets which will
cause ntpd to reject all broadcast mode packets from legitimate NTP
broadcast servers.


:: Tested Versions

NTP 4.2.8p6


:: Product URLs

http://www.ntp.org/


:: CVSS Scores

CVSSv2: 5.0 - (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSSv3: 5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L


:: Details

In response to the NTP Deja Vu vulnerability (CVE-2015-7973),
ntp-4.2.8p6 introduced several new integrity checks on incoming
broadcast mode packets.  Upon receipt of a broadcast mode packet,
before authentication is enforced, ntpd will reject the packet if
any of the following conditions hold:

1. The packet poll value is out of bounds for the broadcast
   association, i.e.

        pkt->ppoll < peer->minpoll || pkt->ppoll > peer->maxpoll

2. The packet was received before a full poll interval has elapsed
   since the last broadcast packet was received from the packet's
   sender.  i.e. A server cannot ingress packets more frequently than
   `peer->minpoll`.

3. The packet transmit timestamp is less than the last seen
   broadcast packet transmit timestamp from the packet's sender.
   i.e. Broadcast packet transmit timestamps must be monotonically
   increasing.

The following logic is used to ensure constraint 2, which ensures
that broadcast associations will process only one incoming packet
per poll interval:

    /* ntp-4.2.8p6 ntpd/ntp_proto.c */
    1305  if (MODE_BROADCAST == hismode) {
    ...
    1341      if (  (current_time - peer->timelastrec)
    1342          < (1 << pkt->ppoll)) {
    1343          msyslog(LOG_INFO, "receive: broadcast packet from %s arrived
after %ld, not %d seconds!",
    1344              stoa(&rbufp->recv_srcadr),
    1345              (current_time - peer->timelastrec),
    1346              (1 << pkt->ppoll)
    1347              );
    1348          ++bail;
    1349      }
    ...
    1361
    1362      peer->bxmt = p_xmt;
    1363
    1364      if (bail) {
    1365          peer->timelastrec = current_time;
    1366          sys_declined++;
    1367          return;
    1368      }
    1369  }

If the time elapsed since the last broadcast packet was received
from this peer is less than the poll interval declared by the sender
(`(current_time - peer->timelastrec) < (1 << pkt->ppoll)`), the
packet will be discarded.  (A previous check ensures that
`pkt->ppoll` is within acceptable bounds.)

Unfortunately, line 1341 compares the current time against the last
time any broadcast mode packet was received with a source IP address
of the peer (`peer->timelastrec`).  In contrast to
`peer->timereceived`, which is updated only when a *clean*
(correctly authenticated and passing integrity checks) packet is
received, `peer->timelastrec` is updated by all incoming broadcast
packets including spoofed and replayed packets.

This leads to a trivial denial of service attack.  The attacker:

1. Discovers the IP address of the victim's broadcast server.
   e.g. Send the victim a client mode NTP packet and discover the
   broadcast server from the refid field of the victim's reply.

2. At least once per poll period, send the victim a spoofed
   broadcast mode packet from the broadcast server.  This will set
   `peer->timelastrec = current_time` such that, when a legitimate
   packet is received, it will appear to have been received too
   early (`(current_time - peer->timelastrec) < (1 << pkt->ppoll)`)
   and will be discarded.

    - The attacker does not need to be on the same subnet as the
      victim.  The attacker can address the spoofed broadcast NTP
      packet directly to the victim's IP address.

    - The attacker can choose any reasonably small estimate for the
      poll period.  Because the `peer->timelastrec` update happens
      even when a packet fails the poll period check, there is no
      penalty for sending packets too frequently.

To prevent this vulnerability, ntpd should only discard packets
broadcast packets when less than one poll interval has elapsed since
the last legitimate packet has been received (`peer->timereceived`).


:: Mitigation

There is no workaround for this issue.  Because the vulnerable logic
is executed before authentication is enforced, authentication and
the `restrict notrust` ntpd.conf directive have no effect.  An
attacker can bypass `notrust` restrictions by sending incorrectly
authenticated packets.

In order to succeed in an attack, the attacker must send at least
one spoofed packet per poll period.  Therefore observing more than
one NTP broadcast packet from the same sender address per poll
period indicates a possible attack.

The following patch can be used to fix this vulnerability:

    From 8522882496d3df2bd764de6d8f7afac4a8d84006 Mon Sep 17 00:00:00 2001
    From: Matthew Van Gundy <mvangund at cisco.com>
    Date: Fri, 5 Feb 2016 17:38:32 -0500
    Subject: [PATCH] Fix unauthenticated broadcast mode denial of service
(peer->timelastrec)

    Drop packets if they arrive less than one poll interval since the last
    **clean** packet received on an association.  If we compare against the
    last time that *any* packet was received, even one that will be dropped
    for failing integrity checks, an attacker can DoS the association by
    sending incorrectly authenticated packets or replaying old packets to
    keep bumping the peer->timelastrec timer forward.
    ---
     include/ntp.h    |  4 +++-
     ntpd/ntp_proto.c | 13 +++++++++++--
     2 files changed, 14 insertions(+), 3 deletions(-)

    diff --git a/include/ntp.h b/include/ntp.h
    index 6a4e9aa..cbf6cec 100644
    --- a/include/ntp.h
    +++ b/include/ntp.h
    @@ -383,7 +383,9 @@ struct peer {
       * Statistic counters
       */
      u_long  timereset;  /* time stat counters were reset */
    - u_long  timelastrec;  /* last packet received time */
    + u_long  timelastrec;  /* last packet received time (may
    +                                 * include spoofed, replayed, or other
    +                                 * invalid packets) */
      u_long  timereceived; /* last (clean) packet received time */
      u_long  timereachable;  /* last reachable/unreachable time */

    diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c
    index ad45409..1ea5cee 100644
    --- a/ntpd/ntp_proto.c
    +++ b/ntpd/ntp_proto.c
    @@ -1338,11 +1338,20 @@ receive(
            ++bail;
          }

    -     if (  (current_time - peer->timelastrec)
    +     /*
    +      * Ensure that at least one poll interval has
    +      * elapsed since the last **clean** packet was
    +      * received.  We limit the check to **clean**
    +      * packets to prevent replayed packets and
    +      * incorrectly authenticated packets, which
    +      * we'll discard, from being used to create a
    +      * denial of service condition.
    +      */
    +     if (  (current_time - peer->timereceived)
              < (1 << pkt->ppoll)) {
            msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after
%ld, not %d seconds!",
              stoa(&rbufp->recv_srcadr),
    -         (current_time - peer->timelastrec),
    +         (current_time - peer->timereceived),
              (1 << pkt->ppoll)
              );
            ++bail;
    --
    2.5.2


:: Credit

Discovered by Matthew Van Gundy of Cisco ASIG.


:: Timeline

2016-09-13 - Vendor Disclosure
YYYY-MM-DD - Public Release

-- 
Configure bugmail: http://bugs.ntp.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


More information about the security mailing list