ntp: restrict authentication of server/peer to specified key
When a server/peer was specified with a key number to enable authentication with a symmetric key, packets received from the server/peer were accepted if they were authenticated with any of the keys contained in the key file and not just the specified key. This allowed an attacker who knew one key of a client/peer to modify packets from its servers/peers that were authenticated with other keys in a man-in-the-middle (MITM) attack. For example, in a network where each NTP association had a separate key and all hosts had only keys they needed, a client of a server could not attack other clients of the server, but it could attack the server and also attack its own clients (i.e. modify packets from other servers). To not allow the server/peer to be authenticated with other keys extend the authentication test to check if the key ID in the received packet is equal to the configured key number. As a consequence, it's no longer possible to authenticate two peers to each other with two different keys, both peers have to be configured to use the same key. This issue was discovered by Matt Street of Cisco ASIG.
This commit is contained in:
parent
370ba5e8fc
commit
df46e5ca5d
2 changed files with 5 additions and 1 deletions
|
@ -2461,6 +2461,9 @@ The syntax of this directive is identical to that for the @code{server}
|
|||
directive (@pxref{server directive}), except that it is used to specify
|
||||
an NTP peer rather than an NTP server.
|
||||
|
||||
When a key is specified by the @code{key} option to enable authentication, both
|
||||
peers must be configured to use the same key and the same key number.
|
||||
|
||||
Please note that NTP peers that are not configured with a key to enable
|
||||
authentication are vulnerable to a denial-of-service attack. An attacker
|
||||
knowing that NTP hosts A and B are peering with each other can send a packet
|
||||
|
|
|
@ -1140,7 +1140,8 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
|
|||
if (inst->do_auth) {
|
||||
if (auth_len > 0) {
|
||||
auth_key_id = ntohl(message->auth_keyid);
|
||||
test5 = check_packet_auth(message, auth_key_id, auth_len);
|
||||
test5 = check_packet_auth(message, auth_key_id, auth_len) &&
|
||||
auth_key_id == inst->auth_key_id;
|
||||
} else {
|
||||
/* If we expect authenticated info from this peer/server and the packet
|
||||
doesn't have it, it's got to fail */
|
||||
|
|
Loading…
Reference in a new issue