/************************************************************************ * proscan.c PROMISC Ethernet Scanner * * * * Questo tool permette la scansione di un LAN * * alla ricerca di interfacce di rete in modalita' * * promiscua. L'effetto viene ottenuto mediante * * utilizzo di query 'anomale'. * * Per la spiegazione vedere l'articolo " TCP/IP * * Hacks For Phun And Profit" su BFi5. * * BFi e' disponibile al seguente URL: * * http://softpj98.bbk.org/bfi/ * * * * OS: Linux (SOCK_PACKET) * * Credits: Apostols, comp.security.unix, vari sniffer :) * * * * NO(C)1998 FuSyS TCP/IP Tools Unlimited * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_LEN 1500 #define IF_LEN 14 #define IP_ALEN 4 #define IP_HLEN 20 #define ICMP_HLEN 8 struct arp_hack { unsigned char h_dest[ETH_ALEN]; unsigned char h_source[ETH_ALEN]; unsigned short h_proto; unsigned short ar_hrd; unsigned short ar_pro; unsigned char ar_hln; unsigned char ar_pln; unsigned short ar_op; unsigned char ar_sha[ETH_ALEN]; unsigned char ar_sip[IP_ALEN]; unsigned char ar_tha[ETH_ALEN]; unsigned char ar_tip[IP_ALEN]; }; struct pinghack { unsigned char h_dest[ETH_ALEN]; unsigned char h_source[ETH_ALEN]; unsigned short h_proto; unsigned char ihl_ver; unsigned char tos; unsigned short tot_len; unsigned short id; unsigned short frag_off; unsigned char ttl; unsigned char protocol; unsigned short check; unsigned long saddr; unsigned long daddr; unsigned char type; unsigned char code; unsigned short checksum; unsigned short icmp_id; unsigned short icmp_seq; }; unsigned char mac[ETH_ALEN]; unsigned long dip, sip, netmask, broadcast, dmp, saddr; char packet[MAX_LEN], *ptr; void uso(void) { fprintf(stderr,"Uso: proscan -[a,p] \n"); exit (0); } char *ntoa(unsigned long ip) { static char buff[18]; char *p; p = (char *) &ip; sprintf(buff, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); return(buff); } char *dumpHW (unsigned char *hw_s) { static char buffer[ETH_ALEN]; sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", hw_s[0], hw_s[1], hw_s[2], hw_s[3], hw_s[4], hw_s[5]); return buffer; } unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) { unsigned int sum; __asm__ __volatile__(" movl (%1), %0 subl $4, %2 jbe 2f addl 4(%1), %0 adcl 8(%1), %0 adcl 12(%1), %0 1: adcl 16(%1), %0 lea 4(%1), %1 decl %2 jne 1b adcl $0, %0 movl %0, %2 shrl $16, %0 addw %w2, %w0 adcl $0, %0 notl %0 2: " : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl)); return(sum); } int main (int argc, char **argv) { struct arp_hack *hack_p; struct pinghack *ping; struct ifreq ifr; struct sockaddr sa; int opt, sockfd, fd_flags, len, sa_len, pid, sent, optA=0, optP=0; if (geteuid() || getuid()) { fprintf(stderr, "Per utilizzare proscan devi essere Root\n", argv[0]); exit(0); } if (argc < 3) uso(); while ((opt = getopt(argc, argv, "ap")) != EOF) { switch(opt) { case 'a': optA=1; break; case 'p': optP =1; break; default: exit(1); break; } } if(optA && optP) { fprintf(stderr, "\nNon puoi usare -a e -p insieme !!!\n"); exit(1); } printf("\n\033[1;32m---] P R O m i s c S C A N n e r [---\033[0m\n"); printf("\033[1;34mno(C)1999 FuSyS - TCP/IP Tools Unlimited\033[0m\n"); if(optA) if((sockfd=socket(AF_INET, SOCK_PACKET, htons(ETH_P_ARP))) <0) { perror("SOCK_PACKET: problemi di allocazione\n"); exit(0); } if(optP) if((sockfd=socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP))) <0) { perror("SOCK_PACKET: problemi di allocazione\n"); exit(0); } strcpy (ifr.ifr_name, argv[2]); if (ioctl (sockfd, SIOCGIFHWADDR, &ifr) < 0) { perror("Non ho trovato l'indirizzo hardware locale !\n"); exit(1); } memcpy(mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN); printf("\n\033[1;34m MAC Locale: \033[1;32m%s\033[0m\n", dumpHW(mac)); if (ioctl (sockfd, SIOCGIFADDR, &ifr) < 0) { perror ("Non ho trovato l'indirizzo IP locale !\n"); exit(1); } memcpy ((void *) &sip, (void *) &ifr.ifr_addr.sa_data + 2, IP_ALEN); printf ("\033[1;34m IP Locale : \033[1;32m%s\033[0m\n", ntoa(sip)); if (ioctl (sockfd, SIOCGIFNETMASK, &ifr) < 0) fprintf(stderr, "Non ho trovato l'indirizzo NETMASK !"); memcpy ((void *)&netmask, (void *)&ifr.ifr_netmask.sa_data+2, IP_ALEN); printf ("\033[1;34m NETMASK : \033[1;32m%s\033[0m\n", ntoa(netmask)); if (ioctl (sockfd, SIOCGIFBRDADDR, &ifr) < 0) fprintf(stderr, "Non ho trovato l'indirizzo BROADCAST !\n"); memcpy((void *)&broadcast,(void *)&ifr.ifr_broadaddr.sa_data+2,IP_ALEN); printf ("\033[1;34m BROADCAST : \033[1;32m%s\033[0m\n", ntoa(broadcast)); if(optA) printf("\033[1;34m TECNICA : \033[1;32mARPOP_REQUEST\033[0m\n"); if(optP) printf("\033[1;34m TECNICA : \033[1;32mICMP_ECHO\033[0m\n"); fcntl(sockfd, F_GETFL); fcntl(sockfd, F_SETFL, fd_flags | O_NONBLOCK); printf("\n\033[1;34m.oO Inizio Scansione Oo.\033[0m\n\n"); if(optA) for(dip=(ntohl(sip)&ntohl(netmask))+1;diph_dest, "\0\1\0\1\0\1", ETH_ALEN); memcpy (hack_p->h_source, mac, ETH_ALEN); hack_p->h_proto = htons(ETH_P_ARP); hack_p->ar_hrd = htons(ARPHRD_ETHER); hack_p->ar_pro = htons(ETH_P_IP); hack_p->ar_hln = 6; hack_p->ar_pln = 4; hack_p->ar_op = htons(ARPOP_REQUEST); memcpy (hack_p->ar_sha, mac, ETH_ALEN); memcpy (hack_p->ar_sip, &sip, IP_ALEN); memcpy (hack_p->ar_tha, "\0\0\0\0\0\0", ETH_ALEN); dmp=htonl(dip); memcpy (hack_p->ar_tip, &dmp, IP_ALEN); strcpy(sa.sa_data, argv[2]); sa.sa_family = AF_UNIX; if( sendto (sockfd, packet, sizeof (struct arp_hack), 0, &sa, sizeof(sa)) <0) fprintf(stderr, "errore sendto\n"); usleep (50); memset(&packet, 0, MAX_LEN); hack_p = (struct arp_hack *) packet; len = recvfrom (sockfd, packet, MAX_LEN, 0, &sa, &sa_len); if (len <= IF_LEN) continue; memcpy (&dmp, hack_p->ar_tip, IP_ALEN); memcpy (&saddr, hack_p->ar_sip, IP_ALEN); if ( ntohs(hack_p->ar_op) == ARPOP_REPLY && dmp == sip && (dip-ntohl(saddr) >= 0 ) && (dip-ntohl(saddr) <= 2 ) ) { printf ("\033[1;32mIP %s, MAC %s - \033[5;32mModalita' Promiscua !\033[0m\n", ntoa(saddr), dumpHW(hack_p->ar_sha)); } } if(optP) for(dip=(ntohl(sip)&ntohl(netmask))+1;diph_dest, "\0\1\0\1\0\1", ETH_ALEN); memcpy(ping->h_source, mac, ETH_ALEN); ping->h_proto = htons(ETH_P_IP); ping->ihl_ver = 0x45; ping->tos = 0x00; ping->tot_len = htons(IP_HLEN+ICMP_HLEN); ping->id = 0x0000; ping->frag_off = 0x0000; ping->ttl = 0xFF; ping->protocol = IPPROTO_ICMP; ptr += 26; *((u_long *)ptr) = sip; ptr += 4; *((u_long *)ptr) = htonl(dip); ping->check = 0; ping->check = ip_fast_csum((unsigned char *) ping+ETH_HLEN, 20); ptr +=4; *((u_char *)ptr) = 8; ptr +=1; *((u_char *)ptr) = 0; ptr +=3; *((u_short *)ptr) = pid; ptr +=2; *((u_short *)ptr) = 0xF001; ping->checksum = 0; ping->checksum = ip_fast_csum((unsigned char *) ping+(ETH_HLEN+IP_HLEN), 8); if((sent=sendto(sockfd, &packet, ETH_HLEN+IP_HLEN+ICMP_HLEN, 0, &sa, sa_len)) < 0 ) { fprintf(stderr, "Errore sendto\n"); return(-1); } usleep(50); memset(&packet, 0, MAX_LEN); ptr = packet; len = recvfrom (sockfd, packet, ETH_HLEN+IP_HLEN+ICMP_HLEN, 0, &sa, &sa_len); if (len <= ETH_HLEN) continue; ptr +=34; if(*((u_char*)ptr) == 0) { ptr +=6; if(*((u_short*)ptr) == 0xF001) { ptr -=14; if((dip - ntohl(*((u_long*)ptr)) >= 0) && (dip - ntohl(*((u_long*)ptr)) <= 2)) { printf ("\033[1;32mIP %s - \033[5;32mModalita' Promiscua !\033[0m\n", ntoa(*((u_long*)ptr))); } } } } printf("\n\033[1;34m.oO Fine Scansione Oo.\033[0m\n\n"); exit (0); }