此事來自于一次故障!
我的windows的wireshark徹底不能用了,不知道為什麼...是以我需要另外一種抓包方式。由于我曾經曾經深入過VMware的橋接機制,我知道所有的到達主控端的資料包也會到達Linux虛拟機的橋接網卡,正如我所了解的那樣,雖然不是很順利,但是最終摸索到為一個橋接模式的網卡設定promisc之後就可以了:
ifconfig eth2 promisc
就這麼簡單,于是我可以在Linux虛拟機裡面抓到了到達Windows主控端的資料包,進而成功替代了Wireshark。
抓包,是一個靜态的過程,把包抓上來,然後靠你的眼睛去看,剩下來的事情就靠你的眼神以及你對協定棧的了解了,找我老婆公司的一個人過來看一個資料包,估計沒戲,但是找我公司我座位周圍随便一個人過來看,都能說點什麼...正如你坐上飛機,你就把生命交給飛行員一樣,如果你不懂協定,抓到的包對你一點用都沒有,你并不能依靠其它什麼,此時的飛行員就是你自己!我不明白為何所有人都喜歡抓包,即使看不懂,也依然抓取好幾G的包...當然,我并不責怪那些必須帶點現場資料回來的人。
我在想,為何不把包導入協定棧,讓協定棧處理呢?此時,你可以依賴的東西就更多了,你可以用snort,你可以用iptables的LOG,你可以用深度解析...工具會幫你動态分析。雖然也有很多工具可以幫你分析你抓到的資料包,但是這種行為卻不是動态的。抓包和現場分析的行為差別在程式員的角度正和看代碼和調試代碼之間的差別一樣!
抓包既然隻是為了給你提供一個靜态的資料,那就是抓到就好了。這種事情在Linux中是通過PACKET套接字實作的,在Linux的鍊路層,資料包傳給了所有的PACKET套接字,然後這些資料包(或許經過了BPF過濾)被直接扔給了使用者态的諸如tcpdump之類的程式。記住,tcpdump程式抓到的資料包是直接鍊路層的包,沒有經過協定棧的任何處理,比如沒有經過NAT,沒有經過路由...實際上,如果資料包是恰好路過本地,并且本機的該網卡又啟動了promisc混雜模式,那麼不是發到本網卡的資料包是不可能被導入到本機協定棧處理的,你能做的僅僅是将其靜态抓取,頂多儲存成一個萬惡的pcap檔案。
把過路的資料包導入協定棧,這是有實際用途的。比如如果本機是一個鏡像機,所有的資料包都發往本機,我覺得僅僅是把資料包抓取再靜态分析肯定不好,讓它們直接經過協定棧處理,豈不更好?然而,導入本地協定棧有一個前提,那就是資料幀的目标MAC位址是接收網卡的MAC位址(僅僅以以太網舉例)。為此,我需要做的僅僅是注冊一個PACKET類型的資料包處理器,處理函數中将資料包的pkt_type改為PACKET_HOST即可,熟悉Linux核心協定棧代碼的應該知道,在網絡層的ip_rcv中會首先丢棄資料包pkt_type不是PACKET_HOST的所有資料包。代碼很簡單:
我不是曾經一直糾結于如何讓Linux實作鏡像端口嗎?此代碼可以實作,不同于諸位前輩或者幾年前的我自己(我是我自己的前輩!)的實作,我并不是直接寫死将資料包導入到ethX,而是通過政策路由将其導入,資料包被我的子產品處理函數複制了一份,然後打上了一個mark,接下來我就可以基于此mark做政策路由了...當然,我也可以将其做REDIRECT(即DNAT),将其導入本地第四層。注意,不是通過抓包的方式,而是通過協定棧處理的方式。
想搞惡作劇嗎?那就安裝這個子產品盡情蹂躏TCP協定本身以及那些懂TCP但不全懂卻有十足鑽研精神的程式員吧!我曉得,如果我想搞清楚到底發生了什麼,我一定可以!但是我不會那樣去浪費有限的生命,一方面是我恨TCP,另一方面是我覺得僅僅出現問題就夠了,并且由于我對TCP變态設計的一貫不認可,它在我的子產品下一定會出問題,這也是我的目的,另外最重要的是,我的以上兩個理由讓我避開了諸如“你懂!你給講一下!”那樣的諷刺或者調侃似的追問,我真的沒有太多的時間!
TCP協定所謂的有連接配接本身沒有錯,但是為何要記住對方?難道不能用類似syn cookie之類的機制麼?且以一個簡單至極的序列号來标示資料,你有認證機制嗎?為何不使用資料或者中繼資料本身?!事實上,我覺得TCP太過複雜了,而且可調的參數不多,且太亂,這些參數之間的關系又太過複雜...不如僅僅保留UDP,然後在UDP以上實作任何你想要的邏輯,比如實作TCP的邏輯,或者比它更好的...不要拿性能說話,性能根本就不是問題,正如Java程式員面對C程式員的诘問時說的那樣,難道Java因為性能問題在成功的路上陷入困境了?一般而言,你花了一個月時間通過軟體方式榨取了那麼一點點性能提升,過不了幾個月,新的硬體就會讓你的成果黯然失色!
廢話不多說了,我僅僅給出一個TCP連接配接在我的這個子產品下被劫持的例子,剩下的可以利用的自己來想吧。隻需要把這個子產品安裝在一台機器上,然後把這個機器挂接在一個Switch或者HUB上,當然HUB更好,在該機器的連接配接交換機的網卡上做一個SNAT:
iptables -t nat -A POSTROUTING -j MASQUERADE
加載子產品!接下來你就會發現,其它好多挂在同一個交換機上的很多人,TCP連接配接都不通了,說白了這是Linux的連接配接跟蹤導緻的,下面我就簡單分析一下為什麼。
首先把Linux嗅探機的下列參數設定一下:
sysctl -w net.netfilter.nf_conntrack_tcp_loose=1
ifconfig eth0 promisc
這樣可以使tcp的conntrack狀态脫離tcp本身的狀态,接下來就是下面的時序圖了,注意,我把嗅探機放在中間,并不意味着它是串接在正常主機和伺服器之間的,因為圖是平面的,我隻能這麼畫,正好相反,嗅探機和正常主機一樣,旁挂在交換機或者HUB上,另外還需注意,隻有在交換機廣播資料,也就是說資料包真正到達你的嗅探機時,劫持才能成功:
<a href="http://blog.51cto.com/attachment/201312/150929250.jpg" target="_blank"></a>
如果你的交換機是一個HUB,那就特别好玩了,如果不是,那就偷偷下班後把它換成一個HUB...别總想着什麼登入進交換機進行一大堆設定,然後在各種場合賣弄那些術語或者咬文嚼字,這都沒用,程式員最大的弊端在于看不起社會工程學,覺得這些沒有技術含量,當然并不包含高手...
本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1346383