掌握本局域网中每一台主机的IP地址和MAC地址信息。

利用libpcap捕获网络中的ARP请求/应答包,最大限度的提取相关信息。如在第五节中的B对A的ARP请求包,我们可以提取出关于B的完整信息(2.2.2.2,02:02:02),也获得了关于A的部分信息(1.1.1.1,null)。在知道网络中有主机A的情况下,我们可以构造并发送对A的ARP请求包,捕获A的ARP应答包,从而完整掌握A的信息。同理,我们也可以捕获TCP/UDP等数据包,从中提取信息。

创建一个向链表增加主机信息的函数:add_host(ip,mac), 每收到一个ARP请求/应答包,都执行add_host( )两次:add_host(发送端IP,发送端MAC),add_host(目的端IP,目的端MAC)。

在收到ARP应答包时,首先检查发送端的IP和MAC,如果IP不是自己的,但MAC是自己的,则说明此应答包是本机构造的ARP欺骗包,程序忽略。

对于正常的ARP请求包和应答包,add_host(ip, mac )中IP或MAC只要有一个是自己的(ip == MYIP || mac ==MYMAC),则程序忽略。显然,没有必要自己欺骗自己。

add_host(ip,mac)遍历主机链表,如果IP存在,且MAC不空,则把MAC地址写入;如果不存在,则增加一个HOST节点,写入IP地址,如果MAC不空,则也把MAC地址写入。 注意到这样一个情况:在ARP请求包中,目的MAC地址是没有意义的,所以我们只写入IP地址,而MAC地址用NULL来表示。这是我们收集网络拓朴结构的一种被动方法。

函数add_host( )逻辑设计MYIP = IP(d),MYMAC = MAC(d)

代码如下:

void add_host(u_long ip, u_char * mac)

{

HOST * new = NULL;

HOST * cur = NULL;

if( (ip == MYIP) || (mac && mac_equal(mac, MYMAC)) )

return;

//遍历链表查询IP地址

for(cur = head; cur; cur = cur->next)

{

if( ip == cur->ip )

{

if( mac ) // MAC地址不空,则写入

{

memcpy(cur->mac, mac, ETHER_ADDR_LEN);

cur->mac_flag = 1;

}

return;

}

}

if(cur == NULL) // 链表中没有此IP地址

{

new = (HOST *)malloc(sizeof(HOST));

new->ip = ip;

if( mac )

{

memcpy(new->mac, mac, ETHER_ADDR_LEN);

new->mac_flag = 1;

}

else

new->mac_flag = 0;

new->next = NULL;

if(! head) // 把新节点加入链表

{

head = new;

tail = new;

}

else

{

tail->next = new;

tail = new;

}

}

return;

}

周期性的向局域网中每一台主机发送ARP欺骗包。

创建一个发送ARP欺骗包的函数send_fake_arp_packet(),遍历主机链表的每一个IP地址,如果此IP地址的MAC地址已知,则遍历主机链表中其它IP地址,以其它IP地址和本机的MAC地址为发送端,以选中的IP地址和MAC地址为目的端,构造并发送ARP应答欺骗包;如果此IP地址的MAC地址未知,则以本机IP地址和MAC地址为发送端,以选中的IP地址为目的端,构造并发送正常的ARP请求包。注意,这是我们收集网络拓朴结构的一种主动方法。


相关内容