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