非中間人就沒法劫持TCP了嗎?
TCP的初始序列號(hào)
Hi,我是Robert,上回說到我費(fèi)了老大勁才考上了Linux帝國(guó)的公務(wù)員,被分配到了網(wǎng)絡(luò)部協(xié)議棧大廈的傳輸層工作。
上班第一天,主管就讓我處理一個(gè)新的TCP連接練練手。雖然我理論背的滾瓜爛熟,不過還沒有實(shí)際上手處理過TCP數(shù)據(jù)包,竟有些緊張起來(lái)。
接過這個(gè)請(qǐng)求連接的數(shù)據(jù)包后,我準(zhǔn)備了一個(gè)響應(yīng)包,將SYN標(biāo)記和ACK標(biāo)記都點(diǎn)亮后,接下來(lái)就犯了難了。這個(gè)確認(rèn)號(hào)ACK我倒是知道是對(duì)方的序列號(hào)+1,不過我回復(fù)的序列號(hào)該是多少呢?
我閉上眼睛在腦子飛快的檢索RFC,很快想了起來(lái),RFC793有言,初始序列號(hào)ISN是一個(gè)計(jì)數(shù)器,每4ms加1。
我趕緊向一旁的Cerf求助,“Hi,Cerf,初始序列號(hào)計(jì)數(shù)器在哪里啊?”
Cerf順手指了一下墻上的一個(gè)鐘表樣式的東西,“喏,那就是,這是個(gè)全局統(tǒng)一的計(jì)數(shù)器,大家共用。”
我填充好了序列號(hào)字段,正欲發(fā)送,Cerf叫住了我,“等等,你打算就拿這個(gè)計(jì)數(shù)器直接當(dāng)初始序列號(hào)發(fā)送出去啊?”
“這有什么不對(duì)嗎?RFC793就是這樣說的啊”
“這都是多老的版本了,現(xiàn)在早就不這樣了!直接用這個(gè)當(dāng)序列號(hào)很危險(xiǎn)的”
你不知道的ISN
我有些不好意思,接下來(lái)Cerf給我介紹了前因后果。
“原來(lái),早先時(shí)候比特宇宙中別的帝國(guó)就是直接按照RFC793來(lái)設(shè)計(jì)ISN的。后來(lái)出了一件事,有一個(gè)攻擊者冒充客戶端給服務(wù)器發(fā)送數(shù)據(jù)包,把別人正常的TCP連接給劫持了,竊取了機(jī)密的數(shù)據(jù)!你猜他是怎么辦到的?”
這可難不倒我,脫口而出:“肯定是這家伙在半道上監(jiān)聽了網(wǎng)絡(luò)通信,拿到了他們通信的序列號(hào)和確認(rèn)號(hào),然后就能偽造一方進(jìn)行通信了”
Cerf搖了搖頭,“非也,這家伙不是中間人,沒有監(jiān)聽通信哦”
這下我倒是蒙了,皺起了眉頭,“不是中間人,那就沒辦法知道序列號(hào)了,不知道序列號(hào)的前提下,怎么能冒充呢?”
聽到我的問題,Cerf會(huì)心一笑,“這家伙太聰明了,在冒充之前,他先和服務(wù)器建立過連接,拿到了服務(wù)器的初始序列號(hào)。因?yàn)檫@個(gè)序列號(hào)是每4ms加1,所以后面掐著時(shí)間推算一下,就能算到后面建立連接的時(shí)候,服務(wù)器新的ISN是什么”
我恍然大悟,“這家伙真雞賊,那看來(lái)這個(gè)ISN不能這樣簡(jiǎn)單設(shè)定。”
“所以啊,我剛剛制止了你,現(xiàn)在RFC出了新規(guī)定1948號(hào)文件,規(guī)定ISN要這么算:”
ISN = M + F(localhost, localport, remotehost, remoteport)
“M就是你剛剛看那個(gè)計(jì)數(shù)器,在此基礎(chǔ)之上,還增加了一個(gè)F,把通信雙方的IP和端口,也就是四元組信息做一個(gè)運(yùn)算,得到一個(gè)值加在計(jì)數(shù)器之上,增加ISN的不可預(yù)測(cè)性”
我點(diǎn)了點(diǎn)頭,“這個(gè)F一般用什么算法呢?”
“在咱們Linux帝國(guó),之前用過MD4算法,后來(lái)升級(jí)成MD5算法了”
“感謝Cerf,要不是你我就要犯錯(cuò)誤了”
Cerf拍拍我的肩,語(yǔ)重心長(zhǎng)的說:“你還要不停學(xué)習(xí)啊,考上帝國(guó)公務(wù)員只是第一步”
“要學(xué)習(xí)的不只是他,你也是啊,不知道關(guān)于ISN又出新規(guī)定了嗎?”
我倆一起回頭,原來(lái)是主管走了過來(lái)。
“主管,啥新規(guī)定啊?”,Cerf問到。
“RFC出了個(gè)新規(guī)定6528號(hào)文件,現(xiàn)在的ISN是這樣計(jì)算的:”
ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
“多了一個(gè)secretkey!”,我一下發(fā)現(xiàn)了不同。
“沒錯(cuò)!如果雙方用同樣的端口先后進(jìn)行兩次通信,四元組是固定的,那F函數(shù)算下來(lái)的結(jié)果也是固定的,這樣隨機(jī)性就大大降低了。所以再增加一個(gè)secretkey,讓ISN變得更難預(yù)測(cè)”
“那是不是這樣就萬(wàn)無(wú)一失啦?再也不怕被劫持了呢?”,我接著問到。
主管頓了一下,說到:“除非是網(wǎng)絡(luò)中其他單位做中間人來(lái)劫持,否則應(yīng)該是沒有辦法了”
主管不愧是主管,懂得是比我們多。
耽誤了半天,我的這條連接還沒有回復(fù),我趕緊按照新的算法,算出了ISN,給對(duì)方回了過去。
第一個(gè)練手的連接就讓我學(xué)到了不少東西,沒想到一個(gè)簡(jiǎn)單的ISN居然還有這么多講究。
神秘的計(jì)數(shù)器
時(shí)間來(lái)到下午,Cerf帶我在大廈到處轉(zhuǎn)轉(zhuǎn),熟悉一下環(huán)境。
不多時(shí),我們來(lái)到了一間屋子,屋子里擺放著一堆計(jì)數(shù)器,上面的信號(hào)燈還在一明一暗的不停閃著。
“這又是一堆什么計(jì)數(shù)器啊,怎么這么多!”,我問一旁的Cerf。
“這些是記錄咱們網(wǎng)絡(luò)部門工作數(shù)據(jù)的重要展示,不僅在咱們傳輸層,下面一樓的網(wǎng)絡(luò)層也有一個(gè)屋子存放了他們的計(jì)數(shù)器。每一次啟動(dòng),咱們發(fā)了多少包、收了多少包、出錯(cuò)了多少、收到多少重復(fù)包等等信息,都在這一筆筆記著呢。你后面正式工作了,少不了要經(jīng)常來(lái)這里的”
我放眼望去,每個(gè)計(jì)數(shù)器上面都貼了標(biāo)簽:
- SyncookiesSent
- SyncookiesRecv
- SyncookiesFailed
- EmbryonicRsts
- PruneCalled
- RcvPruned
- OfoPruned
- ······
- DelayedACKs
- DelayedACKLocked
- DelayedACKLost
- ListenOverflows
- ListenDrops
- TCPPrequeued
正瞧著,忽然發(fā)現(xiàn)有不少同名的計(jì)數(shù)器,再仔細(xì)一瞧,不是同名,而是這里劃分了8個(gè)分區(qū),每個(gè)分區(qū)里的計(jì)數(shù)器都是一樣的。
“Cerf,這里怎么有8份一樣的計(jì)數(shù)器啊”
“那是因?yàn)楹驮蹅兇蚪坏赖腃PU是個(gè)8核的,為了防止多個(gè)線程之間競(jìng)爭(zhēng),加鎖太耽誤事兒了,就弄了8份。最后統(tǒng)計(jì)的時(shí)候再合在一起就行了”
離開了計(jì)數(shù)器的房間,Cerf又帶我參觀了存放連接請(qǐng)求隊(duì)列的倉(cāng)庫(kù),接著又教了我?guī)讉€(gè)TCP定時(shí)器的用法,這一天真是收獲滿滿。
明天就要正式工作了,不知道又是怎樣的一天~
未完待續(xù)······
彩蛋
“醒醒,上峰給我們派任務(wù)了,讓我們配合他劫持TCP連接”
“我們又沒有內(nèi)核權(quán)限怎么能劫持TCP連接呢?”
“信上沒說,只是讓我們匯報(bào)一個(gè)計(jì)數(shù)器的值”
“什么計(jì)數(shù)器?”
預(yù)知后事如何,請(qǐng)關(guān)注后續(xù)精彩······