1、TCP三次握手html
傳輸控制協議(Transport Control Protocol)是一種面向鏈接的,可靠的傳輸層協議。面向鏈接是指一次正常的TCP傳輸須要經過在TCP客戶端和TCP服務端創建特定的虛電路鏈接來完成,該過程一般被稱爲「三次握手」。可靠性能夠經過不少種方法來提供保證,在這裏咱們關心的是數據序列和確認。TCP經過數據分段(Segment)中的序列號保證全部傳輸的數據能夠在遠端按照正常的次序進行重組,並且經過確認保證數據傳輸的完整性。要經過TCP傳輸數據,必須在兩端主機之間創建鏈接。舉例說明,TCP客戶端須要和TCP服務端創建鏈接,過程以下所示:緩存
在第一步中,客戶端向服務端提出鏈接請求。這時TCP SYN標誌置位。客戶端告訴服務端序列號區域合法,須要檢查。客戶端在TCP報頭的序列號區中插入本身的ISN。服務端收到該TCP分段後,在第二步以本身的ISN迴應(SYN標誌置位),同時確認收到客戶端的第一個TCP分段(ACK標誌置位)。在第三步中,客戶端確認收到服務端的ISN(ACK標誌置位)。到此爲止創建完整的TCP鏈接,開始全雙工模式的數據傳輸過程。服務器
2、TCP標誌網絡
這裏有必要介紹一下TCP分段中的標誌(Flag)置位狀況。以下圖所示:socket
·SYN:同步標誌tcp
同步序列編號(Synchronize Sequence Numbers)欄有效。該標誌僅在三次握手創建TCP鏈接時有效。它提示TCP鏈接的服務端檢查序列編號,該序列編號爲TCP鏈接初始端(通常是客戶端)的初始序列編號。在這裏,能夠把TCP序列編號看做是一個範圍從0到4,294,967,295的32位計數器。經過TCP鏈接交換的數據中每個字節都通過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個字節的序列編號。post
·ACK:確認標誌url
確認編號(Acknowledgement Number)欄有效。大多數狀況下該標誌位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure-1)爲下一個預期的序列編號,同時提示遠端系統已經成功接收全部數據。操作系統
·RST:復位標誌翻譯
復位標誌有效。用於復位相應的TCP鏈接。
·URG:緊急標誌
緊急(The urgent pointer) 標誌有效。緊急標誌置位,
·PSH:推標誌
該標誌置位時,接收端不將該數據進行隊列處理,而是儘量快將數據轉由應用處理。在處理 telnet 或 rlogin等交互模式的鏈接時,該標誌老是置位的。
·FIN:結束標誌
帶有該標誌置位的數據包用來結束一個TCP回話,但對應端口仍處於開放狀態,準備接收後續數據。
3、TCP端口
爲了可以支持同時發生的並行訪問請求,TCP提供一種叫作「端口」的用戶接口。端口是操做系統核心用來識別不一樣的網絡回話過程。這是一個嚴格的傳輸層定義。經過TCP端口和IP地址的配合使用,能夠提供到達終端的通信手段。實際上,在任一時刻的互聯網絡鏈接能夠由4個數字進行描述:來源IP地址和來源端口,目的IP地址和目的端口。位於不一樣系統平臺,用來提供服務的一端經過標準的端口提供相應服務。舉例來講,標準的TELNET守護進程(telnet daemon)經過監聽TCP 23端口,準備接收用戶端的鏈接請求。
4、TCP緩存(TCP Backlog)
一般狀況下,操做系統會使用一塊限定的內存來處理TCP鏈接請求。每當用戶端發送的SYN標誌置位鏈接請求到服務端的一個合法端口(提供TCP服務的一端監聽該端口)時,處理全部鏈接請求的內存使用量必須進行限定。若是不進行限定,系統會因處理大量的TCP鏈接請求而耗盡內存,這在某種程度上能夠說是一種簡單的DoS攻擊。這塊通過限定的,用於處理TCP鏈接的內存稱爲TCP緩存(TCP Backlog),它其實是用於處理進站(inbound)鏈接請求的一個隊列。該隊列保存那些處於半開放(half-open)狀態的TCP鏈接項目,和已創建完整鏈接但仍未由應用程序經過accept()調用提取的項目。若是這個緩存隊列被填滿,除非能夠及時處理隊列中的項目,不然任何其它新的TCP鏈接請求會被丟棄。
通常狀況下,該緩存隊列的容量很小。緣由很簡單,在正常的狀況下TCP能夠很好的處理鏈接請求。若是當緩存隊列填滿的時候新的客戶端鏈接請求被丟棄,客戶端只須要簡單的從新發送鏈接請求,服務端有時間清空緩存隊列以相應新的鏈接請求。
在現實環境中,不一樣操做系統支持TCP緩衝隊列有所不一樣。在BSD結構的系統中,以下所示:
5、TCP進站(Inbound)處理過程
爲了更好的講述TCP SYN Flood的攻擊過程,咱們先來介紹一下正常狀況下,TCP進站處理的過程。
服務端處於監聽狀態,客戶端用於創建鏈接請求的數據包(IP packet)按照TCP/IP協議堆棧組合成爲TCP處理的分段(segment)。
分析報頭信息:TCP層接收到相應的TCP和IP報頭,將這些信息存儲到內存中。
檢查TCP校驗和(checksum):標準的校驗和位於分段之中(Figure-2)。若是檢驗失敗,不返回確認,該分段丟棄,並等待客戶端進行重傳。
查找協議控制塊(PCB{}):TCP查找與該鏈接相關聯的協議控制塊。若是沒有找到,TCP將該分段丟棄並返回RST。(這就是TCP處理沒有端口監聽狀況下的機制) 若是該協議控制塊存在,但狀態爲關閉,服務端不調用connect()或listen()。該分段丟棄,但不返回RST。客戶端會嘗試從新創建鏈接請求。
創建新的socket:當處於監聽狀態的socket收到該分段時,會創建一個子socket,同時還有socket{},tcpcb{}和pcb{}創建。這時若是有錯誤發生,會經過標誌位來拆除相應的socket和釋放內存,TCP鏈接失敗。若是緩存隊列處於填滿狀態,TCP認爲有錯誤發生,全部的後續鏈接請求會被拒絕。這裏能夠看出SYN Flood攻擊是如何起做用的。
丟棄:若是該分段中的標誌爲RST或ACK,或者沒有SYN標誌,則該分段丟棄。並釋放相應的內存。
TCP/IP是不少的不一樣的協議組成,其實是一個協議組,TCP用戶數據報表協議(也稱做TCP傳輸控制協議,Transport Control Protocol。可靠的主機到主機層協議。這裏要先強調一下,傳輸控制協議是OSI網絡的第四層的叫法,TCP傳輸控制協議是TCP/IP傳輸的6個基本協議的一種。兩個TCP意思非相同。 )。
TCP是一種可靠的面向鏈接的傳送服務。它在傳送數據時是分段進行的,主機交換數據必須創建一個會話。它用比特流通訊,即數據被做爲無結構的字節流。經過每一個TCP傳輸的字段指定順序號,以得到可靠性。是在OSI參考模型中的第四層,TCP是使用IP的網間互聯功能而提供可靠的數據傳輸,IP不停的把報文放到網絡上,而TCP是負責確信報文到達。在協同IP的操做中TCP負責:握手過程、報文管理、流量控制、錯誤檢測和處理(控制),能夠根據必定的編號順序對非正常順序的報文給予重新排列順序。關於TCP的RFC文檔有RFC79三、RFC79一、RFC1700。
在TCP會話初期,有所謂的「三握手」:對每次發送的數據量是怎樣跟蹤進行協商使數據段的發送和接收同步,根據所接收到的數據量而肯定的數據確認數及數據發送、接收完畢後什麼時候撤消聯繫,並創建虛鏈接。爲了提供可靠的傳送,TCP在發送新的數據以前,以特定的順序將數據包的序號,並須要這些包傳送給目標機以後的確認消息。TCP老是用來發送大批量的數據。當應用程序在收到數據後要作出確認時也要用到TCP。因爲TCP須要時刻跟蹤,這須要額外開銷,使得TCP的格式有些顯得複雜。下面就讓咱們看一個TCP的經典案例,這是後來被稱爲MITNICK攻擊中KEVIN開創了兩種攻擊技術:
兩種攻擊技術:
TCP會話劫持
SYN FLOOD(同步洪流)
在這裏咱們討論的時TCP會話劫持的問題。
先讓咱們明白TCP創建鏈接的基本簡單的過程。爲了建設一個小型的模仿環境咱們假設有3臺接入互聯網的機器。A爲攻擊者操縱的攻擊機。B爲中介跳板機器(受信任的服務器)。C爲受害者使用的機器(可能是服務器),這裏把C機器鎖定爲目標機器。A機器向B機器發送SYN包,請求創建鏈接,這時已經響應請求的B機器會向A機器迴應SYN/ACK代表贊成創建鏈接,當A機器接受到B機器發送的SYN/ACK迴應時,發送應答ACK創建A機器與B機器的網絡鏈接。這樣一個兩臺機器之間的TCP通話信道就創建成功了。
B終端受信任的服務器向C機器發起TCP鏈接,A機器對服務器發起SYN信息,使C機器不能響應B機器。在同時A機器也向B機器發送虛假的C機器迴應的SYN數據包,接收到SYN數據包的B機器(被C機器信任)開始發送應答鏈接創建的SYN/ACK數據包,這時C機器正在忙於響應之前發送的SYN數據而無暇迴應B機器,而A機器的攻擊者預測出B機器包的序列號(如今的TCP序列號預測難度有所加大)假冒C機器向B機器發送應答ACK這時攻擊者騙取B機器的信任,假冒C機器與B機器創建起TCP協議的對話鏈接。這個時候的C機器仍是在響應攻擊者A機器發送的SYN數據。
TCP協議棧的弱點:TCP鏈接的資源消耗,其中包括:數據包信息、條件狀態、序列號等。經過故意不完成創建鏈接所須要的三次握手過程,形成鏈接一方的資源耗盡。
經過攻擊者有意的不完成創建鏈接所須要的三次握手的全過程,從而形成了C機器的資源耗盡。序列號的可預測性,目標主機應答鏈接請求時返回的SYN/ACK的序列號時可預測的。(早期TCP協議棧,具體的能夠參見1981年出的關於TCP雛形的RFC793文檔)
TCP頭結構
TCP協議頭最少20個字節,包括如下的區域(因爲翻譯不由相同,文章中給出相應的英文單詞):
TCP源端口(Source Port):16位的源端口其中包含初始化通訊的端口。源端口和源IP地址的做用是標示報問的返回地址。
TCP目的端口(Destination port):16位的目的端口域定義傳輸的目的。這個端口指明報文接收計算機上的應用程序地址接口。
TCP序列號(序列碼,Sequence Number):32位的序列號由接收端計算機使用,從新分段的報文成最初形式。當SYN出現,序列碼其實是初始序列碼(ISN),而第一個數據字節是ISN+1。這個序列號(序列碼)是能夠補償傳輸中的不一致。
TCP應答號(Acknowledgment Number):32位的序列號由接收端計算機使用,重組分段的報文成最初形式。,若是設置了ACK控制位,這個值表示一個準備接收的包的序列碼。
數據偏移量(HLEN):4位包括TCP頭大小,指示何處數據開始。
保留(Reserved):6位值域,這些位必須是0。爲了未來定義新的用途所保留。
標誌(Code Bits):6位標誌域。表示爲:緊急標誌、有意義的應答標誌、推、重置鏈接標誌、同步序列號標誌、完成發送數據標誌。按照順序排列是:URG、ACK、PSH、RST、SYN、FIN。
窗口(Window):16位,用來表示想收到的每一個TCP數據段的大小。
校驗位(Checksum):16位TCP頭。源機器基於數據內容計算一個數值,收信息機要與源機器數值結果徹底同樣,從而證實數據的有效性。
優先指針(緊急,Urgent Pointer):16位,指向後面是優先數據的字節,在URG標誌設置了時纔有效。若是URG標誌沒有被設置,緊急域做爲填充。加快處理標示爲緊急的數據段。
選項(Option):長度不定,但長度必須以字節。若是沒有選項就表示這個一字節的域等於0。
填充:不定長,填充的內容必須爲0,它是爲了數學目的而存在。目的是確保空間的可預測性。保證包頭的結合和數據的開始處偏移量可以被32整除,通常額外的零以保證TCP頭是32位的整數倍。
標誌控制功能
URG:緊急標誌
緊急(The urgent pointer) 標誌有效。緊急標誌置位,
ACK:確認標誌
確認編號(Acknowledgement Number)欄有效。大多數狀況下該標誌位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure:1)爲下一個預期的序列編號,同時提示遠端系統已經成功接收全部數據。
PSH:推標誌
該標誌置位時,接收端不將該數據進行隊列處理,而是儘量快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的鏈接時,該標誌老是置位的。
RST:復位標誌,復位標誌有效。用於復位相應的TCP鏈接。
SYN:同步標誌
同步序列編號(Synchronize Sequence Numbers)欄有效。該標誌僅在三次握手創建TCP鏈接時有效。它提示TCP鏈接的服務端檢查序列編號,該序列編號爲TCP鏈接初始端(通常是客戶端)的初始序列編號。在這裏,能夠把TCP序列編號看做是一個範圍從0到4,294,967,295的32位計數器。經過TCP鏈接交換的數據中每個字節都通過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個字節的序列編號。
FIN:結束標誌
帶有該標誌置位的數據包用來結束一個TCP回話,但對應端口仍處於開放狀態,準備接收後續數據。
服務端處於監聽狀態,客戶端用於創建鏈接請求的數據包(IP packet)按照TCP/IP協議堆棧組合成爲TCP處理的分段(segment)。
分析報頭信息: TCP層接收到相應的TCP和IP報頭,將這些信息存儲到內存中。
檢查TCP校驗和(checksum):標準的校驗和位於分段之中(Figure:2)。若是檢驗失敗,不返回確認,該分段丟棄,並等待客戶端進行重傳
查找協議控制塊(PCB{}):TCP查找與該鏈接相關聯的協議控制塊。若是沒有找到,TCP將該分段丟棄並返回RST。(這就是TCP處理沒有端口監聽狀況下的機制) 若是該協議控制塊存在,但狀態爲關閉,服務端不調用connect()或listen()。該分段丟棄,但不返回RST。客戶端會嘗試從新創建鏈接請求。
創建新的socket:當處於監聽狀態的socket收到該分段時,會創建一個子socket,同時還有socket{},tcpcb{}和pub{}創建。這時若是有錯誤發生,會經過標誌位來拆除相應的socket和釋放內存,TCP鏈接失敗。若是緩存隊列處於填滿狀態,TCP認爲有錯誤發生,全部的後續鏈接請求會被拒絕。這裏能夠看出SYN Flood攻擊是如何起做用的。
丟棄:若是該分段中的標誌爲RST或ACK,或者沒有SYN標誌,則該分段丟棄。並釋放相應的內存。
發送序列變量
SND.UNA :發送未確認
SND.NXT :發送下一個
SND.WND :發送窗口
SND.UP :發送優先指針
SND.WL1 :用於最後窗口更新的段序列號
SND.WL2 :用於最後窗口更新的段確認號
ISS :初始發送序列號
接收序列號
RCV.NXT :接收下一個
RCV.WND :接收下一個
RCV.UP :接收優先指針
IRS :初始接收序列號
當前段變量
SEG.SEQ :段序列號
SEG.ACK :段確認標記
SEG.LEN :段長
SEG.WND :段窗口
SEG.UP :段緊急指針
SEG.PRC :段優先級
CLOSED表示沒有鏈接,各個狀態的意義以下:
LISTEN :監聽來自遠方TCP端口的鏈接請求。
SYN-SENT :在發送鏈接請求後等待匹配的鏈接請求。
SYN-RECEIVED :在收到和發送一個鏈接請求後等待對鏈接請求的確認。
ESTABLISHED :表明一個打開的鏈接,數據能夠傳送給用戶。
FIN-WAIT-1 :等待遠程TCP的鏈接中斷請求,或先前的鏈接中斷請求的確認。
FIN-WAIT-2 :從遠程TCP等待鏈接中斷請求。
CLOSE-WAIT :等待從本地用戶發來的鏈接中斷請求。
CLOSING :等待遠程TCP對鏈接中斷的確認。
LAST-ACK :等待原來發向遠程TCP的鏈接中斷請求的確認。
TIME-WAIT :等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認。
CLOSED :沒有任何鏈接狀態。
TCP鏈接過程是狀態的轉換,促使發生狀態轉換的是用戶調用:OPEN,SEND,RECEIVE,CLOSE,ABORT和STATUS。傳送過來的數據段,特別那些包括如下標記的數據段SYN,ACK,RST和FIN。還有超時,上面所說的都會時TCP狀態發生變化。
序列號
請注意,咱們在TCP鏈接中發送的字節都有一個序列號。由於編了號,因此能夠確認它們的收到。對序列號的確認是累積性的。TCP必須進行的序列號比較操做種類包括如下幾種:
①決定一些發送了的但未確認的序列號。
②決定全部的序列號都已經收到了。
③決定下一個段中應該包括的序列號。
對於發送的數據TCP要接收確認,確認時必須進行的:
SND.UNA = 最老的確認了的序列號。
SND.NXT = 下一個要發送的序列號。
SEG.ACK = 接收TCP的確認,接收TCP期待的下一個序列號。
SEG.SEQ = 一個數據段的第一個序列號。
SEG.LEN = 數據段中包括的字節數。
SEG.SEQ+SEG.LEN-1 = 數據段的最後一個序列號。
若是一個數據段的序列號小於等於確認號的值,那麼整個數據段就被確認了。而在接收數據時下面的比較操做是必須的:
RCV.NXT = 期待的序列號和接收窗口的最低沿。
RCV.NXT+RCV.WND:1 = 最後一個序列號和接收窗口的最高沿。
SEG.SEQ = 接收到的第一個序列號。
SEG.SEQ+SEG.LEN:1 = 接收到的最後一個序列號