ARP协议获得局域网内活动主机物理地

利用ARP协议来获取局域网内活动主机的IP跟MAC地址
2009/11/15 03:57 P.M.

    

        我们都知道ARP协议可以用来获取已知IP主机的MAC地址,那是不是可以这样说,在同一个 局域网内,我们可以利用ARP回应包来判断局域网内的活动主机?其实是行的,只要局域网内的主机是处于开机状态,那就会对ARP请求包作出回应,通过分析ARP请求包就可以把局域网内所有活动主机的IP地址跟MAC地址提取出来。下面是ARP帧结构和以太网帧结构的定义:

//28字节ARP帧结构
struct arp_head
{
unsigned short hardware_type;    //硬件类型
unsigned short protocol_type;    //协议类型
unsigned char hardware_add_len; //硬件地址长度
unsigned char protocol_add_len; //协议地址长度
unsigned short operation_field; //操作字段
unsigned char source_mac_add[6]; //源mac地址
unsigned long source_ip_add;    //源ip地址
unsigned char dest_mac_add[6]; //目的mac地址
unsigned long dest_ip_add;      //目的ip地址
};


//14字节以太网帧结构
struct ethernet_head
{   
unsigned char dest_mac_add[6];    //目的mac地址
unsigned char source_mac_add[6]; //源mac地址
unsigned short type;              //帧类型
};

//arp最终包结构
struct arp_packet
{
ethernet_head ed;
arp_head ah;
};

    这里我们是用winpcap开发包来构造相应的数据包的(利用pcap_sendpacket()函数可以发送构造后的数据包),具体内容可以自己去看下winpcap开发包的开发文档。下面是具体代码:

//获得自己主机的MAC地址

int GetSelfMac()
{
unsigned char sendbuf[42];//arp包结构大小
int i = -1;
int res;
ethernet_head eh;
arp_head ah;
struct pcap_pkthdr * pkt_header;
const u_char * pkt_data;

memset(eh.dest_mac_add,0xff,6);
memset(eh.source_mac_add,0x0f,6);

memset(ah.source_mac_add,0x0f,6);
memset(ah.dest_mac_add,0x00,6);

eh.type = htons(ETH_ARP);
ah.hardware_type = htons(ARP_HARDWARE);
ah.protocol_type = htons(ETH_IP);
ah.hardware_add_len = 6;
ah.protocol_add_len = 4;
ah.source_ip_add = inet_addr("219.219.71.230"); //随便设的请求方ip
ah.operation_field = htons(ARP_REQUEST);
// unsigned long ip;
// ip = ntohl(inet_addr("192.168.1.101"));
// ah.dest_ip_add =htonl(ip + loop);
ah.dest_ip_add = localIP;//inet_addr("192.168.1.102");
memset(sendbuf,0,sizeof(sendbuf));
memcpy(sendbuf,&eh,sizeof(eh));
memcpy(sendbuf+sizeof(eh),&ah,sizeof(ah));

if(pcap_sendpacket(adhandle,sendbuf,42)==0)
{
//   printf("/nPacketSend succeed/n");
}
else
{
   printf("PacketSendPacket in getmine Error: %d/n",GetLastError());
   return 0;
}

while((res = pcap_next_ex(adhandle,&pkt_header,&pkt_data)) >= 0)
{      
   if(*(unsigned short *)(pkt_data+12) == htons(ETH_ARP)&&
    *(unsigned short*)(pkt_data+20) == htons(ARP_REPLY)&&
    *(unsigned long*)(pkt_data+38) == inet_addr("219.219.71.230"))
   {

    for(i=0; i<6; i++)
    {
     selfMac[i] = *(unsigned char*)(pkt_data+22+i);
     printf("%02x",selfMac[i]);
    }
    break;
   }
}
if(i==6) return 1;
else return 0;
}

//向局域网内的所有可能的IP地址发送ARP请求包线程

void sendArpPacket()
{

unsigned char sendbuf[42];//arp包结构大小
unsigned long ip;
ethernet_head eh;
arp_head ah;


memset(eh.dest_mac_add,0xff,6);
memcpy(eh.source_mac_add,selfMac,6);

memcpy(ah.source_mac_add,selfMac,6);
memset(ah.dest_mac_add,0x00,6);

eh.type = htons(ETH_ARP);
ah.hardware_type = htons(ARP_HARDWARE);
ah.protocol_type = htons(ETH_IP);
ah.hardware_add_len = 6;
ah.protocol_add_len = 4;
ah.operation_field = htons(ARP_REQUEST);
ah.source_ip_add = inet_addr("192.168.1.101");

 

for (unsigned long i=0; i<HostNum; i++)
{
    ip = iptosendh;
    ah.dest_ip_add =htonl(ip + i);
   memset(sendbuf,0,sizeof(sendbuf));
   memcpy(sendbuf,&eh,sizeof(eh));
   memcpy(sendbuf+sizeof(eh),&ah,sizeof(ah));
   if(pcap_sendpacket(adhandle,sendbuf,42)==0)
   {
   // printf("/nRequest Packet succeed/n");
   }
   else
   {
    printf("Request Packet in getmine Error: %d/n",GetLastError());
   }
   Sleep(50);
    }
Sleep(1000);
flag = TRUE;
}

//接收ARP响应线程,分析数据包后即可获得活动的主机IP地址等

void GetlivePc()
{
//pcap_t *p=(pcap_t *)lpParameter;
int res;

 

// arp_head ah;
struct pcap_pkthdr *pkt_header;
const u_char * pkt_data;
unsigned char tempMac[6];
while (true)
{
   if(flag)
   {
    printf("扫描完毕,监听线程退出!/n");
    //ExitThread(0);
    break;
   }

   if ((res = pcap_next_ex(adhandle,&pkt_header,&pkt_data)) >= 0)
   {

    // printf("%x",ntohs(*(unsigned short *)(pkt_data+12)));
    if(*(unsigned short *)(pkt_data+12) == htons(ETH_ARP))
    {
                arp_packet *recv = (arp_packet*)pkt_data;
     if(*(unsigned short *)(pkt_data+20) == htons(ARP_REPLY))
     {
      printf("xx/n");
      printf("IP地址:%d.%d.%d.%d---------->mac地址:",/
       recv->ah.source_ip_add&255, recv->ah.source_ip_add>>8&255,/
       recv->ah.source_ip_add>>16&255, recv->ah.source_ip_add>>24&255);
      pcGroup[aliveNum].ip = *(unsigned long *)(pkt_data+28);
      memcpy(pcGroup[aliveNum].mac,(pkt_data+22),6);
      aliveNum++;
      for(int i=0; i<6; i++)
      {
       tempMac[i] = *(unsigned char*)(pkt_data+22+i);
       printf("%02x",tempMac[i]);
      }
      printf("/n");
     }
    }
   }
   Sleep(50);
}
}

    其实这里可以利用对特定主机发送ARP欺骗包就可以进行ARP攻击,让对方上不了网。具体就是构造一个ARP请求包,包的源IP为所在局域网的网关,源MAC就随便设一个即可,这样被攻击的主机就会把原本到发到网关的数据包发到所设的MAC地址那,这样就没办法跟外部网络进行通信了。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值