Skip to content

How to spoof NTP packets

Last week I had to write an NTP spoofer for a hacking course. The main goal was to manipulate NTP packets on the way to a computer in the LAN.

For this task I used Scapy, a very powerful packet manipulation library for Python.

What is spoofing anyway?

Spoofing is a fancy name to describe a technique for falsifying and forging fake data. Every time you use an application which wants to send some data (your web browser, your Wi-Fi, your computer clock), so-called packets with data are sent over the Internet.
As an attacker, you want to be able to fake some packets. Imagine a victim trying to connect to an online banking website. Would it not be great to make the victim connect to a website you control, so that he or she can hand over his bank pin into your greedy hands?


What you need to do before you can intercept packages is to put yourself between your victim and the server.
Man-In-The-Middle attackSource: Johannes Weber

The graphic shows a typical setting. The attacker tries to intercept and manipulate the traffic between the victim and a server (or another victim). In our case, we want to manipulate the traffic that occurs whenever the victim synchronizes its clock to match the time of an NTP server.

I am using Linux and dsniff to intercept the traffic. The dsniff library contains an ARP spoofing program, which is explained in the next chapter.
Also, I am using Python 3 with scapy and netfilterqueue.

ARP spoofing

ARP is a protocol used for mapping a network address (e.g. to a physical address of a device (a network card, a router, a switch, etc.). Network devices usually have tables with the collected ARP data, used to remember which device is at a specific address. An arp table looks like this:

pi@pi:~$ arp -a ( at e0:60:66:a5:96:70 [ether] on eth0
IdeaPad-Z565.local ( at 00:26:82:b0:fa:67 [ether] on eth0
computer.local ( at 14:7d:c5:ff:f8:2f [ether] on eth0

The protocol works as follows: A device (e.g. your router) send an ARP packet to every device in the network (called broadcast mode). Usually, the messages look like this:

Who has Tell
Who has Tell
Who has Tell

The device at the requested IP address sends a response to, which looks like this: is at 00:26:82:b0:fa:67
... is at b8:27:eb:7d:6e:03

Whenever such a message is received, the devices update their internal arp tables.

So what is ARP spoofing??

If you understood how ARP works, you should understand how we can impersonate another device. You can answer to the WHO-HAS request by sending a fake response. Imagine your victim’s PC has the IP and you want to spoof its identity. Whenever the router asks for the hardware address of, you send a IS-AT response with your own address (the MAC address) to the router.
Consequently, the router thinks the IP belongs to the attacker, and sends any packages to the attacker.
As an attacker, we have to send the fake message repeatedly, because the router will always request the newest state of the network.

You can achieve all of this with arpspoof. Its man page describes how it works:
sudo arpspoof -t <target_IP> <host_IP>
The host IP is the IP you want to set for your device, the target is the device that should receive the arp messages.

There is still a problem: You need to forward all packets to the attacker’s PC after manipulating them, so it does not recognize there is an attack and there won’t be any errors on the victim’s side of the connection.

Forward the packages

The linux kernel offers “kernel IP forwarding”, which is simply a way to tell your computer:

Hey, if you get any packages that are not addressed to you, please forward them to the relevant recipient.

Since we receive any packet destined to the victim and are only interested in a few selected packets, we need to resend the rest to the victim.

You need to set the value of /proc/sys/net/ipv4/ip_forward to 1. Read more about this here.

Just spoof it!

I wrote ntpspoof to spoof any NTP packets and change the year of the response to be 2035. That means that any time the victim tries to update its clock, he or she gets the year 2035 and the clock is set to that year.

Why 2035? Because we can! The number is obviously arbitrary, but the goal is to prove that we can manipulate any packets.

The code can be found on GitHub.

Post any comments or questions below!

Share this post: Print this pageTweet about this on TwitterShare on RedditShare on Google+Share on Facebook
Published inIT-SecurityTechnology


  1. Johannes Weber Johannes Weber

    Hi Davide,

    is there an option to use your script with IPv6? I want to intercept some (own) IPv6 NTP servers. The “arpspoof” can be done with parasite6 from THC-IPv6 toolkit.

    (By the way: Funny to see that you are using my MITM image from my blog: ;))

    Cheers, Johannes

    • dbof dbof

      Hi Johannes,

      Well, if the arpspoof part works with IPv6, you only need to adjust the forwarding part. So enable ipv6 forwarding ( sysctl net.ipv6.conf.all.forwarding ) and install ip6tables (since standard iptables is not compatible).
      I think “scapy”, the python package used in the script, also has IPv6 packet support.

      (The image was taken from Wikipedia and is therefore widely used. If you want me to remove it, shoot me an email).

      • Johannes Weber Johannes Weber

        Hi Davide,

        thanks for the hints. I’ll give it a try. Scapy works with IPv6 as well.

        One more question: Does your script handle NTP Authentication? If authentication is used, does it simply forward the Key ID and Message Authentication Code (MAC)?

        (Please leave the image on your blog. I have seen that someone else uploaded my images to Wikipedia. But that’s of course not your fault.)

        • dbof dbof

          The script acts on the raw packets only. I do not really know how NTP authentication works, but as long as you get regular NTP packets after authentication, it should also work.

          Thanks for the image, I will add the source!

Leave a Reply

Your email address will not be published. Required fields are marked *