The network time protocol synchronizes time across various devices on a network. The network time protocol daemon (NTPD) is an open-source implementation of this protocol. In the last couple of months, a number of vulnerabilities have been reported in NTPD. One is CVE-2016-9311, which can cause a crash leading to a denial of service. We have analyzed this vulnerability and provided detection for our customers. In this post we take a detailed look at this vulnerability.
Finding the changes
Examining the patch, we found that the function “report_event” in ntp_control.c holds the fix for this vulnerability. The patch diff tool gives us the following screen (taken from http://bugs.ntp.org/attachment.cgi?id=1460&action=diff):
The left side of the preceding image shows the unpatched code, while right side has the patched code.
In the vulnerable version of code there is one assert statement:
INSIST is defined in ntp_assert.h. If peer==NULL, then the assertion will fail and NTPD will crash.
In the fixed version, we can see that the INSIST(peer!=NULL) statement is replaced by a simple “if” check:
if ((err & PEER_EVENT) && !peer)
This if statement checks whether the value of “peer” is null. If so, it will simply return and prevent a crash.
Analyzing the root cause
To trigger this vulnerability, program flow needs to reach the “report_event” function with a parameter such that the INSIST assertion check fails. (The variable “peer” should be null.)
When NTPD receives a packet, it goes to the function “receive” in ntp_proto.c. The “receive” function performs various checks on the received packet; one checks for valid or invalid crypto-negative acknowledgement (crypto-NAK) packets:
If NTPD receives an invalid NAK packet, it will call the vulnerable function “report_event.” In this vulnerable function, a check looks for the number of traps. If no traps are configured on NTPD, then the function will simply return and the vulnerable code path will not be taken.
This vulnerability can be exploited only if traps are enabled in NTPD. To check for invalid NAK packets, the function “valid_NAK” is present in ntp_proto.c:
As we see in the preceding image, the following conditions will mark a packet as an invalid NAK:
- If mode is not MODE_SERVER and mode is not MODE_ACTIVE and mode is not MODE_PASSIVE.
- If keyid is not 0.
- If there is no peer or peer does not have a key.
- If the origin does not match.
If the trap functionality is enabled on NTP, then sending an “invalid NAK” packet with no peer present will trigger this vulnerability. We can confirm this using a debugger on vulnerable version. The following screen shows NTPD crashing because of this assertion failure:
This vulnerability can be exploited only on NTPD installations with traps configured to cause a denial of service; traps are not enabled by default. Authorization is not required to exploit this vulnerability.
Apply the latest patches or use an up-to-date version of NTPD to guard against this vulnerability. Customers of McAfee Network Security Platform are protected from this vulnerability through signature ID 0x41b01100.