用ARP探测网络中的混杂模式节点

    技术2022-05-11  97

    由于sniffer的危害,检测网络中是否存在sniffer也非常重要。Anti-Sniff就相应地产生,来检测网络中的sniffer。 检测sniffer的办法有很多,比如有些功能强大的sniffer会对IP地址进行解析获得机器名,那么可以通过发送畸形数据包等待sniffer进行DNS解析等等,但是这些办法局限太大了。    根据sniffer的基本工作原理,其核心就是设置网卡模式为 promiscuous(混杂模式),如果能够检测 到网络有是混杂模式的网卡,那么就可以判断可能存在一个sniffer。ARP协议在深入嗅探中很有作用,同时 也可以用于进行嗅探器的侦测。   在混杂模式中,网卡进行包过滤不同于普通模式。本来在普通模式下,只有本地地址的数据包或者广播 (多播等)才会被网卡提交给系统核心,否则的话,这些数据包就直接被网卡抛弃。现在,混合模式让所有 经过的数据包都传递给系统核心,然后被sniffer等程序利用。因此,如果能利用中间的“系统核心”,就能 有效地进行是否混杂模式的检测。系统核心也会对一些数据包进行过滤,但是,和网卡的标准不一样的是。   以Windows系统为例(实验可得):FF-FF-FF-FF-FF-FF:这个是一个正规的广播地址,不管是正常模式还是其他模式,都会被网卡接收并传递给系统核心。FF-FF-FF-FF-FF-00:这个地址对于网卡来说,不是一个广播地址,在正常模式下会被网卡抛弃,但是系统核心是认为这个地址同FF-FF-FF-FF-FF-FF是完全一样的。如果处于混杂模式,将被系统核心接收,并认为是一个广播地址。所有的Windows操作系统都是如此。FF-FF-00-00-00-00:Windows核心只对前面两字节作判断,核心认为这是一个同FF-FF-FF-FF-FF-FF一样的广播地址。这就是为什么FF-FF-FF-FF-FF-00也是广播地址的原因。FF-00-00-00-00-00:对于Win9x或WinME,则是检查前面的一个字节。因此会认为这个是一个广播地址。    而对于LINUX内核,我则不清楚,不过从一些资料得到会判断一个group bit,不清楚具体什么意思,但是 基本上就是认为FF-00-00-00-00-00,是FF-FF-FF-FF-FF-FF一个类别的吧。(望熟悉LINUX者指点)   所以,目的就要让正常模式的网卡抛弃掉探测包,而让混杂模式的系统核心能够处理探测。发送一个目的 地址为:FF-FF-FF-FF-FF-FE(系统会认为属于广播地址)的ARP请求,对于普通模式(广播等)的网卡,这个 地址不是广播地址,就会直接抛弃,而如果处于混杂模式,那么ARP请求就会被系统核心当作广播地址处理, 然后提交给sniffer程序。系统核心就会应答这个ARP请求。   antisniffer也采用了这样的策略进行检测。   下面这个例子就是FF-FF-FF-FF-FF-FE的ARP请求,可以对网络中的每个节点都发送这样的ARP请求。如果有一般的sniffer存在,并设置网卡为混杂模式,那么系统核心就会作出应答,可以判断这些节点是否存在嗅探器了。这种检测办法也是有局限的,对于那些修改内核的sniffer,就没有办法了,不过这种Sniffer毕竟属于少数 还有就是Win2k中一些动态加载的包捕获驱动(WinPcap就是),可能会让没有在混杂模式的网卡也作出响应。 /// // //Detect Promiscuous Node In Network // // Author: Refdom // Email:refdom@263. net // Home Page:www.opengram.com // // 2002/4/14 // #include "stdafx.h" #include "Mac.h"//GetMacAddr(),我写的把字符串转换为MAC地址的函数,就不列在这里了 #include <stdio.h> #include <conio.h> #include <Packet32.h> #include <Winsock2.h> #include <process.h> #include <ntddndis.h> #pragma comment (lib, "packet.lib") #pragma comment (lib, "ws2_32.lib") #define EPT_IP0x0800/* type: IP*/ #define EPT_ARP0x0806/* type: ARP */ #define EPT_RARP0x8035/* type: RARP */ #define ARP_HARDWARE0x0001/* Dummy type for 802.3 frames*/ #defineARP_REQUEST0x0001/* ARP request */ #defineARP_REPLY0x0002/* ARP reply */ #define Max_Num_Adapter 10 #pragma pack(push, 1) typedef struct ehhdr {   unsigned chareh_dst[6];/* destination ether net addrress */   unsigned chareh_src[6];/* source ether net addresss */   unsigned shorteh_type;/* ether net pachet type*/ }EHHDR, *PEHHDR; typedef struct arphdr {   unsigned shortarp_hrd;/* format of hardware address */   unsigned shortarp_pro;/* format of protocol address */   unsigned chararp_hln;/* length of hardware address */   unsigned chararp_pln;/* length of protocol address */   unsigned shortarp_op;/* ARP/RARP operation */   unsigned chararp_sha[6];/* sender hardware address */   unsigned longarp_spa;/* sender protocol address */   unsigned chararp_tha[6];/* target hardware address */   unsigned longarp_tpa;/* target protocol address */ }ARPHDR, *PARPHDR; typedef struct arpPacket {   EHHDRehhdr;   ARPHDRarphdr; } ARPPACKET, *PARPPACKET; #pragma pack(pop) //the thread for listening void ListenThread(void* Adapter); //the function of sending packet void SendARPPacket(void* Adapter); BOOL DetectIsSniffer(LPPACKET lpPacket); char g_szMyMacAddr[] = "AAAAAAAAAAAA"; char g_szMyIP[]= "192.168.1.1"; char g_szTargetIP[]= "192.168.1.2"; int main(int argc, char* argv[]) {   static char AdapterList[Max_Num_Adapter][1024];   LPADAPTERlpAdapter;   WCHARAdapterName[2048];   WCHAR*temp,*temp1;   ULONG AdapterLength = 1024;     int AdapterNum = 0;   int nRetCode, i;   //Get The list of Adapter   if(PacketGetAdapterNames((char*)AdapterName, &AdapterLength) == FALSE)   {   printf("Unable to retrieve the list of the adapters!/n");   return 0;   }   temp = AdapterName;   temp1 = AdapterName;   i = 0;   while ((*temp != '/0')||(*(temp-1) != '/0'))   {   if (*temp == '/0')   {   memcpy(AdapterList[i],temp1,(temp-temp1)*2);   temp1 = temp+1;   i++;   }     temp++;   }     AdapterNum = i;   for (i = 0; i < AdapterNum; i++)   wprintf(L"/n%d- %s/n", i+1, AdapterList[i]);   printf("/n");     //Default open the 0   lpAdapter = (LPADAPTER) PacketOpenAdapter((LPTSTR) AdapterList[0]);   if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))   {   nRetCode = GetLastError();   printf("Unable to open the driver, Error Code : %lx/n", nRetCode);   return 0;   }   //begin listening   _beginthread(ListenThread, 0, (void*) lpAdapter);   Sleep(500);   //send the packet   _beginthread(SendARPPacket, 0, (void*) lpAdapter);   Sleep(2000);   printf ("/n/nDetecting end./n");   // close the adapter and exit   PacketCloseAdapter(lpAdapter);   return 0; } void SendARPPacket(void* Adapter) {   char MacAddr[6];   char szPacketBuf[600];   LPADAPTERlpAdapter = (LPADAPTER) Adapter;   LPPACKETlpPacket;   ARPPACKET ARPPacket;   lpPacket = PacketAllocatePacket();   if(lpPacket == NULL)   {   printf("/nError:failed to allocate the LPPACKET structure./n");   return;   }   ZeroMemory(szPacketBuf, sizeof(szPacketBuf));   // the fake mac of multicast   if (!GetMacAddr("FFFFFFFFFFFE", MacAddr))   {   printf ("Get Mac address error!/n");   goto Exit0;   }   memcpy(ARPPacket.ehhdr.eh_dst, MacAddr, 6);   //the MAC of sender   if (!GetMacAddr(g_szMyMacAddr, MacAddr))   {   printf ("Get Mac address error!/n");   goto Exit0;   }   memcpy(ARPPacket.ehhdr.eh_src, MacAddr, 6);   ARPPacket.ehhdr.eh_type = htons(EPT_ARP);   //arp header   ARPPacket.arphdr.arp_hrd = htons(ARP_HARDWARE);   ARPPacket.arphdr.arp_pro = htons(EPT_IP);   ARPPacket.arphdr.arp_hln = 6;   ARPPacket.arphdr.arp_pln = 4;   ARPPacket.arphdr.arp_op = htons(ARP_REQUEST);   if (!GetMacAddr("00E04C6A21DF", MacAddr))   {   printf ("Get Mac address error!/n");   goto Exit0;   }   memcpy(ARPPacket.arphdr.arp_sha, MacAddr, 6);   ARPPacket.arphdr.arp_spa = i net_addr(g_szMyIP);   if (!GetMacAddr("000000000000", MacAddr))   {   printf ("Get Mac address error!/n");   goto Exit0;   }   memcpy(ARPPacket.arphdr.arp_tha , MacAddr, 6);   ARPPacket.arphdr.arp_tpa = i net_addr(g_szTargetIP);   memcpy(szPacketBuf, (char*)&ARPPacket, sizeof(ARPPacket));   PacketInitPacket(lpPacket, szPacketBuf, 60);   if(PacketSetNumWrites(lpAdapter, 1)==FALSE)   {   printf("warning: Unable to send more than one packet in a single write!/n");   }     if(PacketSendPacket(lpAdapter, lpPacket, TRUE)==FALSE)   {   printf("Error sending the packets!/n");   goto Exit0;   }   printf ("Send ok!/n/n"); Exit0:   PacketFreePacket(lpPacket);   _endthread(); } void ListenThread(void* Adapter) {   LPPACKET lpPacket;   LPADAPTER lpAdapter = (LPADAPTER) Adapter;   char buffer[256000];   if((lpPacket = PacketAllocatePacket())==NULL){   printf("/nError: failed to allocate the LPPACKET structure.");   return;   }   PacketInitPacket(lpPacket,(char*)buffer,256000);   // set the network adapter in promiscuous mode     if(PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED)==FALSE){   printf("Warning: unable to set promiscuous mode!/n");   }   // set buffer in the driver   if(PacketSetBuff(lpAdapter,512000)==FALSE){   printf("Unable to set the kernel buffer!/n");   return;   }   // set second read timeout   if(PacketSetReadTimeout(lpAdapter, 200)==FALSE){   printf("Warning: unable to set the read tiemout!/n");   }   //main capture loop   printf("Listen..../n");   while(true)   {   // capture the packets   if(PacketReceivePacket(lpAdapter, lpPacket, TRUE)==FALSE){   printf("Error: PacketReceivePacket failed");   return ;   }   //   DetectIsSniffer(lpPacket);   }   PacketFreePacket(lpPacket);   // close the adapter and exit   PacketCloseAdapter(lpAdapter);   _endthread(); } BOOL DetectIsSniffer(LPPACKET lpPacket) {   BOOL bFlag = FALSE;   PARPHDR pARPHeader;   PARPPACKET pARPPacket;   char MacAddr[6];   GetMacAddr(g_szMyMacAddr, MacAddr);   pARPPacket = (PARPPACKET) ((char*)lpPacket->Buffer + 20);   if (pARPPacket->ehhdr.eh_type == htons(EPT_IP))   return FALSE;   if (strcmp((char*)(pARPPacket->ehhdr.eh_dst), MacAddr) == 0   && pARPPacket->ehhdr.eh_type == htons(EPT_ARP))   {   char szTemp[10];   pARPHeader = (PARPHDR)((char*)lpPacket->Buffer + 20 + sizeof(EHHDR));   memcpy(szTemp, &pARPHeader->arp_spa, sizeof(pARPHeader->arp_spa));   printf ("A PROMISCUOUS NODE EXISTS!!/n");   printf ("/tIP:%s/n/n", i net_ntoa(*((struct in_addr *)(szTemp))));   return TRUE;   }   return FALSE; } Reference: 1、Securiteam 《Detecting sniffers on your network》、   《AntiSniff - find sniffers on your local network》 2、l0pht.com的Antisniffer说明书

    最新回复(0)