TCP協議的安全性分析


有算法就有破解法,因為它們都遵循了一定的數據結構和數學知識。所以網絡安全是一個相對的概念,不可能出現絕對的安全!作為當今最流行的網絡協議——TCP也是如此。那么TCP的安全問題究竟是哪些因素引起的呢?

一、TCP漏洞的來源

1.設計初心

我們知道TCP協議誕生於1973年,那時候計算機網絡也是剛剛起步。在沒有經驗的前提下,開發者們主要的目標是為了實現網絡的連通性。對於安全性,一是沒有經驗,二是設計的目的性就不在此。所以TCP協議的誕生之初就意味着它不可能在安全性方面有太高的造詣

2.TCP數據的傳輸形勢——明文傳輸

不同於一些誕生比較晚的計算機網絡協議——https和chap等等。TCP協議在傳輸數據的時候是明文傳輸的。這在一定程度上就導致數據安全存在很大的隱患。這也是很多md5等一些列加密算法產生的重要原因

3.TCP協議的首部字段缺乏安全性認證

TCP協議對於數據發送的源頭是沒有驗證機制的,即使數據報中存在源端口字段(也包括網絡層協議IP數據報中包含源IP字段)!也就是說,很多時候我們關系的問題是如何把該數據報准確無誤的傳給誰,但是卻忘了這個數據報確實是源方(源IP字段指定的客戶端)發送來的未經修改或未經竊取的數據報嗎?

4.TCP的連接性是一把雙刃劍

只要知道TCP協議的人就知道TCP的一個重要特點——它是面向連接的一個網絡協議!更通俗的說就是TCP所進行的數據的交互都是在一個連接周期中進行的!還可以換句話說,如果你想對某個客戶端的發起攻擊,必須要做的一件事情就是劫持(或竊聽)該客戶端和某網絡應用的一個TCP連接(當前計算機網絡的半壁江山都是基於TCP的)!

所以如果我們的某個基於TCP協議進行連接的進程如果被劫持,也就等效於這次數據幾乎全部遇難(除非全部關鍵數據都進行了相關的加密技術)。那么劫持TCP連接的關鍵在哪?

這個關鍵點就是報文首部的序號字段。我們知道,TCP的流量控制、數據失效重傳功能、擁塞控制算法等等都與滑動窗口的大小(起始端點和窗口長度)有着密切的聯系,而滑動窗口的大小取值恰恰依賴着這個 “序號” 字段。我們先回顧一下tcp首部中一些較為關鍵的字段及其分析:

序號 ===> 4byte;序號范圍是[0,2^32 - 1]

序號增加到 2^32 - 1 后,下一個序號就又回到0。也就是說,序號使用mod 2^32 運算;由於序號字段有32位長,可對4GB的數據進行編號。在一般情況下可保證當序號重復使用時,舊序號的數據早已通過網絡到達終點了

在一個TCP連接中傳送的字節流中的每一個字節都按順序編號。字節流的起始序號必須在連接建立時設置。TCP數據報首部中的序號字段值則指的是本報文段所發送的數據的第一個字節的序號。
例如,一報文段的序號字段值是301,而攜帶的數據共有100字節。這就表明:本報文段的數據的第一個字節的序號是301,最后一個字節的序號是400。顯然,下一個報文段(如果還有的話)的數據序號應當從401開始,即下一個報文段的序號字段值應為401。這個字段的名稱也叫做“報文段序號”。

==========================================================================

確認號 ===> 4byte;即期望收到對方下一個報文段的第一個數據字節的序號。若確認號為N,則表明:到序號N-1為止的所有數據都已正確收到。

例如,B收到了A發送的一個報文段,其序號字段值是501,而數據長度是200字節(序號501~700),此時,B期望收到A的下一個數據序號是701,於是B在發送給A的確認報文段中把確認號置為701。

==========================================================================

數據偏移 ===> 4bit;單位為4byte即32bit;它指出TCP報文段的數據起始處距離TCP報文段的起始處有多遠。(即TCP報文段的首部長度)。因為該字段長4bit,單位為4byte。所以數據偏移的最大值是60字節,這也是TCP首部的最大長度(即選項長度不能超過40字節)。

==========================================================================

緊急URG(URGent)===> 1bit;

當URG=1時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應盡快傳送(相當於高優先級的數據),而不要按原來的排隊順序來傳送。於是發送方TCP就把緊急數據插入到本報文段數據的最前面,而在緊急數據后面的數據仍是普通數據。這時要與首部中緊急指針(Urgent Pointer)字段配合使用

==========================================================================

確認ACK(ACKnowledgment)===> 1bit;僅當ACK=1時確認號字段才有效。當ACK=0時,確認號無效。TCP規定,在連接建立后所有傳送的報文段都必須把ACK置1

==========================================================================

推送PSH(PuSH) ===> 1bit;當兩個應用進程進行交互式的通信時,有時在一端的應用進程希望在鍵入一個命令后立即就能夠收到對方的響應,而不再等到整個緩存都填滿了后再向上交付。這時,發送方TCP把PSH置1,並立即創建一個報文段發送出去。接收方TCP收到PSH=1的報文段,就盡快地(即“推送”向前)交付接收應用進程

==========================================================================

復位RST(ReSeT)===> 1bit;當RST=1時,表明TCP連接中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連接,然后再重新建立運輸連接。RST置1還用來拒絕一個非法的報文段或拒絕打開一個連接。RST也可稱為重建位或重置位。

==========================================================================

同步SYN(SYNchronization)===> 1bit;在連接建立時用來同步序號

當SYN=1而ACK=0時,表明這是一個連接請求報文段。對方若同意建立連接,則應在響應的報文段中使SYN=1和ACK=1。因此,SYN置為1就表示這是一個連接請求或連接接受報文

==========================================================================

終止FIN(FINis)===> 用來釋放一個連接

當FIN=1時,表明此報文段的發送方的數據已發送完畢,並要求釋放運輸連接

==========================================================================

窗口 ===> 2byte;值是[0,2^16-1]之間的整數;窗口字段明確指出了現在允許對方發送的數據量。窗口值經常在動態變化着

窗口指的是發送本報文段的一方的接收窗口(而不是自己的發送窗口)。窗口值告訴對方:從本報文段首部中的確認號算起,接收方目前允許對方發送的數據量(以字節為單位)。之所以要有這個限制,是因為接收方的數據緩存空間是有限的

例如,發送了一個報文段,其確認號是701,窗口字段是1000。這就是告訴對方:“從701號算起,我(即發送此報文段的一方)的接收緩存空間還可接收1000個字節數據(字節序號是701~1700)

==========================================================================

大概了解了這些字段的作用之后,我們再從下圖回顧一下TCP滑動窗口實現流量控制的具體步驟:

從上圖中我們可以發現一個關鍵點——那就是只有我們掌握了某個tcp連接的下一個數據報序號和窗口大小,那么我們大多數情況下就可以順利的劫持的此TCP連接,從而實現數據的監控甚至注入!

二、如何利用TCP的這些漏洞

通過以上的分析,我們已經明確了TCP安全的漏洞所在,那就是序號與滑動窗口的大小。而滑動窗口的大小可以通過多次分析tcp數據報首部的關鍵字段和數據長度加以獲取。

對於TCP連接,不同的系統發出的數據報中的序列號的產生方法是不一樣的,換句話說,從序列號可以得到該服務器或客戶端的操作系統是屬於windows系列還是Linux系列或者是mac系列等等。那么具體怎個不一樣法呢?

當tcp連接出現異常的時候,我們向它發送一些不同標志位組合的報文,它們的反映是不一樣的。舉例來說,加入我們發送RET報文,目標主機如果是windows系列,它會返回一個RST報文,如果是LInux則不會做任何響應。得到了目標主機的操作系統型號,就可以更容易的獲取滑動窗口的大小,然后根據報文中的序號字段實行劫持。

因為TCP使用的sequence number是一個32位的計數器,從0-4294967295。tcp為每一個連接選擇一個初始序號ISN,為了防止因為延遲、重傳等擾亂三次握手,ISN不能隨便選取,不同系統有不同算法。理解tcp如何分配ISN以及ISN隨時間變化的規律,對於成功地進行arp欺騙攻擊很重要。

三、如何進行TCP欺騙

1.TCP欺騙的方法

非盲攻擊:攻擊者和被欺騙的目的主機在同一個網絡上,攻擊者可以簡單地使用協議分析器(嗅探器)捕獲tcp報文段,從而獲得需要的序列號

盲攻擊:由於攻擊者和被欺騙的目標主機不在同一個網絡上,攻擊者無法使用嗅探器捕獲tcp報文段。其攻擊步驟與非盲攻擊幾乎相同,只不過在步驟三無法使用嗅探器,以使用tcp初始序列號預測技術得到初始序列號。在步驟攻擊者X可以發送第一個數據包,但收不到A的響應包,難實現交互

2.TCP序號的產生方法

三種常用的產生方法:

①.64K規則---RFC793

②.機器時鍾---RFC1948

③.偽隨機數

以上三種序列號產生都是有一定的規則的,不是雜亂無章的:

RFC793

RFC793指出ISN可看作是一個32比特的計數器函數確定,每4ms加1,我們進行若干次的重復連接之后,求得數據的平均往返時間RTT,然后再根據序號的增速猜測下一個序號可能是多少

RFC1948

RFC1948通過連接標識符來區分序列號空間。每一個連接標識符由本地地址,本地端口,遠程地址,遠程端口來組成,並由一個函數計算標識符分的序列號地址空間偏移值(唯一)

此函數不能被攻擊者獲得,否則,攻擊者可以通過計算獲得ISN。於是,ISN就在這個偏移值上增加。ISN的值以這種方式產生能夠抵受上面提到的對ISN的猜測攻擊

ISN自身的值是按照一個常數值穩定增加的,所以F0需要保持相對的穩定性

<some secret>是一個系統特定的值(例如機器的啟動時間,密碼,初始隨機數等),這些值並不會經常變。但是,如果Hash函數在實現上存在漏洞(我們無法保證一個絕對安全的Hash函數,況且,它的實現又與操作系統密切相關),攻擊者就可以通過大量的采樣,來分析<some secret>,其中,源ip地址,源端口,目的ip地址,目的端口都是不變的,這減少了攻擊者分析的難度

Linux tcp的ISN生成器避免了這一點。它每5分鍾計算一次<some secret>值,把泄漏<some secret>的風險降到了最低。
有一個辦法可以做的更好:
取M=M+R(t)
ISN=M+F(sip,sport,dip,dport,<some secret>)
其中R()是一個關於時間的隨機函數

偽隨機數規則

構造TCPISN生成器的一些更直接的方法是:簡單地選取一些隨機數作為ISN。這就是給定一個32位的空間,指定ISN=R(t)。(假設RO是完全的非偽隨機數生成函數)

4.TCP序號猜測前提

第一,攻擊者能夠在短時間內向服務器的某個開放的端口發起若干個TCP連接請求,這些請求用來分析服務器的ISN增長規律,從而推斷出下一次連接的ISN的可能值,在這若干個連接請求后緊接着的就是用於攻擊的連接請求,如果服務器在攻擊者發起攻擊的這一段時間沒有建立其它的連接,那么其下一次連接建立的ISN被攻擊者推斷出的可能性就很高

第二,攻擊者能夠防止在攻擊的過程中,被授權的客戶機會因為收到從服務器發來的SYN/ACK而對該數據包做出響應(發送RST終止本次連接)。攻擊者可以通過使用一個已經離線的主機的IP地址,或者向其假冒的客戶機發起拒絕服務攻擊來阻止該客戶機響應服務器發來的數據包

第三,攻擊者利用的是服務器上的一個應用層的協議,該協議是單純地依賴於客戶機的口地址認證和授權的,而不是諸如通過密鑰協商或加密密鑰認證的高層認證機制

第四,攻擊者能夠猜測或推斷出從服務器發送給攻擊者假冒的客戶機的TCP數據,這些數據對於攻擊者來說是看不到的RFC1948通過連接標識符來區分序列號空間。每一個連接標識符由本地地址,本地端口,遠程地址,遠程端口來組成,並由一個函數計算標識符分的序列號地址空間偏移值(唯一)。
此函數不能被攻擊者獲得,否則,攻擊者可以通過計算獲得ISN。於是,ISN就在這個偏移值上增加。ISN的值以這種方式產生能夠抵受上面提到的對ISN的猜測攻擊。

3.TCP序列號的獲取步驟

RFC749

1、首先攻擊方先發送一個syn包來獲取服務器現在的tcp序列號
攻擊方:S syn(ISN攻擊方)
S:ACKISN攻擊方)+SYN(ISNS#)

2、緊接着攻擊方冒充被攻擊的客戶端向服務器發送syn包攻擊方:S SYN(ISN攻擊方),SRC=被攻擊的客戶端

3、於是,服務器發出一個響應包給被攻擊的客戶端,這個包攻擊方是收不到的S:被攻擊的客戶端 SYN(ISNSS),ACK(INS被攻擊的客戶端)

4、攻擊方計算INS$ INS$=INS#+R被攻擊的客戶端被攻擊的客戶端*Increment of ISN

5、攻擊方:SACK(ISNSS)(冒充可信主機)

RFC1948

ISN=M+F(sip,sport,dip,dport,<some secret>)
其中

ISN32位的初始序列號

M單調增加的計數器

F單向散列哈希函數(例如MD4 or MD5)sip源ip地址

sport 源端口dip目的ip地址dport目的端口

<some secret>哈希函數可選部分,使遠程攻擊者更難猜到ISN

偽隨機數

ISN=((PRNG())<<16)+R(t)32位
其中PRNG():一組隨機指定的連續的16位數字
0x00000000--0xffff0000
R(t):16位隨機數生成器(它的高位msb設成0)
0x00000000--0x0000ffff上面的公式被用於設計OpenBsd的ISN生成器,相關的源代碼可以從下面的網址獲得

http://www.openbsd.org/cgiin/cvsweb/src/sys/netinet/tcp_subr.c

4.對獲取到的TCP序列號的處理

對TCP序列號的猜測不僅發生在三次握手的過程中,還發生在連接建立后的數據傳送過程中

1、如果猜測正確,數據將會放到接收緩沖區中

2、如果序列號小於目的主機所期望的序列號,包被丟棄

3、如果序列號大於目的主機所期望的序列號.但是小於TCP的接收窗口范圍,將被放到一個緩沖隊列中,因為有可能是后發送的數據先到達了

4、如果不是目的主機所期望的序列號,又不在TCP1的接收窗n范圍內,包被丟棄

5.什么是TCP會話劫持

服務器與信任主機三次握手建立連接后,服務器收到另一台合法主機發送的tcp報文前,攻擊主機根據所截獲的信息向服務器發出一個帶有凈荷的tcp報文,如果服務器先收到攻擊報文,就可以把合法的tcp會話建立在攻擊主機與被攻擊主機之間

帶有凈荷的攻擊報文能夠使被攻擊主機對下一個要收到的tcp報文中的確認序號(ackseq)的值的要求發生變化,從而使正常合法的客戶端主機向被攻擊主機發出的報文被被攻擊主機(服務器)拒絕

tcp會話劫持攻擊方式的好處在於使攻擊者避開了被攻擊主機對訪問者的身份驗證和安全認證,從而使攻擊者直接進入對被攻擊主機的的訪問狀態,因此對系統安全構成的威脅比較嚴重

6.如何進行會話劫持

1.會話劫持的目標應用

基於tcp的任何應用,如HTTP、FTP、Telnet等

2.會話劫持的工作原理

對於攻擊者來說,所必須要做的就是窺探到正在進行tcp通信的兩台主機之間傳送的報文,這樣攻擊者就可以得知該報文的源ip、源tcp端口號、目的ip、目的tcp端號,從而可以得知其中一台主機對將要收到的下一個tcp報文段中seq和ackseq值的要求


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM