前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WireShark TCP分析

WireShark TCP分析

作者头像
Al1ex
发布2023-05-12 11:40:22
8380
发布2023-05-12 11:40:22
举报
文章被收录于专栏:网络安全攻防网络安全攻防
协议介绍

TCP是一种面向连接的、基于字节流的、可靠的传输层通信协议,面向连接意味着使用TCP的应用程序在传输数据前必须先建立连接,就如打电话一样需要先进行拨号等待对方响应之后才能开始说话,字节流是指两个应用程序通过TCP连接交换8 bit字节构成的字节流,TCP对字节流的内容不作任何解释,它并不知道传输的数据字节流是二进制数据,还是ASCII字符或者其他类型数据,对于字节流的解释由TCP连接双方的应用层解释,TCP协议通过以下几种机制来提高可靠性:

  • 确认机制:TCP协议采用确认机制来确保数据的可靠传输,发送方在发送数据后会等待接收方的确认消息,如果没有收到确认消息,则发送方会重传数据,直到接收方确认收到数据为止
  • 超时重传机制:如果发送方在规定的时间内没有收到确认消息,则会认为数据丢失,会触发超时重传机制,即发送方会重新发送数据
  • 滑动窗口机制:TCP协议采用滑动窗口机制来进行流量控制,即发送方和接收方都有一个窗口大小,发送方只能发送接收方窗口大小内的数据,接收方也只能接收发送方窗口大小内的数据,这样可以避免数据丢失和网络拥塞的问题
  • 拥塞控制机制:TCP协议采用拥塞控制算法来避免网络拥塞,发送方会根据网络的拥塞程度动态调整发送数据的速率以避免网络拥塞和数据丢失的问题
报文格式

TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段,一个TCP报文段分为首部和数据两部分,TCP的全部功能都体现在它首部中各字段的作用,TCP报文段首部的前20个字节是固定的,后面有4n字节是根据需要而增加的选项(n是整数),因此TCP首部的最小长度是20字节,TCP报文段的首部格式如下图所示:

  • 源端口:16bits,端口号范围0~65535,计算机上的进程要和其他进程通信需要通过计算机端口,而一个计算机端口某个时刻只能被一个进程占用
  • 目的端口:16bits,端口号范围0~65535,计算机上的进程要和其他进程通信需要通过计算机端口,通过指定目标计算机开放的端口就可以与目标计算机开放的端口通信
  • 序号:Seq序号,32bits(4 bytes),TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,整个要传送的字节流的起始序号必须在连接建立时设置,首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号,例如:一报文段的序号字段值是301,而携带的数据共有100字节,这就表明本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400,显然下一个报文段(如果还有的话)的数据序号应当从401开始,即下一个报文段的序号字段值应为401,这个字段的名称也叫做"报文段序号"
  • 确认号:ACK序号,32bits(4 bytes),是期望收到对方下一个报文段的第一个数据字节的序号。例如:B正确收到了A发送过来的一个报文段,其序号字段值是501,而数据长度是200字节(序号501~700),这表明B正确收到了A发送的到序号700为止的数据。因此B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701,需要注意的是现在的确认号不是501,也不是700,而是701,总之需要记住:若确认号=N,则表明:到序号N-1为止的所有数据都已正确收到,由于序号字段有32位长,可对4GB(即4千兆字节)的数据进行编号,在一般情况下可保证当序号重复使用时,旧序号的数据早已通过网络到达终点了
  • 数据偏移:4bits,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。这个字段实际上是指出TCP报文段的首部长度,由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的,但应注意"数据偏移"的单位是32位字(即以4字节长的字为计算单位),由于4位二进制数能够表示的最大十进制数字是15,因此数据偏移的最大值是60字节,这也是TCP首部的最大长度(即选项长度不能超过40字),数据偏移的实际值为数据偏移除以4,所以该字段值在5(5*4=20)~15(15*4=60)之间
  • 保留字段:6bits,保留为今后使用,但目前应置为0
  • 标志位:6bits,URG、ACK、PSH、RSH、SYN、FIN,具体含义如下:
    • 紧急URG:紧急指针位(URGent),当URG=1时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据,这时要与首部中紧急指针(Urgent Pointer)字段配合使用
    • 确认ACK:确认位(ACKnowledge),仅当ACK=1时确认号字段才有效,当ACK=0时,确认号无效,TCP规定在连接建立后所有传送的报文段都必须把ACK置1
    • 推送PSH:推送位(PuSH),当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应,在这种情况下TCP就可以使用推送(push)操作,这时发送方TCP把PSH置1并立即创建一个报文段发送出去,接收方TCP收到PSH=1的报文段就尽快地(即"推送"向前)交付接收应用进程,而不再等到整个缓存都填满了后再向上交付
    • 复位RST:重置位(ReSeT),当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接然后再重新建立运输连接,RST置1还用来拒绝一个非法的报文段或拒绝打开一个连接,RST也可称为重建位或重置位,RST置为1的情况主要有以下几种:拒绝连接请求、异常终止连接、终止空闲连接
    • 同步SYN:同步位(SYNchronous),在连接建立时用来同步序号,当SYN=1而ACK=0时,表明这是一个连接请求报文段,对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1,因此SYN置为1就表示这是一个连接请求或连接接受报文
    • 终止FIN:终止位(Final),用来释放一个连接,当FIN=1时表明此报文段的发送方的数据已发送完毕并要求释放运输连接
  • 窗口大小:8bits,窗口值是[0,2*16-1]之间的整数,窗口指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口),窗口值告诉对方从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位),之所以要有这个限制是因为接收方的数据缓存空间是有限的,总之窗口值作为接收方让发送方设置其发送窗口的依据,在部分抓包工具中会看到Window和Calculated window size不一样,这时候可以通过Window size scaling factor的值与Window的值相乘得出Calculated window size,表示窗口具有伸缩特性,当前窗口比较小但可以变化,变化的系数是Window size scaling factor,最大是Calculated window size
  • 检验和:16bits,检验和字段检验的范围包括首部和数据这两部分,在计算检验和时要在TCP报文段的前面加上12字节的伪首部,但应把伪首部第4个字段中的17改为6(TCP的协议号是6),把第5字段中的UDP长度改为TCP长度,接收方收到此报文段后仍要加上这个伪首部来计算检验和,若使用IPv6则相应的伪首部也要改变
  • 检验和字段检验的范围包括首部和数据这两部分,在计算校验和时要在TCP报文段的前面加上12字节的伪首部(IP地址)
  • 紧急指针:16bits,紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),因此紧急指针指出了紧急数据的末尾在报文段中的位置,当所有紧急数据都处理完时TCP就告诉应用程序恢复到正常操作,值得注意的是即使窗口为零时也可发送紧急数据
  • 选项字段:长度可变,最长可达40字节,TCP最初只规定了一种选项,即最大报文段长度MSS(Maximum Segment Size),MSS告诉对方TCP缓存所能接收的报文段的数据字段的最大长度是MSS个字节,其最大长度可根据TCP首部长度进行推算,MSS是TCP报文段中数据字段的最大长度,数据字段加上TCP首部才等于整个TCP报文段,MSS=MTU-20(TCP headers)-20(IP headers),一般情况下MTU在以太网中默认是1500bytes,所以得出MSS=1460 bytes
报文示例

下面我们利用Wireshark抓取一个TCP数据包,查看其具体数据结构和实际的数据

在数据帧部分,前14字节为以太网帧头部,之后的20字节为IP头部,后面的32字节为TCP头部数据,故而这里的头部长度为:32/4=8,即1000,加上后面的0000,即为80

三次握手

TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,下图画出了三报文握手建立TCP连接的过程:

假定主机A运行的是TCP客户程序,而B运行TCP服务器程序,最初两端的TCP进程都处于CLOSED(关闭)状态,图中在主机下面的方框分别是TCP进程所处的状态,在开始阶段B的TCP服务器进程会先创建传输控制块TCB准备接受客户进程的连接请求,然后服务器进程就处于LISTEN(收听)状态等待客户的连接请求,如有则会立即作出响应,需要注意的是A主动打开连接,而B被动打开连接:

第一次握手:A的TCP客户进程首先创建传输控制模块TCB,然后在打算建立TCP连接时向B发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x,TCP规定SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号,这时TCP客户进程进入SYN-SENT(同步已发送)状态

第二次握手:B收到连接请求报文段后,如果同意建立连接则向A发送确认,在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y,请注意这个报文段也不能携带数据,但同样要消耗掉一个序号,这时TCP服务器进程进入SYN-RCVD(同步收到)状态

第三次握手:TCP客户进程收到B的确认后还要向B给出确认,确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1,TCP的标准规定ACK报文段可以携带数据,但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=x+1,这时TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态

四次分手

TCP连接释放过程比较复杂,在数据传输结束后通信的双方都可释放连接,现在A和B都处于ESTABLISHED状态,整个流程如下:

第一次挥手:A的应用进程先向其TCP发出连接释放报文段并停止再发送数据并主动关闭TCP连接,A把连接释放报文段首部的终止控制位FIN置1,其序号seq=u,它等于前面已传送过的数据的最后一个字节的序号加1,这时A进入FIN-WAIT-1(终止等待1)状态,等待B的确认,需要注意的是TCP规定FIN报文段即使不携带数据,它也消耗掉一个序号

第二次挥手:B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1,然后B就进入CLOSE-WAIT(关闭等待)状态,TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭(half-close)状态,即A已经没有数据要发送了,但是此时如果B发送数据,那么A仍要接收,也就是说从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间

第三次挥手:A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段,此时如果B已经没有要向A发送的数据,其应用进程就通知TCP释放连接,这时B发出的连接释放报文段必须使FIN=1,现假定B的序号为w(在半关闭状态B可能又发送了一些数据),B还必须重复上次已发送过的确认号ack=u+1,这时B就进入LAST-ACK(最后确认)状态,等待A的确认

第四次挥手:A在收到B的连接释放报文段后必须对此发出确认,在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号),然后进入到TIME-WAIT(时间等待)状态,需要注意的是现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态,时间MSL叫做最长报文段寿命(Maximum Segment Lifetime),RFC 793建议设为2分钟,但这完全是从工程上来考虑的,对于现在的网络MSL=2分钟可能太长了一些,因此TCP允许不同的实现可根据具体情况使用更小的MSL值,因此从A进入到TIME-WAIT状态后要经过4分钟才能进入到CLOSED状态才能开始建立下一个新的连接,当A撤销相应的传输控制块TCB后就结束了这次的TCP连接

很多人可能会问这里为什么A在TIME-WAIT状态必须等待2MSL的时间,主要有两个理由:

  • 第一:为了保证A发送的最后一个ACK报文段能够到达B,这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入到CLOSED状态。如果A在TIME-WAIT状态不等待一段时间而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段,这样B就无法按照正常步骤进入CLOSED状态
  • 第二:防止上一节提到的"已失效的连接请求报文段"出现在本连接中,A在发送完最后一个ACK报文段后再经过时间2MSL就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段,B只要收到了A发出的确认就进入CLOSED状态,同样B在撤销相应的传输控制块TCB后,就结束了这次的TCP连接,我们注意到B结束TCP连接的时间要比A早一些
连接重置

在理想情况中每一个连接都会以TCP终止来正常地结束,但在现实中连接经常会突然断掉,例如:攻击者在进行端口扫描被EDR等检测到后直接阻断连接,在这些情况下就需要使用设置了RST标志的TCP数据包,RST标志用来指出连接被异常中止或拒绝连接请求

下图给出了一个包含有RST数据包网络流量的例子,这个文件中的第一个数据包发自192.168.100.138,其尝试与192.168.100.1的80端口进行通信,这个主机并不知道192.168.100.1并没有在监听80端口,因为那是一个思科路由器并且没有配置Web接口,也就是说并没有服务监听80端口的连接,为了响应这个连接请求,192.168.100.1向192.168.100.138发送了一个数据包告诉它其对80端口的通信无效,图中展示了在第二个数据包的TCP头中这个连接尝试突然终止的情况,RST数据包除了包含RST和ACK标志外,没有任何其他的东西,之后也并没有额外的通信

端口扫描

端口扫描是一种主要用于在目标主机或网络上扫描开放的TCP或UDP端口的网络安全技术,它通常是通过发送网络数据包并等待响应来实现的,端口扫描可以用于检测网络中存在的漏洞和弱点也可以用于发现网络中的潜在攻击目标,常见的端口扫描工具包括Nmap、Zmap、Masscan等,下面是一些快速检索TCP端口扫描的过滤规则

TCP SYN扫描

TCP SYN扫描是一种常见的端口扫描技术,它发送一个TCP SYN包到目标主机的每个端口,然后等待目标主机的响应,如果目标主机响应TCP SYN/ACK包,那么这个端口就是开放的,如果目标主机响应RST包,那么这个端口就是关闭的,过滤语法如下:

代码语言:javascript
复制
tcp.flags.syn == 1 and tcp.flags.ack == 0
TCP Null扫描

TCP NULL扫描是一种常见的端口扫描技术,它发送一个TCP包到目标主机的每个端口,这个TCP包没有设置任何标志位,然后等待目标主机的响应。如果目标主机响应了一个TCP RST包,那么这个端口就是关闭的,如果目标主机不响应,那么这个端口可能是开放的或者过滤了,相关语法如下:

代码语言:javascript
复制
#扫描语法
nmap -sN 192.168.204.132 -p 21,22,80,8888,3306,3389
TCP FIN 扫描

TCP FIN扫描是一种常见的端口扫描技术,它发送一个TCP包到目标主机的每个端口,这个TCP包设置了FIN标志位,然后等待目标主机的响应,如果目标主机响应了一个TCP RST包,那么这个端口就是关闭的,如果目标主机不响应,那么这个端口可能是开放的或者过滤了

代码语言:javascript
复制
#扫描语法
nmap -sF 192.168.204.132 -p 21,22,80,8888,3306,3389
代码语言:javascript
复制
#过滤语法
tcp.flags==0x001
TCP Xmass扫描

TCP Xmas扫描是一种用于探测目标主机的TCP端口扫描技术,它会发送一个TCP数据包,其中所有的标志位都被设置为1(即URG、ACK、PSH、RST、SYN和FIN),如果目标主机的端口是关闭的则它会发送一个RST响应,表示拒绝连接。如果端口是打开的,则目标主机不会发送任何响应,这被视为一种"暗扫描"技术,因为它不会在目标主机的日志中留下任何记录,由于TCP Xmas扫描使用的是非常不寻常的TCP标志组合,因此它可以绕过某些防火墙或入侵检测系统的检测,但是许多网络安全工具现在都可以检测和防止TCP Xmas扫描

代码语言:javascript
复制
#扫描语法
namp -sX
代码语言:javascript
复制
#过滤语法
tcp.flags.fin==1 && tcp.flags.urg==1 && tcp.flags.push==1
TCP ACK扫描

TCP ACK扫描是一种网络扫描技术,它会发送一个ACK包到目标主机的指定端口,如果收到了RST包,则表示该端口关闭;如果收到了带有标志位的包,则表示该端口开放

代码语言:javascript
复制
#扫描语法
nmap -sA 192.168.204.132 -p 21,22,80,8888,3306,3389
代码语言:javascript
复制
#过滤语法
tcp.flags.ack==1 && tcp.flags.syn==0 && tcp.flags.fin==0 && tcp.flags.rest==0
TCP RST扫描

TCP RST扫描是一种常见的端口扫描技术,它发送一个TCP RST包到目标主机的每个端口,然后等待目标主机的响应,如果目标主机响应RST包,那么这个端口就是关闭的,如果目标主机不响应,那么这个端口可能是开放的或者过滤了

代码语言:javascript
复制
#扫描语法
nmap -sR 192.168.204.132 -p 21,22,80,8888,3306,3389
代码语言:javascript
复制
#过滤语法
tcp.flags.reset == 1
文末小结

通过本文的介绍我们了解了WireShark的基本使用和TCP协议的原理,在分析TCP流时我们可以从序列号、确认号、窗口大小等方面入手,深入理解数据包的传输过程,同时我们也学会了如何利用WireShark的过滤器和统计功能,更加高效

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 七芒星实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 协议介绍
  • 报文格式
  • 报文示例
  • 三次握手
  • 四次分手
  • 连接重置
  • 端口扫描
    • TCP SYN扫描
      • TCP Null扫描
        • TCP FIN 扫描
          • TCP Xmass扫描
            • TCP ACK扫描
              • TCP RST扫描
              • 文末小结
              相关产品与服务
              主机安全
              主机安全(Cloud Workload Protection,CWP)基于腾讯安全积累的海量威胁数据,利用机器学习为用户提供资产管理、木马文件查杀、黑客入侵防御、漏洞风险预警及安全基线等安全防护服务,帮助企业构建服务器安全防护体系。现支持用户非腾讯云服务器统一进行安全防护,轻松共享腾讯云端安全情报,让私有数据中心拥有云上同等级别的安全体验。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档