网络工具-Scapy使用介绍

  • A+
所属分类:Python库介绍
摘要这一篇主要介绍Scapy的简单使用, 以及关于计算机网络的基础知识. 同时会有一些使用Scapy的应用.

简介

这一篇主要记录一些关于scapy的内容. 记录一些自己使用到的内容. 逐渐往里面进行更新. 这里会包括Scapy的基础使用, 和一些简单的计算机网络的知识.

参考资料

 

关于网络协议

因为Scapy是网络工具, 因此我们需要首先对计算机网络的知识有所了解. 首先一个pacp文件结构如下所示:

网络工具-Scapy使用介绍

接着我们看一下每一层的头部有什么:

网络工具-Scapy使用介绍
  • 黄色的是数据链路层的头部,一共14字节
  • 蓝色的部分是IP头部,一般是20字节
  • 紫色部分是TCP头部,一般是20字节

 

注意:(源IP地址,目的IP地址,源端口号,目的端口号)这四个字段唯一的确定了一个TCP链接。

数据链路层

  • 目的MAC当前step目的主机的mac地址
  • 源MAC当前step的源主机的mac地址
  • 类型:指定网络层所用的协议类型
    • 0x0800指IPv4协议
    • 0x86dd IPv6协议数据
    • 0x809B AppleTalk协议数据
    • 0x8138 Novell类型协议

网络层

  • 版本:记录数据报属于哪一个版本的协议,如IPv4或IPv6
  • 首部长度:指明IP头部长度,单位是字,也就是两个字节。该域的值最小为5,就是标准的头部长度;最大为15,表明有扩展部分。
  • 服务类型:用来区分不同服务的需要.
  • 数据报总长:包含IP头部的数据报的总长度。注意,这里不包括链路层的头部,目前最大值是65535字节。
  • 分组ID这个域的作用是当一个大的数据报被拆分时,拆分成的小的数据段的这个域都是一样的。
  • 标记:共三个bit,第一个未使用;第二个DF(Don't Fragment),设置成1表示这个数据包不能被分割,这个是针对路由器的一条指令;第三个MF(MoreFragment),如果一个数据包被分割了,那么除了最后一个分段以外的所有分段都必须设置为1,用来表示后面还有更多的分段没有到达,最后一个设置为0,用来表示分割的段全部到达。
  • 段偏移量:这个域有13bit,也就是每一个数据报最多有8192个分段。每一个分段的长度必须是8字节的倍数,也就是说8字节是分段的基本单位,当然分组的最后一个段不做限制。这样最大的数据报长度为8*8192=65536字节,比目前限制的最大数据报长度还多1,能够满足对网络中所有数据报传送的需求。
  • 生存时间:这是一个生存期计数器,最大为255s,但是实际上使用的时候用作跳数计数器,当值为0时数据报被丢弃,用来避免一个数据报过久的逗留在网络中。
  • 高层协议:这里和链路层的类型作用相同,用来表示更高层的协议,这个数据报里是TCP
  • 首部校验和:IP头部的校验和
  • 源IP地址:数据报来源主机的IP地址
  • 目的IP地址:数据报目的主机的IP地址

传输层

  • 源端口号:数据报来源主机的端口号
  • 目的端口号:数据报目的主机的端口号
  • TCP序号(sq)发送的TCP的序号,从0开始,实际中这个值就是发送的数据报中内容的字节数,比如我发送的第一个报中sq=0,数据报内容20字节,那么下一个数据报的sq就应该是21。
  • 捎带的确认(ack)确认收到上一个数据报,然后act的值是指定自己想要收到的下一个数据报的sq,比如我收到一个数据报的sq=0,数据报内容20字节,那么我的ack就应该是21,用来标明我sq=0,内容为20字节的数据报已经收到,我接下来期望收到的是sq=21的数据报
  • 首部长度:和IP头部的长度域类似,这个域用来标明TCP头部的长度,单位也是字。
  • 保留:6bit未使用的域
  • Flag从左到右,[URG|ACK|PSH|RST|SYN|FIN]
    • ACK设置为1表示前面的确认(ack)是有效的,否则前面的确认应被忽略。
    • PSH表示要求对方在接到数据后立即请求递交给应用程序,而不是缓冲起来直到缓冲区收满为止。
    • RST用于重置一个已经混乱的连接。
    • SYN用于建立连接的过程。在链接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域。链接应答则捎带了一个确认,即SYN=1和ACK=1.本质上SYN位是用来表示CONNECTION REQUEST和CONNECTION ACCEPTED,然后进一步用ACK来区分是请求还是应答,的确很高明。
    • FIN用来释放一个连接。它表示发送方已经没有数据要传输了。然后,在关闭一个连接后,关闭进程可能会在一段不确定的时间内继续接收到数据。SYN和FIN数据段都有TCP序号,从而保证了这两种数据段被按照正确的顺序来进行处理。
  • 窗口大小:指定了从被确认的字节算起可以发送多少个字节。要深入理解这个域的含义,可以参看TCP用色控制和慢启动算法
  • 校验和:校验范围包括TCP头、数据报内容和概念性伪头部。概念性伪头部又包括源IP,目的IP,TCP协议号。
  • 紧急指针:指向数据报中紧急数据最后一个字节的下一个字节。

 

参考资料TCP/IP数据包格式详解-包括数据链路层的头部

 

Scapy的简单使用

  1. from scapy.all import *

 

读取和写入pcap文件

读取pcap文件

  1. packet=rdpcap("/spare/captures/isakmp.pcap")

 写入pcap文件

  1. wrpcap('filtered.pcap', pkt, append=True)  #appends packet to output file

 

获取数据包的常用信息

我们可以使用summary来查看总体的信息. 当一个pacp中有多个会话的时候, 查询的结果如下所示:

  1. packet.summary()
网络工具-Scapy使用介绍

为了获得更加详细的信息, 我们可以对其中第一个会话进行查看.

  1. packet[0].show()
  2. # packet[0].summary()

这里的show可以按层级显示所需要的信息.

网络工具-Scapy使用介绍

当然我们也可以具体显示某一层的IP地址, 或是MAC地址. 首先是查看IP地址.

  1. packet[0][IP].dst
网络工具-Scapy使用介绍

接下来是查看MAC地址:

  1. packet[0][Ether].src
网络工具-Scapy使用介绍

 

依次读取数据包-sniff

sniff是嗅探的意思, 我们可以利用这个函数来依次处理pcap中每一个packet. 例如下面的例子, 我们依次打印出源地址和目的地址.

  1. def test(packet):
  2.     return "Src{} => Dst:{}".format(packet[0][IP].src, packet[0][IP].dst)
  3. sniff(offline='64722.pcap', prn=test)

最终的结果如下所示:

网络工具-Scapy使用介绍

 

使用Scapy的一些应用

实现数据匿名化

有的时候, 我们需要将数据包中的IP地址和MAC地址进行匿名化处理, 于是我们可以使用下面的方式进行实现.

首先我们创建一个新的数组packets, 接着使用sniff对逐个packet进行处理, 并将处理的结果保存在packets中, 最后保存packets即可.

  1. def customAction(packet):
  2.     # 匿名化MAC地址
  3.     packet[Ether].dst='00:00:00:00:00:00'
  4.     packet[Ether].src="00:00:00:00:00:00"
  5.     # 匿名化IP地址(需要判断是IPv4还是IPv6)
  6.     if packet[Ether].type==34525: # 0x86dd
  7.         packet[IPv6].src="0:0:0:0:0:0:0:0"
  8.         packet[IPv6].dst="0:0:0:0:0:0:0:0"
  9.     else:
  10.         packet[IP].src="0.0.0.0"
  11.         packet[IP].dst="0.0.0.0"
  12. # 创建一个新的packets用来保存
  13. packets = []
  14. # 逐个packet进行转换
  15. for sniffed_packet in sniff(offline='64722.pcap', prn=customAction):
  16.     packets.append(sniffed_packet)
  17. # 结果保存
  18. wrpcap('res.pcap', packets)

参考资料: Importing packets from trace files with scapy

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: