NoPaste Service
DOWNLOAD
Language: C
Author: Matrix86
Description: Simple sniffer with Filter
Date: 02/09/08 21:07
  1. /*
  2. ######################################################################
  3. #                                                                    #
  4. #       Simple Sniffer with Filter                                   #
  5. #                                                                    #
  6. # Copyright (C) 2007  Matrix86                                       #
  7. #                                                                    #
  8. # This program is free software; you can redistribute it and/or      #
  9. # modify it under the terms of the GNU General Public License        #
  10. # as published by the Free Software Foundation; either version 2     #
  11. # of the License, or (at your option) any later version.             #
  12. #                                                                    #
  13. # This program is distributed in the hope that it will be useful,    #
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of     #
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      #
  16. # GNU General Public License for more details.                       #
  17. #                                                                    #
  18. # http://www.gnu.org/copyleft/gpl.html                               #
  19. #                                                                    #
  20. ######################################################################
  21. */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <pcap.h>
  25. #include <arpa/inet.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <getopt.h>
  29. #include <ctype.h>
  30. #include <netinet/ip.h>
  31. #include <netinet/tcp.h>
  32. #include <netinet/udp.h>
  33. #include <netinet/ip_icmp.h>
  34. #include <netinet/igmp.h>
  35. #include <regex.h>
  36.  
  37. FILE * out = NULL;
  38.  
  39. void usage(char *p){
  40.         fprintf(stdout,"\n--------- Sniffer Filter ---------\n");
  41.         fprintf(stdout,"Simple sniffer by Matrix86\nThx to Evilsocket\n");
  42.         fprintf(stdout,"Usage: %s [opzioni] -i [dispositivo]\n\n",p);
  43.         fprintf(stdout,"\tOpzioni disponibili:\n\t\t-f <espressione> : filtro pcap\n");
  44.         fprintf(stdout,"\t\t-r <espressione> : regex sul payload\n");
  45.         fprintf(stdout,"\t\t-o <file> : file di salvataggio\n");
  46.         fprintf(stdout,"\t\t-h : mostra questo help\n");
  47.         fprintf(stdout,"Esempio:\n\t%s -f \"port 6667\" -i eth0\n",p);
  48.         fprintf(stdout,"\t%s -f \"port 6667\" -o dump.txt -i eth0\n\n");
  49.         return;
  50. }
  51.  
  52. void die(char * error){
  53.         fprintf(out,"[ERROR] %s\n",error);
  54.         exit(1);
  55. }
  56.  
  57. char *get_protocols(struct iphdr *ip){
  58.        
  59.         char *ret;
  60.        
  61.         switch(ip->protocol){
  62.                 case IPPROTO_TCP  :
  63.                         ret = strdup("TCP");
  64.                         break;
  65.                 case IPPROTO_UDP  :
  66.                         ret = strdup("UDP");
  67.                         break;
  68.                 case IPPROTO_IPIP :
  69.                         ret = strdup("IP");
  70.                         break;
  71.                 case IPPROTO_IGMP :
  72.                         ret = strdup("IGMP");
  73.                         break;
  74.                 case IPPROTO_ICMP :
  75.                         ret = strdup("ICMP");
  76.                         break;
  77.         }
  78.        
  79.         return ret;
  80.        
  81. }
  82.  
  83. int matchreg(const char *string, char *pattern) {
  84.  
  85.         int status;
  86.         regex_t re;
  87.  
  88.         if(!regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE|REG_NEWLINE)) {
  89.                 if(regexec(&re, string, (size_t)0, NULL, 0) == 0) status = 1;
  90.                 else status = 0;
  91.         }
  92.         else die("Regex incorretta!");
  93.  
  94.         regfree(&re);
  95.         return status;
  96. }
  97.  
  98. void show_pkt(u_char * pkt,int size,char *ptn_reg){
  99.         struct iphdr * ip;              // IP Header
  100.         struct in_addr addr;
  101.         char addr_str[16];
  102.         char *payload, *n;
  103.         int dataoffset,
  104.             i;
  105.         u_char *pointer = NULL;
  106.        
  107.         ip = (struct iphdr *) pkt;
  108.        
  109.         switch(ip->protocol){
  110.                 case IPPROTO_TCP  :
  111.                         dataoffset = sizeof(struct iphdr) + (((struct tcphdr *)(pkt + sizeof(struct iphdr)))->doff * 4);
  112.                         break;
  113.                 case IPPROTO_UDP  :
  114.                         dataoffset = sizeof(struct iphdr) + sizeof(struct udphdr);
  115.                         break;
  116.                 case IPPROTO_IPIP :
  117.                         dataoffset = sizeof(struct iphdr) * 2;
  118.                         break;
  119.                 case IPPROTO_IGMP :
  120.                         dataoffset = sizeof(struct iphdr) + sizeof(struct igmp);
  121.                         break;
  122.                 case IPPROTO_ICMP :
  123.                         dataoffset = sizeof(struct iphdr) + sizeof(struct icmphdr);
  124.                         break;
  125.                
  126.                 default :
  127.                         fprintf(out,"Protocollo sconosciuto");
  128.                         return;
  129.         }
  130.         pointer = pkt + dataoffset;
  131.         n = payload = calloc(size - dataoffset,1);
  132.        
  133.         for(i = 0; i < (size - dataoffset); i++,n++,pointer++){
  134.                 if(isprint(*pointer)) *n = *pointer;
  135.         }
  136.        
  137.         if(ptn_reg == NULL || matchreg(payload,ptn_reg)){
  138.                
  139.                 fprintf(out,"-------------------------------------------------------------\n");
  140.                 fprintf(out,"Protocollo:\t%s\n",get_protocols(ip));
  141.                 addr.s_addr = ip->saddr;
  142.                 inet_ntop(AF_INET,&addr,addr_str,sizeof(addr_str));
  143.                 fprintf(out,"Sorgente:\t%s\n",addr_str);
  144.                 addr.s_addr = ip->daddr;
  145.                 inet_ntop(AF_INET,&addr,addr_str,sizeof(addr_str));
  146.                 fprintf(out,"Destinatario:\t%s\n",addr_str);
  147.                 fprintf(out,"Payload:\n%s",payload);
  148.                 fprintf(out,"\n-------------------------------------------------------------\n\n");
  149.                 fflush(out);
  150.         }
  151.         return;
  152. }
  153.  
  154. int main(int argc,char *argv[]){
  155.  
  156.         char *device=NULL,
  157.               *pattern = NULL,
  158.               c,
  159.               strnetaddr[INET_ADDRSTRLEN],
  160.               strnetmask[INET_ADDRSTRLEN],
  161.               errbuf[PCAP_ERRBUF_SIZE],
  162.               *filtro = NULL;
  163.         int datalink,offset;
  164.         pcap_t *fd;
  165.         u_char *pcap_pkt;                       // Pachetto attuale
  166.         struct pcap_pkthdr pcap_hdr;                    // Pcap Header Packet
  167.         struct bpf_program filter;
  168.         bpf_u_int32 netmask,netaddr;            // Netmask e Ip del dispositivo di sniffing
  169.        
  170.         if (getuid()){
  171.                 fprintf(stdout,"Bisogna essere root!\n");
  172.                 exit(0);
  173.         }
  174.        
  175.         if(argc < 2) {
  176.                 usage(argv[0]);
  177.                 exit(0);
  178.         }
  179.        
  180.         while ((c = getopt (argc, argv, "i:f:r:o:")) != -1){
  181.                 if(!optarg && c != 'h') c = 'h';
  182.                
  183.                 switch (c){
  184.                         case 'i':
  185.                                 device = strdup(optarg);
  186.                                 break;
  187.                         case 'f':
  188.                                 filtro= strdup(optarg);
  189.                                 break;
  190.                         case 'r':
  191.                                 pattern = strdup(optarg);
  192.                                 break;
  193.                         case 'o':
  194.                                 out=fopen(optarg,"a");
  195.                                 if(out == NULL)
  196.                                         die("Impossibile aprire il file\n");
  197.                                 break;
  198.                         case 'h':
  199.                                 usage(argv[0]);
  200.                                 exit(0);
  201.                                 break;
  202.                         default:
  203.                                 usage(argv[0]);
  204.                                 exit(0);
  205.                                 break;
  206.                 }
  207.         }
  208.        
  209.         if(out == NULL) out = stdout;
  210.        
  211.         if(!device) exit(0);
  212.        
  213.         fprintf(out,"Seleziono il device: %s\n",device);
  214.         if(pcap_lookupnet(device,&netaddr,&netmask,errbuf) == -1) {
  215.                 fprintf(out,"Nessun indirizzo assegnato al device %s\n",device);
  216.                 exit(0);
  217.         }
  218.        
  219.         inet_ntop(AF_INET, (void *) &netaddr, strnetaddr, sizeof(strnetaddr));
  220.         inet_ntop(AF_INET, (void *) &netmask, strnetmask, sizeof(strnetmask));
  221.         fprintf(out,"Netmask: %s\nIndirizzo di rete: %s\n",strnetmask,strnetaddr);
  222.        
  223.         if( (fd = pcap_open_live(device,65535,1,0,errbuf)) <= 0)
  224.                 die(errbuf);
  225.         fprintf(out,"Dispositivo %s inizializzato e settato in Monitor Mode\n",device);
  226.        
  227.         // int pcap_compile(pcap_t * p, struct bpf_ program *fp, char * str,int optimize, bpf_u_int32 netmask);
  228.         if(pcap_compile(fd,&filter,filtro,1,netaddr) == -1)
  229.                 die(pcap_geterr(fd));
  230.        
  231.         if(pcap_setfilter(fd,&filter) == -1)
  232.                 die(pcap_geterr(fd));
  233.        
  234.         if((datalink = pcap_datalink(fd)) < 0)
  235.                 die(errbuf);
  236.        
  237.        
  238.         // Cerchiamo l'offset dell'ip nel pacchetto rispetto il tipo di dispositivo (Thx Evilsocket ;))
  239.         switch( datalink )
  240.         {
  241.                 case DLT_RAW        : offset = 0;  break;
  242.                 case DLT_PPP        :
  243.                 case DLT_LOOP       :
  244.                 case DLT_NULL       : offset = 4;  break;
  245.                 case DLT_PPP_ETHER  : offset = 8;  break;
  246.                 case DLT_EN10MB     :
  247.                 case DLT_EN3MB      : offset = 14; break;
  248.                 case DLT_LINUX_SLL  :
  249.                 case DLT_SLIP       : offset = 16; break;
  250.                 case DLT_SLIP_BSDOS :
  251.                 case DLT_PPP_BSDOS  :
  252.                 case DLT_IEEE802_11 : offset = 24; break;
  253.                 case DLT_PFLOG      : offset = 48; break;
  254.        
  255.                 default         :
  256.  
  257.                         die("Dispositivo non riconosciuto!");
  258.         }
  259.        
  260.         fprintf(out,"Inizio sniffing...\n");
  261.        
  262.         // u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
  263.         while((pcap_pkt = pcap_next(fd, &pcap_hdr))){
  264.                 show_pkt(pcap_pkt + offset, pcap_hdr.len + offset,pattern);
  265.         }
  266.        
  267.        
  268.         free(device);
  269.         pcap_close(fd);
  270.         exit(0);
  271. }