From: Harlan Stenn Date: Mon, 11 Jan 2016 11:02:53 +0000 (-0800) Subject: [Sec 2935] Deja Vu: Replay attack on authenticated broadcast mode. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad22c17c62f0e8c9b8c70078574ca71c12d01f0d;p=thirdparty%2Fntp.git [Sec 2935] Deja Vu: Replay attack on authenticated broadcast mode. bk: 56938bddZ082rJR2isSc8bTl_6L3Mw --- diff --git a/ChangeLog b/ChangeLog index 304bd85ab..8fcfb7ee7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ --- + +* [Sec 2935] Deja Vu: Replay attack on authenticated broadcast mode. HStenn. +* Make leapsec_query debug messages less verbose. Harlan Stenn. +--- (4.2.8p5) 2016/01/07 Released by Harlan Stenn * [Sec 2956] small-step/big-step. Close the panic gate earlier. HStenn. diff --git a/include/ntp.h b/include/ntp.h index adf017cfb..25f681001 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -350,6 +350,7 @@ struct peer { l_fp dst; /* destination timestamp */ l_fp aorg; /* origin timestamp */ l_fp borg; /* alternate origin timestamp */ + l_fp bxmt; /* most recent broadcast transmit timestamp */ double offset; /* peer clock offset */ double delay; /* peer roundtrip delay */ double jitter; /* peer jitter (squares) */ diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index f7704722a..e45d48e21 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -1157,6 +1157,7 @@ receive( } else { peer->delay = sys_bdelay; + peer->bxmt = p_xmt; } break; } @@ -1177,6 +1178,7 @@ receive( sys_restricted++; return; /* ignore duplicate */ } + peer->bxmt = p_xmt; #ifdef AUTOKEY if (skeyid > NTP_MAXKEY) crypto_recv(peer, rbufp); @@ -1286,6 +1288,70 @@ receive( return; } #endif /* AUTOKEY */ + + if (MODE_BROADCAST == hismode) { + u_char poll; + int bail = 0; + + DPRINTF(2, ("receive: PROCPKT/BROADCAST: prev pkt %ld seconds ago, ppoll: %d, %d secs\n", + (current_time - peer->timelastrec), + peer->ppoll, (1 << peer->ppoll) + )); + /* Things we can check: + * + * Did the poll interval change? + * Is the poll interval in the packet in-range? + * Did this packet arrive too soon? + * Is the timestamp in this packet monotonic + * with respect to the previous packet? + */ + + /* This is noteworthy, not error-worthy */ + if (pkt->ppoll != peer->ppoll) { + msyslog(LOG_INFO, "receive: broadcast poll from %s changed from %ud to %ud", + stoa(&rbufp->recv_srcadr), + peer->ppoll, pkt->ppoll); + } + + poll = min(peer->maxpoll, + max(peer->minpoll, pkt->ppoll)); + + /* This is error-worthy */ + if (pkt->ppoll != poll) { + msyslog(LOG_INFO, "receive: broadcast poll of %ud from %s is out-of-range (%d to %d)!", + pkt->ppoll, stoa(&rbufp->recv_srcadr), + peer->minpoll, peer->maxpoll); + ++bail; + } + + if ( (current_time - peer->timelastrec) + < (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), + (1 << pkt->ppoll) + ); + ++bail; + } + + if (L_ISGT(&peer->bxmt, &p_xmt)) { + msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x", + stoa(&rbufp->recv_srcadr), + peer->bxmt.l_ui, peer->bxmt.l_uf, + p_xmt.l_ui, p_xmt.l_uf + ); + ++bail; + } + + peer->bxmt = p_xmt; + + if (bail) { + peer->timelastrec = current_time; + sys_declined++; + return; + } + } + break; /* @@ -1511,6 +1577,7 @@ receive( * clean. Get on with real work. */ peer->timereceived = current_time; + peer->timelastrec = current_time; if (is_authentic == AUTH_OK) peer->flags |= FLAG_AUTHENTIC; else