#!/bin/sh
#
# sf4sf is a Syslog Filter For SlackFire.
#
# Actually, this is `fwfilter' written by Arno van Amersfoort
# (http://rocky.eld.leidenuniv.nl/) slightly modified for use
# with SlackFire.
#
# Possible usage:
#
# tail -f /var/log/syslog | sf4sf
# grep Fired /var/log/syslog | sf4sf
# grep Trojan /var/log/syslog | sf4sf
# ...
#
###############################################################################
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
###############################################################################
#
# Options:
#
# Enable this option if you want to resolve IP adresses to names
RESOLVE_NAMES=0

# Enable this option to use ANSI colors (increases readability)
USE_ANSI_COLORS=1

# Enable this if you want the information to be split and shown on 2 rows
# (increases readability)
USE_2ROWS=1

# Use this variable if your awk binary is in a non-default location 
# (use 'locate awk' or 'whereis awk' to manually locate it).
# Thanks PV, there is no need to use this variable in Slackware :-)
AWK_BIN=""

if [ "$AWK_BIN" == "" ]; then
  if [ -x '/bin/awk' ]; then
    AWK_BIN='/bin/awk'
  fi
  if [ -x '/usr/bin/awk' ]; then
    AWK_BIN='/usr/bin/awk'
  fi
fi

if [ "$AWK_BIN" == "" ]; then
  echo "ERROR: Could not locate the AWK binary (is it installed?)."
  echo "You may want to configure it yourself inside this script."
else
  # Test what awk version is used (gawk, mawk etc...)
  test=`$AWK_BIN -W version /dev/null 2>/dev/null |grep -i mawk`
  if [ "$test" != "" ]; then
    AWK_BIN=$(echo "$AWK_BIN -W interactive")
  fi
  $AWK_BIN '

  # This is the function which performs the portname lookups
  ##########################################################

  function portname_lookup(port)
  {
     if (port=="0") return("0 (Invalid port)")
     if (port=="1") return("1 (tcpmux)")
     if (port=="5") return("5 (remote job)")
     if (port=="7") return("7 (echo)")
     if (port=="9") return("9 (discard-server)")
     if (port=="11") return("11 (systat)")
     if (port=="13") return("13 (daytime)")
     if (port=="15") return("15 (netstat)")
     if (port=="19") return("19 (chargen)")
     if (port=="20") return("20 (ftp-data)")
     if (port=="21") return("21 (ftp)")
     if (port=="22") return("22 (ssh)")
     if (port=="23") return("23 (telnet)")
     if (port=="25") return("25 (smtp)")
     if (port=="37") return("37 (time)")
     if (port=="43") return("43 (whois)")
     if (port=="53") return("53 (domain)")
     if (port=="67") return("67 (dhcpserver)")
     if (port=="68") return("68 (dhcpclient)")
     if (port=="69") return("69 (tftp)")
     if (port=="70") return("70 (gopher)")
     if (port=="79") return("79 (finger)")
     if (port=="80") return("80 (http)")
     if (port=="98") return("98 (linuxconf)")
     if (port=="109") return("109 (pop2)")
     if (port=="110") return("110 (pop3)")
     if (port=="111") return("111 (rpcbind)")
     if (port=="113") return("113 (auth)")
     if (port=="119") return("119 (nntp)")
     if (port=="123") return("123 (ntp)")
     if (port=="135") return("135 (ms-rpc) *Possible Attack*")
     if (port=="137") return("137 (netbios-ns)")
     if (port=="138") return("138 (netbios-dgm)")
     if (port=="139") return("139 (netbios-ssn)")
     if (port=="143") return("143 (imap)")
     if (port=="177") return("177 (xdmcp)")
     if (port=="217") return("217 (dbase)")
     if (port=="433") return("433 (nnsp)")
     if (port=="443") return("443 (https)")
     if (port=="445") return("445 (microsoft-ds)")
     if (port=="513") return("513 (BSD who)")
     if (port=="514") return("514 (syslog)")
     if (port=="515") return("515 (printer)")
     if (port=="520") return("520 (route)")
     if (port=="524") return("524 (ncp)")
     if (port=="525") return("525 (timed)")
     if (port=="554") return("554 (RealTimeSTP)")
     if (port=="635") return("635 (NFS mount)")
     if (port=="666") return("666 *Attack FTP/yoyo*")
     if (port=="901") return("901 (samba-swat)")
     if (port=="993") return("993 (imaps)")
     if (port=="995") return("995 (pop3s)")
     if (port=="1023") return("1023 (netvenuechat)")
     if (port=="1024") return("1024 (kdm)")
     if (port=="1025") return("1025 (blackjack)")
     if (port=="1027") return("1027 *ICQ Trojan*")
     if (port=="1028") return("1028 (ms-lsa)")
     if (port=="1029") return("1029 (ms-lsa) *ICQ Trojan*")
     if (port=="1080") return("1080 (socks)")
     if (port=="1214") return("1214 (KaZaa)")
     if (port=="1243") return("1243 *Sub-7*")
     if (port=="1394") return("1394 (Network Log Client)")
     if (port=="1433") return("1433 (ms-sql-s)")
     if (port=="1434") return("1434 (ms-sql-m)")
     if (port=="1524") return("1524 *Trinoo*")
     if (port=="1723") return("1723 (PPtP)")
     if (port=="1900") return("1900 (UPnP)")
     if (port=="1999") return("1999 *Backdoor*")
     if (port=="2000") return("2000 (callbook)")
     if (port=="2001") return("2001 *Scalper Rootkit*")
     if (port=="2006") return("2006 *CB Rootkit*")
     if (port=="2049") return("2049 (NFS) *Possible Attack*")
     if (port=="2128") return("2128 *MRK*")
     if (port=="2283") return("2283 *Dumaru*")
     if (port=="2745") return("2745 *Beagle.C-K W32*")
     if (port=="2773") return("2773 *Sub-7 KeyLogger*")
     if (port=="3127") return("3127 *MyDoom Backdoor*")
     if (port=="3128") return("3128 (squid-http) *rwwwshell*")
     if (port=="3129") return("3129 *Masters Paradise*")
     if (port=="3389") return("3389 *Remote Desktop W-XP*")
     if (port=="4662") return("4662 (eDonkey)")
     if (port=="4899") return("4899 *Remote Admin*")
     if (port=="5000") return("5000 (UPnP)")
     if (port=="5500") return("5500 (securid)")
     if (port=="5503") return("5503 *Remote Shell*")
     if (port=="5554") return("5554 *Sasser Worm*")
     if (port=="5631") return("5631 *PCanywhere*")
     if (port=="5632") return("5632 *PCanywhere*")
     if (port=="5800") return("5800 (vnc-http)")
     if (port=="5900") return("5900 (vnc)")
     if (port=="6000" || port=="6001" || port=="6002" || port=="6003" || port=="6004" \
      || port=="6005" || port=="6006" || port=="6007" || port=="6008" || port=="6009")\
      return(sprintf("X11 (%i)", port))
     if (port=="6010") return("6010 (X11-ssh)")
     if (port=="6129") return("6129 *DameWare*")
     if (port=="6346") return("6346 (gnutella)")
     if (port=="6667") return("6667 *Trinity*")
     if (port=="6670") return("6670 *Deep Throat*")
     if (port=="6711") return("6711 *Sub-7*")
     if (port=="6712") return("6712 *Sub-7*")
     if (port=="6713") return("6713 *Sub-7*")
     if (port=="6723") return("6723 *Mstream*")
     if (port=="6776") return("6776 *Backdoor-G or Sub-7*")
     if (port=="6838") return("6838 *Mstream*")
     if (port=="6969") return("6969 *BlitzNet*")
     if (port=="6970") return("6870 (RealAudio)")
     if (port=="7215") return("7215 *Sub-7 Matrix Chat*")
     if (port=="7777") return("7777 *Tini*")
     if (port=="7983") return("7983 *Mstream*")
     if (port=="8080") return("8080 (http-proxy)")
     if (port=="9325") return("9325 *Mstream*")
     if (port=="9898") return("9898 *Dabber W32*")
     if (port=="9999") return("9999 *BlitzNet*")
     if (port=="10008") return("10008 *Cheeseworm*")
     if (port=="10498") return("10498 *Mstream*")
     if (port=="11768") return("11768 *Another W32 worm?*")
     if (port=="12345") return("12345 *NetBus*")
     if (port=="12346") return("12346 *NetBus*")
     if (port=="12754") return("12754 *Mstream*")
     if (port=="14856") return("14856 *Optic Kit*")
     if (port=="15104") return("15104 *Mstream*")
     if (port=="16660") return("16660 *Stacheldraht*")
     if (port=="16959") return("16959 *Subseven*")
     if (port=="17300") return("17300 *Kuang2*")
     if (port=="20002") return("20002 *Acidkor*")
     if (port=="20034") return("20034 *Netbus 2 Pro*")
     if (port=="21544") return("21544 *Girlfriend*")
     if (port=="23456") return("23456 *EvilFTP*")
     if (port=="27374") return("27374 *li0n, Sub-7 W32*")
     if (port=="27444") return("27444 *Trin00*")
     if (port=="27665") return("27665 *Trin00*")
     if (port=="31335") return("31335 *Trin00*")
     if (port=="31337") return("31337 *Back Orifice/BlitzNet*")
     if (port=="31338") return("31338 *Back Orifice*")
     if (port=="33270") return("33270 *Trinity*")
     if (port=="47107") return("47107 *T0rn Rootkit*")
     if (port=="50505") return("50505 *Sockets de Trois*")
     if (port=="54283") return("54283 *Sub-7 Spy port*")
     if (port=="54320") return("54320 *Back Orifice*")
     if (port=="54321") return("54321 *Back Orifice/yoyo*")
     if (port=="60001") return("60001 *Trinity*")
     if (port=="60922") return("60922 *zaRwT.KiT*")
     if (port=="65000") return("65000 *Stacheldraht*")
     if (port=="65301") return("65301 *PCanywhere*")
     if (port=="65535") return("65535 *Adore worm*")

     # If nothing else matches just return the port number
     return(port)
  }

# This rule does not work properly for port numbers that consist of less
# than 5 digits
#    if (port>="33434" && port<="33600") return(sprintf("Traceroute? (%i)",port))

  # Main program
  ##############
  {
    if (match($0, "Fire") != 0 || match($0, "IN=") != 0 || match($0, "martian") != 0)
    {
      if (match($0, "IN=") == 0) 
      {
        if (USE_ANSI_COLORS==1)
        {
          printf("\033[0m\033[1;32m")
          printf("%s",$0)
          printf("\033[0m")
        }
        else
        {
          printf("%s",$0)
        }
      }
      else
      {
        for (i = 1; i <= NF; i++)
        # First show message, SRC etc.
        {
          if (i==2 && length($2)==1) printf("0")
          if (i==6) if (USE_ANSI_COLORS==1) if (substr($i, 1,4) == "Fire")
          {
            printf("\033[0m\033[1;33m")
            F=1
          }
          else 
          {
            printf("\033[0m\033[1;32m")
            F=0
          }
          if (substr($i, 1,3) == "IN=") if (USE_ANSI_COLORS==1) printf("\033[0m")
          if (substr($i, 1,3) == "IN=") if (length($i) == 3) i++
          if ((substr($i,1,4) != "MAC=" && substr($i,1,4) != "OUT=" && substr($i,1,4) !="SRC=" && i != 4 && i != 5) || ( substr($i,1,4) == "OUT=" && length($i) != 4 ))
            printf("%s ", $i)

          if (substr($i,1,4) == "SRC=")
          {
            if (USE_ANSI_COLORS==1) 
            {
            if (F==1) printf("\033[0m\033[1;31m")
            else printf("\033[0m\033[1;32m")
            }
            printf("%s ", $i)

            if (RESOLVE_NAMES==1)
            {
              # If multiple names exist for one IP than only use the first (head -n1)
              syscall=sprintf("echo -n \"$(dig +short +time=1 +tries=1 -x %s)\" 2>/dev/null |head -n1", substr($i,5,length($i)-4))
              system(syscall)
            }

            if (USE_ANSI_COLORS==1) printf("\033[0m")
            break
          }
        }
        if (USE_ANSI_COLORS==1) printf("\033[0m")

        if (i==NF)
        {
          printf("\n")
        }
        else
        {
          offset=i+1
          if (USE_2ROWS==1) printf("\n                "); else printf(" ")
        }

        printf("%s ", $(offset))
        save_offset=++offset;
        for (i = offset; i <= NF; i++) if (substr($i,1,6) == "PROTO=") break;

        offset=i

        # First show PROTO=
        if ($offset == "PROTO=UDP")
        {
          # Let it be MAGENTA
          if (USE_ANSI_COLORS==1) printf("\033[0m\033[1;35m")
          printf("%s ", $offset)
          if (USE_ANSI_COLORS==1) printf("\033[0m")
        }
        else
        if ($offset == "PROTO=TCP")
        {
          # Let it be CYAN
          if (USE_ANSI_COLORS==1) printf("\033[0m\033[1;36m")
          printf("%s ", $offset)
          if (USE_ANSI_COLORS==1) printf("\033[0m")
        }
        else
        if ($offset == "PROTO=ICMP")
        {
          if (USE_ANSI_COLORS==1) 
			 {
            # Let it be YELLOW or GREEN
			   if (F==0) printf("\033[0m\033[1;33m")
			   else printf("\033[0m\033[1;32m")
          }
          printf("%s ", $offset)
          if (USE_ANSI_COLORS==1) printf("\033[0m")
        }
        else
        {
          # This is BLUE
          if (USE_ANSI_COLORS==1) printf("\033[0m\033[1;34m")
          printf("%s ", $offset)
          if (USE_ANSI_COLORS==1) printf("\033[0m")
        }

        if (substr($(offset+1),1,4)=="SPT=")
        {

          # Second show DPT=
          # YELLOW
          if (USE_ANSI_COLORS==1) printf("\033[0m\033[1;33m")
          printf("DPT=%s ", portname_lookup(substr($(offset+2), 5, length($(offset+2))-4)))
          if (USE_ANSI_COLORS==1) 
			 {
			   if (F==1) printf("\033[0m\033[1;32m")
			   else printf("\033[0m")
          }
          # Third show SPT=
          printf("SPT=%s ", portname_lookup(substr($(offset+1), 5, length($(offset+1))-4)))
          if (F==1) printf("\033[0m")
        }

        for (i = save_offset; i <= NF; i++)
        # Show all other info
        {
          if (substr($i,1,6) != "PROTO=" && substr($i,1,5) != "PREC=" && substr($i,1,4) != "TOS=" && substr($i,1,3) != "ID=" \
           && substr($i,1,4) != "LEN=" && i != 4 && i != 5 && substr($i,1,2) != "DF" && substr($i,1,4) != "SPT=" && substr($i,1,4) != "DPT=" \
           && $i != "RES=0x00" && $i != "URGP=0" && substr($i,1,7) != "WINDOW=")
           printf("%s ", $i)
        }
      }
      printf("\n")
    }
  }
  ' RESOLVE_NAMES=$RESOLVE_NAMES USE_ANSI_COLORS=$USE_ANSI_COLORS USE_2ROWS=$USE_2ROWS
fi
# EOF
