TCP头部格式详解,附Wireshark对TCP头部抓包分析

TCP之所以能为数据通讯提供可靠的传输,主要在于TCP数据包头部功能非常多。

那么,我们先来看看TCP头部格式(RFC 793、1323定义了TCP头部):

TCP头部格式详解,附Wireshark对TCP头部抓包分析

TCP头部格式中的内容解析如下:(文末还有Wireshark对TCP抓包分析图)

(根据上图,按从上往下,从左往右的顺序)

  • Source Port:16bit源端口,数据发起者的端口号;
  • Destination Port:16bit目的端口,数据接收方的端口号;
  • Sequence Number:32bit的序列号,由发送方使用;
  • Acknowledgment Number:32bit的确认号,接收数据方返回给发送方的通知,会在确认号的基础上加1;
  • Data Length:4bit头部长度,TCP头部长度一般为20字节,若TCP头部的Options选项启用,则会增加;
  • 下面一部分为TCP的功能bit:
    1. Reserved、Reserved、Nonce、CWR、ECN-Echo:共6bit的保留功能,留待以后开发新技术时使用;
    2. URG:1bit紧急指针位,取值1代表这个数据是紧急数据需加速传递,取值0代表这是普通数据;
    3. ACK:1bit确认位,取值1代表这是一个确认的TCP包,取值0则不是确认包;
    4. PSH:1bit紧急位,取值1代表要求发送方马上发送该分段,而接收方尽快的将报文交给应用层,不做队列处理。取值0阿迪表这是普通数据;
    5. RST:1bit重置位,当tcp收到一个不属于该主机的任何一个连接的数据,则向对方发一个复位包,此时该位取值为1,若取值为0代表这个数据包是传给自己的;
    6. SYN:1bit请求位,取值1代表这是一个TCP三次握手的建立连接的包,取值为0就代表是其他包;
  • FIN:1bit完成位,取值1代表这是一个TCP断开连接的包,取值为0就代表是其他包;
  • Window Size:16bit窗口大小,表示准备收到的每个TCP数据的大小;
  • Checksum:16bit的TCP头部校验,计算TCP头部,从而证明数据的有效性;
  • Urgent Pointer:16bit紧急数据点,当功能bit中的URG取值为1时有效;(参考:TCP中URG和PSH以及Urgent Point的作用及区别)
  • Options:TCP的头部最小20个字节。如果这里有设置其他参数,会导致头部增大;
  • Padding:当TCP头部小于20字节时会出现,不定长的空白填充字段,填充内容都是0,但是填充长度一定会是32的倍数;
  • Data:被TCP封装进去的数据,包含应用层协议头部和用户发出的数据。

Wireshark对TCP抓包分析图

大家也可以对照着下面这张Wireshark对TCP抓包分析图,看看一个真正基于TCP数据包中,TCP头部格式是怎样的。

下图为一个telnet数据包的格式,telnet用的传输层协议就是TCP,下图中被红线框中的就是TCP头部:

TCP头部格式详解,附Wireshark对TCP头部抓包分析

三次握手Three-way Handshake
  一个虚拟连接的建立是通过三次握手来实现的
  1. (Client) –> [SYN] –> (Server)
  假如Client和Server通讯. 当Client要和Server通信时,Client首先向Server发一个SYN (Synchronize) 标记的包,告诉Server请求建立连接.
  注意: 一个 SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources). 认识到这点很重要,只有当Server收到Client发来的SYN包,才可建立连接,除此之外别无他法。因此,如果你的防火墙丢弃所有的发往外网接口的SYN包,那么你将不 能让外部任何主机主动建立连接。

  2. (Client) <– [SYN/ACK] <–(Server)
  接着,Server收到来自Client发来的SYN包后,会发一个对SYN包的确认包(SYN/ACK)给Client,表示对第一个SYN包的确认,并继续握手操作.
  注意: SYN/ACK包是仅SYN 和 ACK 标记为1的包.

  3. (Client) –> [ACK] –> (Server)
  Client收到来自Server的SYN/ACK 包,Client会再向Server发一个确认包(ACK),通知Server连接已建立。至此,三次握手完成,一个TCP连接完成。
  Note: ACK包就是仅ACK 标记设为1的TCP包. 需要注意的是当三此握手完成、连接建立以后,TCP连接的每个包都会设置ACK位。

  这就是为何连接跟踪很重要的原因了. 没有连接跟踪,防火墙将无法判断收到的ACK包是否属于一个已经建立的连接.一般的包过滤(Ipchains)收到ACK包时,会让它通过(这绝对不是个 好主意). 而当状态型防火墙收到此种包时,它会先在连接表中查找是否属于哪个已建连接,否则丢弃该包。

  四次握手Four-way Handshake
  四次握手用来关闭已建立的TCP连接

  1. (Client) –> ACK/FIN –> (Server)
  2. (Client) <– ACK <– (Server)
  3. (Client) <– ACK/FIN <– (Server)
  4. (Client) –> ACK –> (Server)

  注意: 由于TCP连接是双向连接, 因此关闭连接需要在两个方向上做。ACK/FIN 包(ACK 和FIN 标记设为1)通常被认为是FIN(终结)包.然而, 由于连接还没有关闭, FIN包总是打上ACK标记. 没有ACK标记而仅有FIN标记的包不是合法的包,并且通常被认为是恶意的。

  连接复位Resetting a connection

  四次握手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送. 注意在,由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记). 但在正常的TCP连接中RST包可以带ACK确认标记

  请注意RST包是可以不要收到方确认的?

  无效的TCP标记Invalid TCP Flags

  到目前为止,你已经看到了 SYN, ACK, FIN, 和RST 标记. 另外,还有PSH (Push) 和URG (Urgent)标记.

  最常见的非法组合是SYN/FIN 包. 注意:由于 SYN包是用来初始化连接的, 它不可能和 FIN和RST标记一起出现. 这也是一个恶意攻击.

  由于现在大多数防火墙已知 SYN/FIN 包, 别的一些组合,例如SYN/FIN/PSH, SYN/FIN/RST, SYN/FIN/RST/PSH。很明显,当网络中出现这种包时,很你的网络肯定受到攻击了。

  别的已知的非法包有FIN (无ACK标记)和”NULL”包。如同早先讨论的,由于ACK/FIN包的出现是为了关闭一个TCP连接,那么正常的FIN包总是带有 ACK 标记。”NULL”包就是没有任何TCP标记的包(URG,ACK,PSH,RST,SYN,FIN都为0)。

  到目前为止,正常的网络活动下,TCP协议栈不可能产生带有上面提到的任何一种标记组合的TCP包。当你发现这些不正常的包时,肯定有人对你的网络不怀好意。

  UDP (用户数据包协议User Datagram Protocol)

  TCP是面向连接的,而UDP是非连接的协议。UDP没有对接受进行确认的标记和确认机制。对丢包的处理是在应用层来完成的。(or accidental arrival).

  此处需要重点注意的事情是:在正常情况下,当UDP包到达一个关闭的端口时,会返回一个UDP复位包。由于UDP是非面向连接的, 因此没有任何确认信息来确认包是否正确到达目的地。因此如果你的防火墙丢弃UDP包,它会开放所有的UDP端口(?)。

  由于Internet上正常情况下一些包将被丢弃,甚至某些发往已关闭端口(非防火墙的)的UDP包将不会到达目的,它们将返回一个复位UDP包。

  因为这个原因,UDP端口扫描总是不精确、不可靠的。

  看起来大UDP包的碎片是常见的DOS (Denial of Service)攻击的常见形式 (这里有个DOS攻击的例子,http://grc.com/dos/grcdos.htm ).

  ICMP (网间控制消息协议Internet Control Message Protocol)

  如同名字一样, ICMP用来在主机/路由器之间传递控制信息的协议。 ICMP包可以包含诊断信息(ping, traceroute - 注意目前unix系统中的traceroute用UDP包而不是ICMP),错误信息(网络/主机/端口 不可达 network/host/port unreachable), 信息(时间戳timestamp, 地址掩码address mask request, etc.),或控制信息 (source quench, redirect, etc.) 。

  你可以在http://www.iana.org/assignments/icmp-parameters 中找到ICMP包的类型。

  尽管ICMP通常是无害的,还是有些类型的ICMP信息需要丢弃。

  Redirect (5), Alternate Host Address (6), Router Advertisement (9) 能用来转发通讯。

  Echo (8), Timestamp (13) and Address Mask Request (17) 能用来分别判断主机是否起来,本地时间 和地址掩码。注意它们是和返回的信息类别有关的。 它们自己本身是不能被利用的,但它们泄露出的信息对攻击者是有用的。

  ICMP消息有时也被用来作为DOS攻击的一部分(例如:洪水ping flood ping,死 ping ?呵呵,有趣 ping of death)?/p>

  包碎片注意A Note About Packet Fragmentation

  如果一个包的大小超过了TCP的最大段长度MSS (Maximum Segment Size) 或MTU (Maximum Transmission Unit),能够把此包发往目的的唯一方法是把此包分片。由于包分片是正常的,它可以被利用来做恶意的攻击。

  因为分片的包的第一个分片包含一个包头,若没有包分片的重组功能,包过滤器不可能检测附加的包分片。典型的攻击Typical attacks involve in overlapping the packet data in which packet header is 典型的攻击Typical attacks involve in overlapping the packet data in which packet header isnormal until is it overwritten with different destination IP (or port) thereby bypassing firewall rules。包分片能作为 DOS 攻击的一部分,它可以crash older IP stacks 或涨死CPU连接能力。

  Netfilter/Iptables中的连接跟踪代码能自动做分片重组。它仍有弱点,可能受到饱和连接攻击,可以把CPU资源耗光。

  OK,到此为止,关于Wireshark抓包工具的一些小教程已经写完了,而导致我想写这么一个纠结的教程的原因是,前几天通过这个抓包解决了梦幻西游在网维大师无盘上容易掉线的问题,当时捕捉到梦幻西游掉线时的数据包是这样的。
  注意下图中的红色数据,123.58.184.241是梦幻西游的服务器,而192.168.1.41是玩梦幻西游的客户机,在掉线时,发现是先有梦幻西游的服务器向客户机发送一个[FIN,ACK]数据包,根据上面的解释,FIN标记的数据包是代表要断开连接的意思,而接着客户机又回给服务器一个确认断开链接包。当看到这个抓包数据时,就意识到,大家说的在网维大师系统虚拟盘上梦幻爱掉线的问题,并非普通的网络问题,因为通过数据包的信息来看,是梦幻服务器主动要求断开链接,产生这个情况无非是以下几个原因:
1、服务器发现客户端非法,比如有外挂什么的,踢掉了客户机;
2、服务器压力大,踢掉了客户机;
3、总之不是客户端问题导致的掉线;
TCP头部格式详解,附Wireshark对TCP头部抓包分析

  那么既然结论是如此,为什么会有在网维大师系统虚拟盘上容易出现梦幻掉线问题呢?原因是由于网维大师系统虚拟盘是模拟真实硬盘方式来实现的,而在模拟过程中,将硬盘的序列号设置为固定过的OSDIY888了,而梦幻西游刚好后识别客户机硬盘信息,发现大量客户端的硬盘序列号都是一样的,就认为是作弊或者使用挂机外挂了,结果就导致随机被服务器踢下线的情况发生,后来我们将硬盘序列号设置为空,则没再出现该问题。这个问题在未来的新版本中会解决掉。

  说这个案例的目的并不是为了说明抓包多有用,而是想说明一些解决问题的思路和方法,有些人是有思路,但是缺方法,比如不会用工具,而有些人收集了很多工具却不会用,而我其实就属于后者,几年前就收集了n多工具,但是用到的没几个。慢慢的学会用这些工具后,发现思维+工具,解决问题是效率暴增,接下来的几天里,会陆续介绍写小工具给大家,也希望大家有空学习下,有问题先百度,再自己摸索,而不是一味的求助,毕竟求人不如求己!自己能直接搞定,是皆大欢喜的事情~

  另外还有一些网络监视相关的小工具也非常好用,这里就在这个帖子里简单介绍一下:
1、CurrPorts:这是一个可以显示系统进程联网状态的工具,他能显示哪个进程链接了哪个IP地址,哪个端口,使用的什么协议,本地端口是多少,本地IP地址是多少等等,而且他还提供了记录网络连接创建信息,点界面左上角的“文件”=》“记录变化到日志”就可以记录日志了。
2、Tcpview:和CurrPorts差不多的工具。
3、X-NetStat Professional:这个工具除了继承了CurrPorts的所有功能,同时还支持每个进程链接的IP地址使用的流量是多少,但是这个工具不要长时间开着,否则可能导致无盘客户机无法获得DHCP问题,只是随机出现,大家注意下就行了。
  这些工具都可以通过本站顶部的“小工具”链接打开工具军火库,然后在NetWork_analysis_Tools分类下就可以下载到了。

上一篇:Android中使用sqlite笔记


下一篇:在Win8 Mertro 中使用SQLite