How to detect NTP Amplification DoS Attacks
Last updated on: December 19, 2022
The ntpd program is an operating system daemon that sets and maintains the system time in synchronization with Internet standard time servers. As described in CVE-2013-5211, a denial of service condition can be caused by the use of the “monlist” feature, which is enabled by default on most NTP servers. NTP runs over UDP port 123, and since it’s on a UDP port, the source address can be spoofed easily.
When the UDP service is queried remotely or the monlist command is run locally (ntpdc-c monlist), the service outputs the list of the last 600 queries that were made from different IP addresses. If the attacker spoofs the source address to be the victim’s address, then all the responses are sent back to the victim’s address. And because the response data is large, the victim’s machine may not be able to handle the response, which can cause a denial of service condition as described in Detect NTP Amplification Flaws.
How This Vulnerability Detection Works
Qualys tracks this vulnerability with QID 121695. The scanner first checks if the NTP service is running. After that it sends the MON_GETLIST request to the NTP server as shown in the screen capture below.
Fig. 1: MON_GETLIST request
If the server responds to this request with MON_GETLIST and the size of each data item in the packet is equal to 0x48 (72 in decimal), then that implies that the monlist feature is enabled and the vulnerability is posted. This is shown in the screen capture below.
Fig. 2: MON_GETLIST response with the first 8 bytes underlined in yellow
NTP Monlist Packet Explanation
In order to understand how the length of the packet is determined, we need to take a look at the monlist packet format. The length is represented in the 7th and 8th bytes.
NTP monlist feature works on packet mode 7. A mode 7 packet is used in exchanging data between an NTP server and a client for purposes other than time synchronization, e.g. monitoring, statistics gathering and configuration. Mode 7 packet has the following format:
Fig. 3: Mode 7 Packet format
In the example listed in Fig. 2, the response field is: “d7 00 03 2a 00 06 00 48” (underlined in yellow).
The first byte 0xd7 is decoded as below:
- R (i.e Response Bit): Since this is a response, the bit is set.
- M (i.e More Bit): Set for all packets but the last in a response which requires more than one packet. In this example set to 1.
- VN (i.e. Version Number): 2 in this example.
- Mode: 7, since this is a mode 7 response.
The second byte 0x00 is decoded as below:
- A (i.e. Authenticated bit): If set, this packet is authenticated. 00 in this example.
- Sequence number: For a multipacket response, this contains the sequence number of the existing packet. 0 is first in the sequence, 127 (or less) is the last. 0000000 in this example as it is the first packet.
The third byte 0x03 is decoded as below:
Implementation number: An implementation number of zero is used for request codes/data formats which all implementations agree on. Implementation number 255 is reserved (for extensions, in case we runout). In our example it is 0x03 (00000011) which is XNTPD.
The fourth byte 0x2a is decoded as below:
Request code: An implementation-specific code which specifies the operation to be (which has been) performed and/or the format and semantics of the data included in the packet. In this example it is 0x2a which is MON_GETLIST_1(42)
The fifth and sixth byte 0x00 and 0x06 is decoded as below:
- Err (4 bits) : Must be 0 for a request. For a response, holds an error coderelating to the request. If nonzero, the operation requested wasn’t performed. Error codes are below: In this response example, it is 0x00 which implies no error.
- 0- no error
- 1- incompatable implementation number
- 2- unimplemented request code
- 3- format error (wrong data items, data size, packet size etc.)
- 4- no data available (e.g. request for details on unknown peer)
- 5-6 – Unknown
- 7- authentication failure (i.e. permission denied)
- Number of data items (12 bits): 0 to 500. In this example 6 data items were returned.
The seventh and eighth byte 0x00 and 0x48 is decoded as below:
- MBZ: A reserved data field, must be zero in requests and responses.
- Size of data item: Size of each data item in packet. 0 to 500. In case of MON_GETLIST_1 it is 0x48 which is also the case in this example.
Next is the Data field which is a variable sized area containing request/response data. For requests and responses the size in octets must be greater than or equal to the product of the number of data items and the size of a data item. For requests the data area must be exactly 40 octets in length. For responses the data area may be any length between 0 and 500 octets inclusive.
If MON_GETLIST request is sent to the vulnerable NTP server and it responds back with request and the size of data in each packet is 0x48, then we are sure that target is vulnerable to NTP monlist Denial of Service Vulnerability.
In order to take immediate action for this vulnerability, users are advised to disable “monlist” functionality by adding the following lines in ntp.conf file:
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
This may restrict the monlist queries on NTP server, and prevent the attack.
We recommend our customers to scan their systems for QID 121695 – NTP monlist feature Denial of Service Vulnerability and apply security updates as soon as possible.
When you include only those 2 lines, in above versions of CentOS or RHEL 7 versions NTP sync will not work. To work we need to include one more line
This will give the client to sync with ntp server and ntpq -c monlist will not provide any output and it will just timeout.