Task 1.1: Sniffifing Packets
Task 1.1A.
ip -br address查看docker网络所在虚拟接口
lo UNKNOWN 127.0.0.1/8 ::1/128
enp0s3 UP 10.0.2.4/24 fe80::a36f:d611:2b08:b94/64
docker0 DOWN 172.17.0.1/16
br-0b0ec52ef4d9 UP 10.9.0.1/24 fe80::42:98ff:fe8a:bfc4/64
veth882e2b4@if10 UP fe80::a468:c4ff:fe23:ea66/64
veth3f2254b@if12 UP fe80::8c7d:c6ff:fe0f:155b/64
编写程序
from scapy.all import *
def print_pkt(pkt):
pkt.show()
pkt = sniff(iface="br-0b0ec52ef4d9", filter="icmp", prn=print_pkt)
使用以上程序在接口br-0b0ec52ef4d9上进行监听即监听网络10.9.0.0
docksh进入hostA的docker命令行,ping 10.9.0.6
监听程序抓到包,产生回显。
若不使用超级用户权限,直接执行python3 task1.1A.py则产生以下报错。权限不够支持程序进行操作。
PermissionError: [Errno 1] Operation not permitted
至此task1.1A完成。
问题一:直接将讲义上程序复制下来运行时会报错,原因是讲义中的引号是中文引号,改为英文引号即可。
Task 1.1B.
使用 BPF (Berkeley Packet Filter) 语法对流量包进行过滤
1、Capture only the ICMP packet
from scapy.all import *
def print_pkt(pkt):
pkt.show()
pkt = sniff(filter="icmp", prn=print_pkt)
2、Capture any TCP packet that comes from a particular IP and with a destination port number 23
from scapy.all import *
def print_pkt(pkt):
pkt.show()
pkt = sniff(filter="tcp and host 10.9.0.6 and dst port 23", prn=print_pkt)
3、Capture packets comes from or to go to a particular subnet. You can pick any subnet, such as 128.230.0.0/16
from scapy.all import *
def print_pkt(pkt):
pkt.show()
pkt = sniff(filter="net 128.230.0.0/16", prn=print_pkt)
至此task1.1B完成。
Task 1.2: Spoofifing ICMP Packets
作为一个数据包欺骗工具,Scapy允许我们将IP数据包的字段设置为任意值。本任务的目的是欺骗具有任意源IP地址的IP报文。我们将欺骗ICMP echo请求数据包,并将它们发送到同一网络上的另一个虚拟机。我们将使用Wireshark来观察我们的请求是否会被接收方接受。如果被接受,将向被欺骗的IP发送一个echo应答报文。
Task 1.2: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.
from scapy.all import *
def print_pkt(pkt):
pkt.show()
pkt = sniff(filter="icmp", prn=print_pkt)
from scapy.all import *
ip=IP(dst='10.9.0.5')
p=ip/ICMP()
send(p)
使用以上程序进行实验,确认可收到spoof构建的包
修改spoof进行伪造
from scapy.all import *
ip=IP(src='101.43.122.221',dst='10.9.0.5')
p=ip/ICMP()
send(p)
我们可以发现hostA上的sniff监听程序收到的包来自101.43.122.221
这证明我们的伪造是生效的。
至此task1.2完成
Task 1.3: Traceroute
这项任务的目标是使用Scapy估计路由器数量之间的距离
您的虚拟机和选定的目标。这基本上是由traceroute工具实现的。在这个任务中,我们将编写自己的工具。其思想非常简单:只要将一个包(任何类型)发送到目的地,并首先将其Time-To-Live (TTL)字段设置为1。这个数据包会被第一个路由器丢弃,它会向我们发送一个ICMP错误消息,告诉我们存活时间已经超过了。这就是我们如何获得第一个路由器的IP地址。然后我们将TTL字段增加到2,发送另一个包,并获得第二个路由器的IP地址。我们将重复这个过程,直到我们的包最终到达目的地。需要注意的是,这个实验只得到了一个估计的结果,因为在理论上,这些数据包并不是都走相同的路线(但在实践中,它们可能在短时间内走相同的路线)。
使用sr()命令发包并等待回应
from scapy.all import *
reply,Nreply = sr(IP(dst='101.43.122.221',ttl=(1,60))/ICMP(),timeout=10)
for i,j in reply:
print(i.ttl,j.src)
print("finish......")
由此可得,在到101.43.122.221之前经过了4个路由
至此task1.2完成
Task 1.4: Sniffifing and-then Spoofifing
在同一个局域网中需要两台机器:VM和用户容器。从用户容器中ping一个IP x。这将生成一个ICMP echo请求包。如果X是活的,ping程序将收到一个回显回复,并打印出响应。您的嗅探-然后欺骗程序在VM上运行,它通过包嗅探监视LAN。无论何时它看到一个ICMP回显请求,不管目标IP地址是什么,您的程序应该立即发送一个回显答复使用包欺骗技术。因此,不管机器X是否活着,ping程序总是会收到一个回复,表明X是活着的。你需要使用Scapy来完成这个任务。
在您的实验中,您应该从用户容器ping以下三个IP地址。报告你的观察和解释结果。
ping 1.2.3.4 # a non-existing host on the Internet
ping 10.9.0.99 # a non-existing host on the LAN
ping 8.8.8.8 # an existing host on the Internet
使用以下代码进行sniff and spoof
from scapy.all import *
def spoof_pkt(pkt):
print("original packet.....")
print("source ip",pkt[IP].src)
print("destination ip", pkt[IP].dst)
ip=IP(src=pkt[IP].dst,dst=pkt[IP].src,ihl=pkt[IP].ihl,ttl=99)
icmp=ICMP(type='echo-reply',code=0,id=pkt[ICMP].id,seq=pkt[ICMP].seq)
#data=pkt[Raw].load
c = Ether()
c.src = pkt['Ethernet'].dst
c.dst = pkt['Ethernet'].src
newpkt = ip/icmp/c
print(type(pkt))
print("spoof packet......")
print("source ip", newpkt[IP].src)
print("destination ip", newpkt[IP].dst)
send(newpkt,verbose=0)
print("sniff start......")
pkt= sniff(iface='br-0b0ec52ef4d9',filter = 'icmp and src host 10.9.0.5', prn =spoof_pkt)