Sniffer has always been an annoyed hacker tool because it is a static attack software, and its existence will not leave any traces, so people are hard to pull it out. However, its harm is quite large (it is like a monitors, your "one move" is under its monitoring, you said that the harm is great). So, we can't think of a way to check if there is Sniffer in the network, which is very necessary.
1. The Sniffer principle The so-called understanding of each other can do it, you have to know how to detect Sniffer, first you first understand the principle of Sniffer. First, let's take a look at how to transfer data in the local area network. When a packet's destination is a computer within a local area network, this packet will be sent to each computer in the form of the network. And each computer's network card will analyze the destination MAC address (ie Ethernet address) in the packet. If this address is the computer MAC address or a broadcast address (FF-FF-FF-FF-FF), then, The packet will be received, and if not, the NIC will discard it directly. However, there is a premise here that the network card of the receiving end computer is working in normal mode. If the NIC is set to a mixed mode, then it can receive all passed packets (of course, including the destination is not a local data package). That is, as long as it is a packet sent to the LAN, it will be set to the network card of the mixed mode! This is the basic principle of SNIFFER. As for the specific implementation of Sniffer and some details, there is not much to talk about it. Everyone is interested in referring to the relevant information.
2. The ARP datagram transmitted in Ethernet knows the basic principle of Sniffer. Now, we must think about how to hide the Sniffer hidden in the LAN, this is the theme of this article. Here, we need to construct an ARP packet, so you will briefly introduce the structure of the ARP request and response datagram:
Typedef struct _t_header // Ethernet head {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_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; the above is the structure of the ARP packet transmitted in the network. As for the specific meaning of each field in the structure and how to initialize, beyond the scope of this article, everyone is interested in seeing the "TCP-IP Protocol Detail" book.
3. Probe into the Sniffer in the LAN finally entered the topic. Since SNIFFER is a static black soft, we will not leave any log, then we have to take the initiative to detect it. Given the principle of Sniffer is to set the network card as a mixed mode, then we can find a network card set to a mixed mode in the network to determine if there is a Sniffer. Here, let's take a look at the rules of the computer to receive the packet. As mentioned earlier, in normal mode, first determine the Package of the data packet by the NIC, if a local MAC address or a broadcast address, the packet will be received into the system core, otherwise it will be discarded. And if the NIC is set to a mixed mode, all packets will directly enter the system core. After the packet reaches the system core, the system will further filter the packet: The system will only respond to the destination MAC address as a local MAC address or a broadcast address, and if the received ARP request message, Then the system will feed back an ARP response message. However, the system core and network cards are somewhat different from the broadcast address: Taking the Windows system as an example, the NIC will determine all six digits of the MAC address, and the system core only determines the first two digits of the MAC address (Win98 or even only Judging the previous one), that is, for the system core, the correct broadcast address FF-FF-FF-FF-FF and the error broadcast address FF-FF-FF-FF-FF-FE is the same It is considered to be broadcast addresses, even FF-FF-00-00-00-00 will also be considered broadcast addresses by the system! Writing here, smart readers have probably know what to do. If we construct a destination MAC address as the ARP request message of the FF-FF-FF-FF-FE, then for the NIC in normal mode of operation, the packet will be discarded, of course, will not give back any report. Text; and for network cards in mixed mode, packets will be received into the system core. The system is attentive that this MAC address is a broadcast address, so it will feed back an ARP response message. In this way, we can judge that there is Sniffer on this machine. 4. The main source code analysis is known from the above analysis, the program is probably divided into two modules, one is an ARP request message that sends a camouflage broadcast address, and the other is the ARP response message that receives the feedback and analyzes. We use two threads separately. The main thread is responsible for sending, listening threads are responsible for receiving.
The first is the structure of the Ethernet head and the ARP header:
★ typedef struct_t_header // Ethernet head {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_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; ★
Then, the main thread that sends an ARP request message and obtains the name of all adapters. Among them, "adapter_name" represents a buffer for storing the name of the adapter, and these adapter names are stored in this buffer in Unicode encoding. The Unicode encoding method is to store a character with a word (two bytes). In this way, one '/ 0' will naturally appear between each character. There will be a word '/ 0' between the two adapter names. Adapter_length: This buffer size: ★ if (packetGetadapter_name, & adapter_length) == false) {printf ("packetGetAdapternames error:% d / n", getLastError ()); return 0;} ★
Open the adapter, here I open the first adapter by default:
★ lpAdapter = (LPADAPTER) PacketOpenAdapter ((LPTSTR) adapter_list [0]); if {printf ( "Unable to open the driver, Error Code (lpAdapter || (lpAdapter-> hFile == INVALID_HANDLE_VALUE)!):% Lx / n ", GetLastError ()); return 0;} ★
The Ethernet head and the ARP head structure are assigned, and the Strtomac function is a function that the author's custom string is converted to the MAC address:
★ STRTOMAC ("00E06E41508F", S_MAC); // "00E06E41508F" is the network card address of the author used by the author test program, the tester should change it to the test network card address Memcpy (et_header.eh_src, s_mac, 6); startACAC ("Fffffffffffffe", d_mac); // The destination physical address is set to fffffffffe. Memcpy (et_header.eh_dst, d_mac, 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 is IP protocol ARP_HEADER.ARP_HLN = 6; // Hardware address length is 6ARP_HEADER.ARP_PLN = 4; // Protocol address length is 4ARP_HEADER.ARP_OPT = HTONS (0x0001); // Identification Request arp_header.arp_spa = inet_addr ("172.24.21.10") for ARP ("172.24.24.21.10" is the IP of the local machine used by my test program, the tester should change it to the test machine ipmemcpy (arp_header.arp_sha, et_header .e_src, 6); arp_header.arp_tpa = inet_addr (argv [1]); memcpy (arp_header.arp_tha, et_header.eh_dst, 6); ★
Send a packet:
★ lppacket = packetAllocatePacket (); // Assign memory packetinitpacket (LPPACKET, BUFER, 512) to Packet Structure Pointer; // Initializing Packet Structure Pointer PacketSetNumWrites (LPADAPTER, 5); // Settings PacketsendPacket (LPADAPTER, LPPACKET, TRUE) ; // Send ARP Request Pack ★ Don't forget to sweep the tail:
★ PacketFreePacket (LPPACKET); // Release Packet Structure Pointer PacketCloseadapter (LPADAPTER); // Close Adapter ★
Finally, the listening thread: Set the series parameters for receiving the packet:
★ PacketSethWFilter (LPADAPTER, NDIS_PACKET_TYPE_DIRECTED); // Setting the network card to Direct mode PacketSetBuff (LPADAPTER, 1024); // Set the network card to receive the buffer size PacketSetReadTimeout (LPADAPTER, 2); // Setting up the package " Rest "time ★
Receive data packets:
★ PacketReceivePacket (LPADAPTER, LPPACKET, TRUE); // Received Packet ★
Analyze packets to draw conclusions:
★ 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 (0x0806)) // determined if the ARP package {ARP_HEADER * LPARPHDR = (ARP_HEADER *) (BUF LPBPFHDR-> BH_HDRLEN SIZEOF (ET_HEADER)); char Source_ip [ 20] = {0}, dest_ip [20] = {0}; addr.s_un.s_addr = lparphdr-> arp_spa; memcpy (Source_IP, INET_NTOA (AddR), Strlen (inet_ntoa (addr))); MEMSET (& addr, 0 SIZEOF (IN_ADDR)); addr.s_un.s_addr = lparphdr-> arp_tpa; memcpy (dest_IP, inet_ntoa (addr), strlen (inet_itoa (addr))); if (! Strcmp (Source_IP, IP) &&! strcmp (dest_ip) "172.24.21.10")) // Determine whether the source IP of the received packet and the destination IP is correct (string variable IP is the detector of the detector passing from the main thread) {if (lparphdr-> arp_opt == HTONS (0x0002)) // Judgment is ARP Answer {Printf ("TheRe IS A Sniffer! / N");}}} ★
5. The end is really a so-called one thing, although Sniffer is powerful, but we finally found the way to crack it. Due to this principle, software Anti-Sniff came into being. Of course, this procedure I wrote can be said to be a little witch than Anti-Sniff, but it does not leave its profile, and their basic principles are the same.