# Packet Sniffing and Spoofing Lab
###### tags: `SUTD` `SEED Labs` `Network Security` `Lab`
For web view: https://hackmd.io/@ephemeral-instance/Bkqj8L5xd
## Lab Task Set 1: Using Tools to Sniff and Spoof Packets
### Task 1.1: Sniffing Packets
#### Task 1.1A.
*… describe and explain your observations.*
The following error is thrown:
```
Traceback (most recent call last):
File "./sniffer.py", line 7, in <module>
pkt = sniff(filter='icmp', prn=print_pkt)
File "/usr/local/lib/python3.5/dist-packages/scapy/sendrecv.py", line 1036, in sniff
sniffer._run(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/scapy/sendrecv.py", line 907, in _run
*arg, **karg)] = iface
File "/usr/local/lib/python3.5/dist-packages/scapy/arch/linux.py", line 398, in __init__
self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) # noqa: E501
File "/usr/lib/python3.5/socket.py", line 134, in __init__
_socket.socket.__init__(self, family, type, proto, fileno)
PermissionError: [Errno 1] Operation not permitted
```
The line highlighted to throw this error included the `sniff()` function from the scapy package. This error is thrown because raw access to network interfaces, which is required for sniffing, requires root privileges.
#### Task 1.1B.
*Please set the following filters and demonstrate your sniffer program again (each filter should be set separately):*
* Capture only the ICMP packet
The filter syntax is as follows: `icmp`
Sample sniffed packet:
```
###[ Ethernet ]###
dst = 08:00:27:08:74:bd
src = 08:00:27:34:8a:17
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 84
id = 47963
flags =
frag = 0
ttl = 64
proto = icmp
chksum = 0xa745
src = 10.0.2.4
dst = 10.0.2.5
\options \
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0x47b9
id = 0x8a2
seq = 0x3
###[ Raw ]###
load = '\xe1\xd8\x1c`\xbfe\x07\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'
```
* Capture any TCP packet that comes from a particular IP and with a destination port number 23.
The filter syntax is as follows: `tcp && src host 10.0.2.5 && dst port 23`
Sample sniffed packet:
```
###[ Ethernet ]###
dst = 08:00:27:34:8a:17
src = 08:00:27:08:74:bd
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 60
id = 57259
flags = DF
frag = 0
ttl = 64
proto = tcp
chksum = 0x4308
src = 10.0.2.5
dst = 10.0.2.4
\options \
###[ TCP ]###
sport = 57394
dport = telnet
seq = 146254376
ack = 0
dataofs = 10
reserved = 0
flags = S
window = 29200
chksum = 0xb53a
urgptr = 0
options = [('MSS', 1460), ('SAckOK', b''), ('Timestamp', (30083, 0)), ('NOP', None), ('WScale', 7)]
```
* Capture packets comes from or to go to a particular subnet. You can pick any subnet, such as 128.230.0.0/16; you should not pick the subnet that your VM is attached to.
The filter syntax is as follows: `net 128.230.0.0/16`
Sample sniffed packet:
```
###[ Ethernet ]###
dst = 52:54:00:12:35:00
src = 08:00:27:34:8a:17
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 84
id = 30932
flags = DF
frag = 0
ttl = 64
proto = icmp
chksum = 0x34ea
src = 10.0.2.4
dst = 128.230.0.1
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = 0xc78c
id = 0xc8e
seq = 0x1
###[ Raw ]###
load = 'q\xdc\x1c`\xa8\xa4\x02\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'
```
### Task 1.2: Spoofing ICMP Packets
*Please make any necessary change to the sample code, and then demonstrate that you can spoof an ICMP echo request packet with an arbitrary source IP address.*
The following code can be used to spoof IP address `10.0.2.3` when sending an ICMP packet to `10.0.2.5`.
``` python
from scapy.all import *
a = IP()
a.src = '10.0.2.3'
a.dst = '10.0.2.5'
b = ICMP()
p = a/b
send(p)
```
Sample spoofed packet received by `10.0.2.5`.
```
###[ Ethernet ]###
dst = 08:00:27:08:74:bd
src = 08:00:27:34:8a:17
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 28
id = 1
flags =
frag = 0
ttl = 64
proto = icmp
chksum = 0x62d9
src = 10.0.2.3
dst = 10.0.2.5
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = 0xf7ff
id = 0x0
seq = 0x0
###[ Padding ]###
load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
```
### Task 1.3: Traceroute
Code:
``` python
from scapy.all import *
a = IP()
a.dst = '1.2.3.4'
b = ICMP()
for i in range(1,100):
a.ttl = i
send(a/b)
```
Screenshot of responses:

Manually recorded full traceroute path:
```
1. 10.0.2.1
2. * * *
3. * * *
4. 10.12.0.1
5. * * *
6. 172.16.1.106
7. 172.16.1.210
8. * * *
9. * * *
10. 202.94.70.1
11. * * *
12. 203.116.245.177
13. 203.118.3.65
14. * * *
15. 203.118.6.25
16. * * *
17. 203.118.12.58
18. * * *
19. * * *
20. 203.118.15.214
```
### Task 1.4: Sniffing and-then Spoofing
The following mappings were used for this task:
* VM A: `10.0.2.5`
* VM B: `10.0.2.4`
* Machine X: `138.34.2.6`
Code:
``` python
from scapy.all import *
def spoof(pkt):
new_p = IP()
new_p.src = pkt[IP].dst
new_p.dst = pkt[IP].src
id = pkt[ICMP].id
seq = pkt[ICMP].seq
load = pkt[Raw].load
new_p = new_p/ICMP(type=0, id=id, seq=seq)/load
send(new_p)
sniff(filter='icmp[icmptype] == icmp-echo and src host 10.0.2.5', prn=spoof)
```
Evidence:
When the sniff-and-then-spoof script is not running on VM B, the terminal gives the following output:

When the script is running on VM B, the terminal gives the following output instead:

As seen, VM A receives a response when pinging machine X even though it does not exist.