|
![]() | 作者: 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号