一. TCP协议简介

TCP是传输层的协议,传输层的作用是:

  • 定义应用层数据报文的端口号
  • 流量控制
  • 对原始数据进行分段处理
  • 纠错

1. 传输层

(1) 传输层所提供的服务

传输连接服务

数据传输服务:浏览控制、差错控制,序列控制

(2) 传输层协议

面向连接的传输协议 - TCP

用户数据报协议 - UDP

2. 传输层的TCP协议

TCP要求数据在传输以前必须建立连接(三次握手);数据传输完成后,必须释放连接(四次挥手),而且它仅支持单播传输:在两个终端之间建立的点对点的连接

二. TCP数据包

我们在kali一个http服务,然后用win7去访问它

  • kali IP:192.168.40.129
  • win7 IP:192.168.40.135

我们抓个包看看,抓到后我们看TCP的报文

1. 前面的一些报文

我们可以看到192.68.40.135和192.168.40.129这两个IP之间搭建了TCP连接

我们打开一个报文看看

可以看到,TCP报文里有一个发送的端口号49189,接收方的端口号80.

往下有一个Sequence Number(raw),这个是真实的序列,然后有raw和没有raw的其实是一个

下面有一个 Acknowledgment number(raw),这个是确认的序列号,有raw和没有raw的这里也是一个

再往下就是Header Length首部长度,这里是32位,标识的是整个TCP的首部长度为32

然后是就是Flags控制位

2. Flags控制位

我们看一下控制位

最常见的就是URG,ACK,PUSH,RESET,SYN和FIN

(1) URG

URG控制位主要表示是否是紧急发送。

这里看到是 Not set,就是没有设置

(2) SYN

SYN是建立连接的时候来用的,比如我们上面的那张图。

SYN那里是标1,代表正在发起请求。

(3) ACK

ACK表示确认的控制位,一般是我们和服务器进行请求,我们请求完后,服务器会有一个确认,所以这个ACK通常是会有set的

我们这张图是第一次请求,还没请求完呢,所以是 Not set

这张图就是后面请求完的,这里就有set了,控制位有一个1

(4) PUSH

PUSH定义是否将数据推到上一层

如果说推到上一层的话,就是应用层,他应该是应用层的协议

就像这个,他的PUSH设置了,就有了一个HTTP协议。

(5) RESET

RESET代表是否重置连接

(6) FIN

当数据传输完毕后会有一个释放连接,当释放连接的时候这个位置就有了。

就像这样,这里就是释放了连接

3. TCP报文字段

(1) 简单看图

我前面也简单的介绍了一下,我们看下图

(2) 字段理解

下面具体介绍以下字段的含义

  • 第一行:源端口和目的端口字段

    • TCP源端口(Source Port):源计算机上的应用程序的端口号,占16 位(bit)。
    • TCP目的端口(Destination Port):目标计算机的应用程序端口号,占16 位(bit)。
  • 第二行:序列号字段

    • CP序列号(Sequence Number):占(32bit)它表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中,所传送的字节流的每一个字节都会按顺序编号。
    • 当SYN标记不为1时,这是当前数据分段第一个字母的序列号;
    • 如果SYN的值是1时,这个字段的值就是初始序列值(ISN),用于对序列号进行同步。这时,第一个字节的序列号比这个字段的值大1,也就是ISN加1。
  • 第三行:确认号字段

    • TCP 确认号:(Acknowledgment Number,ACK Number):占 32 位。它表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。其值是接收计算机即将接收到的下一个序列号,也就是下一个接收到的字节的序列号加1。
  • 第四行

    • 数据偏移字段
      • TCP 首部长度(Header Length):数据偏移是指数据段中的“数据”部分起始处距离 TCP 数据段起始处的字节偏移量,占 4 位。其实这里的“数据偏移”也是在确定 TCP 数据段头部分的长度,告诉接收端的应用程序,数据从何处开始。
    • 保留字段
      • 保留(Reserved):占 4 位。为 TCP 将来的发展预留空间,目前必须全部为 0。
    • 标志位字段
      • CWR(Congestion Window Reduce):拥塞窗口减少标志,用来表明它接收到了设置 ECE 标志的 TCP 包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率
      • ECE==ECN(ECN Echo):用来在 TCP三次握手时表明一个 TCP 端是具备 ECN (显式拥塞通告)功能的。在数据传输过程中,它也用来表明接收到的 TCP 包的 IP 头部的 ECN 被设置为 11,即网络线路拥堵。
      • URG(Urgent):表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效
      • ACK:表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1
      • PSH(Push):告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1,表示应当立即把数据提交给上层,而不是缓存起来
      • RST:表示是否重置连接。如果 RST=1,说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
      • SYN:在建立连接时使用,用来同步序号。
        • 当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;
        • 当 SYN=1,ACK=1 时,表示对方同意建立连接。
        • SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
      • FIN:标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。
    • 窗口大小字段
      • 窗口大小(Window Size):占 16 位。它表示从 Ack Number 开始还可以接收多少字节的数据量,也表示当前接收端的接收窗口还有多少剩余空间。该字段可以用于 TCP 的流量控制。
  • 第五行

    • TCP校验和字段
      • 校验位(TCP Checksum):占 16 位。它用于确认传输的数据是否有损坏。
        发送端基于数据内容校验生成一个数值,接收端根据接收的数据校验生成一个值。两个值必须相同,才能证明数据是有效的。如果两个值不同,则丢掉这个数据包。Checksum 是根据伪头 + TCP 头 + TCP 数据三部分进行计算的。
    • 紧急指针字段
      • 紧急指针(Urgent Pointer):仅当前面的 URG 控制位为 1 时才有意义。它指出本数据段中为紧急数据的字节数,占 16 位。当所有紧急数据处理完后,TCP 就会告诉应用程序恢复到正常操作。即使当前窗口大小为 0,也是可以发送紧急数据的,因为紧急数据无须缓存。
  • 第六行:可选项字段

    • 选项(Option):可以自定义头部字段,长度不定,但长度必须是 32bits 的整数倍
  • 第七行:TCP数据

    • 数据部分(可以不发送任何数据)

三. TCP三次握手

我们简单画一个图就好理解了。

这里有一个客户端和服务端,服务端开启了HTTP服务,也就是说服务端有一个网站

然后客户端访问服务端的网址.

我们可以想象这个过程是两个人在打招呼聊天

1. C向S请求连接

这个过程就是C向S说了一句:’Hi!’

最开始是向服务端请求连接,请求连接,那根据我们上面说的,SYN会设置为1

然后在这里会生成一个序号(seq),我们这里定义它为780071038

这里对应的实际抓包就是这样的

2. 服务器确认请求

这个过程就是S看向C,问:”你在找我?”

C发送S一个数据包后,S会进行一个确认,然后会进行一个确认的响应

这个过程是一个建立请求的过程,所以SYN会有设置,设置为1,同时这是一个S对C的响应,所以还会有一个ACK控制位也设置为1.

然后acknumber的数值是seq+1.

同时这个也是请求的过程,意味着这个也会有seq值,不过是一个新的seq值

这个还有一个新的seq注意一下,我没用红框标注。

3. C确认S

这个过程就是C对S说,问:”对就是找你”

我们想一想这个过程是请求吗?

客户机对服务器说一句:”hi”;S问C:”你和我说话吗?”。

前两个过程,这俩是不是已经就建立好了请求啊,也就是这俩已经有对话了,所以这个就不是请求了,是一个回答,所以只有ACK。

然后这个ack是过程二的seq的值加1.

然后这里的seq,由于没有SYN,所以这玩应没有意义

我们这里也可以注意以下,这个seq的值是不是第二步的ack值相等。

4. TCP三次握手总结

三次握手的目的我们可以看出来,就是为了建立连接。

过程抽象点就是:

“Hi!” -> “你在和我说话?” -> “对”

    1. Hi的过程是建立请求,发送SYN包,有seq值的设置,我们把这个值用一个变量定义

    seq=x

    1. “你在和我说话?”这个过程也是在建立请求,发送SYN包,有seq值的设置;同时也是一个回答,发送ACK包,有ACK值的设置

    ack=x+1=z
    new_seq=y

    1. “对”这个过程就不是请求了,就是一个回答,没有SYN了,有ACK

    ack=y+1
    new_seq=z

四. 发送数据

当经过三次握手后,C和S之间已经建立了连接。

这个时候,S就会向C发送他所要的数据。

五. TCP四次挥手

当发送数据后,就要断开连接了。这个过程就是四次挥手。

这个过程可能会出现一些教学事故。

1. C提示S数据传输完毕

这个过程就是C对S说:”咱俩可以结束了”

这个最明显的是结束的标志,所以一定有FIN控制符。

然后,这里还应该有一个ACK的控制符。

我们想一下,C向S请求数据,然后S开始发送,然后C告诉S数据传输完毕,这也是一个对请求的回应。

然后我们看抓包

这个包就是我们要找的第一个包。

注意一下这些值:seq=3635267377;ack=36812231042

2. S回应C

这个过程就是S对C说:”哦,结束了”

就是一个ack回应

然后注意一下seq和ack的值。

seq是3681231042,ack是3635267378,ack的值是上一个的seq+1

3. 剩下的

这里没抓到……

这就是教学事故,因为这个包还受其他的影响

4.总结

其实就是一张图