TCP協議:說RST標識位 談RST復位攻擊
1.RST標識位
RST表示復位,用來異常的關閉連接,在TCP的設計中它是不可或缺的。發送RST包關閉連接時,不必等緩沖區的包都發出去(FIN包),直接就丟棄緩存區的包發送RST包。而接收端收到RST包后,也不必發送ACK包來確認。
TCP處理程序會在自己認為的異常時刻發送RST包。
2個例子:
1)A向B發起連接,但B之上并未監聽相應的端口,這時B操作系統上的TCP處理程序會發RST包。
2)A和B已經正常建立連接,正在通訊時,A向B發送了FIN包要求關連接,B發送ACK后,A網斷了,A通過若干原因放棄了這個連接(例如進程重啟)。網絡恢復之后,B又開始或重發數據包,A不知道這連接哪來的,就發了個RST包強制把連接關閉,B收到后會出現connect reset by peer錯誤。
2.RST復位報文段
TCP在下列三種情況下產生RST復位報文段。
1.到不存在的端口的連接請求
產生復位的一種常見情況是當連接請求到達時,目的端口沒有進程正在監聽。對于UDP,當一個數據報到達目的端口時,該端口沒在使用,它將產生一個ICMP端口不可達的信息;而TCP則使用復位。
2.異常終止一個連接
終止一個連接的正常方式是一方發送FIN,這也稱為有序釋放,因為在所有排隊數據都已發送之后才發送FIN,正常情況下沒有任何數據丟失。但也有可能發送一個復位報文段而不是FIN來中途釋放一個連接,這也稱為異常釋放。異常終止一個連接對應用程序來說有兩個優點:(1)丟棄任何待發數據并立即發送復位報文段;(2)RST的接收方會區分另一端執行的是異常關閉還是正常關閉。
3.檢測半關閉連接
如果一方已經關閉或異常終止連接而另一方卻還不知道,我們將這樣的TCP連接稱為半打開的。任何一端的主機異常都可能導致發生這種情況。只要不打算在半打開連接上傳輸數據,仍處于連接狀態的一方就不會檢測另一方已經出現異常。下面介紹一種建立半打開連接的情形。在bsdi上運行Telnet客戶程序,通過它和svr4上的丟棄服務器建立連接。接著斷開服務器主機與以太網的電纜,并重啟服務器主機。這可以模擬服務器主機出現異常(在重啟服務器之前斷開以太網電纜是為了防止它向打開的連接發送FIN,某些TCP在關機時會這么做)。服務器主機重啟后,我們重新接上電纜,并從客戶向服務器發送一行字符。由于服務器的TCP已經重新啟動,它將丟失復位前連接的所有信息,因此它不知道數據報文段中提到的連接。TCP處理的原則是接收方以復位作為應答。
3.RST復位攻擊
A和服務器B之間建立了TCP連接,如果此時C偽造了一個TCP包發給B,使B異常的斷開了與A之間的TCP連接,就是RST攻擊。
偽造這樣的TCP包能造成什么后果?
1、假定C偽裝成A發過去的包,這個包如果是RST包,沖區上所有數據B將會丟棄與A的緩,強制關掉連接。
2、如果發過去的包是SYN包,那么,B會表示A已經是正常連接卻又來建新連接,B主動向A發個RST包,并在自己這端強制關掉連接。
如何偽造成A發給B的包?
這里有兩個關鍵因素,源端口和序列號。
一個TCP連接都是四元組,由源IP、源端口、目標IP、目標端口唯一確定一個連接。所以,如果C要偽造A發給B的包,要在上面提到的IP頭和TCP頭,把源IP、源端口、目標IP、目標端口都填對。
1)這里B作為服務器,IP和端口是公開的;
2)A是我們要下手的目標,IP當然知道,但A的源端口就不清楚了,因為這可能是A隨機生成的。當然,如果能夠對常見的OS如windows和linux找出生成source port規律的話,還是可以進行碰撞。
3)序列號問題是與滑動窗口對應的,偽造的TCP包里需要填序列號,如果序列號的值不在A之前向B發送時B的滑動窗口內,B是會主動丟棄的。所以我們要找到能落到當時的AB間滑動窗口的序列號。這個可以暴力解決,因為一個sequence長度是32位,取值范圍0-4294967296,如果窗口大小像上圖中我抓到的windows下的65535的話,只需要相除,就知道最多只需要發65537(4294967296/65535=65537)個包就能有一個序列號落到滑動窗口內。RST包是很小,IP頭+TCP頭才40字節,算算我們的帶寬就知道這實在只需要幾秒鐘就能搞定。
那么,序列號不是問題,源端口會麻煩點,如果各個操作系統不能完全隨機的生成源端口,或者黑客們能通過其他方式獲取到source port,RST攻擊存在可能。
4.如何預防
簡單粗爆的一個可行方法:可以通過防火墻簡單設置。建議使用防火墻將進來的包帶RST位的包丟棄。