Skip to content

How to spoof NTP packets

Last week I had to write an [tooltip tip=”Network Time Protocol”]NTP[/tooltip] spoofer for a hacking course. The main goal was to manipulate [tooltip tip=”Network Time Protocol”]NTP[/tooltip] 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?

Preparation

What you need to do before you can intercept packages is to put yourself between your victim and the server.

Source: Johannes Weber (with permission)

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 [tooltip tip=”Network Time Protocol”]NTP[/tooltip] server.

I am using Linux and dsniff to intercept the traffic. The dsniff library contains an [tooltip tip=”Address Resolution Protocol”]ARP[/tooltip] spoofing program, which is explained in the next chapter.
Also, I am using Python 3 with scapy and netfilterqueue.

ARP spoofing

[tooltip tip=”Address Resolution Protocol”]ARP[/tooltip] is a protocol used for mapping a network address (e.g. 192.168.1.150) 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
easy.box.local (192.168.2.1) at e0:60:66:a5:96:70 [ether] on eth0
IdeaPad-Z565.local (192.168.2.112) at 00:26:82:b0:fa:67 [ether] on eth0
computer.local (192.168.2.104) 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 192.168.2.112? Tell 192.168.2.1
...
Who has 192.168.2.104? Tell 192.168.2.1
...
Who has 192.168.2.198? Tell 192.168.2.1

The device at the requested IP address sends a response to 192.168.2.1, which looks like this:

192.168.2.112 is at 00:26:82:b0:fa:67
...
192.168.2.198 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 1.2.3.4 and you want to spoof its identity. Whenever the router asks for the hardware address of 1.2.3.4, you send a IS-AT response with your own address (the MAC address) to the router.
Consequently, the router thinks the IP 1.2.3.4 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!

Published inIT-SecurityTechnology

7 Comments

  1. alexser

    hi, David. i am trying this for windows 7 and 11 but the datetime is not happening. how can i use it correctly? target receives packages but no change

    • dbof

      Hello alexser,

      I am not sure how it works on Windows, but if Windows is getting the modified packages (you can test it by using Wireshark) there might be other checks in place. You can check if your code is correct, by using something like NetTime [1]. Without more information I do not know how to help you.

      [1] https://www.timesynctool.com/

  2. Marcus

    Great Job!,

    if i edit this line>
    new_time = datetime.datetime(2035, dtime.month, dtime.day, dtime.hour,
    dtime.minute, dtime.second, dtime.microsecond)

    for another year, month, day, etc. This work ?

    • 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

        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

          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 *