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