免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: liudeyi545
打印 上一主题 下一主题

[内核模块] 拦截自己编写的ARP发包程序发出去的ARP包不成功 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2015-01-05 19:34 |只看该作者
我不是很理解了。。我这个抓包程序应该是可以抓到本机发出去的所有ARP包的吧?我的发包程序发出去的包自然应该被捕获到吧?我理解的是这样的。
下面是我的发包程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/types.h>
#include <asm/types.h>
#include <features.h> /* 需要里面的 glibc 版本号 */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
        #include <netpacket/packet.h>
        #include <net/ethernet.h> /* 链路层(L2)协议 */
#else
        #include <asm/types.h>
        #include <linux/if_packet.h>
        #include <linux/if_ether.h> /* 链路层协议 */
#endif
#include <netinet/if_ether.h>

#define INLEN 4
#define MAC_BCAST_ADDR  (uint8_t *) "\xff\xff\xff\xff\xff\xff"

void usage_quit(char *arg0);
int get_ifi(char *dev, char *mac, int macln, struct in_addr *lc_addr, int ipln);
void prmac(u_char *ptr);

int main(int argc, char **argv)
{
        if(argc != 2)
                usage_quit(argv[0]);

        int reqfd, recvfd, salen, n;  
        u_char *mac;
        char recv_buf[120], rep_addr[16];
        struct in_addr lc_addr, req_addr;
        struct sockaddr_ll reqsa, repsa;
        struct arp_pkt {
                struct ether_header eh;
                struct ether_arp ea;
                u_char padding[18];
        } req;
      
        bzero(&reqsa, sizeof(reqsa));
        reqsa.sll_family = PF_PACKET;
        reqsa.sll_ifindex = if_nametoindex("eth0");

        if((reqfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_RARP))) < 0) {
                perror("Socket error");
                exit(1);
        }

        mac = (char *)malloc(ETH_ALEN);
        bzero(&req, sizeof(req));

        if(get_ifi("eth0", mac, ETH_ALEN, &lc_addr, INLEN)) {
                fprintf(stderr, "Error: Get host’s information failed\n");
                exit(0);
        }
        char *temparp="00:31:88:0e:00:45";//随便构造的虚假的mac地址
        /* 填写以太网头部*/
        memcpy(req.eh.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
        memcpy(req.eh.ether_shost, temparp, ETH_ALEN);
        req.eh.ether_type = htons(ETHERTYPE_ARP);

        /* 填写arp数据 */
        req.ea.arp_hrd = htons(ARPHRD_ETHER);
        req.ea.arp_pro = htons(ETHERTYPE_IP);
        req.ea.arp_hln = ETH_ALEN;
        req.ea.arp_pln = INLEN;
        req.ea.arp_op = htons(ARPOP_REQUEST);
        memcpy(req.ea.arp_sha, temparp, ETH_ALEN);
        memcpy(req.ea.arp_spa, &lc_addr, INLEN);
        inet_aton(argv[1], req.ea.arp_tpa);
//下面一直循环发送......
        while(1){       

                if((n = sendto(reqfd, &req, sizeof(req), 0, (struct sockaddr *)&reqsa, sizeof(reqsa))) <= 0) {
                        perror("Sendto error");
                        exit(1);
                }
                printf("Broadcast arp request of %s, %d bytes be sent\n\n", argv[1], n);
        sleep(2);
        }

        recvfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
        bzero(recv_buf, sizeof(recv_buf));
        bzero(&repsa, sizeof(repsa));
        salen = sizeof(struct sockaddr_ll);

        free(mac);
}

int get_ifi(char *dev, char * mac, int macln, struct in_addr *lc_addr, int ipln)
{
        int reqfd, n;
        struct ifreq macreq;

        reqfd = socket(AF_INET, SOCK_DGRAM, 0);
        strcpy(macreq.ifr_name, dev);

        /* 获MAC地址*/
        if(ioctl(reqfd, SIOCGIFHWADDR, &macreq) != 0)
                return 1;
        memcpy(mac, macreq.ifr_hwaddr.sa_data, macln);

        /* 获iP地址*/
        if(ioctl(reqfd, SIOCGIFADDR, &macreq) != 0)
                return 1;
        memcpy(lc_addr, &((struct sockaddr_in *)(&macreq.ifr_addr))->sin_addr, ipln);

        return 0;
}      

void prmac(u_char *ptr)
{
        printf("        Peer MAC is: %02x:%02x:%02x:%02x:%02x:%02x\n",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
}

void usage_quit(char *arg0)
{
        fprintf(stderr, "Usage: %s <query_IP>\n", arg0);
        exit(1);
}

回复 10# tc1989tc

论坛徽章:
0
12 [报告]
发表于 2015-01-05 19:51 |只看该作者
回复 9# liudeyi545
10楼说的很有道理。

这里分析下可能的原因
你自己发送arp包应该是应用程序socket构造包吧
那么你使用的socket类型是什么? SOCK_RAW?
linux socket有很强大的功能。可以在网络层发包,也可以在链路层发包

而arp其实是网络层协议
若果你在链路层发包,而在网络层过滤,那应该是过滤不掉的

当然以上是猜想没试过。你可以写个链路层发包用iptables一试就知道了。不过按道理肯定是这样的。因为既然在链路层发包,自己构造以太网头 和网络头 那还有什么必要走网络层?



   

论坛徽章:
0
13 [报告]
发表于 2015-01-05 19:58 |只看该作者
回复 11# liudeyi545
刚看到你的程序。应该就是链路层构造包引起的。
其实一般arp防御都是做在目的机器上,做在源机器上还真是少见
如果一定要做,估计你只能在驱动里面进行防御了

另外单纯的arp处理一般不能完全杜绝欺骗。因为还可能 有mac转移攻击。一般是arp静态绑定 + 网关或交换机 mac port绑定 就基本解决所有问题了


   

论坛徽章:
0
14 [报告]
发表于 2015-01-05 20:09 |只看该作者
http:  //3y.uu456.com/bp-c31f46ec4afe04a1b071des1-1.html
试试这个发包。sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP)); 应该这种发包方式是能过滤掉的
不过可能存在 arp数据源mac 跟 以太网头源mac不一致的问题

论坛徽章:
0
15 [报告]
发表于 2015-01-05 20:40 |只看该作者
你好,我其实是在开发一款Linux ARP防火墙,想像360一样实现双向拦截,但在做内部发出拦截的时候遇到了这个问题。因为本人对网络了解比较少,不太明白,我的发包程序发出去的包不经过网络层直接是从链路层发出去的吗?如果是这样的话,如果我想彻底拦截本机发出去的所有的包,挂载点又该在哪儿呢?因为如果我只改变我程序发包的位置最后实现拦截是没有意义的,我还是希望彻底拦截本机所有ARP包。我参看了netfilter和iptables的源码,没找到关于挂载点的说明。还望大神指点!回复 13# anyhit


   

论坛徽章:
0
16 [报告]
发表于 2015-01-05 20:48 |只看该作者
你好,我刚才经过您的提醒发现了这个问题,我发包程序的ARP包是链路层产生的,而我ARP拦截是在网络层,那如果我想拦截包括链路层产生的包,netfilter提供这样的机制或者挂载点吗?回复 10# tc1989tc


   

论坛徽章:
0
17 [报告]
发表于 2015-01-06 10:27 |只看该作者
回复 15# liudeyi545
netfilter没用。这个工作在网络最上层
arp 内核模块应该也没用。这个应该工作在网络最底层。走过netfilter之后,ip数据包里的mac构造就是arp模块的事情

而你要做的事情。因为没做过。不好贸然回答。这里有三个 方案,仅供参考,可实现性需你自己验证
1. 做在网络驱动层的tx函数里面。这个肯定是能解决问题的。
  但是要处理的事情就很多了。因为不同的网卡对应的驱动可能不一样。而且需要重新编译内核。主要的工作量在于读源码
2.追踪下socket raw的内核代码。看能不能产生灵感
3.你提到了应用层防火墙的事情
  那么可否换种思路。应用层采用socket raw统计发出去的arp包。然后如果发现有问题,就报出一个警告。或者看看能否定位发包应用

最后你那个过滤程序 其实更重要的是匹配源ip是否本地的ip。一般攻击都是伪造arp包中的ip。有两种方式1.伪造内网pc的所有源ip发包欺骗网关 2.伪造网关源ip欺骗内网所有pc

因为伪造源mac太难了。mac那么多位很难穷尽。但ip一般就一个网段。254个arp包搞定所有

   

论坛徽章:
0
18 [报告]
发表于 2023-05-02 12:06 |只看该作者
你hook的位置不对,NF_ARP_OUT只能拦截链路层进来的包,没法拦截本机生成的包了。要拦截所有的包,试试egress?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP