From 1caa123374f57e95c64c06e8a6fe66b920f72d93 Mon Sep 17 00:00:00 2001 From: Nuno Date: Thu, 15 Jun 2023 02:53:28 +0000 Subject: [PATCH] LOL - totally new version, it actually works this time. still not sure about the nmap input... I should really look into that. --- ExclusionEnforcer.py | 123 ++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/ExclusionEnforcer.py b/ExclusionEnforcer.py index 70d2fcd..31c72dd 100644 --- a/ExclusionEnforcer.py +++ b/ExclusionEnforcer.py @@ -1,70 +1,75 @@ -import os -import sys -from ipaddress import ip_network, ip_address +#!/usr/bin/env python3 +import argparse +from ipaddress import ip_network +from subprocess import run + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='👾 ExclusionEnforcer: Your all-in-one tool for scope grinding and firewall rule manipulation. ✨', + epilog='''Example usage: + python3 scopegrinder.py scope.txt deny.txt output.txt RuleName + python3 scopegrinder.py -r RuleName''') + + parser.add_argument('-s', '--scope', + help='Path to the file containing the scope IP ranges. Each IP or IP range should be on a new line. Required unless -r is set.') + + parser.add_argument('-d', '--deny', + help='Path to the file containing the deny list IP ranges. Each IP or IP range should be on a new line. Required unless -r is set.') + + parser.add_argument('-o', '--output', + help='Path to the file where to write the valid IPs. The file will be created if it does not exist. Required unless -r is set.') + + parser.add_argument('-n', '--rule_name', + help='Name to be used when creating or removing firewall rules. This will be used in the comment field of the iptables rules.') + + parser.add_argument('-r', '--remove', + help='If set with rule name, the script will remove the specified iptables rules instead of adding them. When this is set, scope, deny and output parameters can be omitted.') + + args = parser.parse_args() + + if args.remove: + if any([args.scope, args.deny, args.output]): + parser.error("--remove should not be used with scope, deny, or output parameters.") + else: + if not all([args.scope, args.deny, args.output, args.rule_name]): + parser.error("When not using --remove, the scope, deny, output and rule_name parameters are required.") + + return args def expand_ip_ranges(ip_ranges): for ip_range in ip_ranges: - if '-' in ip_range: # If IP range is a hyphenated range - start_ip, end_ip = ip_range.split('-') - start_last_octet = start_ip.split('.')[-1] - end_last_octet = end_ip.split('.')[-1] - start_ip_prefix = start_ip.rsplit('.', 1)[0] - for i in range(int(start_last_octet), int(end_last_octet) + 1): - yield f"{start_ip_prefix}.{i}" - else: # If IP range is a CIDR notation - for ip in ip_network(ip_range): - yield str(ip) + for ip in ip_network(ip_range): + yield str(ip) -def add_to_iptables(deny_list_ips, rule_name): - for ip in deny_list_ips: - os.system(f"iptables -A OUTPUT -d {ip} -j DROP -m comment --comment \"{rule_name}\"") - print(f"✅ Applied iptables rules to block outgoing traffic to deny list IPs.") - -def remove_from_iptables(rule_name): - os.system(f"iptables -S | grep '\"{rule_name}\"' | sed 's/-A/-D/' | while read -r line ; do iptables $line ; done") - print(f"❌ Removed iptables rules blocking outgoing traffic to deny list IPs.") - -def main(scope_file_path, deny_list_file_path, output_file_path=None, rule_name=None, remove=False): - with open(scope_file_path, 'r') as f: - scope_ips = set(line.strip() for line in f) # Load scope IPs - - with open(deny_list_file_path, 'r') as f: - deny_list_ips = set(expand_ip_ranges(line.strip() for line in f)) # Load and expand deny list IPs - - valid_ips = scope_ips - deny_list_ips # Compute valid IPs - - if output_file_path: # Write valid IPs to output file if provided - with open(output_file_path, 'w') as f: - for ip in valid_ips: - f.write(ip + '\n') - print(f"📝 Valid IP addresses have been written to {output_file_path}.") - else: # Print valid IPs to console otherwise +def write_valid_ips(scope_file, deny_file, output_file): + with open(scope_file) as f: + scope_ips = set(expand_ip_ranges(line.strip() for line in f)) + with open(deny_file) as f: + deny_ips = set(expand_ip_ranges(line.strip() for line in f)) + valid_ips = scope_ips - deny_ips + with open(output_file, 'w') as f: for ip in valid_ips: - print(ip) - print("🖨️ Valid IP addresses have been printed to the console.") + print(ip, file=f) + return valid_ips - if rule_name: # Apply/remove iptables rules if rule name is provided +def update_firewall_rules(valid_ips, rule_name, remove): + for ip in valid_ips: if remove: - remove_from_iptables(rule_name) + cmd = ['iptables', '-D', 'OUTPUT', '-d', ip, '-j', 'DROP', '-m', 'comment', '--comment', rule_name] else: - add_to_iptables(deny_list_ips, rule_name) + cmd = ['iptables', '-A', 'OUTPUT', '-d', ip, '-j', 'DROP', '-m', 'comment', '--comment', rule_name] + run(cmd) -if __name__ == "__main__": - if len(sys.argv) < 3: - print("Usage: python ExclusionEnforcer.py [output_file] [--iptables=] [--remove]") - print("\nArguments:") - print(" scope_file\t\tPath to the file containing the scope IPs") - print(" deny_list_file\tPath to the file containing the deny list IPs") - print(" output_file\t\t(Optional) Path to the output file") - print(" --iptables=\t(Optional) Apply iptables rules to block outgoing traffic to deny list IPs and tag them with a rule name") - print(" --remove\t\t(Optional) Remove iptables rules tagged with the rule name provided with --iptables") - sys.exit(1) +def main(): + args = parse_arguments() - scope_file_path = sys.argv[1] - deny_list_file_path = sys.argv[```python -2] - output_file_path = sys.argv[3] if len(sys.argv) > 3 and not sys.argv[3].startswith('--') else None - rule_name = sys.argv[sys.argv.index('--iptables')+1] if '--iptables' in sys.argv else None - remove = True if '--remove' in sys.argv else False + if args.remove: + update_firewall_rules([], args.remove, True) + else: + valid_ips = write_valid_ips(args.scope, args.deny, args.output) + update_firewall_rules(valid_ips, args.rule_name, False) - main(scope_file_path, deny_list_file_path, output_file_path, rule_name, remove) + print("💥 ExclusionEnforcer has done its job. Check your scope and firewall rules. 💥") + +if __name__ == '__main__': + main() \ No newline at end of file