交换型网络环境嗅探原理及LINUX下的实现(1)(2)
掌握本局域网中每一台主机的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请求包。注意,这是我们收集网络拓朴结构的一种主动方法。
评论暂时关闭