Hacking time: how you can control anyone's clock

David
Security software engineer
Hacking time: how you can control anyone's clock
Messing around with people's clocks can be a great source of practical jokes. Even nowadays, with many people getting their time digitally, this is not as impossible as you might think. (And the month of April, with the switch to summer time and April Fool's Day, provided the perfect timing for this experiment, of course...)

Most computers and phones get their time at least in part from sources on the internet. Because this time synchronization over the internet is almost always unencrypted, it turns out to be rather simple to change their idea of the time. Offer our friends wifi, and we can simply intercept all NTP packets. We can then send these to our own time server and provide everyone on our wifi with a different idea of the current time.

Disclaimer: Depending on local laws, using the techniques shown here against devices without permission can be considered a crime. This article is for educational and entertainment purposes only. Use what you learn here only on devices for which you have permission to do this.

Setup

For our dastardly plan we are going to need two things: a wireless router, and a computer running linux with two, perferably wired, network interfaces. We will be using an ASUS RT-AC66U, and a computer running Ubuntu 22.04.

Network diagram Visual of the required network setup

First, let us setup the computer to be able to provide time to the network. For this, we will install ntpd-rs. After downloading the latest version of ntpd-rs through the above link it can be installed from the graphical interface or through the command line with

sudo dpkg -i /path/to/ntpd-rs.deb

After installation, ntpd-rs by default is configured to set the system time to utc. That won't do for our purposes, and we will also need to configure it to provide time to those in the network that ask for it. To do this, change the configuration in /etc/ntpd-rs/ntp.toml to:

[observability]
log-level = "info"
observation-path = "/var/run/ntpd-rs/observe"

[[server]]
listen = "[::]:123"

[synchronization]
local-stratum = 1

and apply it with

sudo systemctl restart ntpd-rs

This tells ntpd-rs to consider the local clock as being right, and to provide its time to anyone who asks. We can simply configure the time we want to spread by setting the local time on this machine to whatever we want. Now we just need to make sure everyone will ask us, and not some server we don't control.

This is where we will need the two network interfaces. Connect one to a network on which you have internet, and connect the other to the wan port of the wifi router with which we are going to spread our time.

Now we will need to know the names of these network interfaces. We can look this up with ip a, which will show all the network interfaces. If you are using wired network interfaces, they will typically have names like enp4s0.

To see which of the two is giving us internet right now, run ip route. One of the lines will look like default via 192.168.40.1 dev enp4s0 proto dhcp metric 600. The first word after dev indicates the network interface with internet, in this case enp4s0. We will denote this interface in <inet> in the next parts, and the interface connected to the wifi router with <target>.

First, lets give the target interface an ip address and enable it:

sudo ip addr add 172.16.0.1/24 brd 172.16.0.255 dev <target>
sudo ip link set up dev <target>

Next, we want to provide internet to all devices on this network, so we enable forwarding and NAT-ing on the linux machine with

sudo sysctl -w net.ipv4.conf.all.forwarding=1
sudo iptables -t nat -A POSTROUTING -o <inet> -j MASQUERADE

Now is the time to start configuring the wifi router. For this, temporarily connect a computer to one of its other wired network ports. You can now setup the wifi network as usual, and configure it to use the linux computer as upstream. For this last step, we need to assign it a static ip address 172.16.0.2, tell it that the gateway is 172.16.0.1 and need to give it a dns server, for example the google one at 8.8.8.8. (see also the image below).

Wifi configuration Example of wifi network setup

Now we are ready to execute our grand plan and change time. On the linux machine, run

sudo iptables -t nat -A PREROUTING -p udp --dport 123 -j REDIRECT

and all udp traffic will now be sent to our local ntp server. Just connect to the wifi network with a laptop and see its time change to match the linux machine.

Conclusion

Of course, this isn't just fun and games; doing this in production networks could have far greater implications than simply fooling your friends about the current time. A lot of the security on the internet relies fundamentally on time.

Things like certificates of website use the current time to check if they are valid. If the local clock is wrong, this may cause websites to not work. Or worse, if it is wrong enough, old certificates that have either expired or revoked may be accepted again, allowing an attacker to do all sorts of nastiness.

And as you've just read, NTP is trivially easy to hack.

This underlines the importance of moving towards secure mechanisms for time synchronization such as NTS. Their implementation makes an attack like this almost impossible.

Stay up-to-date

Stay up-to-date with our work and blog posts?

Related articles

In Dutch we have a saying 'meten is weten', which translates to 'to measure is to know'. That sentiment is frequently overlooked in setting up computers and networks.
Sovereign Tech Fund will support our effort to build modern and memory-safe implementations of the Network Time Protocol (NTP) and the Precision Time Protocol (PTP).
The latest release of ntpd-rs compiles on several new targets: the FreeBSD and macOS operating systems now work, and ntpd-rs now supports musl libc on Linux. The PRs adding support for these platforms are all community contributions, which is very exciting.