VC++实现IP与ARP信息获取,可以同理实现APR攻击
来源:互联网 发布:手办 邪神 知乎 编辑:程序博客网 时间:2024/06/10 19:52
ARP(Address Resolution Protocol,地址解析协议)是获取物理地址的一个TCP/IP协议。某节点的IP地址的ARP请求被广播到网络上后,这个节点会收到确认 其物理地址的应答,这样的数据包才能被传送出去。RARP(逆向ARP)经常在无盘工作站上使用,以获得它的逻辑IP地址。
地址解析协议(Address Resolution Protocol,ARP)是在仅知道主机的IP地址时确 地址解析协议定其物理地址的一种协议。
因IPv4和以太网的广泛应用,其主要用作将IP地址翻译为以太网的MAC地址,但其也能在ATM( 异步传输模式)和FDDIIP(Fiber Distributed Data Interface 光纤分布式数据接口)网络中使用。
从IP地址到物理地址的映射有两种方式:表格方式和非表格方式。
ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址。
在TCP/IP协议中,A给B发送IP包,在报头中需要填写B的IP为目标地址,但这个IP包在以太网上传输的时候,还需要进行一次以太包的封装,在这个以太包中,目标地址就是B的MAC地址.
计算机A是如何得知B的MAC地址的呢?解决问题的关键就在于ARP协议。
在A不知道B的MAC地址的情况下,A就广播一个ARP请求包,请求包中填有B的IP(192.168.1.2),以太网中的所有计算机都会接收这个请求,而正常的情况下只有B会给出ARP应答包,包中就填充上了B的MAC地址,并回复给A。
A得到ARP应答后,将B的MAC地址放入本机缓存,便于下次使用。
本机MAC缓存是有生存期的,生存期结束后,将再次重复上面的过程。
ARP协议并不只在发送了ARP请求才接收ARP应答。当计算机接收到ARP应答数据包的时候,就会对本地的ARP缓存进行更新,将应答中的IP和MAC地址存储在ARP缓存中。因此,当局域网中的某台机器B向A发送一个自己伪造的ARP应答,而如果这个应答是B冒充C伪造来的,即IP地址为C的IP,而MAC地址是伪造的,则当A接收到B伪造的ARP应答后,就会更新本地的ARP缓存,这样在A看来C的IP地址没有变,而它的MAC地址已经不是原来那个了。由于局域网的网络流通不是根据IP地址进行,而是按照MAC地址进行传输。所以,那个伪造出来的MAC地址在A上被改变成一个不存在的MAC地址,这样就会造成网络不通,导致A不能Ping通C!这就是一个简单的ARP欺骗。
#include <stdio.h>#include <windows.h>#include <Iphlpapi.h>#pragma comment(lib, "Iphlpapi.lib")#pragma comment(lib, "WS2_32.lib")PMIB_IPNETTABLE MyGetIpNetTable(BOOL bOrder);void MyFreeIpNetTable(PMIB_IPNETTABLE pIpNetTable);PMIB_IPADDRTABLE MyGetIpAddrTable(BOOL bOrder);void MyFreeIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable);BOOL InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable, DWORD dwIndex, char str[]);// 根据IP地址表,将接口索引转化为IP地址// pIpAddrTable是IP地址表// dwIndex是接口索引// 函数执行成功之后,str将包含接口的IP地址BOOL InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable, DWORD dwIndex, char str[]){ char* szIpAddr; if(pIpAddrTable == NULL || str == NULL) return FALSE; str[0] = '\0';// 遍历IP地址表,查找索引dwIndex对应的IP地址 for(DWORD dwIdx = 0; dwIdx < pIpAddrTable->dwNumEntries; dwIdx++) { if(dwIndex == pIpAddrTable->table[dwIdx].dwIndex) {// 以字符串的形式返回查询结果 szIpAddr = inet_ntoa(*((in_addr*)&pIpAddrTable->table[dwIdx].dwAddr)); if(szIpAddr) { strcpy(str, szIpAddr); return TRUE; } else return FALSE; } } return FALSE;}//----------------------------------------------------------------------------// ARP表将以如下格式打印出来:// Interface: 157.61.239.34 on Interface 2// Internet Address Physical Address Type// 159.61.230.39 00-aa-00-61-5d-a4 dynamic//// Interface: 157.54.178.219 on Interface 3// Internet Address Physical Address Type// 159.54.170.1 00-10-54-42-c0-88 dynamic// 159.54.170.113 00-aa-00-c0-80-2e dynamic//----------------------------------------------------------------------------int main(){ DWORD i, dwCurrIndex; char szPrintablePhysAddr[256]; char szType[128]; char szIpAddr[128];// 首先获取ARP表PMIB_IPNETTABLE pIpNetTable = MyGetIpNetTable(TRUE); if (pIpNetTable == NULL) { printf( "pIpNetTable == NULL in line %d\n", __LINE__); return -1; }// 获取IP地址表,以便根据它将ARP表项中的接口索引转化为IP地址PMIB_IPADDRTABLE pIpAddrTable = MyGetIpAddrTable(TRUE);// 当前的适配器索引。注意,ARP表应该按照接口索引排序 dwCurrIndex = pIpNetTable->table[0].dwIndex; if(InterfaceIdxToInterfaceIp(pIpAddrTable, dwCurrIndex, szIpAddr)) { printf("\nInterface: %s on Interface 0x%X\n", szIpAddr, dwCurrIndex); printf(" Internet Address Physical Address Type\n"); } else { printf("Error: Could not convert Interface number 0x%X to IP address.\n", pIpNetTable->table[0].dwIndex); return -1; } // 打印出索引为dwCurrIndex的适配器上的ARP表项 for(i = 0; i < pIpNetTable->dwNumEntries; ++i) {// 不相等则说明要打印下一个适配器上的ARP表项了 if(pIpNetTable->table[i].dwIndex != dwCurrIndex) { dwCurrIndex = pIpNetTable->table[i].dwIndex; if (InterfaceIdxToInterfaceIp(pIpAddrTable, dwCurrIndex, szIpAddr)) { printf("Interface: %s on Interface 0x%X\n", szIpAddr, dwCurrIndex); printf(" Internet Address Physical Address Type\n"); } else { printf("Error: Could not convert Interface number 0x%X to IP address.\n", pIpNetTable->table[0].dwIndex); return -1; } }// 打印出此ARP表项中的数据// MAC地址u_char *p = pIpNetTable->table[i].bPhysAddr; wsprintf(szPrintablePhysAddr, "%02X-%02X-%02X-%02X-%02X-%02X", p[0], p[1], p[2], p[3], p[4], p[5]);// IP地址struct in_addr inadTmp; inadTmp.s_addr = pIpNetTable->table[i].dwAddr;// 类型 switch (pIpNetTable->table[i].dwType) { case 1: strcpy(szType,"other"); break; case 2: strcpy(szType,"invalidated"); break; case 3: strcpy(szType,"dynamic"); break; case 4: strcpy(szType,"static"); break; default: strcpy(szType,"invalidType"); } printf(" %-16s %-17s %-11s\n", inet_ntoa(inadTmp), szPrintablePhysAddr, szType); }return 0;}// 获取IP地址到适配器的映射关系,即ARP表PMIB_IPNETTABLE MyGetIpNetTable(BOOL bOrder){PMIB_IPNETTABLE pIpNetTable = NULL;DWORD dwActualSize = 0;// 查询所需缓冲区的大小if(::GetIpNetTable(pIpNetTable, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER){// 为MIB_IPNETTABLE结构申请内存pIpNetTable = (PMIB_IPNETTABLE)::GlobalAlloc(GPTR, dwActualSize);// 获取ARP表if(::GetIpNetTable(pIpNetTable, &dwActualSize, bOrder) == NO_ERROR){return pIpNetTable;}::GlobalFree(pIpNetTable);}return NULL;}void MyFreeIpNetTable(PMIB_IPNETTABLE pIpNetTable){if(pIpNetTable != NULL)::GlobalFree(pIpNetTable);}PMIB_IPADDRTABLE MyGetIpAddrTable(BOOL bOrder){PMIB_IPADDRTABLE pIpAddrTable = NULL;DWORD dwActualSize = 0;// 查询所需缓冲区的大小if(::GetIpAddrTable(pIpAddrTable, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER){// 为MIB_IPADDRTABLE结构申请内存pIpAddrTable = (PMIB_IPADDRTABLE)::GlobalAlloc(GPTR, dwActualSize);// 获取IP地址表if(::GetIpAddrTable(pIpAddrTable, &dwActualSize, bOrder) == NO_ERROR)return pIpAddrTable;::GlobalFree(pIpAddrTable);}return NULL;}void MyFreeIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable){if(pIpAddrTable != NULL)::GlobalFree(pIpAddrTable);}/*void PrintIpAddrTable(){ DWORD i; struct in_addr inadTmp1; struct in_addr inadTmp2; char szAddr[128]; char szMask[128];PMIB_IPADDRTABLE pIpAddrTable = MyGetIpAddrTable(TRUE); if (pIpAddrTable == NULL) { printf( "pIpAddrTable == NULL in line %d\n", __LINE__); return; } printf("ipAdEntAddr\t ifAdEntIfIndex\t ipAdEntNetMask\t ipAdEntBcastAddr\t ipAdEntReasmMaxSize\n"); for (i = 0; i < pIpAddrTable->dwNumEntries; ++i) { inadTmp1.s_addr = pIpAddrTable->table[i].dwAddr; strcpy(szAddr, inet_ntoa(inadTmp1)); inadTmp2.s_addr = pIpAddrTable->table[i].dwMask; strcpy(szMask, inet_ntoa(inadTmp2)); printf(" %s\t 0x%X\t %s\t %s\t %u\n", szAddr, pIpAddrTable->table[i].dwIndex, szMask, (pIpAddrTable->table[i].dwBCastAddr ? "255.255.255.255" : "0.0.0.0"), pIpAddrTable->table[i].dwReasmSize); }MyFreeIpAddrTable(pIpAddrTable);} */
- VC++实现IP与ARP信息获取,可以同理实现APR攻击
- ARP攻击实现方案
- VC++基于winpcap实现ARP攻击禁止访问相关网站
- IP探测实现 ARP与设备发现
- kali 实现arp攻击和arp欺骗
- VC++实现ARP协议
- VC++实现ARP协议
- 手工实现ARP中间人攻击
- ARP攻击及实现详解
- 局域网内实现ARP攻击
- scapy实现arp 毒化攻击
- Linux系统ARP攻击的实现与防范
- localtime函数可以实现获取时间信息
- 封装一个Button的角标类(Image等同理可以实现)
- 获取其他程序的信息(VC实现)
- VC++实现获取本地主机网卡信息
- VC++ 实现获取路由表信息
- 获取其他程序的信息(VC实现)
- c语言 正则表达式可编译c文件
- VC++实现遍历所有进程的TCP与UDP链接
- UVa 10267-Graphical Editor
- H264 Over RTP
- 算法之美——求解 字符串间最短距离(动态规划)
- VC++实现IP与ARP信息获取,可以同理实现APR攻击
- Android编译大全
- 如何成为一个出色的网站架构师
- Thrift入门教程
- jQuery的图片/文字无缝滚动
- android驱动
- python函数引用传递测试
- Eclipse快捷键大全
- CS与BS区别