zoukankan      html  css  js  c++  java
  • ARP欺骗的实现

    arp欺骗的简介我就不复述了,网上挺多解释的,其产生的主要原因就是never check.在这种情况下,什么乱七八糟够早的包都能发了。

    其实有很多工具可以利用,比如,WinArpAttacker(可能会缺少一些dll文件,自己下载加进去,网上资源挺多的,我就不放链接了),不过,本机测验,WinArpAttacker断网效果不咋地啊,不过IP冲突还是不错。估计使用方式不正确(一定要在配置中选择你需要的网卡)。它的断网原理是同时欺骗网关和你攻击的主机。当然还有一种,比较简单但是效果也比较好的:ArpSpoof(额,资源自寻吧,不难),它就是伪造攻击IP持续给网关发包,然后,被攻击的IP就瞬断网了。。。(ps:同一网段)

    IP中间人攻击,做得比较好的是EtterCap,不过,EtterCap在Linux下会比较好。Windows我用了Cain&Abel (更新的version,虽然我不会用,解压之后找不到)当然,如果想看原理,可以用WireShark抓包观察(注意设置过滤条件,不然,包太多了)

    另外,工具能用,不过不要乱用,拿来学习学习是不错,比如开个虚拟机玩就好。

    ————————————————————————————————————————————————————————

    工具介绍完了,如果,要自己编写,可以利用Winpcap编程(资源下载页面——Developer's Pack)实现,Winpcap是运行上面众多软件所需的算一个插件吧,它的exe资源页面——Installer for Windows

    下载之后,如何配置呢:

    http://blog.sina.com.cn/s/blog_57432f380101qh3n.html

    VS2013使用winpcap开发网络应用程序:

    1.首先,从http://www.winpcap.org/下载winpcap.exe和Developer's Pack(资源在上面)。安装winpcap.exe,并将Developer's Pack进行解压。

    2.配置VS2013。在VS2013中新建一个空工程(可以考虑win32空应用程序)。具体设置如下:

    (1)项目 →属性→配置属性→点击C/C++目录,点击展开的目录General,在右侧的Additional Include Directories中添加Include目录(Include目录在WpdPack中)

    (2)项目 →属性→配置属性→点击C/C++目录,在右边的Preprocessor Definition加上WPCAP,HAVE_REMOTE,WIN32;

    (3)项目 →属性→配置属性→点击Linker目录,点击展开的目录General,在右边的Additional Library Directories中添加lib目录(Lib目录在WpdPack中)
    (4)项目 →属性→配置属性→点击Linker目录下的Input,在右侧的Additional Dependencies中添加wpcap.lib和Packet.lib,ws2_32.lib。

    如果你用的 inet_addr 函数,那么可能会碰到下面的问题:

    http://jingyan.baidu.com/article/1709ad8097e5904634c4f03e.html?st=2&os=0&bd_page_type=1&net_type=1

    还有问题可以看下这篇博文:

    winpcap开发包使用中的问题总结

    ————————————————————————————————————————————————————————

    最后就是编程问题,要进行arp欺骗编程,

    First Step:得先得到网卡信息吧。。。

    用winpcap所带的 pcap_findalldevs_ex 得到网卡列表。说实话,不好用啊,因为它的description属性太多简单,我电脑上出现了四五个Microsoft的描述,除此再无其他,这要我怎么选。。。虽然name属性可以区分它们,但是不够直观。

    用GetAdaptersAddresses获取网卡信息,GetAdapterAddresses的介绍可以参看:http://blog.csdn.net/linuxtiger/article/details/7002896 

    这个函数的接口声明是这样的:

    ULONG WINAPI GetAdaptersAddresses(

      __in     ULONGFamily,

      __in     ULONGFlags,

      __in     PVOIDReserved,

      __inout  PIP_ADAPTER_ADDRESSESAdapterAddresses,

      __inout  PULONG SizePointer

    );

    其中最主要的还是 __inout  PIP_ADAPTER_ADDRESSES AdapterAddresses 大部分信息的储存都在这个结构里(ps:网卡是以链表的方式被存储)也就是,你想知道什么,就查看这个结构体所包含的东西就好。具体官方说明https://msdn.microsoft.com/en-us/library/windows/desktop/aa366058 如果想完全熟悉它,就不得不看了。

    代码除了上面的链接,再给一个https://msdn.microsoft.com/en-us/library/windows/desktop/aa366058(其实都差不多)

    下面这个我测试可用:

      1 #include "stdafx.h"
      2 
      3 
      4 #include <winsock2.h>
      5 #include <iphlpapi.h>
      6 #include <stdlib.h>
      7 #pragma comment(lib, "IPHLPAPI.lib")
      8 
      9 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
     10 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
     11 /* Note: could also use malloc() and free() */
     12 
     13 int _tmain(int argc, TCHAR **argv)
     14 {
     15 
     16 	/* Declare and initialize variables */
     17 
     18 	DWORD dwSize = 0;
     19 	DWORD dwRetVal = 0;
     20 
     21 	int i = 0;
     22 
     23 	// Set the flags to pass to GetAdaptersAddresses
     24 	ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
     25 
     26 	// default to unspecified address family (both)
     27 	ULONG family = AF_UNSPEC;
     28 
     29 	LPVOID lpMsgBuf = NULL;
     30 
     31 	PIP_ADAPTER_ADDRESSES pAddresses = NULL;
     32 	ULONG outBufLen = 0;
     33 
     34 	PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
     35 	PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
     36 	PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
     37 	PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
     38 	IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
     39 	IP_ADAPTER_PREFIX *pPrefix = NULL;
     40 
     41 	if (argc != 2) {
     42 		printf(" Usage: getadapteraddresses family
    ");
     43 		printf("        getadapteraddresses 4 (for IPv4)
    ");
     44 		printf("        getadapteraddresses 6 (for IPv6)
    ");
     45 		printf("        getadapteraddresses A (for both IPv4 and IPv6)
    ");
     46 		exit(1);
     47 	}
     48 
     49 	if (_ttoi(argv[1]) == 4)
     50 		family = AF_INET;
     51 	else if (_ttoi(argv[1]) == 6)
     52 		family = AF_INET6;
     53 
     54 	outBufLen = sizeof (IP_ADAPTER_ADDRESSES);
     55 	pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
     56 
     57 	// Make an initial call to GetAdaptersAddresses to get the 
     58 	// size needed into the outBufLen variable
     59 	if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen)
     60 		== ERROR_BUFFER_OVERFLOW) {
     61 			FREE(pAddresses);
     62 			pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
     63 	}
     64 
     65 	if (pAddresses == NULL) {
     66 		printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct
    ");
     67 		exit(1);
     68 	}
     69 	// Make a second call to GetAdapters Addresses to get the
     70 	// actual data we want
     71 	printf("Memory allocated for GetAdapterAddresses = %d bytes
    ", outBufLen);
     72 	printf("Calling GetAdaptersAddresses function with family = ");
     73 	if (family == AF_INET)
     74 		printf("AF_INET
    ");
     75 	if (family == AF_INET6)
     76 		printf("AF_INET6
    ");
     77 	if (family == AF_UNSPEC)
     78 		printf("AF_UNSPEC
    
    ");
     79 
     80 	dwRetVal =
     81 		GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
     82 
     83 	if (dwRetVal == NO_ERROR) {
     84 		// If successful, output some information from the data we received
     85 		pCurrAddresses = pAddresses;
     86 		while (pCurrAddresses) {
     87 			printf("	Length of the IP_ADAPTER_ADDRESS struct: %ld
    ",
     88 				pCurrAddresses->Length);
     89 			printf("	IfIndex (IPv4 interface): %u
    ", pCurrAddresses->IfIndex);
     90 			printf("	Adapter name: %s
    ", pCurrAddresses->AdapterName);
     91 
     92 			pUnicast = pCurrAddresses->FirstUnicastAddress;
     93 			if (pUnicast != NULL) {
     94 				for (i = 0; pUnicast != NULL; i++)
     95 					pUnicast = pUnicast->Next;
     96 				printf("	Number of Unicast Addresses: %d
    ", i);
     97 			} else
     98 				printf("	No Unicast Addresses
    ");
     99 
    100 			pAnycast = pCurrAddresses->FirstAnycastAddress;
    101 			if (pAnycast) {
    102 				for (i = 0; pUnicast != NULL; i++)
    103 					pAnycast = pAnycast->Next;
    104 				printf("	Number of Anycast Addresses: %d
    ", i);
    105 			} else
    106 				printf("	No Anycast Addresses
    ");
    107 
    108 			pMulticast = pCurrAddresses->FirstMulticastAddress;
    109 			if (pMulticast) {
    110 				for (i = 0; pMulticast != NULL; i++)
    111 					pMulticast = pMulticast->Next;
    112 				printf("	Number of Multicast Addresses: %d
    ", i);
    113 			} else
    114 				printf("	No Multicast Addresses
    ");
    115 
    116 			pDnServer = pCurrAddresses->FirstDnsServerAddress;
    117 			if (pDnServer) {
    118 				for (i = 0; pDnServer != NULL; i++)
    119 					pDnServer = pDnServer->Next;
    120 				printf("	Number of DNS Server Addresses: %d
    ", i);
    121 			} else
    122 				printf("	No DNS Server Addresses
    ");
    123 
    124 			printf("	DNS Suffix: %wS
    ", pCurrAddresses->DnsSuffix);
    125 			printf("	Description: %wS
    ", pCurrAddresses->Description);
    126 			printf("	Friendly name: %wS
    ", pCurrAddresses->FriendlyName);
    127 
    128 			if (pCurrAddresses->PhysicalAddressLength != 0) {
    129 				printf("	Physical address: ");
    130 				for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength;
    131 					i++) {
    132 						if (i == (pCurrAddresses->PhysicalAddressLength - 1))
    133 							printf("%.2X
    ",
    134 							(int) pCurrAddresses->PhysicalAddress[i]);
    135 						else
    136 							printf("%.2X-",
    137 							(int) pCurrAddresses->PhysicalAddress[i]);
    138 				}
    139 			}
    140 			printf("	Flags: %ld
    ", pCurrAddresses->Flags);
    141 			printf("	Mtu: %lu
    ", pCurrAddresses->Mtu);
    142 			printf("	IfType: %ld
    ", pCurrAddresses->IfType);
    143 			printf("	OperStatus: %ld
    ", pCurrAddresses->OperStatus);
    144 			printf("	Ipv6IfIndex (IPv6 interface): %u
    ",
    145 				pCurrAddresses->Ipv6IfIndex);
    146 			printf("	ZoneIndices (hex): ");
    147 			for (i = 0; i < 16; i++)
    148 				printf("%lx ", pCurrAddresses->ZoneIndices[i]);
    149 			printf("
    ");
    150 
    151 			pPrefix = pCurrAddresses->FirstPrefix;
    152 			if (pPrefix) {
    153 				for (i = 0; pPrefix != NULL; i++)
    154 					pPrefix = pPrefix->Next;
    155 				printf("	Number of IP Adapter Prefix entries: %d
    ", i);
    156 			} else
    157 				printf("	No IP Adapter Prefix entries
    ");
    158 
    159 			printf("
    ");
    160 
    161 			pCurrAddresses = pCurrAddresses->Next;
    162 		}
    163 	} else {
    164 		printf("Call to GetAdaptersAddresses failed with error: %d
    ",
    165 			dwRetVal);
    166 		if (dwRetVal == ERROR_NO_DATA)
    167 			printf("	No addresses were found for the requested parameters
    ");
    168 		else {
    169 
    170 			if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   // Default language
    171 				(LPTSTR) & lpMsgBuf, 0, NULL)) {
    172 					printf("	Error: %s", lpMsgBuf);
    173 					LocalFree(lpMsgBuf);
    174 					FREE(pAddresses);
    175 					exit(1);
    176 			}
    177 		}
    178 	}
    179 	FREE(pAddresses);
    180 	return 0;
    181 }
    比较全面的使用举例

    虽然GetAdaptersAddresses比较新,而且看到有那么多信息属性,不过好像在网关和子网掩码的获取上,可能没有GetAdapterInfo顺手。我查了一些它的API,不过也出现了下列问题:http://bbs.csdn.net/topics/390036236,没办法,只好用GetAdapterInfo了。

    http://www.cnblogs.com/L-hq815/archive/2012/08/04/2622829.html(基本可以直接跑,它对数据结构解释的代码可别往程序里放)

    我对它的代码做一个粘贴吧:

      1 #include <WinSock2.h>
      2 #include <Iphlpapi.h>
      3 #include <iostream>
      4 using namespace std;
      5 #pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库
      6 
      7 int main(int argc, char* argv[])
      8 {
      9     //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
     10     PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
     11     //得到结构体大小,用于GetAdaptersInfo参数
     12     unsigned long stSize = sizeof(IP_ADAPTER_INFO);
     13     //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
     14     int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);
     15     //记录网卡数量
     16     int netCardNum = 0;
     17     //记录每张网卡上的IP地址数量
     18     int IPnumPerNetCard = 0;
     19     if (ERROR_BUFFER_OVERFLOW == nRel)
     20     {
     21         //如果函数返回的是ERROR_BUFFER_OVERFLOW
     22         //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
     23         //这也是说明为什么stSize既是一个输入量也是一个输出量
     24         //释放原来的内存空间
     25         delete pIpAdapterInfo;
     26         //重新申请内存空间用来存储所有网卡信息
     27         pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
     28         //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
     29         nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);    
     30     }
     31     if (ERROR_SUCCESS == nRel)
     32     {
     33         //输出网卡信息
     34          //可能有多网卡,因此通过循环去判断
     35     while (pIpAdapterInfo)
     36     {
     37         cout<<"网卡数量:"<<++netCardNum<<endl;
     38         cout<<"网卡名称:"<<pIpAdapterInfo->AdapterName<<endl;
     39         cout<<"网卡描述:"<<pIpAdapterInfo->Description<<endl;
     40         switch(pIpAdapterInfo->Type)
     41         {
     42         case MIB_IF_TYPE_OTHER:
     43             cout<<"网卡类型:"<<"OTHER"<<endl;
     44             break;
     45         case MIB_IF_TYPE_ETHERNET:
     46             cout<<"网卡类型:"<<"ETHERNET"<<endl;
     47             break;
     48         case MIB_IF_TYPE_TOKENRING:
     49             cout<<"网卡类型:"<<"TOKENRING"<<endl;
     50             break;
     51         case MIB_IF_TYPE_FDDI:
     52             cout<<"网卡类型:"<<"FDDI"<<endl;
     53             break;
     54         case MIB_IF_TYPE_PPP:
     55             printf("PP
    ");
     56             cout<<"网卡类型:"<<"PPP"<<endl;
     57             break;
     58         case MIB_IF_TYPE_LOOPBACK:
     59             cout<<"网卡类型:"<<"LOOPBACK"<<endl;
     60             break;
     61         case MIB_IF_TYPE_SLIP:
     62             cout<<"网卡类型:"<<"SLIP"<<endl;
     63             break;
     64         default:
     65 
     66             break;
     67         }
     68         cout<<"网卡MAC地址:";
     69         for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++)
     70             if (i < pIpAdapterInfo->AddressLength-1)
     71             {
     72                 printf("%02X-", pIpAdapterInfo->Address[i]);
     73             }
     74             else
     75             {
     76                 printf("%02X
    ", pIpAdapterInfo->Address[i]);
     77             }
     78             cout<<"网卡IP地址如下:"<<endl;
     79             //可能网卡有多IP,因此通过循环去判断
     80             IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);
     81             do 
     82             {
     83                 cout<<"该网卡上的IP数量:"<<++IPnumPerNetCard<<endl;
     84                 cout<<"IP 地址:"<<pIpAddrString->IpAddress.String<<endl;
     85                 cout<<"子网地址:"<<pIpAddrString->IpMask.String<<endl;
     86                 cout<<"网关地址:"<<pIpAdapterInfo->GatewayList.IpAddress.String<<endl;
     87                 pIpAddrString=pIpAddrString->Next;
     88             } while (pIpAddrString);
     89             pIpAdapterInfo = pIpAdapterInfo->Next;
     90             cout<<"--------------------------------------------------------------------"<<endl;
     91     }
     92     
     93     }
     94     //释放内存空间
     95     if (pIpAdapterInfo)
     96     {
     97         delete pIpAdapterInfo;
     98     }
     99  
    100     return 0;
    101 }
    from http://www.cnblogs.com/L-hq815/archive/2012/08/04/2622829.html

    同样的,多放一个链接:http://blog.csdn.net/zjg555543/article/details/7547309 (真的,都差不多)

    add: http://blog.csdn.net/lyd_253261362/article/details/36004167

    SECOND STEP:选择网卡完了总要构造包吧

    用Winpcap的函数,所以看一下Winpcap主要数据结构及函数 或者 Winpcap编程常用函数和数据结构总结 这篇博文。

    Second Step:扫描网段活动主机,选择攻击对象

    本来呢,我觉得我发包之后,然后收到了应答包,arp表里就该有它的记录,我只要在程序里用 system命令将 arp -a 的结果输出到文件夹然后再读出就可以了。

    但是,在我的系统上,即使收到了包,因为我和这些主机没有真正通信过,arp表根本不理好嘛。。。

    所以,我就借用网上某段代码,他用了线程来做这个事情,一边发包,一边收包,我们认为,收到包=主机在活动中

    不过pcap中收包有两个函数:一个是回调方式,一个是非回掉方式,我的代码用了后者

    Third Step:选择攻击方式,构造包,开始攻击

    这个,用pcap的sendpacket和receivepacket就好。主要注意填充的时候啊,那个ip的字节顺序(hton、 ntoh)

    为什么后面讲得这么少,因为代码里都有,也附带说明了http://download.csdn.net/detail/u014576894/9207567

    学习愉快

  • 相关阅读:
    disruptor架构三 使用场景 使用WorkHandler和BatchEventProcessor辅助创建消费者
    disruptor架构二
    disruptor架构一
    线程池基础二
    线程池基础一
    多线程集成设计模式--MasterWorker模式讲解(一)
    多线程集成设计模式--future模式
    线程基础9-quene讲解
    线程基础8-quene讲解
    hdu3613 Best Reward
  • 原文地址:https://www.cnblogs.com/puluotiya/p/4888906.html
Copyright © 2011-2022 走看看