為何不將僅僅路過的資料包匯入本地協議棧呢

來源:互聯網
上載者:User

此事來自於一次故障!
ifconfig eth2 promisc
關於抓包和協議棧的處理

抓包,是一個靜態過程,把包抓上來,然後靠你的眼睛去看,剩下來的事情就靠你的眼神以及你對協議棧的瞭解了,找我老婆公司的一個人過來看一個資料包,估計沒戲,但是找我公司我座位周圍隨便一個人過來看,都能說點什麼...正如你坐上飛機,你就把生命交給飛行員一樣,如果你不懂協議,抓到的包對你一點用都沒有,你並不能依靠其它什麼,此時的飛行員就是你自己!我不明白為何所有人都喜歡抓包,即使看不懂,也依然抓取好幾G的包...當然,我並不責怪那些必須帶點現場資料回來的人。

抓包機制

抓包既然只是為了給你提供一個靜態資料,那就是抓到就好了。這種事情在Linux中是通過PACKET通訊端實現的,在Linux的鏈路層,資料包傳給了所有的PACKET通訊端,然後這些資料包(或許經過了BPF過濾)被直接扔給了使用者態的諸如tcpdump之類的程式。記住,tcpdump程式抓到的資料包是直接鏈路層的包,沒有經過協議棧的任何處理,比如沒有經過NAT,沒有經過路由...實際上,如果資料包是恰好路過本地,並且原生該網卡又啟動了promisc混雜模式,那麼不是發到本網卡的資料包是不可能被匯入到本機協議棧處理的,你能做的僅僅是將其靜態抓取,頂多儲存成一個萬惡的pcap檔案。

匯入協議棧

把過路的資料包匯入協議棧,這是有實際用途的。比如如果本機是一個鏡像機,所有的資料包都發往本機,我覺得僅僅是把資料包抓取再靜態分析肯定不好,讓它們直接經過協議棧處理,豈不更好?然而,匯入本地協議棧有一個前提,那就是資料幀的目標MAC地址是接收網卡的MAC地址(僅僅以乙太網路舉例)。為此,我需要做的僅僅是註冊一個PACKET類型的資料包處理器,處理函數中將資料包的pkt_type改為PACKET_HOST即可,熟悉Linux核心協議棧代碼的應該知道,在網路層的ip_rcv中會首先丟棄資料包pkt_type不是PACKET_HOST的所有資料包。代碼很簡單:
#include <linux/module.h> #include <linux/netpoll.h> #include <linux/moduleparam.h> MODULE_PARM_DESC(capdev, " capdev=ethX" "指定在哪個裝置上啟動匯入本地協議棧的抓包機制"); MODULE_PARM_DESC(mark, " mark=value" "為匯入本地協議棧的資料包打上的mark"); static __u32 mark; module_param(mark, int, 0); static char devname[256]; struct net_device *capdev; module_param_string(capdev, devname, 256, 0); int cappkg_func (struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { if (dev != capdev /*不在capdev鏈表中,目前只有一個*/) { goto release_skb; } if (/*skb->pkt_type == PACKET_OUTGOING ||*/ //本機發出的包,受制於fib_validate_source! //因此需要將源地址SNAT成一個非本機地址! skb->pkt_type == PACKET_OTHERHOST) { skb->pkt_type = PACKET_HOST; skb->mark = mark; return netif_receive_skb(skb); } release_skb: kfree_skb(skb); return NET_RX_SUCCESS; } static struct packet_type cappkg_proto = { .type = __constant_htons(ETH_P_ALL), .func = cappkg_func, }; int init_module (void) { int ret = 0; capdev = dev_get_by_name(&init_net, devname); if (!capdev) { ret = -1; goto err; } dev_add_pack(&cappkg_proto); err: return ret; } void cleanup_module(void) { dev_remove_pack(&cappkg_proto); } MODULE_DESCRIPTION("將僅僅是經過本地的資料包匯入到本地協議棧處理"); MODULE_AUTHOR("Wangran <marywangran@126.com>"); MODULE_LICENSE("GPL");

代碼的用途1.鏡像連接埠我不是曾經一直糾結於如何讓Linux實現鏡像連接埠嗎?此代碼可以實現,不同於諸位前輩或者幾年前的我自己(我是我自己的前輩!)的實現,我並不是直接寫入程式碼將資料包匯入到ethX,而是通過策略路由將其匯入,資料包被我的模組處理函數複製了一份,然後打上了一個mark,接下來我就可以基於此mark做策略路由了...當然,我也可以將其做REDIRECT(即DNAT),將其匯入本地第四層。注意,不是通過抓包的方式,而是通過協議棧處理的方式。

2.惡作劇

想搞惡作劇嗎?那就安裝這個模組盡情蹂躪TCP協議本身以及那些懂TCP但不全懂卻有十足鑽研精神的程式員吧!我曉得,如果我想搞清楚到底發生了什麼,我一定可以!但是我不會那樣去浪費有限的生命,一方面是我恨TCP,另一方面是我覺得僅僅出現問題就夠了,並且由於我對TCP變態設計的一貫不認可,它在我的模組下一定會出問題,這也是我的目的,另外最重要的是,我的以上兩個理由讓我避開了諸如“你懂!你給講一下!”那樣的諷刺或者調侃似的追問,我真的沒有太多的時間!
iptables -t nat -A POSTROUTING -j MASQUERADE
sysctl -w net.netfilter.nf_conntrack_tcp_loose=1

這樣可以使tcp的conntrack狀態脫離tcp本身的狀態,接下來就是下面的時序圖了,注意,我把嗅探機放在中間,並不意味著它是串接在正常主機和伺服器之間的,因為圖是平面的,我只能這麼畫,正好相反,嗅探機和正常主機一樣,旁掛在交換器或者HUB上,另外還需注意,只有在交換器廣播資料,也就是說資料包真正到達你的嗅探機時,劫持才能成功:

 

 



如果你的交換器是一個HUB,那就特別好玩了,如果不是,那就偷偷下班後把它換成一個HUB...別總想著什麼登入進交換器進行一大堆設定,然後在各種場合賣弄那些術語或者咬文嚼字,這都沒用,程式員最大的弊端在於看不起社交工程學,覺得這些沒有技術含量,當然並不包含高手...

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.