安全客 03月26日
深度剖析:用 Scapy 解读 TCP 握手挥手,详细实操步骤 + 序列号变化深度剖析
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Scapy是一个强大的Python库,专为网络协议数据包的构造、解析和嗅探而设计,尤其适合网络协议初学者。文章介绍了Scapy的基本用法,包括如何使用类构造数据包、常用函数(如send、sr、sniff等)以及查看和分析数据包的方法。通过TCP三次握手和四次挥手的实例,详细演示了Scapy在实际网络通信中的应用,帮助读者理解TCP序列号和确认号的变化机制。文章还提供了实验环境和代码示例,方便读者实践。

📦Scapy通过类来表示协议栈,构建IP数据包只需实例化IP类并指定参数,构造DNS查询请求报文则通过“/”连接各层协议,简化了数据包的创建过程。

🚀Scapy提供了丰富的函数用于数据包操作,包括send()和sr()用于发送数据包,sniff()用于捕获数据包,ls()、pkt.summary()和pkt.show()用于查看和分析数据包,满足不同场景的需求。

🤝以TCP三次握手为例,Scapy代码构建了SYN、SYN+ACK和ACK报文,详细演示了如何设置标志位、端口、序列号和确认号,从而建立TCP连接。

📤发送数据时,通过设置push标志位,确保数据尽快推送到应用层。在释放连接的四次挥手中,Scapy构建了FIN、ACK、FIN+ACK、ACK报文,演示了TCP连接的关闭流程。

🔍通过Wireshark,可以直观地看到Scapy构造的TCP报文,包括三次握手和四次挥手过程,以及数据传输和连接释放,便于理解协议细节。

对于网络协议初学者来说要构造或解析一个网络协议数据包是比较困难的,我们可以借助一个功能强大的Python库Scapy来完成网络数据包的构造、解析和嗅探。Scapy使用类来表示协议栈,它能够对任何类型的数据包进行快速描述,例如构造一个ip层数据包只需要实例化一个IP类对象,并指定参数值即可:ip = IP(dst=”192.168.1.2”)。Scapy根据分层来构造数据包,每一层协议之间用”/”符号连接,例如要构造一个DNS协议的查询请求报文,可以通过代码dns = IP(dst=”192.168.1.2”)/UDP(dport=53)/DNS(qd=DNSQR(“www.gysecurity.cn”))来实现。

 

Scapy的常用函数

发送和接收数据包函数‌:

  1. send()‌:用于发送数据包,但不等待响应。
  2. sendp()‌:类似于send(),但可以包含Layer 2头部信息。
  3. sr()和sr1()‌:发送数据包并等待响应,sr()返回所有响应,而sr1()只返回第一个响应。
  4. srloop()‌:发送数据包并循环接收响应。
  5. srp()‌:类似于sr(),但针对数据包进行二层处理,常用于以太网数据包的发送和接收。
  6. sendpfast()‌:以更高的速度发送数据包,适用于性能要求较高的场景。

 

捕获数据包函数‌:

  1. sniff()‌:用于捕获网络接口上的数据包,可以根据需要过滤特定的协议数据报文。

查看和分析数据包函数‌:

  1. ls()‌:列出所有已知的协议和字段,展示协议和字段的层次结构及其关系。
  2. pkt.time‌:显示数据包的时间戳。
  3. pkt.len‌:显示数据包的长度。
  4. pkt.summary()‌:显示数据包的摘要信息,包括源地址、目标地址等。
  5. pkt.show()‌:显示详细的数据包信息,包括协议头、字段和载荷等。

 

下面以TCP三次握手和四次挥手为例子来演示如何使用Scapy来构造TCP报文,帮助大家理解TCP序列号和确认号的变化机制。

 

环境要求

        处于同一个局域网内的两台pc机(可以是Windows或Linux系统)分别充当服务端以及客户端,两台机器都需要安装Python3,作为客户端的机器还需要安装Scapy和Wireshark。

实现过程

  1. 使用Python的socket模块编写一个TCP服务端。首先创建socket_server套接字,监听8888端口,然后接收客户端的连接请求,读取完客户端发送过来的数据后关闭连接,代码如下:

2. 启动Wireshark,选择局域网ip所使用的网卡,并设置过滤规则:tcp.port==8888

3. 客户端实现

     3.1 建立连接

        TCP协议通过3次握手实现建立连接,客户端需要进行第1次和第3次握手,第2次握手由服务端构建。第1次需要把标志位SYN设置为1,因此需要把flags设置为S,目标端口设置为服务端的端口8888,由于需要接收由服务端返回的第2次握手,所以需要使用sr()函数发送第1次握手报文,其代码如下:

第3次握手的dport,sport,seq,ack,flags需要根据第2次握手的数据报文内容构建,res为服务端返回的第2次握手,其中fields = res[0].res[0][1][1].fields为第2次握手数据内容,因此第3次握手的seq = fields[ack],ack = fields[seq] + 1,sport = fields[dport],第三次握手不需要服务端回复,所以只需要用send()函数发送。其代码如下:

运行客户端代码,切换到Wireshark,可以看到捕获到了TCP建立连接3次握手的数据报文,如下图:

3.2 发送数据

        第3次握手并没有发送数据内容,服务端也没有返回响应,所以发送数据的时候ack和seq应该和第3次握手一样,未来将数据尽快推送到应用层需要将push标志位设置为1。客户清空Wireshark数据,运行客户端代码,可以看到捕获到了发送的数据报文,如下图:

3.3 释放连接

        TCP释放连接需要进行4次挥手,其中第1次和第4次挥手由服务端发送,第2次和第3次挥手由客户端发送。服务端返回的第1次挥手为res_data,其中msg_fields = res_data[0].res[0][1][1].fields为第1次挥手数据内容,则第2次挥手需要设置ack = msg_fields[‘seq’] + 1,seq = msg_fields[‘ack’] ,flags = A由于第2次挥手并没有携带数据,因此第3次挥手的ack和seq和第2次挥手一样,flags设置为FA,因为第3次挥手后需要接收服务端返回的第4次挥手,所以用sr()函数发送。实现代码如下:

运行客户端代码后,发现Wireshark捕获到了4次挥手的数据包,如下图所示:

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Scapy 网络协议 数据包 TCP
相关文章