⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 用arp探测网络中的混杂模式节点.txt

📁 可以对黑客编程有一定的了解
💻 TXT
字号:
用ARP探测网络中的混杂模式节点


    由于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就是),可能会让没有在混杂模式的网卡也作出响应。

#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 ethernet addrress */
	unsigned char	eh_src[6];		/* source ethernet addresss */
	unsigned short	eh_type;		/* ethernet 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(g_szMyMacAddr, MacAddr))
	{
		printf ("Get Mac address error!\n");
		goto Exit0;
	}
	memcpy(ARPPacket.arphdr.arp_sha, MacAddr, 6);
	ARPPacket.arphdr.arp_spa = inet_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 = inet_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", inet_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说明书


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -