Linux tcplogd hack able to log any tcp portscan attack (nmap2)

From: phroid (phroidat_private)
Date: Mon Dec 21 1998 - 18:38:29 PST

  • Next message: Ben Winslow: "Re: DCC HiJacking patch for BitchX 75p1"

    This is a multi-part message in MIME format.
    --------------E996E9CE15C4CD44CDCB1052
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 7bit
    
    Hi there.
    I noticed a little program called tcplogd, shipped with Debian linux,
    which logs, using syslogd facilities, any tcp (SYN) connection attempt
    to your host.
    
    Here is a modified version. It is now able to detect FTPbounce attacks,
    FIN packet based scan (like Uriel's and Xmas tree scan) as well as Null
    flag scan (see nmap 2.01 documentation for details).
    Compiles under Linux 2.0/2.1 with libc5 or glibc2.
    
    a much more advanced (and portable) logger will follow soon.
    
    hope you will find this useful. greetings.
    --
    
    -----------------------------
    phroid - phroidat_private
    -----------------------------
    --------------E996E9CE15C4CD44CDCB1052
    Content-Type: text/plain; charset=UTF-8;
     name="tcplogd.c"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline;
     filename="tcplogd.c"
    
    /* tcplogd.c v 2.1 (20th dic. 1998) for linux
       by phroid (phroidat_private)
       (a simple hack of Mike Edulla's tcplogger)
    
       the difference are:
    initial release:
       0 - compiles on libc5 AND glibc2 system.
       1 - stripped ident support (whould reveal the logger IMHO!)
       2 - added tcp FIN packet logging, they are used in many attacks
    since 2.1:
           removed LOG_ALL_FIN option, not useful anymore
       3 - added FIN+URG+PUSH packet logging ("Xmas tree scan" attack)
       4 - added logging of tcp packets w/o any flag set ("Null scan" attack)
    
       write me if you like this or if you are interested in IPdump and IPlogd
       IPdump is a single packets DETAILED dumper for advanced diagnostic use
       IPlogd would be the definitive tcp/ip log daemon, supporting tcp, udp, icmp,
       and even raw data using user-defined matching parameters.
    */
    
    #include <netdb.h>
    #include <signal.h>
    #include <stdio.h>
    #include <arpa/inet.h>
    #include <fcntl.h>
    #include <syslog.h>
    #include <sys/ioctl.h>
    #ifdef __GLIBC__
    #include <net/if.h>
    #include <netinet/ip.h>
    #include <netinet/tcp.h>
    #else
    #include <stdlib.h> /* some of these were included in the original */
    #include <unistd.h> /* but not really needed */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <sys/stat.h>
    #include <netinet/in.h>
    #include <linux/ip.h>
    #include <linux/tcp.h>
    #endif
    
    extern int errno;
    
    #ifndef NOFILE
    #define NOFILE 1024
    #endif
    
    int go_background(void);
    char *hostlookup(unsigned long int);
    char *servlookup(unsigned short);
    
    struct ippkt
    {
       struct iphdr ip;
       struct tcphdr tcp;
       char buffer[10000];
    }pkt;
    
    int go_background(void)
    {
       int fd;
       int fs;
    
       if(getppid() != 1)
       {
          signal(SIGTTOU, SIG_IGN);
          signal(SIGTTIN, SIG_IGN);
          signal(SIGTSTP, SIG_IGN);
          fs=fork();
          if(fs < 0)
          {
             perror("fork");
             exit(1);
          }
          if(fs > 0) exit(0);
          setpgrp();
          fd=open("/dev/tty", O_RDWR);
          if(fd >= 0)
          {
             ioctl(fd, TIOCNOTTY, (char *)NULL);
             close(fd);
          }
       }
       for(fd=0;fd < NOFILE;fd++) close(fd);
       errno=0;
       chdir("/");
       umask(0);
    }
    
    int main(void)
    {
       int s;
       int i;
       char tmpbuff[1024];
    
       setuid(0);
       if(geteuid() != 0)
       {
          printf("This program requires root privledges\n");
          exit(0);
       }
       go_background();
       s=socket(AF_INET, SOCK_RAW, 6);
       openlog("tcplog", 0, LOG_DAEMON);
    
       while(1)
       {
          read(s, (struct ippkt *)&pkt, 9999);
          if(pkt.tcp.syn == 1 && pkt.tcp.ack == 0)
             if(ntohs(pkt.tcp.source) == 20)
                syslog(LOG_NOTICE, "probable FTPBounce attack detected from %s", hostlookup(pkt.ip.saddr));
             else
                syslog(LOG_NOTICE, "%s connection (SYN) attempt from %s", servlookup(pkt.tcp.dest), hostlookup(pkt.ip.saddr));
    
          if(pkt.tcp.fin == 1 && pkt.tcp.ack == 0)
             if(pkt.tcp.urg == 1 && pkt.tcp.psh == 1)
                syslog(LOG_NOTICE, "%s connection (Xmas tree probe) attempt from %s", servlookup(pkt.tcp.dest), hostlookup(pkt.ip.saddr));
             else
                syslog(LOG_NOTICE, "%s connection (FIN) attempt from %s", servlookup(pkt.tcp.dest), hostlookup(pkt.ip.saddr));
    
          if(pkt.tcp.syn == 0 && pkt.tcp.fin == 0 && pkt.tcp.ack == 0 && pkt.tcp.rst == 0 && pkt.tcp.urg == 0 && pkt.tcp.psh == 0)
             syslog(LOG_NOTICE, "%s connection (Null probe) attempt from %s", servlookup(pkt.tcp.dest), hostlookup(pkt.ip.saddr));
       }
    }
    
    char *hostlookup(unsigned long int in)
    {
       static char blah[1024];
       struct in_addr i;
       struct hostent *he;
    
       i.s_addr=in;
       he=gethostbyaddr((char *)&i, sizeof(struct in_addr),AF_INET);
       if(he == NULL) strcpy(blah, inet_ntoa(i));
       else strcpy(blah, he->h_name);
       return blah;
    }
    
    
    char *servlookup(unsigned short port)
    {
       struct servent *se;
       static char buff[1024];
    
       se=getservbyport(port, "tcp");
       if(se == NULL) sprintf(buff, "port %d", ntohs(port));
       else sprintf(buff, "%s", se->s_name);
       return buff;
    }
    
    
    --------------E996E9CE15C4CD44CDCB1052--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:25:28 PDT