近來學校宿捨樓ARP攻擊一直很猖獗,而且大多數是主機欺騙型ARP攻擊。每次攻擊都要至少半天整棟宿捨樓上不去網(我們這邊每棟宿捨樓劃分一個網段,像我們樓就是10.1..23.254/22)。我曾經抓到過ARP攻擊數據包,局域網遭受攻擊的時候被我逮了個正著:某台主機廣播一個ARP數據包,內容是10.1.23.254 is at xxxxxxxx(即錯誤的網關MAC,我們的網關是10.1.23.254),然後整棟樓就斷網大半天。
沒有辦法,絕大部分人不懂MAC綁定,沒有主動防御意識。我自己綁定了MAC只能保護自己,卻只能眼睜睜看著局域網癱瘓。這不端午放假前一天的晚上又被攻擊,然而網絡中心的管理員都放假了,我們一下就斷網3天!
我真的怒了!
偶爾看到百度百科上ARP那一詞條上,作者推薦了一個叫做“欣向全ARP工具”的東西,說是具有主動維護功能,就是向網內廣播正確的網關與MAC地址。我覺的這個功能挺好,就下載下來試了試。那是WIN下的軟件,我平時都是用Ubuntu,只好在同學機器上試,反正都上不去網,就死馬當作活馬醫吧。沒想到那個破爛玩意兒在使用其他任何功能之前,都必須掃描網絡。我想掃就掃吧,反正很快(Linux下用nmap掃描10.1.23.254/22 的網段半分鐘左右就OK了)。沒想到那破東西居然明知道我的網段,卻硬是從10.0.0.0掃描到10.254.254.254!!還掃了將近1個小時!終於掃描完成了啊,我就迫不及待用那個“主動維護”功能吶,沒想到它不讓自己填寫網關跟MAC,還彈出窗口說自己找不到MAC(廢話嘛,估計它是要讀ARP表。都受ARP攻擊了,ARP表裡面就算有網關對應的MAC也不是間的是正確的啊,真不知這作者怎麼設計的!),那我就手動綁定MAC吧(我知道正確的MAC地址,因為網絡中心的網站上都公布這些信息的。),沒想到同學那WIN7也不知道怎麼的就不讓綁定,用管理員權限運行CMD也不行,寫個批處理也不行!我無奈,只好重啟系統,可是再次打開那個破爛工具,它卻說還要再掃描一次!!
我已經出離憤怒了!每次運行都要掃描,每次掃描都要一個小時的話,局域網早就癱了,還維護個P啊!
後來有發現我那個網絡接口不管用了,沒信號(不是同學掃描局域網那台機器,而是那台機器上網的網口!一個宿捨才倆網口啊!大家都是用交換機的,XD!)那是被網絡中心給封了啊!!估計掃描的時候流量太大了,它掃的本來就慢,還掃那麼多,我只好開最大速度掃描(本以為網絡中心放假呢,難道它們寫了腳本自動封掉超流量端口?!可惡的是封端口,封一個MAC就行了嘛!),我都想直接找百度百科那個ARP詞條作者去理論了!神馬破爛玩意兒都往百科上放!!
我還知道一些P2P軟件可以發這種東西,都是WIN下的,但是害怕不安全,怕被人發現痕跡(雖說想做好事兒,但是手段畢竟有點hack)。就罷手Windows了,自己在Linux下來寫!
首先,我寫這個東西不是想做壞事兒的,也希望看到這篇博客的朋友不要拿去做壞事兒!
我只給出實現最基本功能的代碼,稍微修改一下還可以實現好多其他的功能(我所在局域網的網關是10.1.23.254,其MAC地址為00:1c:f9:6a:4c:00)
下面是代碼:(sendarp.c)
- #include <stdio.h>
- #include <libnet.h>
- int main()
- {
- int res;
- /*********init paras*****************/
- libnet_t *l;/*****libnet handler*/
- libnet_ptag_t p_tag;
- char *device="eth0";
- char err_buff[LIBNET_ERRBUF_SIZE];
- char *src_ip_str="10.1.23.254";
- char *dest_ip_str="0.0.0.0";
- u_char src_mac[6]={0x00,0x1c,0xf9,0x6a,0x4c,0x00};
- u_char dest_mac[6]={0xff,0xff,0xff,0xff,0xff,0xff};
- u_long src_ip;
- u_long dest_ip;
- src_ip=libnet_name2addr4(l,src_ip_str,LIBNET_RESOLVE);
- dest_ip=libnet_name2addr4(l,dest_ip_str,LIBNET_RESOLVE);
- /**********init libnet*****************/
- l=libnet_init(
- LIBNET_LINK_ADV,
- device,
- err_buff
- );
- if(l==NULL)
- {
- printf("libnet_init err!\n");
- fprintf(stderr,"%s",err_buff);
- exit(0);
- }
- /**********build arp packet************/
- p_tag=libnet_build_arp(
- ARPHRD_ETHER,/*hardware type ethernet*/
- ETHERTYPE_IP,/*protocol type*/
- 6,/*length of mac*/
- 4,/*length of IP*/
- ARPOP_REPLY,/*ARP operation type*/
- src_mac,
- (u_int8_t*) &src_ip,
- dest_mac,
- (u_int8_t*) &dest_ip,
- NULL,/*payload*/
- 0,/*payload size*/
- l,/*libnet handler*/
- 0/*'0' stands out building a new packet*/
- );
- if(p_tag==-1)
- {
- printf("libnet_build_arp err!\n");
- exit(0);
- }
- /***********build ethernet packet header*************/
- p_tag=libnet_build_ethernet(
- dest_mac,
- src_mac,
- ETHERTYPE_ARP,
- NULL,
- 0,
- l,
- 0
- );
- if(p_tag==-1)
- {
- printf("libnet_build_ethernet err!\n");
- exit(0);
- }
- /*********send packets*******************************/
- for(;;)
- {
- if((res=libnet_write(l))==-1)
- {
- printf("libnet_write err!\n");
- exit(0);
- }
- printf("arp packet has been sent\n");
- sleep(1);
- }
- /*********over and destroy**************************/
- libnet_destroy(l);
- return 0;
- }
終端裡編譯:
- gcc -o sendarp sendarp.c -lnet
運行(root權限才可以運行):sudo ./sendarp
運行時抓包:
PS:1、上述代碼總體在Windows下可用,只是包含頭文件的方式有所不同,有興趣的朋友可以研究一下windows下libnet的安裝、配置與使用。
2、代碼中第9行:char *device="eth0",是指Linux下默認的有線網絡接口,如果把“eth0"換做"wlan0"則是默認的無線網絡接口。其實我是在無線網絡下測試的(怕影響有線局域網),所以才有那麼一堆不對應網關為10.1.23.254的IP地址。