论坛: 编程破解 标题: 黑客(hacker)成长的代码之路:嗅探(1) 复制本贴地址    
作者: kf701 [kf701]    论坛用户   登录
                  黑客(hacker)成长的代码之路:嗅探(1)
        作者:kf_701  写作时间:2005/4  Email:kf_701@21cn.com
        转载请保留原作者信息,谢谢。
      http://blog.chinaunix.net/index.php?blogId=3063

要求的专业知识:
    一:    精通OSI参考模型,精通网络五层:物理层,数据链路层,网络层,传
        输层,应用层。精通每一层的协议,数据报格式。精通网络拓扑结构,
        第一层,第二层,第三层的网络互联,数据的转发和路由等。
    二:    精通C语言程序设计,UNIX/LINUX程序设计,网络程序设计。熟悉
        UNIX/LINUX系统操作,熟悉著名服务的基本配置,特性及使用的端口
        号。熟悉经典网络命令的使用,如:netstat,ping,traceroute,
        netcat,arp等。
    三:    精通标准SQL语言,熟悉流行的数据库使用,如:Oracle,Mysql等。
        掌握数据库与WEB语言的结合使用。

  sniffer,我想大家都听说过,不过是截获数据报而已了。这样的事情多是发生在局域
网内。因此我们要完全明白内网的工作原理。
  由于写这个文章的时候,用的多的是以太网,因此我们的实验也在以太网环境里完成。
  首先要知道是的局域网的互联方式,目前使用的有第一层(物理层)的互联,主要使用
转发器,常用的转发器就是集线器了,也就是我们常称的HUB,用HUB互联的网络是一个总
线结构的网络,在总线结构的网络里,数据是广播形式的传送的。也就是两台主机间的通
信信息,其它的主机也可以收到,不过网络设备检查到目标物理地址并非是自己,便丢掉
这个数据包。但必境是收到了。
  我们用程序把这些数据报全部复制一份保存下来,就是所谓的sniffer了。还要做的一
件事就是把网卡设为混杂模式(Linux里面可用命令#ifconfig ethx promisc),我们
将在程序里自己完成。
  物理层互联的局域网称为共享式局域网。
  但现在不少的局域网是在第二层(数据链路层)互联的,使用的网络设备多是网桥,最
出名的网桥叫交换机,想必你也听说过了。这样联成的局域网叫交换式局域网。在这样的
网内,数据不再是广播了。
  那我们如何才能sniffer呢?也就是如何让别人的数据还能发到我们的机器上的网络设
备上来呢?问题出来了,答案是ARP欺骗。留作后续。
  进入我们的主题,如何写程序把数据报从数据链路层copy过来。
  Unix里常用的方法是:BSD的BPF(分组过滤器),SVR的DLPI(数据链路提供者接口),
Linux的SOCK_PACKET接口。
  如果你没有听说过开放源代码,那么你可能没有必要再读下去了。我可不想去重复已经
完成的工作。
  libpcap,一个公开可得源码的截获函数库,它在三种接口上都可以使用。因此我们将
使用这个函数库来完成我们的程序。
  53行,打开一个网络设备用来嗅探。
  59-64行,加入一条过滤规则,这里是只截UDP数据报。
  74行,返回一个数据报。
  我们用data_print函数分析打印出IP报头的源IP和目的IP,UDP报头中的源端口和目
标端口。

    1  /* author  :    kf_701
    2  * mtime  :    2005
    3  * email  :    kf_701@21cn.com
    4  * address :    合肥大学生公寓
    5  * school  :    ahau.edu
    6  */
    7
    8  /* The program is used to capture data from data
    9  * link layer,It is simply,only output ip address
    10  * and port,read this code,then you will understand
    11  * how to use libpcap functions.
    12  *      ****Best wishes to you !****
    13  *
    14  * if you want to use it ,please compile like:
    15  *      $gcc -lpcap thisfile.c
    16  */
    17  #include<stdio.h>
    18  #include<unistd.h>
    19  #include<string.h>
    20  #include<stdlib.h>
    21  #include<pcap.h>
    22
    23  #include<arpa/inet.h>
    24  #include<sys/socket.h>
    25  #include<netinet/in_systm.h> /* required for ip.h */
    26  #include<netinet/in.h>
    27  #include<netinet/ip.h>
    28  #include<netinet/udp.h>
    29  #include<netinet/if_ether.h>
    30  #include<net/if.h>
    31
    32  #define MAXLINE        255
    33
    34  static void data_print(char *,int);
    35
    36  int main(int argc,char **argv)
    37  {
    38          char            *device;
    39          pcap_t          *pd;
    40          int            snlen=80,link_type;
    41          uint32_t        netip,netmask;
    42          char            errbuf[PCAP_ERRBUF_SIZE],cmd[MAXLINE];
    43          int            data_len;      /* captured data length */
    44          char            *data_ptr;      /* captured data ptr */
    45          struct bpf_program      fcode;
    46          struct pcap_pkthdr      pkthdr;
    47          struct ether_header    *eptr;
    48
    49          /* open device and init struct pcap */
    50          if((device=pcap_lookupdev(errbuf)) == NULL)
    51                  printf("pcap_lookupdev: %s\n",errbuf),exit(1);
    52
    53          if((pd=pcap_open_live(device,snlen,1,500,errbuf)) == NULL)
    54                  printf("pcap_open_live: %s\n",errbuf),exit(1);
    55
    56          if(pcap_lookupnet(device,&netip,&netmask,errbuf)<0)
    57                  printf("pcap_lookupnet: %s\n",errbuf),exit(1);
    58
    59          strcpy(cmd,"udp");/* only capture UDP packet */
    60          if(pcap_compile(pd,&fcode,cmd,0,netmask)<0)
    61                  printf("pcap_compile: %s\n",pcap_geterr(pd)),exit(1);
    62
    63          if(pcap_setfilter(pd,&fcode)<0)
    64                  pcap_perror(pd,"pcap_setfilter"),exit(1);
    65
    66          if((link_type=pcap_datalink(pd)) < 0)
    67                  pcap_perror(pd,"pcap_datalink"),exit(1);
    68
    69          printf("-----------------------------------\n\
    70  kf_701 sniffer,listen on %s for udp packets...\n",
    71                  device);
    72
    73          while(1){      /* catpture data and print */
    74                  data_ptr=(char *)pcap_next(pd,&pkthdr);
    75                  if(data_ptr == NULL)
    76                          continue;
    77                  data_len = pkthdr.caplen;
    78
    79                  switch(link_type){
    80                          case DLT_NULL:          /* loopback header = 4 bytes */
    81                                  data_print(data_ptr+4,data_len-4);
    82                                  break;
    83                          case DLT_EN10MB:        /* ether header = 14 bytes */
    84                                  eptr = (struct ether_header *)data_ptr;
    85                                  if(ntohs(eptr->ether_type) != ETHERTYPE_IP)
    86                                          break;
    87                                  data_print(data_ptr+14,data_len-14);
    88                                  break;
    89                          case DLT_PPP:          /* ppp header = 24 bytes */
    90                                  data_print(data_ptr+24,data_len-24);
    91                                  break;
    92                          default:
    93                                  ;
    94                  }
    95          }/* end while */
    96  }
    97
    98  static void
    99  data_print(char *ptr,int len)
  100  {
  101          int ip_hlen;
  102          struct ip *ip;
  103          struct udphdr *udp;
  104          char *src,*dst;
  105
  106          printf("Captured a packet!----------------------------\n");
  107
  108          /* deal with part of ip head */
  109          if(len < sizeof(struct ip)+sizeof(struct udphdr)){
  110                  printf("* error,data_len = %d\n",len);
  111                  return;
  112          }
  113          ip = (struct ip *)ptr;
  114          if(ip->ip_v != 4){
  115                  printf("* error,not ipv4,dropped.\n");
  116                  return;
  117          }
  118          ip_hlen = ip->ip_hl << 2;
  119          if(ip_hlen < sizeof(struct ip)){
  120                  printf("* error:ip_hl = %d\n",ip->ip_hl);
  121                  return;
  122          }
  123          src = malloc(sizeof(char)*20);
  124          dst = malloc(sizeof(char)*20);
  125          strncpy(src,inet_ntoa((struct in_addr)ip->ip_src),20);
  126          strncpy(dst,inet_ntoa((struct in_addr)ip->ip_dst),20);
  127          printf("* ip_src = %s,ip_dst = %s\n",src,dst);
  128
  129          /* deal with udp part of udp head */
  130          if(len<ip_hlen+sizeof(struct udphdr)){
  131                  printf("* error:data_len = %d,ip_hlen = %d\n",len,ip_hlen);
  132                  return;
  133          }
  134          udp = (struct udphdr *)(ptr+ip_hlen);
  135          printf("* source(port) = %d,dest(port) = %d,length(ip+udp+data) = %d\n",\
  136                  ntohs(udp->source),ntohs(udp->dest),ntohs(udp->len)+ip_hlen);
  137
  138          return;
  139  }

关于libpcap函数库的详细使用,请自行查阅文章或手册。
有问题请给我mail,谢谢。
*****待续*******




地主 发表时间: 05-04-15 21:13

回复: X-H [xh21317]   论坛用户   登录
谢谢你的大作,有机会多向你学习呀
还有你学网络多少时间了/

B1层 发表时间: 05-04-19 14:18

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号