2008-11-2 0:03:46
黑客防线
sniffer技术原理及应用,包括编程方法和工具使用
|
sniffer中文翻译过来就是嗅探器,在当前网络技术中使用得非常得广泛。sniffer既可以做为网络故
障的诊断工具,也可以作为黑客嗅探和监听的工具。最近两年,网络监听(sniffer)技术出现了新的 重要特征。传统的sniffer技术是被动地监听网络通信、用户名和口令。而新的sniffer技术出现了主 动地控制通信数据的特点,把sniffer技术扩展到了一个新的领域。Sniffer 技术除了目前在传统的 网络侦测管理外,也开始被应用在资讯保全的领域。可以这样说,sniffer技术是一把双刃剑,如何 更好的利用它,了解它的一些特性,将能使这项技术更好的为我们带来便利。 sniffer的编程方法比较通用的有以下几种,1.winpcap 这是一个比较通用的库,相信做过抓包的 工 具大多数人都不会太陌生 2.raw socket 在2000以后的版本都支持此项功能,2000 server有个网络监视器就是基于raw socket 3.tdi,ndis,spi,hook socket技术,这种技术比较大的不同是可以将包截取而不是仅仅获得包的一份拷贝。总的说来,一般以前两者居多。 我这里提的都还比较片面,更多的需要大家来补充。我办这个专题的目的是希望大家共同来了解,讨论sniffer技术,让更多的人参与进来,让大家知道,这个板块能够给大家带来真正想要的东西。 warton: libpcap是个好东西,linux,windows下都能用,很多入侵检测之类的安全系统都是以这为核心。不 过我一直没用过它,不知道它的跨平台性如何? 要用spi的话,看看xfilter的代码和书,特别是那本书上讲得不错,可惜一直没用它做出什么东西来。 raw socket写的sniffer比较多,网上代码也很多! 昨天见csdn首页有几篇关于sniffer的文章,保存了,还没来得及看... 俺明天来说说目前常用的sniffer类工具和它们的技术实现! csdn首页的两篇文章,大家可以看看,里面好像还有几篇,暂时找不到了 netsys2: 一)winpcap驱动简介 发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项 功能:
winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报。也就是说,winp cap不能阻塞,过滤或控制其他应用程序数据报的发收,它仅仅只是监听共享网络上传送的数据报。因此,它不能用于QoS调度程序或个人防火墙。 目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的 用户中只有一小部分是仅使用windows 95/98/Me,并且M$也已经放弃了对win9x的开发。因 此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和 NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使 用Unicode编码。 zzhong2: 流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便 只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和 密码.它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件. 只能用在用HUB网络上
warton: 获目标主机返回的数据包的。 packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用pacap.dll是当然的选择。
一些著名的嗅探器: 单一用途的噢探器 等口令 专用 嗅探器: 交换网络嗅探器:Ettercap 嗅探对策......... netsys2: 网络上流传的GUNIFFER是个基本的原型: http://asp.6to23.com/nowcan/code/guniffer.zip void main(int argc, char ** argv) { int iErrorCode; char RecvBuf[MAX_PACK_LEN] = {0}; usage(); if(GetCmdLine(argc, argv)==CMD_PARAM_HELP) exit(0); //初始化SOCKET WSADATA wsaData; iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData); CheckSockError(iErrorCode, "WSAStartup"); SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP); CheckSockError(SockRaw, "socket"); //获取本机IP地址 char FAR name[MAX_HOSTNAME_LAN]; iErrorCode = gethostname(name, MAX_HOSTNAME_LAN); CheckSockError(iErrorCode, "gethostname"); struct hostent FAR * pHostent; //注意下面这三句,这里先对pHostent分配了一块 pHostent = (struct hostent * )malloc(sizeof(struct hostent)); //内存,然后有让它等于gethostbyname函数的返回 pHostent = gethostbyname(name); //值,但gethostbyname函数是自己在函数内部分配内 存的,因此上一句根本就是多余,把上一句删除后一切正常。但此程序用VC6编译运行都没有问题 ,不知为何?也许是VC6的编译器优化在起作用。 SOCKADDR_IN sa; sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); free(pHostent); //由于前面分配内存的语句已经删除,所以这一句也要去掉,否则出错。感谢网 友 Heyuming 发现这个问题。 iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa)); CheckSockError(iErrorCode, "bind"); //设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包 DWORD dwBufferLen[10] ; DWORD dwBufferInLen = 1 ; DWORD dwBytesReturned = 0 ; iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL ); CheckSockError(iErrorCode, "Ioctl"); //侦听IP报文 while(1) { memset(RecvBuf, 0, sizeof(RecvBuf)); iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0); CheckSockError(iErrorCode, "recv"); iErrorCode = DecodeIpPack(RecvBuf, iErrorCode); CheckSockError(iErrorCode, "Decode"); } } 它有2个不方便之处: sevencat(): 可以通过TDI调用核心TCPIP驱动,而且可以完全绕开WINSOCK,在大多数情况下这不是一个问 题。例如:QOS的实现可以在WINSOCK LSP上。 近核心态的方法来实现。 原则",这些过滤原则会被低层的TCPIP实现用来过滤包。这种过滤工主要是对IP原地址、目标地址、端口号(或者端口号范围)进行pass或者drop操作。 的API的文档并不是很容易能找到。这篇文章向你演示了怎样对特定IP地址或者特定TCP端口的包 进行阻塞的编程。 需要HtsCpp运行时库(免费),下载地址http://www.hollistech.com/ 如实现顺利的话,自己的DLL会接收用户的WINSOCK调用请求,然后还可以调用原来的WINSOC K DLL来处理。 公开的内部使用的函数,一个WINSOCK代替DLL至少要处理其中的一些未公开函数。 变得不太可行。总的说来,使用WINSOCK DLL替换不是一个坏主意。(Xfilter就是用的这种技 术,原代码可能在网上有流传,我以前看到过的) NT风格的驱动,使用了基于IRP的API,这里有两种方法来实现。 动开发编程技术十分了解,对TDI函数也要相当的了解。 严重的限制。(平时所见的drvipflt就是用的这个) 照微软有关文档http://msdn.microsoft.com/library/default.asp?url=/library/en-us /network/hh/network/firewall_3wfb.asp 说有些不正规,但一个有系统的NDIS-Hooking过滤会非常有效。 d services都能很有用的帮你HOOK由Ndis wrapper导出的函数。 文档支持较少,而且基本上不会被WHQL认证。 P)。地址http://www.pcausa.com/ndispim/Default.htm 其他: 可能会想知道是哪个进程在一个特定的IP端口上发送或接收数据。 以处理这个问题。而TCPIP驱动下层的过滤程序根本看不到进程信息。特别要注意的是有些网络服 务操作生成一个新的进程attach到系统进程上的。在这种情况下进程信息并不能告诉我们原先是哪 个进程生成的。特别是单独在核心模式下的WIN服务(TDI客户) methodology for managing internet access on a per application basis for client computers connected to the internet " uspto.gov/patft/index.html ============================================ switch (ioControlCode) 以了吧,我想。 //DeviceIoControl(drivehandle,START_IP_HOOK,NULL,0,NULL,0,&bytereturned,NU LL) break; // ioctl to stop filtering // ioctl to add a filter rule nf = (IPFilter *)ioBuffer; break; // ioctl to free filter rule list break; default: STATUS_INVALID_PARAMETER;
break; break; PF_SET_EXTENSION_HOOK_INFO filterData; KEVENT event; //首先获得一个设备指针。 &ipFileObject, &ipDeviceObject); //we need initialize the event used later by the IpFilterDriver to signal us //这个就是最重要的注册回调函数过程。DDK中具体讲述是这样的 the IP filter driver clears filter-hook 数,就将原先的清除掉了, 仅是生成这样的IRP,并没有注册 IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, ipDeviceObject, (PVOID) &filterData, sizeof(PF_SET_EXTENSION_HOOK_INFO), NULL, 0, FALSE, &event, &ioStatus);
if(irp != NULL) //and finally, we wait for "acknowledge" of IpDriverFilter Executive, KernelMode, FALSE, NULL); if (waitStatus != STATUS_SUCCESS ) {} status = ioStatus.Status; if(!NT_SUCCESS(status)){} else corresponding code error } if(ipFileObject != NULL) ipFileObject = NULL; else return status; ROP就拦住了。是不是 unsigned char *Packet, IN unsigned int PacketLength, IN unsigned int RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long RecvLinkNextHop, IN unsigned long SendLinkNextHop) int countRule=0; struct filterList *aux = first; //we "extract" the ip Header // dprintf("Source: %x/nDestination: %x/nProtocol: %d", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol); //TCP -> protocol = 6 // dprintf("FLAGS: %x/n", tcph->flags); //if we havent the bit SYN activate, we pass the packets //otherwise, we compare the packet with our rules //if protocol is the same.... aux->ipf.protocol) aux->ipf.sourceMask) != aux->ipf.sourceIp) & aux->ipf.destinationMask) != aux->ipf.destinationIp) countRule++; tcph->sourcePort == aux->ipf.sourcePort) || tcph->destinationPort == aux->ipf.destinationPort) //puerto tcp destino to do with the packet return PF_DROP; return PF_FORWARD; if(aux->ipf.sourcePort == 0 || udph->sourcePort == aux->ipf.sourcePort) || udph->destinationPort == aux->ipf.destinationPort) to do with the packet PF_DROP; PF_FORWARD; .... packet //compare with the next rule //we accept all not registered winpcap也是用的NDIS,将自己注册为一个协议处理驱动。(在原代码的driverentry里面能看到) 又:上面这个drvipflt这个代码的过滤部分不知道大家是不是看起来很熟悉,是的,是抄的那个nu mege的驱动开发包里面的一个包过滤程序里的,看来老外也是喜欢到处抄的。 ruike: 人,它有一个致命的缺陷就是只适用于共享式以太网络,对于交换式网络下的数据则无能为力,我 专门做过测试,在使用交换机连接的局域网下,只能监听到本网段内的数据,而对于来自其他网段 的数据则无法监听,除非你把probe接到交换机之前或者接到交换机的console口上,不过那样的 弊端是显而易见的。 kingzai: warton: entinel等) 目前这用利用网卡混合模式来进行sniffer的软件看来作用不太大了,所以应该多考虑交换网络的可 行办法: MAC Flooding,MAC Duplicating,ARP欺骗等等 netsys: netsys2: 混合模式的网卡则会响应。 当然,ARP与IP处于同层,因此你不能用RAW SOCKET完成,你需WinPcap支持工作。 下面是部分代码 AnsiString msgStatus; int BuildARPPacket(PArpPacket ArpPacket, unsigned char *dst_etheraddr, char *ar_sha, PacketOpenAdapter(wParams.AdapterList[wParams.SelectedAdapter]); if(!(*lpAdapter) || ((*lpAdapter)->hFile == INVALID_HANDLE_VALUE)) } ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1); OidData = (struct _PACKET_OID_DATA *)malloc(IoCtlBufferLength); *result) buf = (char *)lpPacket->Buffer; *remotemac) LPPACKET lpPacketRequest; TArpPacket ArpPacket; DWORD timestamp = 0; /* Init packet structure */ /* Build ARP Request packet */ wParams.srcMAC, wParams.srcIPAdd, mactarget, iptarget,wParams.ar_hw); /* Init ARP Request packet */ /* Set number of ARP Request packets to send */ /* Allocate PACKET structure for ARP Reply packet */ /* Main capture loop */ UB一起用的,这样小范围内是有效地,至于ADSL CABLE FTTB,我的FTTB是用华为设计的设备 ,呵呵,不仅仅工网IP,只有我和交换机两个MAC(这次中国人干的不错),没希望找到第三者,很安全,但 不都这样安全,很多人的网络还是很糟糕的. 时间内完全取代,而且加密也是有待价的,所以对于要求较高的场合,才会加密. 分析网络的健康与否,其实这样的话,你知道,很有可能sniffer就是接在我需要探测的网络上,听诊器 吗,到处都听听,呵呵,因此即使用了交换机,sniffer仍然是有用处的,但不是抓密码!! 换一下,不过写这种程序,你最好先熟悉协议,很多协议在linux里有现成的源代码,主要是一些struct 吧,移植时注意VC可不是gcc,有些c的高级语法,编译选项要注意,否则差一个byte你就得不到正确的 结果. |
所属专题: