ISN
A -------------------> B
SYN/ACK
A <------------------- B
ACK
A -------------------> B
在 A 向 B 發出 TCP 請求的時候,它發出一個隨機的 ISN (Initial Sequence Number),B 收到后給 A 回復一個 ACK = ISN + 1,同時再回復一個自己的 SYN 號,接著會保存 A 發來的這些信息,同時再內存中開辟緩沖區進行保存,然后 A 再給 B 回復一個 ACK。經歷過這三次之后,一個端到端的 TCP 連接已經建立起來了,這是正常的情況。但是,考慮這種情況,如果在 A 向 B 發出請求,B 給 A 回復并且開辟了資源之后,A 不再進行第三次的回復,會怎么辦?這就好比說,張三收到錢了,也不給我打電話,我一等 2 個月,按照常理的話張三早該收到錢了,但是他還沒來電話,沒辦法,我只有再去匯錢了,那么如果每一次都這樣,我這里的錢是不是很快就匯完了?TCP 中也是這樣,如果 A 一直在向B 發起 TCP 請求,B 也按照正常情況進行響應了,但是 A 不進行第三次的握手,造成半連接,那么 B 分配出去的內存資源就一直這么耗著,直到資源耗盡。
對于這種攻擊,似乎是沒有辦法防范的,因為 TCP 的三次握手是協議規定死的,所有使用 TCP 協議的軟件都必須遵循其規定,否則無法通信。但是,有一種辦法,似乎可以防范,那就是限制通信源的 TCP 并發連接數,例如:如果 A 在 1 秒鐘之內連續產生 100 個 TCP 半連接,那么 B 就丟棄 A 所有的 TCP 信息,并且在一定時間內不再響應攻擊者的釋放內存資源。這看起來似乎似乎一種行之有效的辦法,可是實際并非這么簡單,因為在第三層的 IP 協議是一個不可靠的協議,它的源地址可以被偽造,如果一個攻擊者制造大量的偽造源地址來對受害者進行攻擊,而每一個 IP 地址的 TCP 半連接只建立 3~5 次,這個時候如何防范?
基于此,一種新型的防御方式產生了—— TCP Cookie,TCP Cookie 技術針對 TCP 協議的軟肋,做出了一些改進。仍以上面的通信過程為例,在 A 向 B 發出一個 TCP 請求之后,B 并不立即為 A 的 TCP 請求分配資源,而是利用 A 發來的連接信息計算出一個 Cookie 值——取 Client 端的 IP、端口,以及 Server 端的 IP、端口,再進行一種散列算法,得到一個 Cookie,取該 Cookie 的前 24 位作為 SYN 值對對方進行回復。當對方對這個 SYN/ACK 再次進行 ACK (ACK=SYN+1)回復的時候,利用某種算法和這個 ACK 來倒推回原來的 Cookie,如果在一定范圍內符合,即認為是合法的 TCP 請求,對它進行響應,如果不符合,則認為其是非法的 TCP 請求,丟棄。為什么說是一定范圍內呢,因為 Cookie 的變化和時間有關,那么在 TCP 超時之內的所有的 ACK 都應該是合法的,那么在倒推回去的時候,只要得到的 Cookie 和原來的 Cookie 在一個合法的時間段內相符,就認為是合法的。