#!/usr/bin/python #written by Nicholas Nachefski #init import getopt, sys, datetime, re, os, subprocess #subs def usage(): print "Usage: %s -w"%sys.argv[0] sys.exit(2) #get options if len(sys.argv) < 1: usage() #globals #global array for watched files Files = [] #global array for syscall and other rules System = [] #get date and time for report info t = datetime.datetime.now() timestamp = t.strftime("%m/%d/%Y %H:%M:%S\n") #discover what arch this system is if re.match('^x86_64$', os.uname()[4]): arch='b64' if re.match('^i\d*86$', os.uname()[4]): arch='b32' #check our args from optparse import OptionParser parser = OptionParser() parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="do not write the policy, print to stdout") (options, args) = parser.parse_args() #main function def main(): print "Starting run:", timestamp #check for httpd # look for active httpd conf files with 'httpd -S' try: retcode = subprocess.call(['/sbin/service httpd status &> /dev/null'], shell=True) if retcode == 0: if os.path.isfile('/etc/httpd/conf/httpd.conf'): Files.append(['/etc/httpd/conf/httpd.conf', 'ids-file-low']) f = open('/etc/httpd/conf/httpd.conf', 'r') for line in f: if re.match('^\s*Include', line): m = re.match(r"^\s*Include\s*(.+)", line) test = m.group(1) if re.match('^/.+', test): lsline = test else: lsline = "/etc/httpd/" + test output = subprocess.Popen(['ls ' + lsline], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ).communicate()[0] array = output.split("\n") for a in array: if re.match('^$', a): continue else: Files.append([a, 'ids-file-low']) output = subprocess.Popen(['httpd -S'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0] if re.search('\(.+\:\d\)', output): m = re.findall('\(.+\:', output) for line in m: c = line.strip(':') conf = c.strip('(') inc = 0 for test in Files: if test[0] == conf: inc = inc+1 if inc == 0: Files.append([conf, 'ids-file-low']) except OSError, e: print >>sys.stderr, "Execution failed:", e sys.exit(1) #check for mysql retcode = subprocess.call(['/sbin/service mysqld status &> /dev/null'], shell=True) if retcode == 0: if os.path.isfile('/etc/my.cnf'): Files.append(['/etc/my.cnf', 'ids-file-hi']) #check for yum if os.path.isfile('/etc/yum.conf'): Files.append(['/etc/yum.conf', 'ids-file-med']) #check for user cronjobs files = os.listdir('/var/spool/cron') for i in files: Files.append(['/var/spool/cron/' + i, 'ids-file-hi']) #check for xinetd services files = os.listdir('/etc/xinetd.d') for i in files: Files.append(['/etc/xinetd.d/' + i, 'ids-file-low']) #check for pam files files = os.listdir('/etc/pam.d') for i in files: Files.append(['/etc/pam.d/' + i, 'ids-file-hi']) #check for system crons if os.path.isfile('/etc/crontab'): Files.append(['/etc/crontab', 'ids-file-hi']) files = os.listdir('/etc/cron.hourly') for i in files: Files.append(['/etc/cron.hourly/' + i, 'ids-file-low']) files = os.listdir('/etc/cron.daily') for i in files: Files.append(['/etc/cron.daily/' + i, 'ids-file-low']) files = os.listdir('/etc/cron.weekly') for i in files: Files.append(['/etc/cron.weekly/' + i, 'ids-file-low']) files = os.listdir('/etc/cron.monthly') for i in files: Files.append(['/etc/cron.monthly/' + i, 'ids-file-low']) #check for ldap/nss files if os.path.isfile('/etc/ldap.conf'): Files.append(['/etc/ldap.conf', 'ids-file-hi']) if os.path.isfile('/etc/nsswitch.conf'): Files.append(['/etc/nsswitch.conf', 'ids-file-hi']) if os.path.isfile('/etc/nscd.conf'): Files.append(['/etc/nscd.conf', 'ids-file-hi']) #user stuff if os.path.isfile('/etc/passwd'): Files.append(['/etc/passwd', 'ids-file-low']) if os.path.isfile('/etc/shadow'): Files.append(['/etc/shadow', 'ids-file-low']) if os.path.isfile('/etc/group'): Files.append(['/etc/group', 'ids-file-low']) #grub if os.path.isfile('/boot/grub/grub.conf'): Files.append(['/boot/grub/grub.conf', 'ids-file-hi']) #check for ssh configs if os.path.isfile('/etc/ssh/sshd_config'): Files.append(['/etc/ssh/sshd_config', 'ids-file-hi']) if os.path.isfile('/etc/ssh/ssh_config'): Files.append(['/etc/ssh/ssh_config', 'ids-file-hi']) #shell files if os.path.isfile('/etc/bashrc'): Files.append(['/etc/bashrc', 'ids-file-low']) #iptables policy if os.path.isfile('/etc/sysconfig/iptables.save'): Files.append(['/etc/sysconfig/iptables.save', 'ids-file-low']) if os.path.isfile('/etc/sysconfig/iptables'): Files.append(['/etc/sysconfig/iptables', 'ids-file-low']) #host stuff if os.path.isfile('/etc/hosts'): Files.append(['/etc/hosts', 'ids-file-low']) if os.path.isfile('/etc/resolv.conf'): Files.append(['/etc/resolv.conf', 'ids-file-med']) if os.path.isfile('/etc/sysconfig/network'): Files.append(['/etc/sysconfig/network', 'ids-file-hi']) #network scripts files = os.listdir('/etc/sysconfig/network-scripts/') for i in files: if re.search('ifcfg-eth', i): Files.append(['/etc/sysconfig/network-scripts/' + i, 'ids-file-hi']) #system stuff if os.path.isfile('/etc/sysctl.conf'): Files.append(['/etc/sysctl.conf', 'ids-file-hi']) #check sudoers file if os.path.isfile('/etc/sudoers'): Files.append(['/etc/sudoers', 'ids-file-hi']) #check fstab if os.path.isfile('/etc/fstab'): Files.append(['/etc/fstab', 'ids-file-hi']) #inittab if os.path.isfile('/etc/inittab'): Files.append(['/etc/inittab', 'ids-file-hi']) #prelude stuff if os.path.isfile('/etc/prelude/default/global.conf'): Files.append(['/etc/prelude/default/global.conf', 'ids-file-med']) if os.path.isfile('/etc/prelude/default/client.conf'): Files.append(['/etc/prelude/default/client.conf', 'ids-file-med']) #audit config if os.path.isfile('/etc/audit/audit.rules'): Files.append(['/etc/audit/audit.rules', 'ids-file-hi']) if os.path.isfile('/etc/audisp/audispd.conf'): Files.append(['/etc/audisp/audispd.conf', 'ids-file-hi']) if os.path.isfile('/etc/audisp/audisp-prelude.conf'): Files.append(['/etc/audisp/audisp-prelude.conf', 'ids-file-hi']) if os.path.isfile('/etc/audisp/audisp-remote.conf'): Files.append(['/etc/audisp/audisp-remote.conf', 'ids-file-hi']) #finished finding configs to monitor ##now add syscall related stuff to monitor here ##- Unauthorized access attempts to files (unsuccessful) System.append('-a always,exit -F arch=' + arch + ' -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k ids-exec-hi') System.append('-a always,exit -F arch=' + arch + ' -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k ids-exec-hi') ##watch for nmap usage System.append('-a always,exit -F path=/usr/bin/nmap -F perm=x -k ids-exec-hi') ###now build the audit plolicy if options.debug: print "-D\n-b 1024" for path, pri in Files: print '-a exit,always -F arch=' + arch + ' -S open -F path=' + path + ' -F perm=wa ' + '-k ' + pri else: filename = "/etc/audit/audit.rules" print "Writing audit policy to: %s" % filename file = open(filename, 'w') file.write("#policy created: " + timestamp) file.write("-D\n-b 1024\n") for path, pri in Files: file.write('-a exit,always -F arch=' + arch + ' -S open -F path=' + path + ' -F perm=wa ' + '-k ' + pri + '\n') file.close() #now restart auditd for the changes to take effect retcode = subprocess.call(['/sbin/service auditd restart &> /dev/null'], shell=True) if retcode != 0: print "Restart of auditd failed!!!!!" sys.exit(1) else: print "auditd restarted...." #exit cleanly sys.exit(0) #call main if __name__ == "__main__": main()