自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你猜一個 TCP 重置報文的序列號是多少?

網(wǎng)絡(luò) 通信技術(shù)
TCP 重置攻擊是使用一個單一的數(shù)據(jù)包來執(zhí)行的,只有幾個字節(jié)大小。攻擊者制作并發(fā)送一個偽造的 TCP 重置包來干擾用戶和網(wǎng)站的連接,欺騙通信雙方終止 TCP 連接。

本文轉(zhuǎn)載自微信公眾號「 云原生實驗室」,轉(zhuǎn)載本文請聯(lián)系 云原生實驗室公眾號。

 TCP 重置攻擊是使用一個單一的數(shù)據(jù)包來執(zhí)行的,只有幾個字節(jié)大小。攻擊者制作并發(fā)送一個偽造的 TCP 重置包來干擾用戶和網(wǎng)站的連接,欺騙通信雙方終止 TCP 連接。我們偉大的 xx 長城便運用了這個技術(shù)來進(jìn)行 TCP 關(guān)鍵字阻斷[1]。

理解 TCP 重置攻擊并不需要具備深厚的網(wǎng)絡(luò)知識功底,只需要一臺筆記本就可以對自己進(jìn)行模擬攻擊。本文將會帶你了解 TCP 重置攻擊的原理,同時會幫助你理解很多關(guān)于 TCP 協(xié)議的特性。本文主要內(nèi)容:

  • 回顧 TCP 協(xié)議的基礎(chǔ)知識
  • 了解 TCP 重置攻擊的原理
  • 使用一個簡單的 Python 腳本來模擬攻擊

下面開始分析 TCP 重置攻擊原理。

1. 偉大的 xx 長城是如何利用 TCP 重置攻擊的?這一段略過,原因你懂得,感興趣的請直接看原文。

2. TCP 重置攻擊的工作原理

在 TCP 重置攻擊中,攻擊者通過向通信的一方或雙方發(fā)送偽造的消息,告訴它們立即斷開連接,從而使通信雙方連接中斷。正常情況下,如果客戶端收發(fā)現(xiàn)到達(dá)的報文段對于相關(guān)連接而言是不正確的,TCP 就會發(fā)送一個重置報文段,從而導(dǎo)致 TCP 連接的快速拆卸。

TCP 重置攻擊利用這一機制,通過向通信方發(fā)送偽造的重置報文段,欺騙通信雙方提前關(guān)閉 TCP 連接。如果偽造的重置報文段完全逼真,接收者就會認(rèn)為它有效,并關(guān)閉 TCP 連接,防止連接被用來進(jìn)一步交換信息。服務(wù)端可以創(chuàng)建一個新的 TCP 連接來恢復(fù)通信,但仍然可能會被攻擊者重置連接。萬幸的是,攻擊者需要一定的時間來組裝和發(fā)送偽造的報文,所以一般情況下這種攻擊只對長連接有殺傷力,對于短連接而言,你還沒攻擊呢,人家已經(jīng)完成了信息交換。

從某種意義上來說,偽造 TCP 報文段是很容易的,因為 TCP/IP 都沒有任何內(nèi)置的方法來驗證服務(wù)端的身份。有些特殊的 IP 擴展協(xié)議(例如 IPSec)確實可以驗證身份,但并沒有被廣泛使用??蛻舳酥荒芙邮請笪亩?,并在可能的情況下使用更高級別的協(xié)議(如 TLS)來驗證服務(wù)端的身份。但這個方法對 TCP 重置包并不適用,因為 TCP 重置包是 TCP 協(xié)議本身的一部分,無法使用更高級別的協(xié)議進(jìn)行驗證。

盡管偽造 TCP 報文段很容易,但偽造正確的 TCP 重置報文段并完成攻擊卻并不容易。為了理解這項工作的難度,我們需要先了解一下 TCP 協(xié)議的工作原理。

3. TCP 協(xié)議工作原理

TCP 協(xié)議的目標(biāo)是向客戶端發(fā)送一份完整的數(shù)據(jù)副本。例如,如果我的服務(wù)器通過 TCP 連接向你的計算機發(fā)送我的網(wǎng)站的 HTML,你的計算機的 TCP 協(xié)議棧應(yīng)該能夠以我發(fā)送的形式和順序輸出HTML。

 

然而現(xiàn)實生活中我的 HTML 內(nèi)容并不是按順序發(fā)送的,它被分解成許多小塊(稱為 TCP 分組),每個小塊在網(wǎng)絡(luò)上被單獨發(fā)送,并被重新組合成原來發(fā)送的順序。這種重新組合后的輸出被稱為 TCP 字節(jié)流。

 

將分組重建成字節(jié)流并不簡單,因為網(wǎng)絡(luò)是不可靠的。TCP分組可能會被丟棄,可能不按發(fā)送的順序到達(dá)客戶端,也可能會被重復(fù)發(fā)送、報文損壞等等。因此,TCP 協(xié)議的職責(zé)是在不可靠的網(wǎng)絡(luò)上提供可靠的通信。TCP 通過要求連接雙方保持密切聯(lián)系,持續(xù)報告它們接收到了哪些數(shù)據(jù)來實現(xiàn)可靠通信,這樣服務(wù)端就能夠推斷出客戶端尚未接收到的數(shù)據(jù),并重新發(fā)送丟失的數(shù)據(jù)。

為了進(jìn)一步理解這個過程,我們需要了解服務(wù)端和客戶端是如何使用序列號(sequence numbers)來標(biāo)記和跟蹤數(shù)據(jù)的。

TCP 序列號

TCP 協(xié)議的通信雙方, 都必須維護(hù)一個序列號(sequence numbers),對于客戶端來說,它會使用服務(wù)端的序列號來將接收到的數(shù)據(jù)按照發(fā)送的順序排列。

 

當(dāng)通信雙方建立 TCP 連接時,客戶端與服務(wù)端都會向?qū)Ψ桨l(fā)送一個隨機的初始序列號,這個序列號標(biāo)識了其發(fā)送數(shù)據(jù)流的第一個字節(jié)。TCP 報文段包含了 TCP 頭部,它是附加在報文段開頭的元數(shù)據(jù),序列號就包含在 TCP 頭部中。由于 TCP 連接是雙向的,雙方都可以發(fā)送數(shù)據(jù),所以 TCP 連接的雙方既是發(fā)送方也是接收方,每一方都必須分配和管理自己的序列號。

確認(rèn)應(yīng)答

當(dāng)接收方收到一個 TCP 報文段時,它會向發(fā)送方返回一個 ACK 應(yīng)答報文(同時將 TCP 頭部的 ACK 標(biāo)志位置 1),這個 ACK 號就表示接收方期望從發(fā)送方收到的下一個字節(jié)的序列號。發(fā)送方利用這個信息來推斷接收方已經(jīng)成功接收到了序列號為 ACK 之前的所有字節(jié)。

TCP 頭部格式如下圖所示:

 

一個確認(rèn)應(yīng)答報文的 TCP 頭部必須包含兩個部分:

  • ACK 標(biāo)志位置位 1
  • 包含確認(rèn)應(yīng)答號(ACK number)

TCP 總共有 6 個標(biāo)志位,下文就會講到其中的 RST 標(biāo)志位。

 

TCP 頭部包含了多個選項,其中有一個選擇確認(rèn)選項(SACK),如果使用該選項,那么當(dāng)接收方收到了某個范圍內(nèi)的字節(jié)而不是連續(xù)的字節(jié)時,就會發(fā)送 SACK 告知對方。例如,只收到了字節(jié) 1000~3000 和 4000~5000,但沒有收到 3001~3999。為了簡單起見,下文討論 TCP 重置攻擊時將忽略選擇確認(rèn)選項。

如果發(fā)送方發(fā)送了報文后在一段時間內(nèi)沒有收到 ACK,就認(rèn)為報文丟失了,并重新發(fā)送報文,用相同的序列號標(biāo)記。這就意味著,如果接收方收到了重復(fù)的報文,可以使用序列號來判斷是否見過這個報文,如果見過則直接丟棄。網(wǎng)絡(luò)環(huán)境是錯綜復(fù)雜的,往往并不是如我們期望的一樣,先發(fā)送的數(shù)據(jù)包,就先到達(dá)目標(biāo)主機,反而它很騷,可能會由于網(wǎng)絡(luò)擁堵等亂七八糟的原因,會使得舊的數(shù)據(jù)包,先到達(dá)目標(biāo)主機。一般分兩種情況:

  1. 發(fā)送的數(shù)據(jù)包丟失了
  2. 發(fā)送的數(shù)據(jù)包被成功接收,但返回的 ACK 丟失了

這兩種情況對發(fā)送方來說其實是一樣的,發(fā)送方并不能區(qū)分是哪種情況,所以只能重新發(fā)送數(shù)據(jù)包。

 

只要不頻繁重復(fù)發(fā)送數(shù)據(jù),額外的開銷基本可以忽略。

為偽造的重置包選擇序列號

構(gòu)建偽造的重置包時需要選擇一個序列號。接收方可以接收序列號不按順序排列的報文段,但這種容忍是有限度的,如果報文段的序列號與它期望的相差甚遠(yuǎn),就會被直接丟棄。

因此,一個成功的 TCP 重置攻擊需要構(gòu)建一個可信的序列號。但什么才是可信的序列號呢?對于大多數(shù)報文段(除了重置包,即 RST 包)來說,序列號是由接收方的接收窗口大小決定的。

TCP 滑動窗口大小

想象一下,將一臺上世紀(jì) 90 年代初的古老計算機,連接到現(xiàn)代千兆光纖網(wǎng)絡(luò)。閃電般快速的網(wǎng)絡(luò)可以以令人瞠目結(jié)舌的速度向這臺古老的計算機傳送數(shù)據(jù),速度遠(yuǎn)遠(yuǎn)超過該計算機的處理能力。但并沒有什么卵用,因為只有接收方接收并處理了報文,才能認(rèn)為這個報文已經(jīng)被收到了。

 

TCP 協(xié)議棧有一個緩沖區(qū),新到達(dá)的數(shù)據(jù)被放到緩沖區(qū)中等待處理。但緩沖區(qū)的大小是有限的,如果接收方的處理速度跟不上發(fā)送方的發(fā)送速度,緩沖區(qū)就會被填滿。一旦緩沖區(qū)被填滿,多余的數(shù)據(jù)就會被直接丟棄,也不會返回 ACK。因此一旦接收方的緩沖區(qū)有了空位,發(fā)送方必須重新發(fā)送數(shù)據(jù)。也就是說,如果接收方的處理速度跟不上,發(fā)送方的發(fā)送速度再快也沒用。

緩沖區(qū)到底有多大?發(fā)送方如何才能知道什么時候可以一次發(fā)送更多的數(shù)據(jù),什么時候該一次發(fā)送很少的數(shù)據(jù)?這就要靠 TCP 滑動窗口了。接收方的滑動窗口大小是指發(fā)送方無需等待確認(rèn)應(yīng)答,可以持續(xù)發(fā)送數(shù)據(jù)的最大值。 假設(shè)接收方的通告窗口大小為 100,000 字節(jié),那么發(fā)送方可以無需等待確認(rèn)應(yīng)答,持續(xù)發(fā)送 100,000 個字節(jié)。再假設(shè)當(dāng)發(fā)送方發(fā)送第 100,000 個字節(jié)時,接收方已經(jīng)發(fā)送了前 10,000 個字節(jié)的 ACK,這就意味著窗口中還有 90,000 個字節(jié)未被確認(rèn),發(fā)送方還可以再持續(xù)發(fā)送 10,000 個字節(jié)。如果發(fā)送了 10,000 個字節(jié)的過程中沒有收到任何的 ACK,那么接收方的滑動窗口將被填滿,發(fā)送方將停止發(fā)送新數(shù)據(jù)(可以繼續(xù)發(fā)送之前丟失的數(shù)據(jù)),直到收到相關(guān)的 ACK 才可以繼續(xù)發(fā)送。

 

TCP 連接雙方會在建立連接的初始握手階段通告對方自己窗口的大小,后續(xù)還可以動態(tài)調(diào)整。TCP 緩沖區(qū)大的服務(wù)器可能會聲明一個大窗口,以便最大限度提高吞吐量。TCP 緩沖區(qū)小的服務(wù)器可能會被迫聲明一個小窗口,這樣做會犧牲一定的吞吐量,但為了防止接收方的 TCP 緩沖區(qū)溢出,還是很有必要的。

 

換個角度來看,TCP 滑動窗口大小是對網(wǎng)絡(luò)中可能存在的未確認(rèn)數(shù)據(jù)量的硬性限制。我們可以用它來計算發(fā)送方在某一特定時間內(nèi)可能發(fā)送的最大序列號(max_seq_no):

  1. max_seq_no = max_acked_seq_no + window_size 

其中 max_acked_seq_no 是接收方發(fā)送的最大 ACK 號,它表示發(fā)送方知道接收方已經(jīng)成功接收的最大序列號。window_size 是窗口大小,它表示允許發(fā)送方最多發(fā)送的未被確認(rèn)的字節(jié)。所以發(fā)送方可以發(fā)送的最大序列號是:max_acked_seq_no + window_size。

TCP 規(guī)范規(guī)定,接收方應(yīng)該忽略任何序列號在接收窗口之外的數(shù)據(jù)。例如,如果接收方確認(rèn)了所有序列號在 15,000 以下的字節(jié),且接收窗口大小為 30,000,那么接下來接收方只能接收序列號范圍在 15,000 ~ 45,000 之間的數(shù)據(jù)。如果一個報文段的部分?jǐn)?shù)據(jù)在窗口內(nèi),另一部分?jǐn)?shù)據(jù)在窗口外,那么窗口內(nèi)的數(shù)據(jù)將被接收確認(rèn),窗口外的數(shù)據(jù)將被丟棄。注意:這里忽略了選擇確認(rèn)選項,再強調(diào)一遍!

對于大多數(shù) TCP 報文段來說,滑動窗口的規(guī)則告訴了發(fā)送方自己可以接收的序列號范圍。但對于重置報文來說,序列號的限制更加嚴(yán)格,這是為了抵御一種攻擊叫做盲目 TCP 重置攻擊(blind TCP reset attack),下文將會解釋。

TCP 重置報文段的序列號

對于 TCP 重置報文段來說,接收方對序列號的要求更加嚴(yán)格,只有當(dāng)其序列號正好等于下一個預(yù)期的序列號時才能接收。繼續(xù)搬出上面的例子,接收方發(fā)送了一個確認(rèn)應(yīng)答,ACK 號為 15,000。如果接下來收到了一個重置報文,那么其序列號必須是 15,000 才能被接收。

 

如果重置報文的序列號超出了接收窗口范圍,接收方就會直接忽略該報文;如果其序列號在接收窗口范圍內(nèi),那么接收方就會返回一個 challenge ACK,告訴發(fā)送方重置報文段的序列號是錯誤的,并告之正確的序列號,發(fā)送方可以利用 challenge ACK 中的信息來重新構(gòu)建和發(fā)送重置報文。

其實在 2010 年之前,TCP 重置報文段和其他報文段的序列號限制規(guī)則一樣,但無法抵御盲目 TCP 重置攻擊,后來才采取這些措施施加額外的限制。

盲目 TCP 重置攻擊如果攻擊者能夠截獲通信雙方正在交換的信息,攻擊者就能讀取其數(shù)據(jù)包上的序列號和確認(rèn)應(yīng)答號,并利用這些信息得出偽裝的 TCP 重置報文段的序列號。相反,如果無法截獲通信雙方的信息,就無法確定重置報文段的序列號,但仍然可以批量發(fā)出盡可能多不同序列號的重置報文,以期望猜對其中一個序列號。這就是所謂的盲目 TCP 重置攻擊(blind TCP reset attack)。

在 2010 年之前 TCP 的原始版本中,攻擊者只需要猜對接收窗口內(nèi)的隨便哪一個序列號即可,一般只需發(fā)送幾萬個報文段就能成功。采取額外限制的措施后,攻擊者需要發(fā)送數(shù)以百萬計的報文段才有可能猜對序列號,這幾乎是很難成功的。更多細(xì)節(jié)請參考 RFC-5963[2]。

4. 模擬攻擊

以下實驗是在 OSX 系統(tǒng)中完成的,其他系統(tǒng)請自行測試。

現(xiàn)在來總結(jié)一下偽造一個 TCP 重置報文要做哪些事情:

  • 嗅探通信雙方的交換信息。
  • 截獲一個 ACK 標(biāo)志位置位 1 的報文段,并讀取其 ACK 號。
  • 偽造一個 TCP 重置報文段(RST 標(biāo)志位置為 1),其序列號等于上面截獲的報文的 ACK號。這只是理想情況下的方案,假設(shè)信息交換的速度不是很快。大多數(shù)情況下為了增加成功率,可以連續(xù)發(fā)送序列號不同的重置報文。
  • 將偽造的重置報文發(fā)送給通信的一方或雙方,時其中斷連接。

為了實驗簡單,我們可以使用本地計算機通過 localhost 與自己通信,然后對自己進(jìn)行 TCP 重置攻擊。需要以下幾個步驟:

在兩個終端之間建立一個 TCP 連接。

編寫一個能嗅探通信雙方數(shù)據(jù)的攻擊程序。

修改攻擊程序,偽造并發(fā)送重置報文。

下面正式開始實驗。

建立 TCP 連接

可以使用 netcat[3] 工具來建立 TCP 連接,這個工很多操作系統(tǒng)都預(yù)裝了。打開第一個終端窗口,運行以下命令:

  1. $ nc -nvl 8000 

這個命令會啟動一個 TCP 服務(wù),監(jiān)聽端口為 8000。接著再打開第二個終端窗口,運行以下命令:

  1. $ nc 127.0.0.1 8000 

該命令會嘗試與上面的服務(wù)建立連接,在其中一個窗口輸入一些字符,就會通過 TCP 連接發(fā)送給另一個窗口并打印出來。

 

嗅探流量

編寫一個攻擊程序,使用 Python 網(wǎng)絡(luò)庫 scapy 來讀取兩個終端窗口之間交換的數(shù)據(jù),并將其打印到終端上。完整的代碼參考我的 GitHub 倉庫[4],代碼的核心是調(diào)用 scapy 的嗅探方法:

  1. t = sniff( 
  2.         iface='lo0'
  3.         lfilter=is_packet_tcp_client_to_server(localhost_ip, localhost_server_port, localhost_ip), 
  4.         prn=log_packet, 
  5.         count=50) 

這段代碼告訴 scapy 在 lo0 網(wǎng)絡(luò)接口上嗅探數(shù)據(jù)包,并記錄所有 TCP 連接的詳細(xì)信息。

  • iface : 告訴 scapy 在 lo0(localhost)網(wǎng)絡(luò)接口上進(jìn)行監(jiān)聽。
  • lfilter : 這是個過濾器,告訴 scapy 忽略所有不屬于指定的 TCP 連接(通信雙方皆為 localhost,且端口號為 8000)的數(shù)據(jù)包。
  • prn : scapy 通過這個函數(shù)來操作所有符合 lfilter 規(guī)則的數(shù)據(jù)包。上面的例子只是將數(shù)據(jù)包打印到終端,下文將會修改函數(shù)來偽造重置報文。
  • count : scapy 函數(shù)返回之前需要嗅探的數(shù)據(jù)包數(shù)量。

發(fā)送偽造的重置報文

下面開始修改程序,發(fā)送偽造的 TCP 重置報文來進(jìn)行 TCP 重置攻擊。根據(jù)上面的解讀,只需要修改 prn 函數(shù)就行了,讓其檢查數(shù)據(jù)包,提取必要參數(shù),并利用這些參數(shù)來偽造 TCP 重置報文并發(fā)送。

例如,假設(shè)該程序截獲了一個從(src_ip, src_port)發(fā)往 (dst_ip, dst_port)的報文段,該報文段的 ACK 標(biāo)志位已置為 1,ACK 號為 100,000。攻擊程序接下來要做的是:

  • 由于偽造的數(shù)據(jù)包是對截獲的數(shù)據(jù)包的響應(yīng),所以偽造數(shù)據(jù)包的源 IP/Port 應(yīng)該是截獲數(shù)據(jù)包的目的 IP/Port,反之亦然。
  • 將偽造數(shù)據(jù)包的 RST 標(biāo)志位置為 1,以表示這是一個重置報文。
  • 將偽造數(shù)據(jù)包的序列號設(shè)置為截獲數(shù)據(jù)包的 ACK 號,因為這是發(fā)送方期望收到的下一個序列號。
  • 調(diào)用 scapy 的 send 方法,將偽造的數(shù)據(jù)包發(fā)送給截獲數(shù)據(jù)包的發(fā)送方。

對于我的程序而言,只需將這一行[5]取消注釋,并注釋這一行的上面一行,就可以全面攻擊了。按照步驟 1 的方法設(shè)置 TCP 連接,打開第三個窗口運行攻擊程序,然后在 TCP 連接的其中一個終端輸入一些字符串,你會發(fā)現(xiàn) TCP 連接被中斷了!

 

進(jìn)一步實驗

  1. 可以繼續(xù)使用攻擊程序進(jìn)行實驗,將偽造數(shù)據(jù)包的序列號加減 1 看看會發(fā)生什么,是不是確實需要和截獲數(shù)據(jù)包的 ACK 號完全相同。
  2. 打開 Wireshark,監(jiān)聽 lo0 網(wǎng)絡(luò)接口,并使用過濾器 ip.src == 127.0.0.1 && ip.dst == 127.0.0.1 && tcp.port == 8000 來過濾無關(guān)數(shù)據(jù)。你可以看到 TCP 連接的所有細(xì)節(jié)。
  3. 在連接上更快速地發(fā)送數(shù)據(jù)流,使攻擊更難執(zhí)行。

總的來說,TCP 重置攻擊既深奧又簡單,祝你實驗順利。

文章鏈接:https://mp.weixin.qq.com/s/crgraQv6qQ-aVJd9L2u1eg

責(zé)任編輯:武曉燕 來源: 云原生實驗室
相關(guān)推薦

2019-07-09 06:13:09

TCPHTTP網(wǎng)絡(luò)協(xié)議

2013-03-06 17:27:36

僵尸網(wǎng)絡(luò)

2009-09-04 08:17:04

Windows 7序列號檢查器

2011-04-19 09:25:51

2009-09-14 08:36:21

Windows 7正版序列號

2017-11-22 09:46:53

分布式架構(gòu)系統(tǒng)

2022-01-14 13:53:03

TCP進(jìn)程窗口

2012-11-20 12:38:29

2011-04-19 09:30:33

2009-02-09 15:51:48

Windows 7序列號免費

2010-01-11 17:49:36

VB.NET硬盤序列號

2009-12-04 13:56:58

安裝Windows 7

2010-09-02 17:27:18

SQL Server安裝

2019-11-14 16:05:29

TCPHTTP前端

2019-10-12 00:03:07

MyCat數(shù)據(jù)庫分庫分表

2009-12-07 17:17:00

Windows 7操作

2023-12-29 08:22:52

lsblk命令存儲

2019-12-20 09:31:23

TCPHTTP瀏覽器

2019-09-23 09:11:02

Python文本編輯器操作系統(tǒng)

2009-11-25 10:00:37

點贊
收藏

51CTO技術(shù)棧公眾號