歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Ubuntu下C語言+libnet實現ARP數據包廣播

      近來學校宿捨樓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)

  1. #include <stdio.h>   
  2. #include <libnet.h>   
  3. int main()   
  4. {   
  5.     int res;   
  6.     /*********init paras*****************/  
  7.     libnet_t *l;/*****libnet handler*/  
  8.     libnet_ptag_t p_tag;   
  9.     char *device="eth0";   
  10.     char err_buff[LIBNET_ERRBUF_SIZE];   
  11.     char *src_ip_str="10.1.23.254";   
  12.     char *dest_ip_str="0.0.0.0";   
  13.     u_char src_mac[6]={0x00,0x1c,0xf9,0x6a,0x4c,0x00};   
  14.     u_char dest_mac[6]={0xff,0xff,0xff,0xff,0xff,0xff};   
  15.     u_long src_ip;   
  16.     u_long dest_ip;   
  17.     src_ip=libnet_name2addr4(l,src_ip_str,LIBNET_RESOLVE);   
  18.     dest_ip=libnet_name2addr4(l,dest_ip_str,LIBNET_RESOLVE);   
  19.     /**********init libnet*****************/  
  20.     l=libnet_init(   
  21.         LIBNET_LINK_ADV,   
  22.         device,   
  23.         err_buff   
  24.     );   
  25.     if(l==NULL)   
  26.     {   
  27.         printf("libnet_init err!\n");   
  28.         fprintf(stderr,"%s",err_buff);   
  29.         exit(0);   
  30.     }   
  31.     /**********build arp packet************/  
  32.     p_tag=libnet_build_arp(   
  33.         ARPHRD_ETHER,/*hardware type ethernet*/  
  34.         ETHERTYPE_IP,/*protocol type*/  
  35.         6,/*length of mac*/  
  36.         4,/*length of IP*/  
  37.         ARPOP_REPLY,/*ARP operation type*/  
  38.         src_mac,   
  39.         (u_int8_t*) &src_ip,   
  40.         dest_mac,   
  41.         (u_int8_t*) &dest_ip,   
  42.         NULL,/*payload*/  
  43.         0,/*payload size*/  
  44.         l,/*libnet handler*/  
  45.         0/*'0' stands out building a new packet*/  
  46.     );   
  47.     if(p_tag==-1)   
  48.     {   
  49.         printf("libnet_build_arp err!\n");   
  50.         exit(0);   
  51.     }   
  52.     /***********build ethernet packet header*************/  
  53.     p_tag=libnet_build_ethernet(   
  54.         dest_mac,   
  55.         src_mac,   
  56.         ETHERTYPE_ARP,   
  57.         NULL,   
  58.         0,   
  59.         l,   
  60.         0   
  61.     );   
  62.     if(p_tag==-1)   
  63.     {   
  64.         printf("libnet_build_ethernet err!\n");   
  65.         exit(0);   
  66.     }   
  67.     /*********send packets*******************************/  
  68.     for(;;)   
  69.     {   
  70.         if((res=libnet_write(l))==-1)   
  71.         {   
  72.             printf("libnet_write err!\n");   
  73.             exit(0);   
  74.         }   
  75.         printf("arp packet has been sent\n");   
  76.         sleep(1);   
  77.     }   
  78.     /*********over and destroy**************************/  
  79.     libnet_destroy(l);   
  80.     return 0;   
  81. }  

終端裡編譯:

  1. 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地址。

Copyright © Linux教程網 All Rights Reserved