本帖最后由 xxx314 于 2013-6-15 02:40 编辑
TCP会话,UDP会话,IP会话等等,在网络安全领域中,进行网络异常行为识别是离不开各种各样的数据会话的,那么什么是会话?会话意味着什么?我们网络传输的单个数据包如何重组为会话?
会话,我们常说session,本来的含义是指有始有终的一系列的动作/消息。Eg:打电话时,从拿起电话拨号到挂断电话这之间的一系列过程,我们可以称为一个session。
TCP是一个可靠的,连接定向的发送服务,数据分段传送。连接定向意味着在主机交换数据之前必须建立会话(建立连接),一次TCP会话通过经典的Three-Way Handshake(跟对方打招呼→对方回应→建立连接)来实现。即TCP会话就是Three-Way Handshake这一系列过程。
大家知道,在传输数据的时候,通常是不能够进行一个数据包就传输了所有的数据包,一般都是会涉及到数据的分段传输,如下图所示(这里不分段)
那么,我们想,我们的这些数据被分割了,怎么才能组装回来呢?组装的机制是什么呢?这个跟诸如文件分割了,再进行组装有什么不同?区别在哪些地方?下面就给大家分享一下基于TCP的会话重组.
TCP建立连接
一次TCP会话建立的时候需要三个报文交换,即大家常说的三次握手,其建立过程如下所示
TCP数据的传输
当双方建立了连接时,网络就可以传输数据了,传输过程中,发送方每次发送一个数据包,在接收方都会给予应答ACK,以示接收成功(注:由于网络延迟或者其他原因诸如丢包等等造成应答ACK没有在发送方的等待时间内给予应答,这时,就会涉及到重传)。数据包的发送的先后关系也就可以用在TCP首部中的SEQ和ACK来进行确定,在客户端和服务器端两个方面,发送数据包的长度为X,序号为SEQ,确认号为ACK,那么下一个将要发送的数据包的序号即为SEQ+X,接收方的应答的数据包的序号为ACK,意为应答的是上一个序号为SEQ,长度为X的数据包,对这个数据包在进行确认。
TCP断开连接
TCP终止一次会话连接需要经过四次握手信息,在TCP连接上,由于是全双工(数据在两个方向都能同时进行传输),所以在每个方向都必须进行单独的关闭,所以在TCP会话终止过程也就是双方单独关闭的一个过程。如下图所示:
TCP会话还原的依据:
在TCP建立连接之后,会为后续的TCP数据的传输设定一个初始的序列号,以后每次传输TCP数据包,后续的传输的TCP就会在序列号上面做出相应的修改。所以,为了保证TCP数据包的按序传输,也就有了序列号,也就保证了TCP数据的完整传输,特别是我们的数据在传输过程中出现了错误,这样可以进行错误的修正。在TCP会话的重新组合过程中,我们也就需要按照数据包的序列号来进行排序,重组会话(过程中会涉及到会话的重传,数据的重复等等网络数据情况,这些都是需要进行数据的偏移重定位)
主机A在即将发送的报文中的SEQ的值应等于它所刚刚收到的报文的ACK的值,而它所要发送报文中的ACK的值应为其所收到的报文中的SEQ的值加上其报文中所发送的TCP的数据的长度,所以在当前发送的报文中SEQ和ACK存在如下关系:
1、
本次发送SEQ=上次收到报文的ACK的值
2、
本次发送的ACK=上次收到的SEQ+本次发送的TCP的数据段的长度
报文的还原
其实在网络上,我们知道可以同时传输的数据是来自不同的计算机的,所以会存在很多的不同的会话,那么这些会话在进行数据重组的时候,怎么区分了?这里引进一个叫元组的概念用以进行唯一会话的标识,这里我们以源、目的IP地址,源、目的MAC地址,源、目的端口这样的一个六元组来进行会话的唯一标识,在网络上的数据,只有满足这六元组信息,我们才认为是同一个会话的数据。
首先,我们需要设计两个报文队列,用于存储TCP会话报文,一个存放正常序列的报文,一个用以存储失序的报文。
报文来的序列假设如下,文数据段第一个字节序号如下所示:
下一个来到的报文可能存在如下情况:
1、正常报文
这样,seq2=
seq1+len1
所以,此报文携带数据序号为200~399,是第一个报文的期望后续报文,因此直接做追加操作即可,即把此报文追加在第一个报文之后即可。
2、完全重复报文
Seq2= seq1
& len2 = len1
所以,此报文携带数据序号为100~199,与上一个报文携带的数据完全重复了,直接丢弃报文(重复可能原因:由于网络延迟,导致报文延迟到达了,但是这边服务器端不知道是因为延迟,所以客户端又会重传,但是上一个报文还在网络中传输,所以就可能存在重复报文)
3、重复子报文
这样直到TCP断开这个socket的链接(FIN=1<正常情况>),此时将正常报文队列和失序报文队列中的数据合并起来,完成重组。取出正常报文队列最后一
第二、三这两种情况可以合并,即seq2 ==seq1而且len2<=len1,这里分别列出只是为了说明各种不同情况。
4、部分重复报文情况一
seq2>seq1而且seq2<seq1+len1而且seq2+len2<=seq1+len1
即这个报文携带序号150~179,这个序号段被包含在上一个报文段中(100~199),
所以应该丢弃这个报文。
5、部分重复报文情况二
seq2>seq1而且seq2<seq1+len1而且seq2+len2>seq1+len1
即这个报文携带序号150~249,这个序号段前一部分150~199被包含在上一个报文段(100~199)中,后一部分200~249是新的数据,此时应该对这个报文作如下处理:
A. 计算重复字节数
(seq1+len1)- Seq2= 100+100-150 =
50
即这个报文段前50个字节是重复的,直接丢弃不要,后面的50字节的保留存储。
B. 截取报文段新数据
丢弃这个报文段的前50字节,截取后面的新数据,即只保留字节序号段200~249。
C. 重新设置这个报文段的seq
seq2= seq2+50 = 150+50 = 200
D. 重新设置这个报文段的数据长度
len2= len2-50 =100-50=50
E. 重新设置后报文段如下
即现在这个报文段携带数据序号200~249,正好是上一个报文的后续报文,现在可以将其作为正常报文追加到正常报文队列。
6、提前到达的报文
seq2>seq1+len1
这个报文段携带序号300~399的数据,即不是上一个报文100~199的后续报文,而是提前到来的报文,此时应该将这个报文放置到失序报文队列存储起来,以备后续重组使用。
个报文的seq和len,在失序报文队列中查找属于它的后续报文,该报文是否可以作为正常报文队列的后续报文处理过程同前面1~5的分析。
把正常报文和失序报文进行合并重组即可完成会话的重组! |