ip欺骗不需要将网卡设为混杂模式,只要你修改ip首部就可以了。  
  下面是一个例子,在win2k下冒充其他机器(192.168.5.52)给192.168.4.55发送icmp报文。  
   
  #include   <stdio.h>  
  #include   <winsock2.h>  
  #include   <ws2tcpip.h>  
   
  #define   ICMP_ECHO 8  
   
  typedef   struct   iphdr   {  
  unsigned   char verlen; //   length   and   version   of   the   header  
  unsigned   char tos; //   Type   of   service  
  unsigned   short total_len; //   total   length   of   the   packet  
  unsigned   short ident; //   unique   identifier  
  unsigned   short frag_and_flags; //   flags  
  unsigned   char ttl;    
  unsigned   char proto; //   protocol   (TCP,   UDP   etc)  
  unsigned   short checksum; //   IP   checksum  
  unsigned   int sourceIP;  
  unsigned   int destIP;  
   
  }   IPHDR;  
   
  typedef   struct   icmphdr   {  
  BYTE   i_type;  
  BYTE   i_code; //   type   sub   code  
  USHORT   i_cksum;  
  USHORT   i_id;  
  USHORT   i_seq;  
   
  }   ICMPHDR;  
   
  unsigned   short   cal_checksum(   unsigned   short   *buf,   int   size);  
   
  void   main()  
  {  
  SOCKET   s;  
  WSADATA   WSAData;  
  BOOL   bIphdrIncl;  
  int   iRtn;  
  IPHDR   *pIphdr;  
  ICMPHDR   *pIcmphdr;  
  unsigned   long   *pIcmpdata;  
  char   buf[1024];  
  struct   sockaddr_in   dest;  
   
  if   (   WSAStartup(   MAKEWORD(   2,   2),   &WSAData))   {  
  printf(   “fail   to   start   up   winsock.n”);  
  return;  
  }  
   
  //   create   a   raw   socket   to   send   fake   ICMP_ECHO   message   …  
  s   =   socket(   AF_INET,   SOCK_RAW,   IPPROTO_IP);  
  if   (   s   ==   INVALID_SOCKET)   {  
  printf(   “socket   error.n”);  
  return;  
  }  
   
  bIphdrIncl   =   TRUE;  
  iRtn   =    
  setsockopt(   s,   IPPROTO_IP,   IP_HDRINCL,   (const   char   *)&bIphdrIncl,   sizeof(BOOL));  
  if   (   iRtn)   {  
  printf(   “fail   to   set   sock   option.n”);  
  return;  
  }  
   
  //   fill   in   ip   header   …  
  pIphdr   =   (IPHDR   *)buf;  
  pIphdr->verlen   =   0x45;  
  pIphdr->tos   =   0;  
  pIphdr->total_len   =   sizeof(   IPHDR)   +   sizeof(   ICMPHDR)   +   sizeof(   unsigned   long);  
  pIphdr->ident   =   htons(0);  
  pIphdr->frag_and_flags   =   htons(0);  
  pIphdr->ttl   =   255;  
  pIphdr->proto   =   IPPROTO_ICMP;  
  pIphdr->sourceIP   =   inet_addr(   “192.168.5.52”);  
  pIphdr->destIP   =   inet_addr(   “192.168.4.55”);  
  pIphdr->checksum   =   0; //   ip   checksum   is   set   to   0   temperarily.  
   
  //   fill   in   icmp   header   …  
  pIcmphdr   =   (ICMPHDR   *)(buf   +   sizeof(   IPHDR));  
  pIcmphdr->i_type   =   ICMP_ECHO;  
  pIcmphdr->i_code   =   0;  
  pIcmphdr->i_cksum   =   0;  
  pIcmphdr->i_id   =   (   unsigned   short)GetCurrentProcessId();  
  pIcmphdr->i_seq   =   0;  
   
  //   fill   in   icmp   data   …  
  pIcmpdata   =   (   unsigned   long   *)(buf   +   sizeof(   IPHDR)   +   sizeof(   ICMPHDR));  
  *pIcmpdata   =   GetTickCount();  
   
  //   calculate   icmp   check   sum   …  
  pIcmphdr->i_cksum   =   cal_checksum(   (unsigned   short   *)pIcmphdr,   sizeof(ICMPHDR)   +   sizeof(unsigned   long));  
   
  //   calculate   ip   check   sum   …  
  pIphdr->checksum   =   cal_checksum(   (unsigned   short   *)pIphdr,   pIphdr->total_len);  
   
  dest.sin_addr.S_un.S_addr   =   inet_addr(   “192.168.4.55”);  
  dest.sin_family   =   AF_INET;  
   
  iRtn   =    
  sendto(   s,   buf,   pIphdr->total_len,   0,   (const   SOCKADDR   *)&dest,   sizeof(   dest));  
  if   (   iRtn   ==   SOCKET_ERROR)   {  
  printf(   “fail   to   send   raw   ip   packet   to   destination.n”);  
  return;  
  }   else   {  
  printf(   “success.n”);  
  }  
   
  closesocket(   s);  
  WSACleanup();  
  }  
   
  unsigned   short   cal_checksum(   unsigned   short   *buf,   int   size)  
  {  
  unsigned   long   cksum   =   0;  
   
  while(   size   >   1)   {  
  cksum   +=   *buf++;  
  size   -=   sizeof(   unsigned   short);  
  }  
       
  if(size)   {  
  cksum   +=   *(   unsigned   char   *)buf;  
  }  
   
  cksum   =   (   cksum   >>   16)   +   (   cksum   &   0xffff);  
  cksum   +=   (cksum   >>16);  
  return   (   unsigned   short)(~cksum);  
  }   
 

Comments are closed.

Post Navigation