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