def main(): parser = argparse.ArgumentParser( description='Analyse audit information from mod_security2') parser.add_argument('--rule-summary', action='store_true', help='Print a summary of rules triggered') parser.add_argument('--file-summary', action='store_true', help='Print a summary of rule files used') parser.add_argument('--client-summary', action='store_true', help='Print a summary of clients') parser.add_argument('--uri-summary', action='store_true', help='Print a summary of host/uri requests') build_parser(parser) args = parser.parse_args() entries = parse_and_filter(args) if len(entries) > 0: fh = sys.stdout if args.output is None else open(args.output, 'w') if args.rule_summary: fh.write(rule_summary(entries)) if args.file_summary: fh.write(file_summary(entries)) if args.client_summary: fh.write(client_summary(entries)) if args.uri_summary: fh.write(uri_summary(entries)) if args.show_requests: fh.write("\nREQUEST SUMMARIES:\n") for e in entries: fh.write(entries[e].as_string(args.include_headers)) if args.show_full: fh.write("\nFULL REQUEST LOG:\n") for e in entries: fh.write(entries[e].raw_data()) if args.output is not None: fh.close() print("\nOutput saved to {}".format(args.output)) print("\nFinished.")
def main(): parser = argparse.ArgumentParser(description='Analyse audit information from mod_security2') parser.add_argument('--rule-summary', action='store_true', help='Print a summary of rules triggered') parser.add_argument('--file-summary', action='store_true', help='Print a summary of rule files used') parser.add_argument('--client-summary', action='store_true', help='Print a summary of clients') parser.add_argument('--uri-summary', action='store_true', help='Print a summary of host/uri requests') build_parser(parser) args = parser.parse_args() entries = parse_and_filter(args) if len(entries) > 0: fh = sys.stdout if args.output is None else open(args.output, 'w') if args.rule_summary: fh.write(rule_summary(entries)) if args.file_summary: fh.write(file_summary(entries)) if args.client_summary: fh.write(client_summary(entries)) if args.uri_summary: fh.write(uri_summary(entries)) if args.show_requests: fh.write("\nREQUEST SUMMARIES:\n") for e in entries: fh.write(entries[e].as_string(args.include_headers)) if args.show_full: fh.write("\nFULL REQUEST LOG:\n") for e in entries: fh.write(entries[e].raw_data()) if args.output is not None: fh.close() print("\nOutput saved to {}".format(args.output)) print("\nFinished.")
def main(): parser = argparse.ArgumentParser(description='Analyse audit logs and extract rules') build_parser(parser) parser.add_argument('--ignore', type=int, default=20, help='Level below which to ignore rules (default=20)') parser.add_argument('--block', action='store_true', help='Set all rules to block') parser.add_argument('--log', action='store_true', help='Set all rules to log') parser.add_argument('--nolog', action='store_true', help='Set all rules to NOT log') parser.add_argument('--deny', action='store_true', help='Set all rules to deny') parser.add_argument('--allow', action='store_true', help='Set all rules to allow') parser.add_argument('--skip-conf', help='Ignore rules from the file specified') parser.add_argument('--copy-files', action='store_true', help='Attempt to copy required files') args = parser.parse_args() if args.log and args.nolog: print("You cannot use --log and --nolog at the same time. D'uh.") sys.exit(0) if args.allow and (args.block or args.deny): print("Using --allow and --block or --deny won't work.") sys.exit(0) if args.copy_files and args.output is None: print("Unable to copy any files as you haven't specified an output filename.") entries = parse_and_filter(args) if len(entries) == 0: print("No entries to work with... Nothing to do :-)") sys.exit(0) rules = {} files = {} for e in entries: for rr in entries[e].rules: rules.setdefault(rr.tag(b'msg'), RuleSummary(rr)).increment() print("\nGetting a list of rules to be extracted...\n") for r in rules: rr = rules[r] if rr.n < args.ignore: print(" - '{}' is below ignore threshold, ignoring...".format(rr.msg)) continue files.setdefault(rr.file, {'rules': []})['rules'].append(rr) print("\nComplete.\n\nExtracting rules...") for fn in files: if not os.path.exists(fn): print(" - {} does not exist, skipping.".format(fn)) continue if args.skip_conf == fn: print(" - skipping file {} due --skip-conf setting".format(fn)) continue rf = RulesFile(fn) for r in files[fn]['rules']: r.get_rules(rf) if args.block: r.add_action('block') if args.deny: r.add_action('deny') if args.allow: r.add_action('allow') r.remove_action('deny') r.remove_action('block') if args.log: r.add_action('log') r.remove_action('nolog') elif args.nolog: r.add_action('nolog') r.remove_action('log') fh = sys.stdout if args.output is None else open(args.output, 'w') fh.write("# Automatically generated file by extract_rules\n") fh.write("# https://github.com/zathras777/modsec_tools\n#\n") fh.write("# Created {}\n".format(datetime.today())) fh.write("# Files analysed:\n") for fn in args.files: fh.write("# - {}\n".format(fn)) fh.write("#\n") if has_filters(args): fh.write("# Filter Criteria:\n") for crit in filter_description(args): fh.write("# - {}\n".format(crit)) fh.write("#\n") fh.write("# Total of {} audit log entries analysed.\n#\n\n".format(len(entries))) file_list = [] for r in rules: rr = rules[r] if rr.n < args.ignore: continue fh.write(rr.as_string()) fh.write("\n\n") if rr.needs_files: file_list.extend(rr.file_list()) if len(file_list) > 0: print("\nAdditional files are needed for some rules:\n") for fn in list(set(file_list)): print(" - {}".format(fn)) if args.output is not None and args.copy_files: if os.path.exists(fn): nfn = os.path.join(os.path.dirname(args.output), os.path.basename(fn)) if not os.path.exists(nfn): print(" found file, attempting to copy...") shutil.copy(fn, nfn) else: print(" file already exists in required location") else: print(" file not found, unable to copy.") print("\n") if args.output is not None: fh.close() print("\nNew rule file saved to {}".format(args.output))
def main(): parser = argparse.ArgumentParser( description='Analyse audit logs and extract rules') build_parser(parser) parser.add_argument('--ignore', type=int, default=20, help='Level below which to ignore rules (default=20)') parser.add_argument('--block', action='store_true', help='Set all rules to block') parser.add_argument('--log', action='store_true', help='Set all rules to log') parser.add_argument('--nolog', action='store_true', help='Set all rules to NOT log') parser.add_argument('--deny', action='store_true', help='Set all rules to deny') parser.add_argument('--allow', action='store_true', help='Set all rules to allow') parser.add_argument('--skip-conf', help='Ignore rules from the file specified') parser.add_argument('--copy-files', action='store_true', help='Attempt to copy required files') args = parser.parse_args() if args.log and args.nolog: print("You cannot use --log and --nolog at the same time. D'uh.") sys.exit(0) if args.allow and (args.block or args.deny): print("Using --allow and --block or --deny won't work.") sys.exit(0) if args.copy_files and args.output is None: print( "Unable to copy any files as you haven't specified an output filename." ) entries = parse_and_filter(args) if len(entries) == 0: print("No entries to work with... Nothing to do :-)") sys.exit(0) rules = {} files = {} for e in entries: for rr in entries[e].rules: rules.setdefault(rr.tag(b'msg'), RuleSummary(rr)).increment() print("\nGetting a list of rules to be extracted...\n") for r in rules: rr = rules[r] if rr.n < args.ignore: print(" - '{}' is below ignore threshold, ignoring...".format( rr.msg)) continue files.setdefault(rr.file, {'rules': []})['rules'].append(rr) print("\nComplete.\n\nExtracting rules...") for fn in files: if not os.path.exists(fn): print(" - {} does not exist, skipping.".format(fn)) continue if args.skip_conf == fn: print(" - skipping file {} due --skip-conf setting".format(fn)) continue rf = RulesFile(fn) for r in files[fn]['rules']: r.get_rules(rf) if args.block: r.add_action('block') if args.deny: r.add_action('deny') if args.allow: r.add_action('allow') r.remove_action('deny') r.remove_action('block') if args.log: r.add_action('log') r.remove_action('nolog') elif args.nolog: r.add_action('nolog') r.remove_action('log') fh = sys.stdout if args.output is None else open(args.output, 'w') fh.write("# Automatically generated file by extract_rules\n") fh.write("# https://github.com/zathras777/modsec_tools\n#\n") fh.write("# Created {}\n".format(datetime.today())) fh.write("# Files analysed:\n") for fn in args.files: fh.write("# - {}\n".format(fn)) fh.write("#\n") if has_filters(args): fh.write("# Filter Criteria:\n") for crit in filter_description(args): fh.write("# - {}\n".format(crit)) fh.write("#\n") fh.write("# Total of {} audit log entries analysed.\n#\n\n".format( len(entries))) file_list = [] for r in rules: rr = rules[r] if rr.n < args.ignore: continue fh.write(rr.as_string()) fh.write("\n\n") if rr.needs_files: file_list.extend(rr.file_list()) if len(file_list) > 0: print("\nAdditional files are needed for some rules:\n") for fn in list(set(file_list)): print(" - {}".format(fn)) if args.output is not None and args.copy_files: if os.path.exists(fn): nfn = os.path.join(os.path.dirname(args.output), os.path.basename(fn)) if not os.path.exists(nfn): print(" found file, attempting to copy...") shutil.copy(fn, nfn) else: print(" file already exists in required location") else: print(" file not found, unable to copy.") print("\n") if args.output is not None: fh.close() print("\nNew rule file saved to {}".format(args.output))