diff --git a/abck b/abck index 4b55f9a..b3d1488 100755 --- a/abck +++ b/abck @@ -1,7 +1,7 @@ #!/usr/local/bin/python # # abck - Examine and report on unauthorized intrusion attempts. -# Copyright (c) 2001, TundraWare Inc., All Rights Reserved. +# Copyright (c) 2001, 2002 TundraWare Inc., All Rights Reserved. # See the accompanying file called, abck-License.txt # for Licensing Terms @@ -9,7 +9,7 @@ ########## -VERSION = "$Id: abck,v 1.99 2001/07/27 08:02:23 tundra Exp $" +VERSION = "$Id: abck,v 2.0 2002/09/04 21:06:59 tundra Exp $" @@ -35,6 +35,10 @@ DONE = FALSE +IGNORE = TRUE +LISTIGNORED = FALSE + + #################### # General Constants #################### @@ -81,12 +85,16 @@ PROMPT = "\nLog Record:\n%s\n\nWho Gets Message For: <%s>? %s[%s] " USAGE = "abck " + VERSION.split()[2] + " " + \ - "Copyright (c) 2001, TundraWare Inc. All Rights Reserved.\n" + \ - " usage:\n" + \ - " abck [-d # days to look back]\n" + \ - " [-e except string]\n" + \ - " [-m match string]\n" + \ - " [-s Show, but do not process matching records]\n" + "Copyright (c) 2001, 2002 TundraWare Inc. All Rights Reserved.\n" + \ + " usage: abck [-hilsv] [-d num][ -e string][-m string] where,\n\n" + \ + " -d # days to look back\n" + \ + " -e except string]\n" + \ + " -h Display this help information\n" + \ + " -i Do not ignore any addresses or names\n" + \ + " -l Display records/IPs/hostnames being ignored\n" + \ + " -m match string\n" + \ + " -s Show, but do not process matching records\n" + \ + " -v Show detailed version information\n" #################### @@ -101,10 +109,23 @@ "unauthorized" : 7 } -# Cache dictionary of all attacking hosts discovered this run of the program +# Associate IPs and Hostnames + +DNSCache = {} + + +# Associate attacking hosts with who to notify NameCache = {} +# List of IP addesses to ignore. Records with IP addresses or names +# found in this list will be ignored entirely. The addresses here may +# be partial IP quads. If IGNOREDFILE exists, its contents will +# be appended to the IGNORED data structure at program startup. + +Ignored = [] +IGNOREDFILE = os.path.join(os.getenv("HOME"), ".abck_ignored") + #################### # Globals @@ -131,6 +152,13 @@ def __init__(self, args=None): self.args = args +# Signify we want to ignore a record + + +class IgnoreRecord(exceptions.Exception): + def __init__(self, args=None): + self.args = args + # Signify that the user want to quit the program @@ -230,9 +258,9 @@ # Check for each known attack keyword sendto = "" + logfield = logrecord.split() for attackkey in AttackKeys.keys(): - logfield = logrecord.split() if logrecord.count(attackkey): # Even if it is a legitimate attack record, @@ -251,13 +279,34 @@ if hostquad[-1] == ',': hostquad = hostquad[:-1] # Strip trailing dots - # Go do a reverse resolution if we need to - hostname = CheckIPReverse(hostquad) - # Check for the case of getting a PTR record back - hostname = ReversePTR(hostname) + # See if we've already done a reverse. If so, use it, + # otherwise do the lookup and store result in the cache + if DNSCache.has_key(hostquad): + hostname = DNSCache[hostquad] + else: + # Go do a reverse resolution if we need to + hostname = CheckIPReverse(hostquad) + + # Check for the case of getting a PTR record back + hostname = ReversePTR(hostname) + + DNSCache[hostquad] = hostname + + # Check if record should be ignored + + if IGNORE: + for ihost in Ignored: + if (hostquad.startswith(ihost)) or (hostname.endswith(ihost)): + if LISTIGNORED: + print "Ignoring record on match for: [%s]\n%s" % (ihost, logrecord) + + raise IgnoreRecord + # Check if we've seen this abuser before + # i.e., Do we already know who to notify? + if NameCache.has_key(hostname): sendto = NameCache[hostname] @@ -339,10 +388,11 @@ # Program entry and command line processing try: - opts, args = getopt.getopt(sys.argv[1:], '-d:e:m:s') + opts, args = getopt.getopt(sys.argv[1:], '-d:e:hilm:sv') except getopt.GetoptError: print USAGE sys.exit(2) + OLDEST = 0 MATCH = "" @@ -354,10 +404,32 @@ OLDEST = time.time() - (int(val) * DLEN) if opt == "-e": NOMATCH = val + if opt == "-h": + print USAGE + sys.exit(0) + if opt == "-i": + IGNORE = FALSE + LISTIGNORED = FALSE + if opt == "-l": + LISTIGNORED = TRUE + IGNORE = TRUE if opt == "-m": MATCH = val if opt == "-s": SHOWONLY = TRUE + if opt == "-v": + print VERSION + sys.exit(0) + + +# Process the ignored rc file, if any + +if os.path.exists(IGNOREDFILE): + i = open(IGNOREDFILE) + for entry in i.read().splitlines(): + Ignored.append(entry) + i.close() + # Read the log into a list @@ -420,7 +492,7 @@ if DOIT: try: sendto = ProcessLogRecord(logrecord, NOMATCH, SHOWONLY) - except (ForgetRecord): + except (ForgetRecord, IgnoreRecord): Processed.append(logrecord) except (QuitAbck): sys.exit() @@ -441,3 +513,9 @@ f.close() +if LISTIGNORED: + print "\n\n--------------------------------------------------" + print "Records with the following IP Quads/Hostnames Were Ignored:\n" + for x in Ignored: + print x +