网络嗅探scapy
1 导入scapy包
from scapy.all import *
from scapy.layers.inet import IP,TCP,UDP,ICMP
1.1 必要的插件
- 如果电脑上没有winpcap或者npcap,scapy好像没法发包
2 构造IP包
构造空的IP包
- 如果不知道IP包里要填哪些参数,可以先构造个空包,然后用pkt.show()显示参数
pkt=IP()
pkt.show()
可以看到打印的参数有version、ihl、tos、len、id、flags、frag、ttl、proto、chksum、src、dst等
不带负载的IP包
pkt=IP(dst='6.6.6.6')
ls(pkt)
- IP()中没有指定src,就是用本机的IP作为源IP,这里也可以设置src的参数
- ls(pkt)可以查看构造出来的报文的详情,具体的参数有
- version参数,值是4,说明版本是4,也就是IPv4
- ttl参数的值是64(可能默认设置是64),ttl是time-to-live,报文生存时间
- tos参数是服务类型,此时是0
- src参数是源IP,此时是本机IP
- dst参数是目的IP,此时是6.6.6.6
- chksum参数是首部检验和,此时是None
- ihl = None
- len = None
- id = 1
- flags = <Flag 0 ()>
- frag = 0
- proto = 0
- options = []
带负载的IP包
data = 'abcdefg'
pkt=IP(dst='6.6.6.6') / data # 把负载data挂在后面
ls(pkt)
- 使用ls(pkt)可以看到详情里有个load参数,值是b’abcdefg’
3 ICMP报文
3.1 构造ICMP报文
data = 'abcdefg'
pkt=IP(dst='6.6.6.6') / ICMP() / data
ls(pkt)
- ls(pkt)打印出来,除了有IP报文的参数,还有ICMP的参数,ICMP的参数如下:
- type = 8
- code = 0
- chksum = None
- id = 0
- seq = 0
- ts_ori = None
- ts_rx = None
- ts_tx = None
- gw = None
- ptr = None
- 可以看到此时type=8,code=0,这时ICMP的请求回显echo request
3.2 ICMP报文相关知识点
- ICMP协议:Internet Control Message Protocal, Internet控制报文协议
- ICMP有两大类报文,一种是Query查询报文,一种是Error差错报文
- ICMP协议是IP协议的一部分,因此ICMP报文位于IP报文的数据部分
- 类型是type
- 代码是code
- 校验和是chksum
- ICMP协议通过type和code的组合来标明报文的类型
- 第一类常见组合,type=8,code=0的请求,途中没有异常,就会收到一个type=0,code=0的响应
- 第二类常见组合,响应的type=3,code=0,是网络不可达;响应的type=3,code=1,是主机不可达;响应的type=3,code=2,是协议不可达;type=3,code=3,是端口不可达;
3.3 ICMP时间戳请求与应答
- ICMP的请求报文,要把type设置为13,code设置为0,请求报文会自动把请求时间附上,此时ICMP报文就是时间戳请求
- 获取参数
- 获取原始包中IP包的参数,用pkt[IP].dst
- 获取原始包中ICMP包的参数,用pkt[ICMP].type、pkt[ICMP].code
- 获取响应包中ICMP包的参数,用reply[0][1][ICMP].type、reply[0][1][ICMP].code、reply[0][1][ICMP].ts_ori
- ICMP包中的时间戳
- ts_ori是源端发送消息的时间
- ts_rx是目的端接收到消息的时间
- ts_tx是目的端返回应答消息的时间
- 并不是所有的主机和网络设备都会回应ICMP的时间戳请求,有的会把这个功能关闭
pkt=IP(dst='6.6.6.6', ttl=10) / ICMP(type=13, code=0)
print(pkt[IP].dst) # 6.6.6.6
print(pkt[ICMP].type) # 13
print(pkt[ICMP].code) # 0
print(pkt[ICMP].ts_ori) # 6789278
reply = sr1(pkt, timeout=1,verbose=False)
print(reply[0][1]