FutureSharks / rpi-security

A security system written in python to run on a Raspberry Pi with motion detection and mobile notifications
GNU General Public License v2.0
215 stars 71 forks source link

Scapy ARP request breaks dhcpcd #53

Open FutureSharks opened 4 years ago

FutureSharks commented 4 years ago

I use this code to send an ARP request to a MAC to see if it's alive:

answered,unanswered = srp(Ether(dst='64:A2:F9:A9:2E:A9')/ARP(pdst='192.168.178.0/24'), timeout=1, verbose=False)

If the host is alive, then answered[0][1].hwsrc will be the same as the destination MAC, i.e. the host replied.

The problem is, when I run this 4 times in a row on my raspberry pi, I get these errors from dhcpcd:

Dec 29 18:24:10 raspberrypi dhcpcd[505]: wlan1: hardware address 00:00:00:00:00:00 claims 192.168.178.34
Dec 29 18:24:10 raspberrypi dhcpcd[505]: wlan1: 10 second defence failed for 192.168.178.34
Dec 29 18:24:11 raspberrypi dhcpcd[505]: wlan1: deleting route to 192.168.178.0/24
Dec 29 18:24:11 raspberrypi dhcpcd[505]: wlan1: deleting default route via 192.168.178.1
Dec 29 18:24:11 raspberrypi dhcpcd[505]: wlan1: rebinding lease of 192.168.178.34
Dec 29 18:24:11 raspberrypi dhcpcd[505]: wlan1: probing address 192.168.178.34/24
Dec 29 18:24:12 raspberrypi dhcpcd[505]: wlan1: hardware address 00:00:00:00:00:00 claims 192.168.178.34
Dec 29 18:24:12 raspberrypi dhcpcd[505]: wlan1: DAD detected 192.168.178.34
Dec 29 18:24:13 raspberrypi dhcpcd[505]: wlan1: soliciting a DHCP lease
Dec 29 18:24:13 raspberrypi dhcpcd[505]: wlan1: offered 192.168.178.35 from 192.168.178.1
Dec 29 18:24:13 raspberrypi dhcpcd[505]: wlan1: probing address 192.168.178.35/24

With kamene it works fine.

FutureSharks commented 4 years ago

This causes the raspberry pi host to continually cycling through DHCP IP addresses.

@gpotter2 do you have an idea why or how this is?

gpotter2 commented 4 years ago

This seems weird. I don't expect the packet format to differ between the two.

Could you try sniffing the outgoing packets with Wireshark for instance in both case, to see if there's any difference ?

FutureSharks commented 4 years ago

The classes are quite different: https://github.com/phaethon/kamene/blob/master/kamene/layers/l2.py#L320 https://github.com/secdev/scapy/blob/master/scapy/layers/l2.py#L318

I'll make a dump tomorrow and see what the deal is.

gpotter2 commented 4 years ago

Classes are different because:

But fundamentally, apart from the fact that due to the first point, kamene is likely to generate wrongly built ARP packets that may or may not be discarded by the receiver, the formats are alike.

FutureSharks commented 4 years ago

@gpotter2 thanks for much for the comparison between the 2!

I think I've worked out the difference by looking at the packet dumps. Taken by running tcpdump -w file.pcap -nn -i wlan1 port not ssh and not multicast

Here I'm sending ARP requests to a MAC that is not present on the network, you can see the ARP requests cycling through all IP addresses in the subnet but the difference is when we hit the IP address for the interface/host I'm running scapy/kamene from.

kamene (192.168.178.23 was on wlan1):

12:17:33.972637 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.21 tell 192.168.178.23, length 28
12:17:33.973413 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.22 tell 192.168.178.23, length 28
12:17:33.974143 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Announcement 192.168.178.23, length 28
12:17:33.974973 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.24 tell 192.168.178.23, length 28

scapy (192.168.178.32 was on wlan1):

13:09:48.688548 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.30 tell 192.168.178.32, length 28
13:09:48.691429 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.31 tell 192.168.178.32, length 28
13:09:48.694330 00:00:00:00:00:00 > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Announcement 192.168.178.32, length 28
13:09:48.698681 00:0e:8e:58:d6:af > aa:bb:cc:dd:ee:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.178.33 tell 192.168.178.32, length 28

scapy uses source address 00:00:00:00:00:00 but kamene uses the source address of the interface, like all other requests 00:0e:8e:58:d6:af.

Any idea why this, what one is correct, and how I can do the kamene way in scapy?

gpotter2 commented 4 years ago

It's a bug. Happens on master

FutureSharks commented 4 years ago

OK cool. That's the second scapy bug I've found from use in this project 😃

Do you want me to create an issue in scapy repo?