| | #!/usr/local/bin/python |
---|
| | # |
---|
| | # abck - Part of the ABMGMT package from TundraWare Inc. |
---|
| | # abck - Examine and report on unauthorized intrusion attempts. |
---|
| | # Copyright (c) 2001, TundraWare Inc., All Rights Reserved. |
---|
| | # See the accompanying file called, 1-ABMGMT-License.txt |
---|
| | # See the accompanying file called, abck-License.txt |
---|
| | # for Licensing Terms |
---|
| | # |
---|
| | # Build a report of all unauthorized access attempts |
---|
| | # |
---|
| | # Usage: abck [-d date offset] -e [Except String] -s [Match String] |
---|
| | |
---|
| | |
---|
| | |
---|
| | ########## |
---|
| | |
---|
| | VERSION = "$Id: abck,v 1.94 2001/07/19 01:18:19 tundra Exp $" |
---|
| | VERSION = "$Id: abck,v 1.95 2001/07/27 01:45:24 tundra Exp $" |
---|
| | |
---|
| | |
---|
| | |
---|
| | #################### |
---|
| |
---|
| | #################### |
---|
| | |
---|
| | import commands |
---|
| | import getopt |
---|
| | import os |
---|
| | import re |
---|
| | import sys |
---|
| | import socket |
---|
| | import time |
---|
| | |
---|
| | #################### |
---|
| | # Booleans |
---|
| |
---|
| | |
---|
| | DONE = FALSE |
---|
| | |
---|
| | #################### |
---|
| | # Constants And Literals |
---|
| | # Constants |
---|
| | #################### |
---|
| | |
---|
| | ANS = ";; ANSWER SECTION:" |
---|
| | AUTH = ";; AUTHORITY SECTION:" |
---|
| | DLEN = 24*60*60 |
---|
| | DIG = "dig -t ptr -x " |
---|
| | HIST = ".abck_history" |
---|
| | HISTFILE = os.path.join(os.getenv("HOME"), HIST) |
---|
| | HOSTNAME = socket.gethostname() |
---|
| | HOSTADDR = socket.gethostbyname(HOSTNAME) |
---|
| | HOSTTZ = time.tzname |
---|
| | LOG = "/var/log/messages" |
---|
| | MOS = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
---|
| | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] |
---|
| | OUT = "./ABUSERS" |
---|
| | NOTIFYWHO = ("abuse", "root") |
---|
| | ORG = os.getenv("ORGANIZATION") |
---|
| | PROMPT = "\nLog Record:\n%s\n\nWho Gets Message For: <%s>? %s[%s] " |
---|
| | WHO = "whois " |
---|
| | |
---|
| | #################### |
---|
| | # Prompt And Message Strings |
---|
| | #################### |
---|
| | |
---|
| | |
---|
| | MAILMSG = "An *unauthorized* attempt to access one of our computers\n" + \ |
---|
| | "has been detected originating from your address space/domain.\n\n" + \ |
---|
| | "Our machine, %s, has IP address,\n%s, and is located in the " + \ |
---|
| | "%s Time Zone.\n\n" + \ |
---|
| | "Our log entry documenting the attempted intrusion\n" + \ |
---|
| | "from your address space/domain, follows:\n\n\"%s\"\n\n" + \ |
---|
| | "Please take the necessary steps to remedy this situation.\n" + \ |
---|
| | "Thank-You\n" + ORG + "\n" |
---|
| | |
---|
| | |
---|
| | USAGE = "abck " + VERSION.split()[2] + " " + \ |
---|
| | "Copyright (c) 2001, TundraWare Inc. All Rights Reserved.\n" + \ |
---|
| | " usage:\n" + \ |
---|
| |
---|
| | # Cache dictionary of all attacking hosts discovered this run of the program |
---|
| | |
---|
| | NameCache = {} |
---|
| | |
---|
| | |
---|
| | #################### |
---|
| | # Globals |
---|
| | #################### |
---|
| | |
---|
| | Processed = [] |
---|
| | |
---|
| | #################### |
---|
| | # Regular Expression Handlers |
---|
| | #################### |
---|
| | |
---|
| |
---|
| | components = host.split(".") |
---|
| | |
---|
| | # And return the recombined pieces we want |
---|
| | return '.'.join(components[-depth:]) |
---|
| | |
---|
| | |
---|
| | #################### |
---|
| | |
---|
| | # Check a name, see if it's an IP quad, and if so, return reverse. |
---|
| |
---|
| | hostname = hostquad |
---|
| | |
---|
| | return hostname |
---|
| | |
---|
| | |
---|
| | #################### |
---|
| | |
---|
| | # Notify the responsible authority about the attempted intrusion |
---|
| | |
---|
| | def Notify(logrecord, domain): |
---|
| | dest=[] |
---|
| | msg = (MAILMSG % (HOSTNAME, HOSTADDR, "/".join(HOSTTZ), logrecord)) |
---|
| | for x in NOTIFYWHO: |
---|
| | dest.append(x + "@" + domain) |
---|
| | dest.append("root@" + HOSTNAME) |
---|
| | |
---|
| | print msg |
---|
| | print dest |
---|
| | |
---|
| | |
---|
| | |
---|
| | |
---|
| | #################### |
---|
| | |
---|
| | # Paw through a log record, doing any reverse resolution needed, |
---|
| |
---|
| | if opt == "-s": |
---|
| | SHOWONLY = TRUE |
---|
| | |
---|
| | |
---|
| | # Loop through the log, processing matching records |
---|
| | |
---|
| | logfile = open(LOG) |
---|
| | abuserfile = open(OUT, "w") |
---|
| | |
---|
| | # Read in the whole log logfileile |
---|
| | for logrecord in logfile.read().splitlines(): |
---|
| | # Read the log into a list |
---|
| | |
---|
| | f = open(LOG, "r") |
---|
| | logfile = [x for x in f.read().splitlines()] |
---|
| | f.close() |
---|
| | |
---|
| | # Remove any previously handled log events from further consideration |
---|
| | |
---|
| | if os.path.exists(HISTFILE): |
---|
| | f = open(HISTFILE, "r") |
---|
| | for histrec in f.read().splitlines(): |
---|
| | if logfile.count(histrec): |
---|
| | logfile.remove(histrec) |
---|
| | f.close() |
---|
| | |
---|
| | |
---|
| | |
---|
| | # Examine, and possibly process, each record in the log |
---|
| | for logrecord in logfile: |
---|
| | |
---|
| | # Check to see whether this record should even be |
---|
| | # processed. |
---|
| | |
---|
| |
---|
| | |
---|
| | # If we passed all those tests, it's time to process this record. |
---|
| | if DOIT: |
---|
| | sendto = ProcessLogRecord(logrecord, NOMATCH, SHOWONLY) |
---|
| | |
---|
| | # If we get a non-null string back, we need to let someone know |
---|
| | # about the attempted intrusion |
---|
| | if sendto: |
---|
| | abuserfile.write("abnot \"" + logrecord + "\" " + |
---|
| | sendto + "\n") |
---|
| | |
---|
| | logfile.close() |
---|
| | abuserfile.close() |
---|
| | |
---|
| | Notify(logrecord, sendto) |
---|
| | Processed.append(logrecord) |
---|
| | |
---|
| | if os.path.exists(HISTFILE): |
---|
| | f = open(HISTFILE, "a") |
---|
| | else: |
---|
| | f = open(HISTFILE, "w") |
---|
| | |
---|
| | for x in Processed: |
---|
| | f.write(x + "\n") |
---|
| | f.close() |
---|
| | |
---|
| | |
---|
| | |
---|
| | |