Binary analysis of NTP protocol
In this article I wish to share some insights
into the NTP (Network Time Protocol). We do not usually do much apart from
making sure its default port (123 udp) is open through firewalls and ensure the
configuration of the service is provided with synchronisation servers.
Kali comes with several Metasploit modules that allow you to quickly check if NTP is flowed against the below vulnerabilities – none of them, according to my knowledge does the buffer overflow. They all seem to check the NTP packets amplification attacks and denial of service. All of them will work with changing only the RHOSTS parameter to read the IP address of your NTP agent.
There are,however, several exploits that seem to
exploit the notorious buffer overflow and get some code execution, but as of
now (late 2019), these exploits all seem to apply to some older versions of
NTP, mostly for unix environments…Anyway, none of them worked for me against
recent equipment (CentOS 7.x, Cisco and HPE switches, VMWare VMs).
NTP defines its protocol in several RFC-s ,
depending on the version of the NTP you deploy. This is why some of the below
links may be of use:
Kali comes with several Metasploit modules that allow you to quickly check if NTP is flowed against the below vulnerabilities – none of them, according to my knowledge does the buffer overflow. They all seem to check the NTP packets amplification attacks and denial of service. All of them will work with changing only the RHOSTS parameter to read the IP address of your NTP agent.
So let us have a look at one NTP exploit that will be launched from Metasploit. This attack will try to exploit the READVAR vulnerability. The point here is not primarily to exploit the NTP but to see information and structure is contained within NTP packets.
The tcpdump session run on the destination host confirms
that there is no response sent.
Note that the NTP message does not say mode
"client" but rather "reserved for NTP control message"
(Flags: 0x16 - "no warning" + "NTP Version 2" +
"reserved for NTP control message")
RFC can help us understand what these parameters
are (Leap indicator, version number, mode). Have a look at the RFC definition
of the “Mode: reserved for NTP Control Message (6)”. Flags 2 (see below screenshot) (0x02) confirm that ("Opcode:READVAR
(2) " is a reserved/control message) and this is the one that our above
metasploit probe checks.
So, Flags 0x16 is "reserved for NTP control
message" + "NTP version 2" + "no waiting". Flags 0x02 is "opcode:READVAR". The rest of the message ("Sequence",
"Status", "AssociationID", "Offset" and
"Count" are all set to 0)
We can consult an RFC (for NTP version 2 , in our
case) to understand what these are.
Given all the explanations of the NTP parameters
and following our Wireshark PCAP structure of the request, we can try to
simulate an NTP request via nping, for example. I put “dead beef” string to the
end of the NTP request to locate it easier in the Wireshark capture.
This upper one indeed returns the response. So ,
lets first look at the request.
Note the “dead beef” in the wireshark capture- so
we know where our packet ends. Note the “0xd3” as the start of our NTP packet.
I outlined the whole packet in blue to make it more visible. Flags:0xd3 equals to: "Leap indicator:Clock
unsynchronized" + "NTP Version 2" + "mode:client")
The below response is : Flags 0x14 ("no
warning" + "NTP version 2" + "mode:server")
This is another case where we sent a legitimate
NTP sync request.
A legitimate NTP sync request was sent from a local centos local VM (10.0.2.15) and the reply was received from 85.91.1.164.
Note where this remote NTP uses the "Reference ID:188.125.64.6" which is embedded in the NTP response from 85.91.1.164).
Note that in the example above we managed to
obtain the IP address of the NTP sync server (193.120.10.3) that NTP that we are exploiting (193.120.10.3) will use.
This is an example of an NTP "chatty"
server on the HPE switch which responds to the "READVAR" opcode.
Asking for a sync data from public server with our
reconstructed valid NTP request works ok. We do receive replies (Flags 0xd302) after submitting NTP request via nping.
However, READVAR request (Flags 0x16) against it
does not return any response (0x1602) meaning the destination NTP is vulnerable
to reading NTP variables (hence READVAR).
A small proof of concept is on the https://github.com/adenosine-phosphatase/ntp where a python script retrieves the NTP upstream server IP address from the IP address you specify.
The assumption is that the upstream NTP server will be a higher-precision stratum level.
Comments
Post a Comment