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.
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 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
220.127.116.11 and you want to spoof its identity. Whenever the router asks for the hardware address of
18.104.22.168, you send a IS-AT response with your own address (the MAC address) to the router.
Consequently, the router thinks the IP
22.214.171.124 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!
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!