使用scapy构造数据包时的总结

Zss 发表于:

在一些数据包的构造的时候,譬如一些校验和字段,长度,scapy是会帮我们自动来计算的,所不是一定要去修改的时候尽量不要去自己填写修改

防止出现构造上的错误,导致数据包错误

另外在构造数据包的时候,可以选择先构造哟个不带任何信息的数据包使用pack.show()来查看这个数据包的相关的字段,然后根据字段来进行补充

 

1.在设置本地mac地址时可以设置为localmac–》src=localmac

2.关闭信息则 verbose=False

3.将结果数据包变成一个列表pack[0].res

4.地址等参数可以使用列表来填充

 

譬如:我们在构造一个arp的请求的时候

先构造一个Ether()/ARP(),然后使用pack.show()显示出来各个字段名,再根据这些字段来构造

>>> pack = Ether()/ARP()
>>> pack.show()
###[ Ethernet ]###
dst= e4:f3:f5:8a:5f:ec
src= 04:7d:7b:b7:fd:7e
type= 0x806
###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= 6
plen= 4
op= who-has
hwsrc= 04:7d:7b:b7:fd:7e
psrc= 192.168.0.102
hwdst= 00:00:00:00:00:00
pdst= 0.0.0.0

可以看到这个ARP数据包中的各个字段是怎样的

以太网帧type类型表示的是后面的数据类型,ARP请求和ARP应答这个值为0x806

ARPtype表示要映射的协议地址的类型,要对IPv4地址进行映射,此值为0x800

op操作类型字段,值为1,表示进行ARP请求;值为2,表示进行ARP应答;值为3,表示进行RARP请求;值为4,表示进行RARP应答

 

当我需要查询到192.168.0.1的mac地址,那么根据上面的字段来分别设置值,dst那么就是广播地址:全F

hwsrc和psrc不设置将会自动填充到这个网卡的mac和ip,设置hwdst为全0,pdst为需要请求的ip地址

pack = Ether(dst=’ff:ff:ff:ff:ff:ff’,type=0x0806,src=’04:7D:7B:B7:FD:7E’)/ARP(op=1,pdst=’192.168.0.1′)

 

数据包的发送没有p,那么是在三层发送,sendp,srp,都是在二层发送,那么需要自己来构造eth层的mac等,send,sr1则不需要,会自动处理eth

1.sr1()方法  发送一个数据包接受一个回应的数据包

2.send()在第三层发送数据包,但没有接收功能

3.sendp(),在第二层发送数据包,同样没有接收功能

4.sr(),在第三层发送数据包,有接收功能

5.srp()、srp1()、srploop(),只是工作在第二层

 

接受的数据包查看(sr)

>>> result=sr(IP(dst=”www.baidu.com”,ttl=1)/ICMP())
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> result[0].show()
0000 IP / ICMP 192.168.0.102 > 119.75.217.26 echo-request 0 ==> IP / ICMP 192.168.0.1 > 192.168.0.102 time-exceeded ttl-zero-during-transit / IPerror / ICMPerror

接受的数据包查看(sr1)

>>> result=sr1(IP(dst=”www.baidu.com”,ttl=1)/ICMP())
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> result.show()
###[ IP ]###
version= 4
ihl= 5
tos= 0x0
len= 56
id= 19966
flags=
frag= 0
ttl= 64
proto= icmp
chksum= 0xab0f
src= 192.168.0.1
dst= 192.168.0.102
\options\
###[ ICMP ]###
type= time-exceeded
code= ttl-zero-during-transit
chksum= 0xf4ff
reserved= 0
length= 0
unused= None
###[ IP in ICMP ]###
version= 4
ihl= 5
tos= 0x0
len= 28
id= 1
flags=
frag= 0
ttl= 1
proto= icmp
chksum= 0xa86c
src= 192.168.0.102
dst= 119.75.217.26
\options\
###[ ICMP in ICMP ]###
type= echo-request
code= 0
chksum= 0xf7ff
id= 0x0
seq= 0x0

可以看到sr1和sr的返回值应该是不一样的

>>> result=sr1(IP(dst=”www.baidu.com”,ttl=1)/ICMP())
Begin emission:
..Finished sending 1 packets.
.*
Received 4 packets, got 1 answers, remaining 0 packets
>>> print type(result)
<class ‘scapy.layers.inet.IP’>
>>> result=sr(IP(dst=”www.baidu.com”,ttl=1)/ICMP())
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> print type(result)
<type ‘tuple’>

 

几个方法

>>> pack = srp(Ether(dst=’ff:ff:ff:ff:ff:ff’,type=0x0806,src=’04:7D:7B:B7:FD:7E’)/ARP(pdst=’192.168.0.1′))
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> pack[0].res[0][1][0].fields   eth头部变成字典    pack[0].res[0][1][1].fields则读取的是arp字段,arp字段转化为字典格式
{‘dst’: ’04:7d:7b:b7:fd:7e’, ‘src’: ‘e4:f3:f5:8a:5f:ec’, ‘type’: 2054}

>>> pack[0].res  转化为list
[(<Ether dst=ff:ff:ff:ff:ff:ff src=04:7D:7B:B7:FD:7E type=0x806 |<ARP pdst=192.168.0.1 |>>,
<Ether dst=04:7d:7b:b7:fd:7e src=e4:f3:f5:8a:5f:ec type=0x806 |<ARP hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=e4:f3:f5:8a:5f:ec psrc=192.168.0.1 hwdst=04:7d:7b:b7:fd:7e pdst=192.168.0.102 |<Padding load=’\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00′ |>>>)]

>>> pack[0].show()  显示其中的数据包简介
0000 Ether / ARP who has 192.168.0.1 says 192.168.0.102 ==> Ether / ARP is at e4:f3:f5:8a:5f:ec says 192.168.0.1 / Padding