znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
阅读:3858回复:10

raw socket 非驱动方式 监听本机数据包

楼主#
更多 发布于:2007-04-18 10:28
  raw socket 非驱动方式 监听本机数据
附件名称/大小 下载次数 最后更新
Sniffer_construction.txt (21KB)  122 2007-04-18 10:28
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2007-04-18 10:29
Windows 版本

一个例子可以看看  
  步骤:  
    
       1.   把网卡置于混杂模式。                                                                     2.   捕获数据包。                                                                               3.   分析数据包。    
    
  注:下面的源代码取至Chad   Renfro的<<   Basic   Packet-Sniffer   Construction   from   the   Ground   Up>>一文中    
  /************************Tcp_sniff_2.c********************/    
  1.#include        
  2.#include        
  3.#include    
  4.#include    
  5.#include    
  6.#include    
  7.#include        
  8.#include    
  9.#include   "headers.h"    
          
  #define   INTERFACE   "eth0"    
          
   /*Prototype   area*/    
          
  10.int   Open_Raw_Socket(void);     
  11.int   Set_Promisc(char   *interface,   int   sock);     
  12.int   main()   {        
  13.int   sock,   bytes_recieved,   fromlen;      
  14.char   buffer[65535];    
  15.struct   sockaddr_in   from;     
  16.struct   ip   *ip;    
  17.struct   tcp   *tcp;        
  18.sock   =   Open_Raw_Socket();    
  19.   Set_Promisc(INTERFACE,   sock);    
          
  20.   while(1)    
  22.   {    
  23.   fromlen   =   sizeof   from;    
  24.   bytes_recieved   =   recvfrom(sock,   buffer,   sizeof   buffer,   0,   (struct   sockaddr   *)&from,   &fromlen);    
  25.   printf("\nBytes   received   :::   %5d\n",bytes_recieved);    
  26.   printf("Source   address   :::   %s\n",inet_ntoa(from.sin_addr));    
  27.   ip   =   (struct   ip   *)buffer;    
  /*See   if   this   is   a   TCP   packet*/    
  28.   if(ip->ip_protocol   ==   6)   {    
  29.   printf("IP   header   length   :::   %d\n",ip->ip_length);    
  30.   printf("Protocol   :::   %d\n",ip->ip_protocol);    
  31.   tcp   =   (struct   tcp   *)(buffer   +   (4*ip->ip_length));    
  32.   printf("Source   port   :::   %d\n",ntohs(tcp->tcp_source_port));    
  33.   printf("Dest   port   :::   %d\n",ntohs(tcp->tcp_dest_port));    
  34.   }    
          
  35.   }    
  36.}    
  37.int   Open_Raw_Socket()   {        
  38.   int   sock;    
  39.   if((sock   =   socket(AF_INET,   SOCK_RAW,   IPPROTO_TCP))   <   0)   {    
  /*Then   the   socket   was   not   created   properly   and   must   die*/    
  40.   perror("The   raw   socket   was   not   created");    
  41.   exit(0);    
  42.   };      
  43.   return(sock);      
  44.   }    
          
  45.int   Set_Promisc(char   *interface,   int   sock   )   {        
  46.   struct   ifreq   ifr;              
  47.   strncpy(ifr.ifr_name,   interface,strnlen(interface)+1);    
  48.   if((ioctl(sock,   SIOCGIFFLAGS,   &ifr)   ==   -1))   {      
  /*Could   not   retrieve   flags   for   the   interface*/    
  49.   perror("Could   not   retrive   flags   for   the   interface");    
  50.   exit(0);    
  51.   }     
  52.   printf("The   interface   is   :::   %s\n",   interface);      
  53.   perror("Retrieved   flags   from   interface   successfully");    
  54.   ifr.ifr_flags   |=   IFF_PROMISC;        
  55.   if   (ioctl   (sock,   SIOCSIFFLAGS,   &ifr)   ==   -1   )   {        
  /*Could   not   set   the   flags   on   the   interface   */        
  56.   perror("Could   not   set   the   PROMISC   flag:");    
  57.   exit(0);          
  58.   }    
  59.   printf("Setting   interface   :::   %s   :::   to   promisc",   interface);    
  60.   return(0);    
  61.   }    
          
  /***********************EOF**********************************/    
    
        
    
    上面这段程序中有很详细的注解,不过我想还是有必要说一说,首先第10行--int   Open_Raw_Socket(void); 是我们的自定义函数,具体内容如下:    
    
    
  37.int   Open_Raw_Socket()   {        
  38.   int   sock;    
  39.   if((sock   =   socket(AF_INET,   SOCK_RAW,   IPPROTO_TCP))   <   0)   {    
  /*Then   the   socket   was   not   created   properly   and   must   die*/    
  40.   perror("The   raw   socket   was   not   created");    
  41.   exit(0);    
  42.   };      
  43.   return(sock);      
  44.   }    
          
    
                             
    
  第39行   if((sock   =   socket(AF_INET,   SOCK_RAW,   IPPROTO_TCP))   <   0)   {    
    
  这里我们调用了socket函数,使创建了了一个原始套接口,使之收到TCP/IP信息包。    
    
    接下来第11行-int   Set_Promisc(char   *interface,   int   sock),这也是我们的自定义函数,目的是把网卡置于混杂模式,具体内容如下:    
  45.int   Set_Promisc(char   *interface,   int   sock   )   {        
  46.   struct   ifreq   ifr;              
  47.   strncpy(ifr.ifr_name,   interface,strnlen(interface)+1);    
  48.   if((ioctl(sock,   SIOCGIFFLAGS,   &ifr)   ==   -1))   {      
  /*Could   not   retrieve   flags   for   the   interface*/    
  49.   perror("Could   not   retrive   flags   for   the   interface");    
  50.   exit(0);    
  51.   }     
  52.   printf("The   interface   is   :::   %s\n",   interface);      
  53.   perror("Retrieved   flags   from   interface   successfully");    
  54.   ifr.ifr_flags   |=   IFF_PROMISC;        
  55.   if   (ioctl   (sock,   SIOCSIFFLAGS,   &ifr)   ==   -1   )   {        
  /*Could   not   set   the   flags   on   the   interface   */        
  56.   perror("Could   not   set   the   PROMISC   flag:");    
  57.   exit(0);          
  58.   }    
  59.   printf("Setting   interface   :::   %s   :::   to   promisc",   interface);    
  60.   return(0);    
  61.   }    
    
    首先   struct   ifreq   ifr;   定一了一个ifrreg的结构ifr,接下来   strncpy(ifr.ifr_name,   interface,strnlen(interface)+1);,就是把我们网络设备的名字填充到ifr结构中,在这里   #define   INTERFACE   "eth0"   ,让我们再往下看,ioctl(sock,   SIOCGIFFLAGS,   &ifr),SIOCGIFFLAGS请求表示需要获取接口标志,现在到了第54行,在我们成功的获取接口标志后把他设置成混杂模式,ifr.ifr_flags   |=   IFF_PROMISC;ioctl   (sock,   SIOCSIFFLAGS,   &ifr)。OK,现在我们所说的第一步已经完成--------把网卡置于混杂模式。    
    
    现在进入第二步,捕获数据包。从第20行开始,我们进入了一个死循环,while(1),在第24行,recvfrom(sock,   buffer,   sizeof   buffer,   0,   (struct   sockaddr   *)&from,   &fromlen),这个函数要做的就是接收数据,冰把接收到的数据放入buffer中。就是这么简单,已经完成了我们要捕获数据包的任务。    
    
    到了第三步,分析数据包。27行,ip   =   (struct   ip   *)buffer,使我们在头文件中的IP结构对应于所接收到的数据,接下来判断在网络层中是否使用的是TCP协议,if(ip->ip_protocol   ==   6)   ,如果答案是,tcp信息包从整个IP/TCP包   buffer   +   (4*ip->ip_length)   地址处开始,所以31行   tcp   =   (struct   tcp   *)(buffer   +   (4*ip->ip_length)),然后对应结构把你所需要的信息输出。    
  /*************************headers.h**************************/    
  /*structure   of   an   ip   header*/     
  struct   ip   {         
  unsigned   int   ip_length:4;   /*little-endian*/     
  unsigned   int   ip_version:4;    
  unsigned   char   ip_tos;     
  unsigned   short   ip_total_length;        
  unsigned   short   ip_id;        
  unsigned   short   ip_flags;    
  unsigned   char   ip_ttl;    
  unsigned   char   ip_protocol;    
  unsigned   short   ip_cksum;    
  unsigned   int   ip_source;   unsigned   int   ip_dest;        
  };    
          
  /*   Structure   of   a   TCP   header   */    
  struct   tcp   {    
  unsigned   short   tcp_source_port;    
  unsigned   short   tcp_dest_port;    
  unsigned   int   tcp_seqno;        
  unsigned   int   tcp_ackno;    
  unsigned   int   tcp_res1:4,   /*little-endian*/    
  tcp_hlen:4,    
  tcp_fin:1,    
  tcp_syn:1,    
  tcp_rst:1,    
  tcp_psh:1,    
  tcp_ack:1,    
  tcp_urg:1,    
  tcp_res2:2;    
  unsigned   short   tcp_winsize;    
  unsigned   short   tcp_cksum;    
  unsigned   short   tcp_urgent;    
  };    
  /*********************EOF***********************************/
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
wangjianfeng
驱动小牛
驱动小牛
  • 注册日期2004-05-28
  • 最后登录2013-10-02
  • 粉丝0
  • 关注0
  • 积分1002分
  • 威望263点
  • 贡献值0点
  • 好评度260点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-04-18 20:15
必收!
softbiao
驱动牛犊
驱动牛犊
  • 注册日期2007-04-09
  • 最后登录2008-08-26
  • 粉丝0
  • 关注0
  • 积分240分
  • 威望26点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-04-23 12:07
windows版本的?我怎么看象是linux源码
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
地下室#
发布于:2007-04-23 12:40
再来一份windows版本的
再来一份windows版本的
附件名称/大小 下载次数 最后更新
Raw Socket(原始套接字)实现Sniffer(嗅探).mht (284KB)  79 2007-04-23 12:40
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
5楼#
发布于:2007-04-23 17:24
来一份可以编译通过的代码,适用于win2k /xp
附件名称/大小 下载次数 最后更新
ipMon_zw_2K.rar (127KB)  73 2007-04-23 17:26
A_Packet_S14527610122002.zip (3KB)  84 2007-04-23 17:26
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
strpic
驱动小牛
驱动小牛
  • 注册日期2006-11-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望238点
  • 贡献值0点
  • 好评度156点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-04-24 10:03
收下
softbiao
驱动牛犊
驱动牛犊
  • 注册日期2007-04-09
  • 最后登录2008-08-26
  • 粉丝0
  • 关注0
  • 积分240分
  • 威望26点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-04-24 14:50
xp那份还不够raw,只能收到IP层以上的包。。。看来要发送arp之类的包还得写驱动,麻烦
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
8楼#
发布于:2007-04-24 15:05
raw socket只是ip层及以上的,arp是和ip一层的东东,铁定不行...
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
hpulx
驱动牛犊
驱动牛犊
  • 注册日期2005-09-07
  • 最后登录2009-03-30
  • 粉丝0
  • 关注0
  • 积分151分
  • 威望17点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-12-18 17:32
这个windows版本的,貌似没有将网卡设为混杂模式吧。
将网卡设为混杂模式什么概念呢?我的理解是在同一局域网内,凡是经过本机网卡的数据包,不管MAC地址是不是自己的都接收过来。
可这个只能监听到本机发出或接入的数据吧。
有两点缺陷:1、MAC非本机地址的不能监听。
            2、本机发往本机的不能监听(似乎没经过IP层)
lxwyk
驱动牛犊
驱动牛犊
  • 注册日期2007-01-27
  • 最后登录2010-05-19
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2008-01-14 16:12
请问这种方式可以获取到一些木马或者rootkit的隐藏通信信息么?
游客

返回顶部