[LWN Logo]

Date:	Tue, 22 Dec 1998 03:38:29 +0100
From:	phroid <phroid@CYBERDUDE.COM>
Subject:      Linux tcplogd hack able to log any tcp portscan attack (nmap2)
To:	BUGTRAQ@NETSPACE.ORG

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 - phroid@cyberdude.com
-----------------------------
--------------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 (phroid@cyberdude.com)
   (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--