def __init__(self, config_in=None, verbose=0, log_response=False, execute=True): super(SetFirewall, self).__init__(verbose=verbose) self.config_in = config_in self.verbose = verbose self.parse_args() self.it = Interact() self.root_check = self.it.root_check(debug=False) self.firewall = {} self.execute = execute self.command_list = [] # TODO Check if IPTABLES is in path and raise Exception if not if self.config_in is not None: self.config = BWConfig(self.config_in)
def __init__(self, config_in=None, DEBUG=False, VERBOSE=False, legacy=False): self.debug = DEBUG self.verbose = VERBOSE self.legacy = legacy self.win_config = [] self.errlog = [] self.it = Interact() if config_in is not None: self.configs = config(config=config_in, VERBOSE=self.verbose) Validation(config_in, verbose=self.verbose).validate() if self.verbose: self.set_firewall = SetFirewall(config_in=config_in, verbose=2) else: self.set_firewall = SetFirewall(config_in=config_in, verbose=0) self.target_ranges = self.configs.configs.get('target_range', '') self.trusted_range = self.configs.configs.get('trusted_range', '') self.nostrike = self.configs.configs.get('nostrike', '') if self.debug: print self.configs else: raise Exception("[-] Please specify a configuration path!") self.GREEN_PLUS = "[{gp}+{endc}]".format(gp=bcolors.OKGREEN, endc=bcolors.ENDC)
def __init__(self, subnet=None, config_in=None, threads=4, shuffle=False, verbose=False): super(pingSweep, self).__init__(verbose=verbose) if subnet is not None: try: self.subnet_raw = subnet self.subnet = list(ipaddr.IPNetwork(subnet)) except: raise Exception( 'Please ensure your subnet is in proper format: 192.168.1.0/24' ) # TODO ADD NOSTRIKE AND MAKE OUTPUT FOR SCANNER NESSUS COMPATIBLE (IP,\n,IP) self.threads = threads self.queue = Queue() self.alive = 0 self.alive_hosts = [] self.shuffle = random self.it = Interact() self.root_check = self.it.root_check(debug=False) self.parse_args() self.config_in = config_in self.shuffle = shuffle self.verbose = verbose print config_in if config_in is not None: self.configs = config(config=config_in, VERBOSE=self.verbose) #Validation(config_in, verbose=self.verbose).validate() self.target_ranges = self.configs.configs.get('target_range', '') self.trusted_range = self.configs.configs.get('trusted_range', '') self.nostrike = self.configs.configs.get('nostrike', '') else: #print("[-] Please specify a configuration path!") self.nostrike = None self.GREEN_PLUS = "[{green}+{endc}]".format(green=bcolors.OKGREEN, endc=bcolors.ENDC) self.WARN = "[{red}!{endc}]".format(red=bcolors.WARNING, endc=bcolors.ENDC) self.INFO = "[{obc}INFO{endc}]".format(obc=bcolors.OKBLUE, endc=bcolors.ENDC)
def eth_iface_check(self, data): valid = False all_iface = [ iface for iface in Interact().run_command( "nmcli d | cut -d' ' -f 1").split('\n')[1:] if iface != '' ] if data in all_iface: valid = True return valid
def __init__(self, VERBOSE=False, DEBUG=False, config=None, legacy=False): self.verbose = VERBOSE self.debug = DEBUG self.it = Interact() self.ethIFName = None self.mac_address = None self.legacy = legacy self.GET_HOSTNAME = "nmcli d | grep ethernet | cut -d' ' -f 1" self.ETH_CONFIG_PATH = "/etc/sysconfig/network-scripts/ifcfg-" self.SET_HOSTNAME = "hostnamectl set-hostname " if config is not None: self.configs = AOR(config=config).configs if self.debug: print self.configs else: print( "[*] No config was passed. Some functions may not work properly" )
class SetFirewall(BwCli): def __init__(self, config_in=None, verbose=0, log_response=False, execute=True): super(SetFirewall, self).__init__(verbose=verbose) self.config_in = config_in self.verbose = verbose self.parse_args() self.it = Interact() self.root_check = self.it.root_check(debug=False) self.firewall = {} self.execute = execute self.command_list = [] # TODO Check if IPTABLES is in path and raise Exception if not if self.config_in is not None: self.config = BWConfig(self.config_in) ALLOW_DHCP = '1 -p udp --dport 67:68 --sport 67:68 -j ACCEPT' ALLOW_ICMP_8 = '1 -p icmp --icmp-type 8 -j ACCEPT' ALLOW_ICMP_0 = '1 -p icmp --icmp-type 0 -j ACCEPT' ALLOW_NET_ICMP_8 = '1 -d {net} -p icmp --icmp-type 8 -j ACCEPT' ALLOW_NET_ICMP_0 = '1 -d {net} -p icmp --icmp-type 0 -j ACCEPT' ALLOW_NET_ICMP = '1 -d {net} -p icmp -j ACCEPT' DISALLOW_DHCP = '1 -p udp --dport 67:68 --sport 67:68 -j DROP' DISALLOW_ICMP_8 = '1 -p icmp --icmp-type 8 -j DROP' DISALLOW_NET_ICMP = '1 -d {net} -p icmp -j DROP' # COLOR OUTPUT GREEN_PLUS = "[{green}+{endc}]".format(green=bcolors.OKGREEN, endc=bcolors.ENDC) OUTBOUND_C = "{obc}outbound{endc}".format(obc=bcolors.BOLD, endc=bcolors.ENDC) INBOUND_C = "{obc}outbound{endc}".format(obc=bcolors.BOLD, endc=bcolors.ENDC) def rule_builder(self, argument, append_rule=None, chain_options='iof'): chains = {'i': 'INPUT', 'o': 'OUTPUT', 'f': 'FORWARD'} if append_rule is not None: rule_list = ['iptables -{argument} {chain} {append_rule}'.format(chain=chains[i], argument=argument, append_rule=append_rule) for i in chain_options] else: rule_list = ['iptables -{argument} {chain}'.format(chain=chains[i], argument=argument) for i in chain_options] return rule_list def network_validator(self, network): try: ipaddr.IPNetwork(network) except Exception as e: raise Exception("Please validate your subnet. Valid input: 192.168.0.0/24") return True def data_validator(self, data): if type(data) == str: data = [data] elif type(data) == list: data = data return data def flush_rules(self): # Clear rules rules = self.rule_builder('F') self.command_list.extend(rules) if self.verbose > 0: print('{gp} Rules Flushed!'.format(gp=self.GREEN_PLUS)) return def set_policy(self, policy): # Set Policy for each chain rules = self.rule_builder('P', policy) self.command_list.extend(rules) return rules def set_defaults(self): self.set_policy('DROP') self.allow_related_conn() return def log_exceptions(self): rules = self.rule_builder('A', append_rule='-m limit --limit 5/min -j LOG') self.command_list.extend(rules) if self.verbose > 0: print('{gp} Logging Exceptions'.format(gp=self.GREEN_PLUS)) return rules def allow_localhost(self): rules = self.rule_builder('I', chain_options='io', append_rule='-s 127.0.0.1/8 -d 127.0.0.1/8 -j ACCEPT') self.command_list.extend(rules) if self.verbose > 0: print("{gp} Allowing traffic for localhost.".format(gp=self.GREEN_PLUS)) return def allow_all(self): # FLUSH RULES self.flush_rules() rules = self.set_policy('ACCEPT') self.command_list.extend(rules) if self.verbose > 0: print("{gp} Allowing all...".format(gp=self.GREEN_PLUS)) return def deny_all(self): # FLUSH RULES self.set_defaults() self.allow_localhost() if self.args.log_exceptions: self.log_exceptions() if self.verbose > 0: print("{gp} Disallowing all...".format(gp=self.GREEN_PLUS)) return def allow_dhcp(self): rules = self.rule_builder('I', chain_options='io', append_rule=self.ALLOW_DHCP) self.command_list.extend(rules) if self.verbose > 0: print("{gp} Allowing DHCP...".format(gp=self.GREEN_PLUS)) return def disallow_dhcp(self): rules = self.rule_builder('I', chain_options='io', append_rule=self.DISALLOW_DHCP) self.command_list.extend(rules) if self.verbose > 0: print( "{gp}{red} Disallowing {endc} DHCP...".format(gp=self.GREEN_PLUS, red=bcolors.FAIL, endc=bcolors.ENDC)) return def all_icmp(self, status=1): if status == 0: rules = self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_ICMP_8) rules += self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_ICMP_0) self.command_list.extend(rules) else: rules = self.rule_builder('I', chain_options='o', append_rule=' 1 -p icmp -j ACCEPT') self.command_list.extend(rules) if self.verbose > 0: print("{gp} Allowing {outbound} ICMP...".format(gp=self.GREEN_PLUS, outbound=self.OUTBOUND_C)) return def all_icmp_network(self, status=1, networks='0.0.0.0/0'): networks = self.data_validator(networks) try: for network in networks: self.network_validator(network) # STATUS 0 allows just Ping, set to 1 to allow ALL if status == 0: rules = self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_NET_ICMP_8.format(net=network)) rules += self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_NET_ICMP_0.format(net=network)) self.command_list.extend(rules) else: rules = self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_NET_ICMP.format(net=network)) self.command_list.extend(rules) if self.verbose > 0: print( "{gp} Allowing {outbound} ICMP/traceroute to {net}...".format(net=network, outbound=self.OUTBOUND_C, gp=self.GREEN_PLUS)) except: raise Exception("[!] Could not parse subnet. Please ensure proper format: 192.168.0.0/24") return def allow_ping(self): rules = [] rules += self.rule_builder('I', chain_options='i', append_rule=self.ALLOW_ICMP_0) rules += self.rule_builder('I', chain_options='i', append_rule=self.ALLOW_ICMP_8) rules += self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_ICMP_0) rules += self.rule_builder('I', chain_options='o', append_rule=self.ALLOW_ICMP_8) self.command_list.extend(rules) if self.verbose > 0: print("{gp} Respond to pings...".format(gp=self.GREEN_PLUS)) return def disallow_ping(self): rules = self.rule_builder('I', chain_options='i', append_rule=self.DISALLOW_ICMP_8) self.command_list.extend(rules) if self.verbose > 0: print("{gp} Disallowing incoming pings...".format(gp=self.GREEN_PLUS)) return def set_nostrike(self, networks=[]): networks = self.data_validator(networks) if networks: rules = [] for network in networks: rules += self.rule_builder('I', chain_options='i', append_rule='1 -s {net} -j DROP'.format(net=network)) rules += self.rule_builder('I', chain_options='o', append_rule='1 -d {net} -j DROP'.format(net=network)) if self.verbose: print("{gp} {red}DISALLOWING{endr} traffic to {net} ".format(net=network, red=bcolors.FAIL, endr=bcolors.ENDC, gp=self.GREEN_PLUS)) self.command_list.extend(rules) return def reset_conn(self): rules = self.rule_builder('A', append_rule='-j REJECT') self.command_list.extend(rules) if self.verbose > 0: print("{gp} Send tcp-reset for unwanted connections...".format(gp=self.GREEN_PLUS)) return def allow_related_conn(self): rules = self.rule_builder('I', chain_options='io', append_rule=' 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT') self.command_list.extend(rules) if self.verbose > 0: print("{gp} Allowing related connections...".format(gp=self.GREEN_PLUS)) return def allow_outbound_transport(self, protocol='tcp', ports=[]): # TODO Maybe able to remove allowed_protocols = ['tcp', 'udp'] if protocol not in allowed_protocols: raise Exception('[!] Protocol must be udp or tcp') if len(ports) == 0: rules = self.rule_builder('I', chain_options='o', append_rule='1 -p {protocol} -j ACCEPT'.format(protocol=protocol)) self.command_list.extend(rules) if self.verbose > 0: print("{gp} Not limiting {outbound} {protocol} connections.".format(protocol=protocol.upper(), gp=self.GREEN_PLUS, outbound=self.OUTBOUND_C)) else: ports = ','.join([str(p) for p in ports]) rules = self.rule_builder('I', chain_options='o', append_rule='1 -p {protocol} -m multiport --dports {ports} -j ACCEPT'.format( ports=ports, protocol=protocol)) self.command_list.extend(rules) if self.verbose > 0: print("[+] Limiting {outbound} connections to {protocol} ports: {ports}".format(ports=ports, outbound=self.OUTBOUND_C, protocol=protocol.upper())) return def allow_network_transport(self, direction=None, trusted=False, protocol='tcp', ports=[], networks='0.0.0.0', policy='ACCEPT'): if direction is None: raise Exception("[-] Must specify a direction!\nOptions: inbound, outbound") direction_map = {'inbound': 'i', 'outbound': 'o'} policy_accept = ['ACCEPT', 'DROP', 'REJECT'] if policy not in policy_accept: raise Exception('Policy must be either ACCEPT, DROP or REJECT') allowed_protocols = ['tcp', 'udp'] ports = ','.join([str(p) for p in ports]) networks = self.data_validator(networks) # Adding ability to switch between source and destination path = 'd' if trusted: path = 's' if protocol not in allowed_protocols: raise Exception('[!] Protocol must be udp or tcp') try: if networks: for network in networks: if len(ports) == 0: rules = self.rule_builder('I', chain_options=direction_map[direction], append_rule='1 -{path} {net} -p {protocol} -j {policy}'.format( path=path, protocol=protocol, net=network, policy=policy)) self.command_list.extend(rules) if self.verbose > 0: print("{gp} Limiting {direction} {protocol} connections to {net}.".format( protocol=protocol.upper(), gp=self.GREEN_PLUS, direction=bcolors.BOLD + direction + bcolors.ENDC, net=network)) else: rules = self.rule_builder('I', chain_options=direction_map[direction], append_rule='1 -{path} {net} -p {protocol} -m multiport --dports {ports} -j {policy}'.format( path=path, ports=ports, policy=policy, protocol=protocol, net=network)) self.command_list.extend(rules) if self.verbose > 0: if policy == 'DROP': print( "{red} Disallowing{end} {direction} {protocol} connections to {net} ports: {ports}".format( ports=ports, protocol=protocol.upper(), direction=bcolors.BOLD + direction + bcolors.ENDC, red=bcolors.FAIL, end=bcolors.ENDC, net=network)) print("{gp} Limiting {direction} {protocol} connections to {net} ports: {ports}".format( ports=ports, protocol=protocol.upper(), direction=bcolors.BOLD + direction + bcolors.ENDC, gp=self.GREEN_PLUS, net=network)) except Exception as e: raise Exception("[-] Rule could not be applied.\nReason: %s" % e) return def outbound_host(self): self.all_icmp() self.allow_outbound_transport(protocol='tcp') return def show_rules(self): self.it.run_command('iptables -nvL', VERBOSE=2) return def process_commands(self): if self.verbose: verbose = 2 else: verbose = 0 self.it.run_commands(self.command_list, VERBOSE=0) return
class config(object): def __init__(self, VERBOSE=False, DEBUG=False, config=None, legacy=False): self.verbose = VERBOSE self.debug = DEBUG self.it = Interact() self.ethIFName = None self.mac_address = None self.legacy = legacy self.GET_HOSTNAME = "nmcli d | grep ethernet | cut -d' ' -f 1" self.ETH_CONFIG_PATH = "/etc/sysconfig/network-scripts/ifcfg-" self.SET_HOSTNAME = "hostnamectl set-hostname " if config is not None: self.configs = AOR(config=config).configs if self.debug: print self.configs else: print( "[*] No config was passed. Some functions may not work properly" ) def get_rhel_eth_ifaces(self): return [ iface for iface in Interact().run_command( "nmcli d | cut -d' ' -f 1").split('\n')[1:] if iface != '' ] def get_rhel_eth_name(self): eth_if_name = self.value_extract('iface') #eth_if_name = Interact().run_command(self.GET_HOSTNAME).strip() return eth_if_name def generate_mac(self): mac = [ 0x00, 0x16, 0x3e, random.randint(0x00, 0x7f), random.randint(0x00, 0xff), random.randint(0x00, 0xff) ] return ':'.join(map(lambda x: "%02x".upper() % x, mac)) def config_rhel(self): self.ethIFName = self.get_rhel_eth_name() if self.ethIFName: self.create_rhel_eth_config() self.cycle_rhel_ethernet(restart_network=False) else: self.log_error( "Error, ethernet device not found. RHEL interface not configured." ) self.set_rhel_hostname() return def value_extract(self, key): setting = '' try: setting = self.configs.get(key)[0] except: pass return setting def create_rhel_eth_config(self): config_path = self.ETH_CONFIG_PATH + self.ethIFName if self.verbose or self.debug: print "writing eth config to " + config_path dns_addr = self.value_extract('dns') rh_ipaddr = self.value_extract('rh_ipaddr') cidr_prefix = self.value_extract('cidr_prefix') gateway_addr = self.value_extract('gateway_addr') try: self.mac_address = self.value_extract('rh_mac') except: self.mac_address = None if self.debug: print self.configs.get('dns')[0] print self.configs.get('rh_ipaddr')[0] print self.configs.get('cidr_prefix')[0] print self.configs.get('gateway_addr')[0] with open(config_path, 'w') as c: c.write('TYPE="Ethernet"' + '\n') c.write('BOOTPROTO=none' + '\n') c.write('NAME=' + self.ethIFName + '\n') c.write('DEVICE="' + self.ethIFName + '"\n') c.write('ONBOOT=no\n') c.write('DEFROUTE="yes"\n') c.write('IPV4_FAILURE_FATAL=no\n') c.write('DNS1=' + dns_addr + '\n') c.write('IPADDR=' + rh_ipaddr + '\n') c.write('PREFIX=' + cidr_prefix + '\n') c.write('GATEWAY=' + gateway_addr + '\n') if self.mac_address is not None or self.mac_address != '': if self.mac_address == '*': c.write("MACADDR=" + self.generate_mac() + '\n') else: c.write("MACADDR=" + self.mac_address + '\n') if self.verbose: verify_config = open(config_path).read() print("[{blue}CONFIGURATION{end}]".format(blue=bcolors.OKBLUE, end=bcolors.ENDC)) print(verify_config) def cycle_rhel_ethernet(self, restart_network=False): self.it.run_command("ifdown " + self.ethIFName) if self.verbose: print("[+] Interface {name} shutdown.".format(name=self.ethIFName)) if restart_network: self.restart_network_service() self.it.run_command("ifup " + self.ethIFName) if self.verbose: print("[+] Interface {name} brought up.".format( name=self.ethIFName)) def restart_network_service(self): self.it.run_command("systemctl restart network") if self.verbose: print("[+] Restarting Network Service") def set_rhel_hostname(self): try: rh_host = self.configs['rh_host'][0] except: rh_host = self.it.demand_input( "RHEL hostname not defined. Please enter a hostname: ") self.it.run_command(self.SET_HOSTNAME + rh_host) def legacy_files(self, trusted_file=None, target_file=None, nostrikes_file=None): if self.legacy: """ process targets """ if target_file: AOR.target_parser(target_file) if self.verbose: print("[+] Target file written to {target_file}".format( target_file=target_file)) if trusted_file: AOR.trusted_parser(trusted_file) if self.verbose: print("[+] Trusted file written to {trusted_file}".format( trusted_file=trusted_file)) if nostrikes_file: AOR.trusted_parser(nostrikes_file) if self.verbose: print("[+] No-strikes file written to {nostrikes_file}". format(nostrikes_file=nostrikes_file))
def get_rhel_eth_ifaces(self): return [ iface for iface in Interact().run_command( "nmcli d | cut -d' ' -f 1").split('\n')[1:] if iface != '' ]
class pingSweep(BsCli): def __init__(self, subnet=None, config_in=None, threads=4, shuffle=False, verbose=False): super(pingSweep, self).__init__(verbose=verbose) if subnet is not None: try: self.subnet_raw = subnet self.subnet = list(ipaddr.IPNetwork(subnet)) except: raise Exception( 'Please ensure your subnet is in proper format: 192.168.1.0/24' ) # TODO ADD NOSTRIKE AND MAKE OUTPUT FOR SCANNER NESSUS COMPATIBLE (IP,\n,IP) self.threads = threads self.queue = Queue() self.alive = 0 self.alive_hosts = [] self.shuffle = random self.it = Interact() self.root_check = self.it.root_check(debug=False) self.parse_args() self.config_in = config_in self.shuffle = shuffle self.verbose = verbose print config_in if config_in is not None: self.configs = config(config=config_in, VERBOSE=self.verbose) #Validation(config_in, verbose=self.verbose).validate() self.target_ranges = self.configs.configs.get('target_range', '') self.trusted_range = self.configs.configs.get('trusted_range', '') self.nostrike = self.configs.configs.get('nostrike', '') else: #print("[-] Please specify a configuration path!") self.nostrike = None self.GREEN_PLUS = "[{green}+{endc}]".format(green=bcolors.OKGREEN, endc=bcolors.ENDC) self.WARN = "[{red}!{endc}]".format(red=bcolors.WARNING, endc=bcolors.ENDC) self.INFO = "[{obc}INFO{endc}]".format(obc=bcolors.OKBLUE, endc=bcolors.ENDC) def shuffle_host(self): random.shuffle(self.subnet) return self.subnet def pinger(self, i, q): """PING SUBNET""" nostrike = None # ACCOUNTS FOR IPS IN NO STRIKE -- THEY WILL NOT BE TOUCHED if self.nostrike: nostrike = [ str(x) for b in self.nostrike for x in ipaddr.IPNetwork(b) ] while True: ip = q.get() if nostrike and ip not in nostrike: ret = subprocess.call("ping -c 1 %s" % ip, shell=True, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT) if ret == 0: print('{gp} {ip} is alive'.format(gp=self.GREEN_PLUS, ip=str(ip))) self.alive += 1 self.alive_hosts.append(str(ip)) q.task_done() return # Spawn thread pool def thread_pool(self): for i in range(self.threads): worker = Thread(target=self.pinger, args=(i, self.queue)) worker.setDaemon(True) worker.start() return def queue_workers(self): for ip in self.subnet: self.queue.put(ip) return def get_alive(self): if self.shuffle: self.shuffle_host() self.thread_pool() self.queue_workers() print( str('{info} Processing {subnet_length} hosts for {subnet} using {x} threads' .format(info=self.INFO, subnet=self.subnet_raw, subnet_length=len(self.subnet), x=self.threads))) self.queue.join() if self.verbose and self.alive: print( str("{gp} {alive} alive hosts in subnet".format( alive=self.alive, gp=self.INFO))) if self.verbose and not self.alive: print( str("{rm} {alive} alive hosts in subnet".format( alive=self.alive, rm=self.WARN))) return self.alive_hosts # ALLOW PING BY DEFAULT #ps = pingSweep(subnet='172.16.63.0/24', config_in='/home/assessor/PycharmProjects/bluewall/configs/exampleconfig.ini', shuffle=True)