藉由丟棄封包來防禦欺騙封包 - Bad Packets Come Back, Worse Ones Don't 論文解析
簡介
防禦 DDoS 常見的防禦方式包含
- 有狀態的防禦方式,像是防火牆的 Connection Tracking Table,但記憶體容易被吃完
- 無狀態的防禦方式,像是
- 故意送錯誤的回硬,像是錯誤的 ACK 看對面是不是正常用戶,就會有自己的 TCP Stack,也就是當你的電腦收到一個「序號不對」的封包時,你的 OS 內核會自動觸發修正機制,回傳一個帶有正確預期序號 (Expected Sequence Number) 的 ACK 封包,告訴對方:「嘿,你送錯了,我現在其實是收到這裡…」
- Packet Fingerprinting: 檢查封包有沒有長的怪怪的
我們這篇討論丟棄封包這個策略,這種策略是一種主動式流量驗證」(Active Traffic Verification),特別是利用 TCP 協議的重傳機制 (Retransmission) 作為「挑戰-應答」(Challenge-Response) 的訊號。
並且 ISP 上面的防禦機制都是需要非對稱的防禦方式,像是 SYN Cookie 就是需要對成,一定會經過兩邊的環境,所以 SYN Cookie 不能用在 ISP 防禦,Drop Packet 就是一個適合非對成環境的防禦。
重傳
在了解丟棄封包策略,我們先要了解重傳機制。
超時重傳 (RTO - Retransmission Timeout)
當發送端送出一個封包(例如 Sequence 100)時,它會啟動一個「碼表」。它預期在時間 $T$ 內收到對方的 ACK。
如果時間到了還沒收到 ACK,TCP 就認定封包遺失。重新發送該封包,並且將下一次的等待時間加倍(指數退避,Exponential Backoff),以避免癱瘓網路。
TCP 會動態測量封包去回一趟要多久,然後根據這個時間計算出 RTO (Retransmission Timeout)。
快速重傳 (Fast Retransmit)
依靠超時太慢了(通常 RTO 至少是 200ms 或 1秒),這會導致嚴重的延遲。所以有了快速重傳機制。
假設發送端送了封包 1, 2, 3, 4。封包 2 丟了,但 3 和 4 到了。
所以 3 and 4 and 1 會有三個重複的 ACK 封包,當收到三個,那就馬上重傳,它就知道「雖然時間還沒到,但 2 肯定丟了」,於是立刻重傳封包 2,不用等計時器歸零。
但這邊有以前是重傳會 2 3 4 全部重傳,因此有了 SACK (Selective Acknowledgment - 選擇性確認),接收端回傳 ACK 時會帶上 SACK 選項:「我收到了 1,而且我還收到了 3 到 5 這一段」。
發送端看到後,只重傳封包 2,這樣效率會快一點。
丟棄封包策略簡介
攻擊者為了達到最大破壞力,攻擊者通常使用「偽造來源 IP (Spoofing)」且採用射後不理 (Fire-and-forget) 的策略 (通常使用簡單的 Python/C 腳本 (Raw Socket) 發送封包)。
因為偽造來源 IP,所以真正的 IP 不會知道自己送過 SYN,所以不會重傳,所以丟棄封包的策略可以成功。
Bad Packets Come Back, Worse Ones Don’t 論文就在討論這個策略,他們說這個方法叫做 Penny,這個防禦方式可能可以延伸很多討論空間,像是假如攻擊者一直送同樣 Seq 的 SYN 封包,看起來就像重傳,就可能會成功繞過,因此以下來討論看看。
SIGCOMM 是計算機網路領域最頂級、最權威的學術會議。論文的作者群來自 University College London (UCL),其中包含了 Mark Handley。
Mark Handley 是網路界的傳奇人物之一。他是 SIP 協議(VoIP 的核心)的作者之一,也是許多基礎網路協議 RFC 的貢獻者。
更詳細的策略
丟棄不是簡單的丟棄一個隨一封包,只丟帶有 Payload 的 TCP 數據封包 (Data Packets)。不能丟純 ACK 封包,因為純 ACK 通常不會被重傳。
實際上第一個 SYN 建立連線的封包也可以丟掉,但這邊是講說,為了讓系統能隨時介入測試任何連線,Penny 必須設計成能針對 「數據封包」 進行測試,因為數據封包在整個連線過程中都會持續出現。
用戶可能已經下載檔案下載了 5 分鐘,ISP 才發現路徑異常想要測試,這時候 SYN 封包早在 5 分鐘前就發送完了,Penny 根本沒機會丟棄 SYN。
並且要丟多個封包,因為單一個封包的信號太弱且充滿雜訊:
- 如果是正常流量,可能因為發送端故障或路徑改變而沒重傳
- 如果是欺騙流量,可能因為網路上有重複封包 (Duplicates) 而看起來像重傳
這邊會設定丟包機率,可能 0.1 ~ 5% 之間,這樣假如我們明明沒丟棄封包,但有重複的封包,就要注意可能是壞人惡意模擬重傳。
怎麼判斷重傳?
最簡單的想法是:如果我收到一個跟剛剛丟掉的封包「一模一樣」的封包,那就是重傳。 但論文指出 TCP 協定並不保證這一點,如果路徑上的 MTU 變小了,重傳的資料可能會被切成更小的封包,重傳的資料也可能會跟新的應用層資料(Application Data)合併在一起,變成一個更大的封包。
Penny 不去比對封包本身,而是比對 TCP 序列號 (Sequence Numbers),當 Penny 決定丟棄一個封包時,它會記錄下這個封包造成的「序列號缺口」。
每當收到新封包,Penny 就檢查這個封包的序列號範圍是否填補了某個已知的缺口。
Penny 需要知道何時該放棄等待重傳,並將該次丟包標記為「無重傳 (Non-retransmitted)」?
不同的作業系統(Linux vs Windows)和擁塞控制演算法有不同的重傳超時時間 (RTO) 。為了確保準確性,Penny 設定了一個非常保守的超時時間 $T_{maxRTX}$(預設 3 秒)。
封包真的看得到嘛?
你可能想,封包沒丟棄後,沒觀察到可能有很多理由。
像是,重傳不一定會走同樣的 router 路徑,這樣 ISP 不一定能觀察到,但論文說
- 現代路由器(ECMP)通常是基於 Flow (五元組) 來做雜湊分流的。這意味著屬於同一個 TCP 連線(相同的 Source IP/Port 和 Dest IP/Port)的封包,通常會走同一條物理路徑 。
- Penny 的測試通常只持續幾秒鐘。在這個極短的時間窗口內,域間路由(Inter-domain routing)通常是穩定的 。
並且 Penny 是用統計,他有統計到對方可能真的在路上不見的機率,Penny 會繼續丟下一個包測試。只要後續有抓到重傳,信心指數又會補回來。
如果運氣真的很差,發生了 BGP 路由震盪,導致重傳路徑永久性地避開了 Penny:Penny 會發現它丟了包,但一直沒看到重傳,同時也沒有足夠的證據證明這是攻擊(因為沒有看到大量的重複封包),測試會變成 「無結論」(Inconclusive) 。
Penny 的設計原則是「寧可放過,不可殺錯」。如果測試無結論,它就不會發出警報。這對 ISP 來說是可以接受的(只是錯失了一次發現問題的機會,而不是製造假警報)。
更聰明的攻擊者
挑戰:攻擊者可能會故意發送重複的封包(Duplicate packets),試圖讓偽造流量看起來像是有重傳的正常流量,以此欺騙 Penny 。
Penny 設定了一個最小丟包數為 12,這意味著 Penny 必須至少丟棄並觀察 12 個封包的結果(重傳或未重傳)才會下結論,絕不會因為只看了兩三個包就草率判定 。
這句話的核心含義是:「因為攻擊者看不到 Penny 丟了哪個包,只能『盲猜』去重複發送。但在 15% 的重複上限下,要剛好『猜中』 Penny 丟的那 12 個包,機率比中樂透還低。」
因為攻擊者是偽造 IP 的,所以當 Penny 丟掉封包時,攻擊者收不到這個訊號,自然無法針對性地重傳「被丟掉的那個包」。
為了騙過 Penny,攻擊者唯一的策略就是「亂槍打鳥」:在發送封包時,隨機把某些封包發送兩次。攻擊者希望 Penny 剛好丟掉了一個封包,而那個封包剛好有發送兩次(第二個包就會看起來像重傳)。
你可能會問:「那攻擊者就把所有封包都發兩次(100% 重複),不就一定能騙過 Penny 了嗎?」不行,因為 Penny 有另一個檢查機制:規則: 正常的 TCP 連線不應該有太多的重複封包。如果 Penny 觀察到某股流量的重複封包比例 ($f_{dup}$) 超過 15%,它會直接判定這股流量異常(非正常的閉環流量),測試失敗 1。
閥值
作者建議在 0.1% 到 5% 之間
- 高丟包率 (5%): 測試速度快,適合短流,但對單一連線的效能影響稍大(雖然仍在 TCP 可恢復範圍內)
- 低丟包率 (0.1%): 對使用者幾無影響,適合流量大的聚合測試
Penny 怎麼放在 ISP
傳統路由器雖然可以轉發封包,但缺乏深度監控和分析流量的能力(通常只有簡單的計數器)。
Penny 採用「旁路檢查」的架構。當 ISP 懷疑某股流量(例如來自 AS2 但從錯誤接口進入)有問題時,會透過路由策略(如 Route-maps 或 P4 可編程交換機)將這部分流量重定向到一個專門的檢查器(Checker)。
其他方法
有可能有其他的無狀態防禦方式:
- 被動監控 (Passive Monitoring): 觀察雙向封包(如 SYN 和 ACK)來確認連線
- 路徑不對稱 (Asymmetry):ISP 通常只能看到單向流量,看不到回傳的封包,因此無法確認連線是否成功 。單純檢查序列號遞增也容易被聰明的攻擊者欺騙
- 主動探測 (Active Probing): 檢查器主動發送 SYN 給來源 IP 測試反應
- 不可靠:很多伺服器不回應未知的 SYN;且由於 ECMP 負載平衡,回傳的封包可能走完全不同的路徑,檢查器收不到
並且有可能有其他類似的工具,但都有缺點
- 傳統的 ISP 監控工具(如 SNMP 、Netflow 、sFlow )通常只能提供聚合的流量資訊,且主要關注熱門的目的地
- 較新的技術(如 Planck 、Everflow 、Magnifier )雖然改進了流量的可見性,但它們無法區分「閉環流量(正常)」與「欺騙流量(Spoofed)」 。因此,這些工具無法解決論文提出來的核心問題(即判斷異常路徑流量是否為真)
雖然有許多防 IP 欺騙的標準(如 BCP38 、SAVI ),但由於對 ISP 缺乏經濟誘因,這些技術在網際網路上的部署率仍然很低。
並且還有 QUIC 協定,QUIC 的封包是加密的,無法識別重傳。Penny 的策略是針對握手階段的封包(Client Hello)進行丟包測試 。雖然這會增加建立連線的延遲,但這是唯一可行的方法。
Reference
- Bad Packets Come Back, Worse Ones Don’t