感谢支持
我们一直在努力

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


运行时抓包:wireshark抓的ARP数据包


PS:1、上述代码总体在Windows下可用,只是包含头文件的方式有所不同,有兴趣的朋友可以研究一下windows下libnet的安装、配置与使用。


2、代码中第9行:char *device=”eth0″,是指Linux下默认的有线网络接口,如果把“eth0″换做”wlan0″则是默认的无线网络接口。其实我是在无线网络下测试的(怕影响有线局域网),所以才有那么一堆不对应网关为10.1.23.254的IP地址。

赞(0) 打赏
转载请注明出处:服务器评测 » Ubuntu下C语言+libnet实现ARP数据包广播
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏