[SOLUCIONADO] Ayuda con analisis, ideas u otras formas de escaneo para red local

Iniciado por proxy_lainux, Enero 25, 2014, 02:29:53 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

hola

Estoy intentando hacer un codigo para analizar redes locales basandome en el codigo "arptool" de Cristiano Lincoln Mattos, ya logre entender parte del codigo despues de estar  buscando en google algunas estructuras y funciones, y tambien ya logre hacer funcionar un codigo hecho por mi pero solo logro saber la ip, netmask y Mac address de mi computadora

viendo mas su codigo el manda peticiones arp para sacar la informacion de las demas computadoras conectadas como la ip, netmask y mac address... algo parecido a lo que hace nmap con el comando -sP que te dice que computadoras estan activas

pero aqui es donde tengo el problema...  recuerdo que hace un tiempo cuando encontre por primera ves arptool, lo compile y funcionaba bien, a veces tenia sus pequeños fallos pero me daba la informacion de las ip locales

ahora lo volvi a encontrar, lo compile pero ya no me muestra las demas ip's mas que la mia, asi que ya no se si todavia funcione

me gustaria saber si alguien de aqui me podria dar ideas para lograr scanear las redes locales y encontrar la misma infomacion  "ip, netmask y mac address", o si podrian ayudarme a analizar el codigo y que me puedan decir porque ya no funciona bien el codigo ó que me puedan explicar algunas funciones que no logre entender, seria de bastante ayuda

ya entendi la mayoria pero hay parte del codigo que ya no logre entender, por ejemplo, la funcion str_to_hwaddr, la funcion hexstr_to_int y ya casi le entiendo a la funcion add_to_list que sera casi lo ultimo, porque la funcion show_list es solo para mandar a la consola la informacion guardada en las estructuras y sendarp  es la funcion send y recv para mandar los paquetes y lo demas ya lo tengo entendido bien.

espero me puedan ayudar, dejo el codigo

Código: c
/* 
*      ARPTool v0.1, (c) Cristiano Lincoln Mattos, 1999 - <[email protected]>
*
*      - Compiled and tested on Linux 2.0.33, 2.0.35, 2.0.36, libc5 & glibc. 
*        Will port to Solaris 2.5.1 as soon as i have time.
*      - For usage, run it without arguments.
*      - If you dont know what this is for, or what you can do with it,
*        read yuri volobuev's excellent bugtraq post about ARP spoofing
*        (available from the bugtraq archives).
*      - The netmap results depend on the network latency.. try adjusting the
*        usleep() delay, if you think it's too small/big.
*      - The latest version will be always at
*              http://www.hotlink.com.br/users/lincoln/arptool
*      - Some code borrowed from neped (apostols.org), thanks.
*     
*      #include <stddisclaimer.h>
*
*      CHANGELOG:
*         09/12/98 - General code cleanup.
*         07/12/98 - Removed the option for hiding in the process list, and
*                    double mode: didn't work as expected, stupid oversight.
*         29/12/98 - Better display of MAC's with more than one IP (proxy
*                    arp or virtual interfaces).
*         28/12/98 - Added check for arp reply being to source ip (netmap).
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <linux/if_ether.h>
#include <unistd.h>
#include <fcntl.h>

#define ARP_ETHER       1
#define ARP_REQUEST     1
#define ARP_REPLY       2

/* Structures */
struct pkt_struct {
        unsigned char eth_dst[6];
        unsigned char eth_src[6];
        unsigned short eth_proto;
        unsigned short int arp_hw_type;
        unsigned short int arp_proto;
        unsigned char arp_hw_len;
        unsigned char arp_proto_len;                    // proto is IP.
        unsigned short arp_oper;
        unsigned char arp_hw_src[6];
        unsigned char arp_ip_src[4];
        unsigned char arp_hw_dst[6];
        unsigned char arp_ip_dst[4];
};

struct spoof_struct {
        unsigned char hw_src[6];
        unsigned char hw_dst[6];
        unsigned long int ip_src;
        unsigned long int ip_dst;
        unsigned short op;
};

/* List structures */
struct iplist_struct {
        unsigned long int ip;
        struct iplist_struct * next;
};

struct list_struct {
        unsigned char hw[ETH_ALEN];
        struct iplist_struct * iplist;
        struct iplist_struct * lastip;
        struct list_struct * next;
} * head = NULL, * tail = NULL;

/* Functions */
char * hwaddr_to_str (unsigned char * str);
unsigned char * str_to_hwaddr (char * str);
unsigned int hexstr_to_int (char *cptr);
void netmap (int fd, unsigned long int start_ip);
void usage (char * av, int mode);
void add_to_list (unsigned long int ip, unsigned char * hw);
void show_list ();

/* Global variables */
unsigned long netmask, broadcast;                       /* struct in_addr */
unsigned char hwaddr[ETH_ALEN];
struct sockaddr sock;
int verbose = 0;

void sendarp (int fd, unsigned char * h_source, unsigned char * h_dest, \
                      unsigned char * arp_src, unsigned char * arp_dst, \
                      unsigned long int ip_source, unsigned long int ip_dest, unsigned char op) {
        struct pkt_struct pkt;

        // Ethernet header.
        memcpy(&pkt.eth_dst,h_dest,ETH_ALEN);
        memcpy(&pkt.eth_src,h_source,ETH_ALEN);
        pkt.eth_proto = htons(ETH_P_ARP);
        // ARP header.
        pkt.arp_hw_type = htons(ARP_ETHER);
        pkt.arp_proto = htons(ETH_P_IP);
        pkt.arp_hw_len = ETH_ALEN;
        pkt.arp_proto_len = 4;
        pkt.arp_oper = htons(op);

        if (arp_src==0) bzero(&pkt.arp_hw_src,ETH_ALEN);
                else memcpy(&pkt.arp_hw_src,arp_src,ETH_ALEN);
        if (arp_dst==0) bzero(&pkt.arp_hw_dst,ETH_ALEN);
                else memcpy(&pkt.arp_hw_dst,arp_dst,ETH_ALEN);

        memcpy(&pkt.arp_ip_src,&ip_source,4);
        memcpy(&pkt.arp_ip_dst,&ip_dest,4);

        if ( (sendto(fd,&pkt,sizeof(pkt),0,&sock,sizeof(sock))) < 0) perror("Error sending ARP");

       

}

void netmap (int fd, unsigned long int start_ip) {
        unsigned long int ip, ip_s;
        struct pkt_struct * pkt;
        int i;

        ip_s = start_ip;
        ip = ip_s & netmask;

        i = fcntl(fd,F_GETFL);
        if ((fcntl(fd,F_SETFL, i | O_NONBLOCK))<0) {
                perror("FCNTL"); exit (1);
        }

        pkt = (struct pkt_struct *) malloc(sizeof(struct pkt_struct));
        bzero(pkt,sizeof(struct pkt_struct));

        printf(" - Mapping network... \n");
        while (ip < broadcast) {
                unsigned long int iptmp;
                unsigned char hwa[ETH_ALEN];
                ip = ntohl(ip);
                ip = htonl(++ip);

                sendarp(fd,hwaddr,str_to_hwaddr("FF:FF:FF:FF:FF:FF"),hwaddr,0,ip_s,ip,ARP_REQUEST);
                usleep(1000);

                i = sizeof(sock);
                bzero(pkt,sizeof(struct pkt_struct));
                if ((recvfrom(fd,pkt,sizeof(struct pkt_struct),0,&sock,&i)) < 0) continue;

                memcpy(&iptmp,pkt->arp_ip_dst,4);
                if ((iptmp!=ip_s) || (ntohs(pkt->arp_oper)!=ARP_REPLY)) continue;               
                memcpy(&iptmp,pkt->arp_ip_src,4);
                add_to_list(iptmp,pkt->eth_src);
        }
        show_list();
        free (pkt);
}
       

void main (int argc, char ** argv) {
        struct ifreq ifr;
        struct sockaddr_in sin;
        struct spoof_struct sp;
        unsigned long int ip;
        int fd, ret;
        int i = 0, map = 0, spoof = 0, interval = 0;
        char * dev;

        // Parsing the arguments.
        if (argc < 2) { usage(argv[0],0); exit(1); }
       
        usage(argv[0],1);
        dev = (char *) malloc(6); strncpy(dev,"wlan0",5);
        while ((i = getopt(argc, argv, "dc:vmi:s:")) != EOF) {
                switch (i) {
                        case 'm': map = 1; continue;
                        case 'v': verbose = 1; continue;
                        case 'i': dev = optarg; continue;
                        case 'c': interval = atoi(optarg); continue;
                        case 's': spoof = optind-1; continue;
                        case '?': exit(1);
                        default: usage(argv[0],0); exit;
                }
        }
        if ((map) && (spoof)) {
                printf(" Error: cannot run in map mode (-m) and spoof mode (-s) simultaneously.\n");
                exit(1);
        }
        if ((!map) && (!spoof)) {
                printf(" Error: map mode (-m) or spoof mode (-s) must be specified.\n");
                exit(1);
        }
        if (spoof) {
                unsigned long int ips;
                int origspoof = spoof;

                spoof = optind;
                if ((!argv[origspoof]) || (!argv[spoof]) || (!argv[spoof+1]) || (!argv[spoof+2]) || (!argv[spoof+3])) {
                        printf(" Error: spoof (-s) requires five arguments: \n");
                        exit(1);
                }

                ips = atoi(argv[spoof+3]);
                if ( (ips!=1) && (ips!=2) ) {
                        printf(" Erro: wrong arp operation.  Must be 1 for request or 2 for reply. \n");
                        exit(1);
                }
                memcpy(&sp.hw_src,str_to_hwaddr(argv[origspoof]),ETH_ALEN);
                memcpy(&sp.hw_dst,str_to_hwaddr(argv[spoof++]),ETH_ALEN);               
                ips= inet_addr(argv[spoof++]);
                memcpy(&sp.ip_src,&ips,4);
                ips = inet_addr(argv[spoof++]);
                memcpy(&sp.ip_dst,&ips,4);
                ips = atoi(argv[spoof]);
                memcpy(&sp.op,&ips,1);
        }


        // Setting up the sockets, interface, and getting data.
        strcpy(sock.sa_data,dev);
        sock.sa_family = AF_INET;
        fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ARP));
        if (fd==-1) {
                perror("Socket: "); exit (1);
        }

        // HW Addr.
        strcpy(ifr.ifr_name,dev);
        ret = ioctl(fd,SIOCGIFHWADDR,&ifr);
        if (ret==-1) {
                perror("Error getting HW Address"); exit (1);
        }
        memcpy(hwaddr,ifr.ifr_hwaddr.sa_data,ETH_ALEN);

        // IP.
        ret = ioctl(fd,SIOCGIFADDR,&ifr);
        if (ret==-1) {
                perror("Error getting IP Address"); exit (1);
        }
        memcpy(&sin,&ifr.ifr_addr,sizeof(struct sockaddr_in));
        ip = sin.sin_addr.s_addr;

        // Netmask.
        ret = ioctl(fd,SIOCGIFNETMASK,&ifr);
        if (ret==-1) {
                perror("Error getting netmask"); exit (1);
        }
        memcpy(&sin,&ifr.ifr_netmask,sizeof(struct sockaddr_in));
        netmask = sin.sin_addr.s_addr;
//      netmask = 16777215;             // 24 bit Netmask

        // Broadcast.
        ret = ioctl(fd,SIOCGIFBRDADDR,&ifr);
        if (ret==-1) {
                perror("Error getting broadcast"); exit (1);
        }
        memcpy(&sin,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in));
        broadcast = sin.sin_addr.s_addr;

printf("- Hardware Address: %s\n", hwaddr_to_str(hwaddr));
    printf("- Interface IP: %s (%s)\n", inet_ntoa(*(struct in_addr*)&ip), dev);
printf("- Netmask: %s\n", inet_ntoa(*(struct in_addr*)&netmask));
printf("- Brodcast: %s\n\n", inet_ntoa(*(struct in_addr*)&broadcast));

        while (1) {
                if (map) netmap (fd,ip);
                if (spoof) {
                        sendarp(fd,sp.hw_src,sp.hw_dst,sp.hw_src,sp.hw_dst,sp.ip_src,sp.ip_dst,sp.op);
                }
                if (interval) sleep(interval);
                        else break;
        }
}


char * hwaddr_to_str (unsigned char * str) {
        static char tmp[20];
        sprintf(tmp,"%02X:%02X:%02X:%02X:%02X:%02X",str[0],str[1],str[2],str[3],str[4],str[5]);
        return tmp;
}

unsigned int hexstr_to_int(char *cptr) {
      unsigned int i, j = 0;
       
      while (cptr && *cptr && isxdigit(*cptr)) {
            i = *cptr++ - '0';
            if (9 < i) i -= 7;
            j <<= 4;
            j |= (i & 0x0f);
      }
      return(j);
}       

unsigned char * str_to_hwaddr (char * str) {
        unsigned char tmp[2], strbuf[17], t[2];
        static unsigned char * buf, * tt;
        int e, i;

        buf = (unsigned char *) malloc(6);
        bzero(t,2); bzero(tmp,2); bzero(strbuf,17); bzero(buf,6);
        strncpy(strbuf,str,17); strbuf[17]='\0';
        tt = buf;
       
        e = 0;
        for (i=0; i < strlen(strbuf); i++) {
                if ((strbuf[i]==':') && (e==0)) continue;
                tmp[e] = strbuf[i]; e++;
                if (e==2) {
                        unsigned int a;
                        a = hexstr_to_int(tmp);
                        memcpy(tt,&a,1); tt++;
                        bzero(tmp,2); e = 0;
                }
        }
        return buf;
}

void usage (char * av, int mode) {
        printf(" ARPTool v0.1, (c) Cristiano Lincoln Mattos, 1999.  <[email protected]> \n");
        if (!mode) {
                printf(" Sintax: %s [-i interface] [-m] [-c] [-s hwsrc hwdest ipsrc ipdst op]\n",av);
                printf("         -i interface: use this interface.  If ommited, default to eth0\n");
                printf("         -m: network map mode.  Will identify all hosts on the same \n                  cable segment. \n");
                printf("         -s src_hwaddress dst_hwaddress src_ipaddress dst_ipaddress operation:\n");
                printf("            send arbitrary ARP packets.  The hardware address must be \n                specified in the usual form, i.e. 00:00:FD:FF:1E:C1.\n                  Operation is 1 for ARP request, 2 for ARP reply. \n");
                printf("         -c interval: continuous mode.  Will keep sending the specified \n              packets every interval seconds (requires -s or -m).\n");
                exit(1);
        }
}       


void show_list () {
        struct list_struct * tmp, * tmp2;
        tmp = head;
        while (tmp!=NULL) {
                struct iplist_struct * iptmp;
                iptmp = tmp->iplist;
                printf(" -- HW Address: %s",hwaddr_to_str(tmp->hw));
                if (iptmp->next) printf(" - Several IP's: probably router with proxy arp, or virtual interfaces.\n");
                while (iptmp!=NULL) {
                        printf("            IP: %s\n",inet_ntoa(*(struct in_addr*)&iptmp->ip));
                        iptmp = iptmp->next;
                }
                free(iptmp); tmp2 = tmp->next;
                free(tmp); tmp = tmp2;
        }
        return;
}
             

void add_to_list (unsigned long int ip, unsigned char * hw) {
        struct list_struct * tmp;
        struct iplist_struct * iptmp;
        tmp = head;
        while (tmp) {
                if ((hw[0]==tmp->hw[0]) && (hw[1]==tmp->hw[1]) && (hw[2]==tmp->hw[2]) && (hw[3]==tmp->hw[3]) &&\
                        (hw[4]==tmp->hw[4]) && (hw[5]==tmp->hw[5])) break;
                tmp = tmp->next;
        }
        if (!tmp) {                     // If it's the first HW entry, or did not find HW in list, create
                if ((tmp = (struct list_struct *) malloc(sizeof(struct list_struct))) == NULL) {
                        printf("\n malloc error. \n"); exit (1);
                }
                if ((iptmp = (struct iplist_struct *) malloc(sizeof(struct iplist_struct))) == NULL) {
                        printf("\n malloc error. \n"); exit (1);
                }
                iptmp->ip = ip;
                iptmp->next = NULL;
                tmp->iplist = iptmp;           
                tmp->lastip = iptmp;
                tmp->next = NULL;
                memcpy(tmp->hw,hw,ETH_ALEN);
                if (tail) {
                        tail->next = tmp;
                        tail = tmp;
                }
        } else {                        // Found the HW entry in the list, just add the IP.
                if ((iptmp = (struct iplist_struct *) malloc(sizeof(struct iplist_struct))) == NULL) {
                        printf("\n malloc error. \n"); exit (1);
                }
                iptmp->ip = ip;
                iptmp->next = NULL;
                tmp->lastip->next = iptmp;
                tmp->lastip = iptmp;
        }
        if (!head) head = tail = tmp;
}



Yo también me quede en esta parte. Hace ya tiempo que no programo en c pero el último proyecto que quería hacer era relacionado con el manejo de interfaces y enviar paquetes. Pero no conseguí entender del todo bien las estructuras que usa el kernel.

El documento que yo "intente" entender fue:
No tienes permitido ver enlaces. Registrate o Entra a tu cuenta

Se agradece si alguien ayuda.