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--