CVE-2015-8138
CERT VU#357792
To distinguish legitimate peer responses from forgeries, a client attempts to verify a response packet by ensuring that the origin timestamp in an incoming packet matches the transmit timestamp it transmitted in its last request. A logic error exists that allows packets with an origin timestamp of zero to bypass this check whenever there is not an outstanding request to the server.
It appears this defect applies to all modes except interleaved and broadcast modes and was introduced in version 4.2.5p179.
ntp 4.2.8p3
NTPsec aa48d001683e5b791a743ec9c575aaf7d867a2b0c
http://www.ntp.org
http://www.ntpsec.org/
CVSSv2: 5.0 - AV:N/AC:L/Au:N/C:N/I:P/A:N
CVSSv3: 5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
receive() in ntp_proto.c contains the following sanity check for the origin timestamp when running in basic mode:
if (!L_ISEQU(&p_org, &peer->aorg)) {
peer->bogusorg++;
peer->flash |= TEST2; /* bogus */
if (!L_ISZERO(&peer->dst) && L_ISEQU(&p_org,
&peer->dst)) {
peer->flip = 1;
report_event(PEVNT_XLEAVE, peer, NULL);
}
} else {
L_CLR(&peer->aorg);
}
If the incoming origin timestamp is not equal to the stored origin timestamp in the peer structure, the packet is marked as bogus and will be ignored. If the origin timestamp matches the saved origin timestamp in the peer structure, the origin timestamp in the peer structure is zeroed out.
This means an attacker can spoof the peer server and send a time update with a zero origin timestamp. The client will check that incoming timestamp against the one stored in the peer, which is zero. The timestamps will match and the client will process the incoming packet for time. The client is not in a state in which it is expecting a reply from the server, but it processes it anyway.
We have successfully used this vulnerability to force a client to move its time. Our proof-of-concept requires no authentication or special access and works for any client configured in basic mode.
We can maintain the client at our spoofed time by sending regular updates, every 5 seconds for example, enough to overcome the real server time updates in the clock selection process. The client will oscillate between the peered and rejected state with the peer since it is receiving drastically different times between the spoofed and real packets.
In order to be considered for clock selection, we have to ensure that the measured dispersion and delay for our packets are low. We achieve this by setting the receive timestamp to the offset value by which we want to move the clock for the initial time change. For example, to move the clock 20 years forward we set the transmit timestamp to (current time + 630720000) and the receive timestamp to 630720000. We also must set the precision to -128 to minimize the dispersion. Once the time has changed, we can maintain that spoofed time by changing receive to zero and keeping transmit the same. This keeps the delay low enough to be considered in clock selection.
Additionally, even when the update has too large of an offset or too big of a delay to win the clock selection, we can at least use the zero origin timestamp to make a client ignore real time updates in some instances by forcing the client to think a real server update is a popcorn spike.
Ideally, the client would not process any packet from a peer if it did not have an active request out.
2015-10-16 - Vendor Disclosure
2016-01-19 - Public Release
Matthew Van Gundy and Jonathan Gardner