本篇內容介紹了“TCP重置攻擊的工作原理是什么”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!
TCP 重置攻擊 是使用一個(gè)單一的數據包來(lái)執行的,只有幾個(gè)字節大小。攻擊者制作并發(fā)送一個(gè)偽造的 TCP 重置包來(lái)干擾用戶(hù)和網(wǎng)站的連接,欺騙通信雙方終止
TCP
連接。我們偉大的 xx 長(cháng)城便運用了這個(gè)技術(shù)來(lái)進(jìn)行 TCP 關(guān)鍵字阻斷。
理解 TCP 重置攻擊并不需要具備深厚的網(wǎng)絡(luò )知識功底,只需要一臺筆記本就可以對自己進(jìn)行模擬攻擊。本文將會(huì )帶你了解 TCP 重置攻擊的原理,同時(shí)會(huì )幫助你理解很多關(guān)于 TCP 協(xié)議的特性。本文主要內容:
回顧 TCP 協(xié)議的基礎知識
了解 TCP 重置攻擊的原理
使用一個(gè)簡(jiǎn)單的 Python
腳本來(lái)模擬攻擊
下面開(kāi)始分析 TCP 重置攻擊原理。
這一段略過(guò),原因你懂得,感興趣的請直接看原文。
在 TCP 重置攻擊中,攻擊者通過(guò)向通信的一方或雙方發(fā)送偽造的消息,告訴它們立即斷開(kāi)連接,從而使通信雙方連接中斷。正常情況下,如果客戶(hù)端收發(fā)現到達的報文段對于相關(guān)連接而言是不正確的,TCP 就會(huì )發(fā)送一個(gè)重置報文段,從而導致 TCP 連接的快速拆卸。
TCP 重置攻擊利用這一機制,通過(guò)向通信方發(fā)送偽造的重置報文段,欺騙通信雙方提前關(guān)閉 TCP 連接。如果偽造的重置報文段完全逼真,接收者就會(huì )認為它有效,并關(guān)閉 TCP 連接,防止連接被用來(lái)進(jìn)一步交換信息。服務(wù)端可以創(chuàng )建一個(gè)新的 TCP 連接來(lái)恢復通信,但仍然可能會(huì )被攻擊者重置連接。萬(wàn)幸的是,攻擊者需要一定的時(shí)間來(lái)組裝和發(fā)送偽造的報文,所以一般情況下這種攻擊只對長(cháng)連接有殺傷力,對于短連接而言,你還沒(méi)攻擊呢,人家已經(jīng)完成了信息交換。
從某種意義上來(lái)說(shuō),偽造 TCP 報文段是很容易的,因為 TCP/IP 都沒(méi)有任何內置的方法來(lái)驗證服務(wù)端的身份。有些特殊的 IP 擴展協(xié)議(例如 IPSec
)確實(shí)可以驗證身份,但并沒(méi)有被廣泛使用??蛻?hù)端只能接收報文段,并在可能的情況下使用更高級別的協(xié)議(如 TLS
)來(lái)驗證服務(wù)端的身份。但這個(gè)方法對 TCP 重置包并不適用,因為 TCP 重置包是 TCP 協(xié)議本身的一部分,無(wú)法使用更高級別的協(xié)議進(jìn)行驗證。
盡管偽造 TCP 報文段很容易,但偽造正確的 TCP 重置報文段并完成攻擊卻并不容易。為了理解這項工作的難度,我們需要先了解一下 TCP 協(xié)議的工作原理。
TCP 協(xié)議的目標是向客戶(hù)端發(fā)送一份完整的數據副本。例如,如果我的通過(guò) TCP 連接向你的計算機發(fā)送我的網(wǎng)站的 HTML
,你的計算機的 TCP 協(xié)議棧應該能夠以我發(fā)送的形式和順序輸出 HTML
。
然而現實(shí)生活中我的 HTML 內容并不是按順序發(fā)送的,它被分解成許多小塊(稱(chēng)為 TCP 分組),每個(gè)小塊在網(wǎng)絡(luò )上被單獨發(fā)送,并被重新組合成原來(lái)發(fā)送的順序。這種重新組合后的輸出被稱(chēng)為 TCP 字節流。
將分組重建成字節流并不簡(jiǎn)單,因為網(wǎng)絡(luò )是不可靠的。TCP分組可能會(huì )被丟棄,可能不按發(fā)送的順序到達客戶(hù)端,也可能會(huì )被重復發(fā)送、報文損壞等等。因此,TCP 協(xié)議的職責是在不可靠的網(wǎng)絡(luò )上提供可靠的通信。TCP 通過(guò)要求連接雙方保持密切聯(lián)系,持續報告它們接收到了哪些數據來(lái)實(shí)現可靠通信,這樣服務(wù)端就能夠推斷出客戶(hù)端尚未接收到的數據,并重新發(fā)送丟失的數據。
為了進(jìn)一步理解這個(gè)過(guò)程,我們需要了解服務(wù)端和客戶(hù)端是如何使用序列號(sequence numbers)來(lái)標記和跟蹤數據的。
TCP 協(xié)議的通信雙方, 都必須維護一個(gè)序列號(sequence numbers),對于客戶(hù)端來(lái)說(shuō),它會(huì )使用服務(wù)端的序列號來(lái)將接收到的數據按照發(fā)送的順序排列。
當通信雙方建立 TCP 連接時(shí),客戶(hù)端與服務(wù)端都會(huì )向對方發(fā)送一個(gè)隨機的初始序列號,這個(gè)序列號標識了其發(fā)送數據流的第一個(gè)字節。TCP 報文段包含了 TCP 頭部,它是附加在報文段開(kāi)頭的元數據,序列號就包含在 TCP 頭部中。由于 TCP 連接是雙向的,雙方都可以發(fā)送數據,所以 TCP 連接的雙方既是發(fā)送方也是接收方,每一方都必須分配和管理自己的序列號。
當接收方收到一個(gè) TCP 報文段時(shí),它會(huì )向發(fā)送方返回一個(gè) ACK
應答報文(同時(shí)將 TCP 頭部的 ACK
標志位置 1),這個(gè) ACK
號就表示接收方期望從發(fā)送方收到的下一個(gè)字節的序列號。發(fā)送方利用這個(gè)信息來(lái)推斷接收方已經(jīng)成功接收到了序列號為 ACK
之前的所有字節。
TCP 頭部格式如下圖所示:
一個(gè)確認應答報文的 TCP 頭部必須包含兩個(gè)部分:
ACK 標志位置位 1
包含確認應答號(ACK number)
TCP 總共有 6
個(gè)標志位,下文就會(huì )講到其中的 RST
標志位。
TCP 頭部包含了多個(gè)選項,其中有一個(gè)選擇確認選項(
SACK
),如果使用該選項,那么當接收方收到了某個(gè)范圍內的字節而不是連續的字節時(shí),就會(huì )發(fā)送SACK
告知對方。例如,只收到了字節1000~3000
和4000~5000
,但沒(méi)有收到3001~3999
。為了簡(jiǎn)單起見(jiàn),下文討論 TCP 重置攻擊時(shí)將忽略選擇確認選項。
如果發(fā)送方發(fā)送了報文后在一段時(shí)間內沒(méi)有收到 ACK
,就認為報文丟失了,并重新發(fā)送報文,用相同的序列號標記。這就意味著(zhù),如果接收方收到了重復的報文,可以使用序列號來(lái)判斷是否見(jiàn)過(guò)這個(gè)報文,如果見(jiàn)過(guò)則直接丟棄。網(wǎng)絡(luò )環(huán)境是錯綜復雜的,往往并不是如我們期望的一樣,先發(fā)送的數據包,就先到達目標主機,反而它很騷,可能會(huì )由于網(wǎng)絡(luò )擁堵等亂七八糟的原因,會(huì )使得舊的數據包,先到達目標主機。一般分兩種情況:
發(fā)送的數據包丟失了
發(fā)送的數據包被成功接收,但返回的 ACK 丟失了
這兩種情況對發(fā)送方來(lái)說(shuō)其實(shí)是一樣的,發(fā)送方并不能區分是哪種情況,所以只能重新發(fā)送數據包。
只要不頻繁重復發(fā)送數據,額外的開(kāi)銷(xiāo)基本可以忽略。
構建偽造的重置包時(shí)需要選擇一個(gè)序列號。接收方可以接收序列號不按順序排列的報文段,但這種容忍是有限度的,如果報文段的序列號與它期望的相差甚遠,就會(huì )被直接丟棄。
因此,一個(gè)成功的 TCP 重置攻擊需要構建一個(gè)可信的序列號。但什么才是可信的序列號呢?對于大多數報文段(除了重置包,即 RST
包)來(lái)說(shuō),序列號是由接收方的接收窗口大小決定的。
想象一下,將一臺上世紀 90
年代初的古老計算機,連接到現代千兆光纖網(wǎng)絡(luò )。閃電般快速的網(wǎng)絡(luò )可以以令人瞠目結舌的速度向這臺古老的計算機傳送數據,速度遠遠超過(guò)該計算機的處理能力。但并沒(méi)有什么卵用,因為只有接收方接收并處理了報文,才能認為這個(gè)報文已經(jīng)被收到了。
TCP 協(xié)議棧有一個(gè)緩沖區,新到達的數據被放到緩沖區中等待處理。但緩沖區的大小是有限的,如果接收方的處理速度跟不上發(fā)送方的發(fā)送速度,緩沖區就會(huì )被填滿(mǎn)。一旦緩沖區被填滿(mǎn),多余的數據就會(huì )被直接丟棄,也不會(huì )返回 ACK。因此一旦接收方的緩沖區有了空位,發(fā)送方必須重新發(fā)送數據。也就是說(shuō),如果接收方的處理速度跟不上,發(fā)送方的發(fā)送速度再快也沒(méi)用。
緩沖區到底有多大?發(fā)送方如何才能知道什么時(shí)候可以一次發(fā)送更多的數據,什么時(shí)候該一次發(fā)送很少的數據?這就要靠 TCP 滑動(dòng)窗口了。接收方的滑動(dòng)窗口大小是指發(fā)送方無(wú)需等待確認應答,可以持續發(fā)送數據的最大值。 假設接收方的通告窗口大小為 100,000
字節,那么發(fā)送方可以無(wú)需等待確認應答,持續發(fā)送 100,000
個(gè)字節。再假設當發(fā)送方發(fā)送第 100,000
個(gè)字節時(shí),接收方已經(jīng)發(fā)送了前 10,000
個(gè)字節的 ACK,這就意味著(zhù)窗口中還有 90,000
個(gè)字節未被確認,發(fā)送方還可以再持續發(fā)送 10,000
個(gè)字節。如果發(fā)送了 10,000
個(gè)字節的過(guò)程中沒(méi)有收到任何的 ACK
,那么接收方的滑動(dòng)窗口將被填滿(mǎn),發(fā)送方將停止發(fā)送新數據(可以繼續發(fā)送之前丟失的數據),直到收到相關(guān)的 ACK
才可以繼續發(fā)送。
TCP 連接雙方會(huì )在建立連接的初始握手階段通告對方自己窗口的大小,后續還可以動(dòng)態(tài)調整。TCP 緩沖區大的服務(wù)器可能會(huì )聲明一個(gè)大窗口,以便最大限度提高吞吐量。TCP 緩沖區小的服務(wù)器可能會(huì )被迫聲明一個(gè)小窗口,這樣做會(huì )犧牲一定的吞吐量,但為了防止接收方的 TCP 緩沖區溢出,還是很有必要的。
換個(gè)角度來(lái)看,TCP 滑動(dòng)窗口大小是對網(wǎng)絡(luò )中可能存在的未確認數據量的硬性限制。我們可以用它來(lái)計算發(fā)送方在某一特定時(shí)間內可能發(fā)送的最大序列號(max_seq_no
):
max_seq_no = max_acked_seq_no + window_size
其中 max_acked_seq_no
是接收方發(fā)送的最大 ACK 號,它表示發(fā)送方知道接收方已經(jīng)成功接收的最大序列號。window_size 是窗口大小,它表示允許發(fā)送方最多發(fā)送的未被確認的字節。所以發(fā)送方可以發(fā)送的最大序列號是:max_acked_seq_no + window_size
。
TCP 規范規定,接收方應該忽略任何序列號在接收窗口之外的數據。例如,如果接收方確認了所有序列號在 15,000
以下的字節,且接收窗口大小為 30,000
,那么接下來(lái)接收方只能接收序列號范圍在 15,000 ~ 45,000
之間的數據。如果一個(gè)報文段的部分數據在窗口內,另一部分數據在窗口外,那么窗口內的數據將被接收確認,窗口外的數據將被丟棄。注意:這里忽略了選擇確認選項,再強調一遍!
對于大多數 TCP 報文段來(lái)說(shuō),滑動(dòng)窗口的規則告訴了發(fā)送方自己可以接收的序列號范圍。但對于重置報文來(lái)說(shuō),序列號的限制更加嚴格,這是為了抵御一種攻擊叫做盲目 TCP 重置攻擊(blind TCP reset attack
),下文將會(huì )解釋。
對于 TCP 重置報文段來(lái)說(shuō),接收方對序列號的要求更加嚴格,只有當其序列號正好等于下一個(gè)預期的序列號時(shí)才能接收。繼續搬出上面的例子,接收方發(fā)送了一個(gè)確認應答,ACK 號為 15,000
。如果接下來(lái)收到了一個(gè)重置報文,那么其序列號必須是 15,000
才能被接收。
如果重置報文的序列號超出了接收窗口范圍,接收方就會(huì )直接忽略該報文;如果其序列號在接收窗口范圍內,那么接收方就會(huì )返回一個(gè) challenge ACK
,告訴發(fā)送方重置報文段的序列號是錯誤的,并告之正確的序列號,發(fā)送方可以利用 challenge ACK
中的信息來(lái)重新構建和發(fā)送重置報文。
其實(shí)在 2010 年之前,TCP 重置報文段和其他報文段的序列號限制規則一樣,但無(wú)法抵御盲目 TCP 重置攻擊,后來(lái)才采取這些措施施加額外的限制。
如果攻擊者能夠截獲通信雙方正在交換的信息,攻擊者就能讀取其數據包上的序列號和確認應答號,并利用這些信息得出偽裝的 TCP 重置報文段的序列號。相反,如果無(wú)法截獲通信雙方的信息,就無(wú)法確定重置報文段的序列號,但仍然可以批量發(fā)出盡可能多不同序列號的重置報文,以期望猜對其中一個(gè)序列號。這就是所謂的盲目 TCP 重置攻擊(blind TCP reset attack
)。
在 2010 年之前 TCP 的原始版本中,攻擊者只需要猜對接收窗口內的隨便哪一個(gè)序列號即可,一般只需發(fā)送幾萬(wàn)個(gè)報文段就能成功。采取額外限制的措施后,攻擊者需要發(fā)送數以百萬(wàn)計的報文段才有可能猜對序列號,這幾乎是很難成功的。更多細節請參考 RFC-5963。
以下實(shí)驗是在
OSX
系統中完成的,其他系統請自行測試。
現在來(lái)總結一下偽造一個(gè) TCP 重置報文要做哪些事情:
嗅探通信雙方的交換信息。
截獲一個(gè) ACK
標志位置位 1 的報文段,并讀取其 ACK
號。
偽造一個(gè) TCP 重置報文段(RST
標志位置為 1),其序列號等于上面截獲的報文的 ACK
號。這只是理想情況下的方案,假設信息交換的速度不是很快。大多數情況下為了增加成功率,可以連續發(fā)送序列號不同的重置報文。
將偽造的重置報文發(fā)送給通信的一方或雙方,時(shí)其中斷連接。
為了實(shí)驗簡(jiǎn)單,我們可以使用本地計算機通過(guò) localhost
與自己通信,然后對自己進(jìn)行 TCP 重置攻擊。需要以下幾個(gè)步驟:
在兩個(gè)終端之間建立一個(gè) TCP 連接。
編寫(xiě)一個(gè)能嗅探通信雙方數據的攻擊程序。
修改攻擊程序,偽造并發(fā)送重置報文。
下面正式開(kāi)始實(shí)驗。
可以使用 netcat 工具來(lái)建立 TCP 連接,這個(gè)工很多操作系統都預裝了。打開(kāi)第一個(gè)終端窗口,運行以下命令:
$ nc -nvl 8000
這個(gè)命令會(huì )啟動(dòng)一個(gè) TCP 服務(wù),監聽(tīng)端口為 8000
。接著(zhù)再打開(kāi)第二個(gè)終端窗口,運行以下命令:
$ nc 127.0.0.1 8000
該命令會(huì )嘗試與上面的服務(wù)建立連接,在其中一個(gè)窗口輸入一些字符,就會(huì )通過(guò) TCP 連接發(fā)送給另一個(gè)窗口并打印出來(lái)。
編寫(xiě)一個(gè)攻擊程序,使用 Python 網(wǎng)絡(luò )庫 scapy
來(lái)讀取兩個(gè)終端窗口之間交換的數據,并將其打印到終端上。完整的代碼參考我的 GitHub 倉庫,代碼的核心是調用 scapy
的嗅探方法:
t = sniff( iface='lo0', lfilter=is_packet_tcp_client_to_server(localhost_ip, localhost_server_port, localhost_ip), prn=log_packet, count=50)
這段代碼告訴 scapy
在 lo0
網(wǎng)絡(luò )接口上嗅探數據包,并記錄所有 TCP 連接的詳細信息。
iface : 告訴 scapy 在 lo0
(localhost)網(wǎng)絡(luò )接口上進(jìn)行監聽(tīng)。
lfilter : 這是個(gè)過(guò)濾器,告訴 scapy 忽略所有不屬于指定的 TCP 連接(通信雙方皆為 localhost
,且端口號為 8000
)的數據包。
prn : scapy 通過(guò)這個(gè)函數來(lái)操作所有符合 lfilter
規則的數據包。上面的例子只是將數據包打印到終端,下文將會(huì )修改函數來(lái)偽造重置報文。
count : scapy 函數返回之前需要嗅探的數據包數量。
下面開(kāi)始修改程序,發(fā)送偽造的 TCP 重置報文來(lái)進(jìn)行 TCP 重置攻擊。根據上面的解讀,只需要修改 prn 函數就行了,讓其檢查數據包,提取必要參數,并利用這些參數來(lái)偽造 TCP 重置報文并發(fā)送。
例如,假設該程序截獲了一個(gè)從(src_ip
, src_port
)發(fā)往 (dst_ip
, dst_port
)的報文段,該報文段的 ACK 標志位已置為 1,ACK 號為 100,000
。攻擊程序接下來(lái)要做的是:
由于偽造的數據包是對截獲的數據包的響應,所以偽造數據包的源 IP/Port
應該是截獲數據包的目的 IP/Port
,反之亦然。
將偽造數據包的 RST
標志位置為 1,以表示這是一個(gè)重置報文。
將偽造數據包的序列號設置為截獲數據包的 ACK 號,因為這是發(fā)送方期望收到的下一個(gè)序列號。
調用 scapy
的 send
方法,將偽造的數據包發(fā)送給截獲數據包的發(fā)送方。
對于我的程序而言,只需將這一行取消注釋?zhuān)⒆⑨屵@一行的上面一行,就可以全面攻擊了。按照步驟 1 的方法設置 TCP 連接,打開(kāi)第三個(gè)窗口運行攻擊程序,然后在 TCP 連接的其中一個(gè)終端輸入一些字符串,你會(huì )發(fā)現 TCP 連接被中斷了!
可以繼續使用攻擊程序進(jìn)行實(shí)驗,將偽造數據包的序列號加減 1 看看會(huì )發(fā)生什么,是不是確實(shí)需要和截獲數據包的 ACK
號完全相同。
打開(kāi) Wireshark
,監聽(tīng) lo0 網(wǎng)絡(luò )接口,并使用過(guò)濾器 ip.src == 127.0.0.1 && ip.dst == 127.0.0.1 && tcp.port == 8000
來(lái)過(guò)濾無(wú)關(guān)數據。你可以看到 TCP 連接的所有細節。
在連接上更快速地發(fā)送數據流,使攻擊更難執行。
總的來(lái)說(shuō),TCP 重置攻擊既深奧又簡(jiǎn)單,祝你實(shí)驗順利。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站