標籤:style class code http tar color
大家知道,乙太網路採用廣播機制,所有與網路連接的工作站都可以看到網路上傳遞的資料。通過查看包含在幀中的目標地址,確定是否進行接收或放棄。如果證明資料確實是發給自己的,工作站將會接收資料並傳遞給高層協議進行處理。但是,如果讓網卡置於混雜模式(Promiscuous mode),則網卡不會鑒別幀的MAC地址,而是一律接收。
給出了乙太網路的框架格式,網卡是通過圖中的MAC地址進行ID標識的。傳說中的網路嗅探(sniffer)就是指讓網卡進入混雜模式從而接收正在區域網路匯流排上發送的所有報文。為什麼能夠嗅探到區域網路上的所有報文,是因為基於IEEE 802.3的乙太網路在MAC層採用廣播方式發送幀。因此,從理論上來講,我們可以編寫駭客程式監聽區域網路上的所有資訊。QQ、MSN監聽軟體就是基於這一機理的,它可以監聽區域網路上所有使用者的QQ、MSN聊天記錄。
為了實現sniffer,我們應首先讓網卡進入混雜模式並建立和設定原始通訊端為親自處理前序:
//初始化SOCKET WSADATA wsaData; iErrorCode = WSAStartup(MAKEWORD(2, 1), &wsaData); CheckSockError(iErrorCode, "WSAStartup"); SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP); CheckSockError(SockRaw, "socket"); //擷取本機IP地址 char name[MAX_HOSTNAME_LAN]; iErrorCode = gethostname(name, MAX_HOSTNAME_LAN); CheckSockError(iErrorCode, "gethostname"); struct hostent *pHostent; pHostent = (struct hostent*)malloc(sizeof(struct hostent)); pHostent = gethostbyname(name); SOCKADDR_IN sa; sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); iErrorCode = bind(SockRaw, (PSOCKADDR) &sa, sizeof(sa)); CheckSockError(iErrorCode, "bind"); //設定SOCK_RAW為SIO_RCVALL,以便接收所有的IP包 DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; iErrorCode = WSAIoctl(SockRaw, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen) , &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL); CheckSockError(iErrorCode, "Ioctl"); |
下面就可以接收並處理IP報文:
//偵聽IP報文 while (1) { memset(RecvBuf, 0, sizeof(RecvBuf)); iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0); CheckSockError(iErrorCode, "recv"); iErrorCode = DecodeIpPack(RecvBuf, iErrorCode); CheckSockError(iErrorCode, "Decode"); } |
Sniffer程式接收到報文後,即可調用相應的程式來分析具體的報文。
對於sniffer我們不得不說的是,僅僅將網卡置於混雜模式並不能保證我們能嗅探到交換式區域網路上的所有幀,因為交換式區域網路已經不再是廣播式/匯流排傳輸了,為了能嗅探到交換式區域網路上的幀,我們需要採用另一項技術ARP欺騙。