Exemplo n.º 1
0
    def __init__(self, cred, debug=False):
        """Initialize FirewallEngine."""

        self.cred = cred
        self.logger = logger.SecureTeaLogger(__name__, debug)

        # Parse and setup rules and actions
        (self.ip_inbound,
         self.action_inbound_IPRule) = self.parse_inbound_IPRule()

        (self.ip_outbound,
         self.action_outbound_IPRule) = self.parse_outbound_IPRule()

        (self.protocols, self.action_protocolRule) = self.parse_protocolRule()

        (self.sports,
         self.action_source_portRule) = self.parse_source_portRule()

        (self.dports, self.action_dest_portRule) = self.parse_dest_portRule()

        (self.dns, self.action_DNSRule) = self.parse_DNSRule()

        (self.extensions, self.action_scanLoad) = self.parse_scanLoad()

        self.action_HTTPRequest = self.parse_HTTPRequest()

        self.action_HTTPResponse = self.parse_HTTPResponse()

        # Interface
        self.interface = str(self.cred['interface'])
        if self.interface == "":
            self.interface = utils.get_interface()

        # Setup PacketFilter object
        self.packetFilterObj = PacketFilter(
            interface=self.interface,
            debug=debug,
            ip_inbound=self.ip_inbound,
            ip_outbound=self.ip_outbound,
            protocols=self.protocols,
            dns=self.dns,
            dports=self.dports,
            sports=self.sports,
            extensions=self.extensions,
            action_inbound_IPRule=self.action_inbound_IPRule,
            action_outbound_IPRule=self.action_outbound_IPRule,
            action_DNSRule=self.action_DNSRule,
            action_source_portRule=self.action_source_portRule,
            action_dest_portRule=self.action_dest_portRule,
            action_HTTPResponse=self.action_HTTPResponse,
            action_HTTPRequest=self.action_HTTPRequest,
            action_protocolRule=self.action_protocolRule,
            action_scanLoad=self.action_scanLoad)

        # Setup Montior object
        self.monitorObj = FirewallMonitor(interface=self.interface,
                                          debug=debug)

        # Integrations
        self.integrations = ['Firewall', 'Monitor']
Exemplo n.º 2
0
    def setUp(self):
        """
        Setup test class for FirewallMonitor.
        """

        # Setup firewall_monitor object
        self.firewall_obj = FirewallMonitor(interface='XYZ',
                                            debug=False)
Exemplo n.º 3
0
class FirewallEngine(object):
    """Class for FirewallEngine.

    Working:
        Perform all the heavy lifting and parsing.
        Call PacketFilter and Monitor.
    """
    def __init__(self, cred, debug=False, test=False):
        """Initialize FirewallEngine."""

        self.cred = cred
        self.logger = logger.SecureTeaLogger(__name__, debug)

        # Parse and setup rules and actions
        (self.ip_inbound,
         self.action_inbound_IPRule) = self.parse_inbound_IPRule()

        (self.ip_outbound,
         self.action_outbound_IPRule) = self.parse_outbound_IPRule()

        (self.protocols, self.action_protocolRule) = self.parse_protocolRule()

        (self.sports,
         self.action_source_portRule) = self.parse_source_portRule()

        (self.dports, self.action_dest_portRule) = self.parse_dest_portRule()

        (self.dns, self.action_DNSRule) = self.parse_DNSRule()

        (self.extensions, self.action_scanLoad) = self.parse_scanLoad()

        self.action_HTTPRequest = self.parse_HTTPRequest()

        self.action_HTTPResponse = self.parse_HTTPResponse()

        # Interface
        self.interface = str(self.cred['interface'])
        if self.interface == "":
            self.interface = utils.get_interface()

        # Setup PacketFilter object
        self.packetFilterObj = PacketFilter(
            interface=self.interface,
            debug=debug,
            ip_inbound=self.ip_inbound,
            ip_outbound=self.ip_outbound,
            protocols=self.protocols,
            dns=self.dns,
            dports=self.dports,
            sports=self.sports,
            extensions=self.extensions,
            action_inbound_IPRule=self.action_inbound_IPRule,
            action_outbound_IPRule=self.action_outbound_IPRule,
            action_DNSRule=self.action_DNSRule,
            action_source_portRule=self.action_source_portRule,
            action_dest_portRule=self.action_dest_portRule,
            action_HTTPResponse=self.action_HTTPResponse,
            action_HTTPRequest=self.action_HTTPRequest,
            action_protocolRule=self.action_protocolRule,
            action_scanLoad=self.action_scanLoad,
            test=test)

        # Setup Montior object
        self.monitorObj = FirewallMonitor(interface=self.interface,
                                          debug=debug)

        # Integrations
        self.integrations = ['Firewall', 'Monitor']

    @staticmethod
    def restore_state():
        """
        Restore the iptables state.

        Args:
            None

        Raises:
            None

        Returns:
            None
        """
        resp = utils.excecute_command('iptables --flush')

        if resp[1]:
            self.logger.log(resp[1], logtype="error")

    def parse_inbound_IPRule(self):
        """
        Parse the inbound IP rules and
        generate ip_inbound list.

        Args:
            None

        Raises:
            None

        Returns:
            temp_ip_inbound (list): Parsed IP inbound list
            action (int): 0 or 1
        """
        try:
            return self._extracted_from_parse_outbound_IPRule_4(
                'inbound_IPRule', 'ip_inbound')

        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_outbound_IPRule(self):
        """
        Parse the outbound IP rules and
        generate ip_outbound list.

        Args:
            None

        Raises:
            None

        Returns:
            temp_ip_outbound (list): Parsed IP outbound list
            action (int): 0 or 1
        """
        try:
            return self._extracted_from_parse_outbound_IPRule_4(
                'outbound_IPRule', 'ip_outbound')

        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def _extracted_from_parse_outbound_IPRule_4(self, arg0, arg1):
        action = int(self.cred[arg0]['action'])
        temp_ip_inbound = []
        if len(self.cred[arg0][arg1]):
            list_of_IPs = str(self.cred[arg0][arg1])
            list_of_IPs = list_of_IPs.split(',')
            for IP in list_of_IPs:
                if '-' in IP:
                    for new_ip in utils.generate_IPs(IP):
                        if new_ip not in temp_ip_inbound and utils.check_ip(
                                new_ip):
                            temp_ip_inbound.append(str(new_ip).strip())
                elif utils.check_ip(IP):
                    if IP not in temp_ip_inbound:
                        temp_ip_inbound.append(str(IP).strip())
        return temp_ip_inbound, action

    def parse_protocolRule(self):
        """
        Parse the protocol configurations passed.

        Args:
            None

        Raises:
            None

        Returns:
            temp_protocol (list): Parsed protocol list
            action (int): 0 or 1
        """
        try:
            temp_protocol = []
            action = int(self.cred['protocolRule']['action'])
            if len(self.cred['protocolRule']['protocols']):
                protocols = str(self.cred['protocolRule']['protocols'])
                protocols = protocols.split(',')
                protocols = map(utils.map_protocol, protocols)
                protocols = list(protocols)
                for protocol in protocols:
                    if (protocol and protocol not in temp_protocol):
                        temp_protocol.append(protocol)

            return temp_protocol, action
        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_DNSRule(self):
        """
        Parse the DNS configurations passed.

        Args:
            None

        Raises:
            None

        Returns:
            temp_DNS (list): Parsed DNS list
            action (int): 0 or 1
        """
        try:
            temp_DNS = []
            action = int(self.cred['DNSRule']['action'])
            if len(self.cred['DNSRule']['dns']):
                dns = str(self.cred['DNSRule']['dns'])
                dns = dns.split(',')
                for single_dns in dns:
                    if single_dns not in temp_DNS:
                        temp_DNS.append(str(single_dns).strip())

            return temp_DNS, action
        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_source_portRule(self):
        """
        Parse the source port rules passed and
        generate source ports list.

        Args:
            None

        Raises:
            None

        Returns:
            temp_sports (list): Parsed list of source ports
            action (int): 0 or 1
        """
        try:
            temp_sports = []
            action = int(self.cred['source_portRule']['action'])
            if len(self.cred['source_portRule']['sports']):
                sports = str(self.cred['source_portRule']['sports'])
                sports = sports.split(',')
                for port in sports:
                    if '-' in port:
                        for new_port in utils.generate_ports(port):
                            if (new_port not in temp_sports
                                    and utils.check_port(new_port)):
                                temp_sports.append(str(new_port).strip())
                    elif utils.check_port(port):
                        if port not in temp_sports:
                            temp_sports.append(str(port).strip())

            return temp_sports, action
        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_dest_portRule(self):
        """
        Parse the destination port rules passed and
        generate destination ports list.

        Args:
            None

        Raises:
            None

        Returns:
            temp_dports (list): Parsed list of destination ports
            action (int): 0 or 1
        """
        try:
            temp_dports = []
            action = int(self.cred['dest_portRule']['action'])
            if len(self.cred['dest_portRule']['dports']):
                dports = str(self.cred['dest_portRule']['dports'])
                dports = dports.split(',')
                for port in dports:
                    if '-' in port:
                        for new_port in utils.generate_ports(port):
                            if (new_port not in temp_dports
                                    and utils.check_port(new_port)):
                                temp_dports.append(str(new_port).strip())
                    elif utils.check_port(port):
                        if port not in temp_dports:
                            temp_dports.append(str(port).strip())

            return temp_dports, action
        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_HTTPResponse(self):
        """
        Parse HTTPResponse configurations.

        Args:
            None

        Raises:
            None

        Returns:
            action (int): 0 or 1
        """
        try:
            return int(self.cred['HTTPResponse']['action'])
        except Exception as e:
            self.logger.log('Error: ' + str(e), logtype='error')
            return 1

    def parse_HTTPRequest(self):
        """
        Parse HTTPRequest configurations.

        Args:
            None

        Raises:
            None

        Returns:
            action (int): 0 or 1
        """
        try:
            return int(self.cred['HTTPRequest']['action'])
        except Exception as e:
            self.logger.log('Error: ' + str(e), logtype='error')
            return 1

    def parse_scanLoad(self):
        """
        Parse scan load configurations.

        Args:
            None

        Raises:
            None

        Returns:
            temp_extension (list): Parsed extension list
            action (int): 0 or 1
        """
        try:
            temp_extension = []
            action = int(self.cred['scanLoad']['action'])
            if len(self.cred['scanLoad']['extensions']):
                extensions = str(self.cred['scanLoad']['extensions'])
                extensions = extensions.split(',')
                for extension in extensions:
                    if extension not in temp_extension:
                        temp_extension.append(str(extension).strip())

            return temp_extension, action
        except Exception as e:
            self.logger.log("Error: " + str(e), logtype="error")
            # Return empty list and block action
            return [], 0

    def parse_time(self):
        """
        Parses the time passed and checks
        with the current time.

        Args:
            None

        Raises:
            None

        Returns:
            bool
        """
        try:
            current_time = datetime.datetime.now()
            time_lb = self.cred['time']['time_lb']
            time_ub = self.cred['time']['time_ub']

            datetime_lb = current_time.replace(hour=int(
                (time_lb).split(':')[0]),
                                               minute=int(
                                                   (time_lb).split(':')[1]))
            datetime_ub = current_time.replace(hour=int(
                (time_ub).split(':')[0]),
                                               minute=int(
                                                   (time_ub).split(':')[1]))

            return (current_time > datetime_lb and current_time < datetime_ub)
        except Exception as e:
            self.logger.log('Error: ' + str(e), logtype='error')

    def process_packet(self, pkt):
        """
        Process the packet passed to the PacketFilter.
        If the current CPU time matches the time rule and
        the packet satisfies the packet filter rules,
        allow the packet, else drop the packet.

        Args:
            None

        Raises:
            None

        Returns:
            None
        """
        if (self.packetFilterObj.process(pkt) and self.parse_time):
            pkt.accept()
        else:
            pkt.drop()

    def startFirewall(self):
        """
        Setup netfilterqueue and start
        processing packets in the queue.

        Args:
            None

        Raises:
            None

        Returns:
            None
        """
        input_command = 'iptables -I INPUT -j NFQUEUE --queue-num 0'
        output_command = 'iptables -I OUTPUT -j NFQUEUE --queue-num 0'

        resp = utils.excecute_command(input_command)
        if resp[1]:
            self.logger.log(resp[1], logtype="error")

        resp = utils.excecute_command(output_command)
        if resp[1]:
            self.logger.log(resp[1], logtype="error")

        try:
            queue = netfilterqueue.NetfilterQueue()
            queue.bind(0, self.process_packet)
            queue.run()
        except KeyboardInterrupt:
            # Restore iptables state
            self.restore_state()

    def startMonitor(self):
        """
        Start the montior engine.

        Args:
            None

        Raises:
            None

        Returns:
            None
        """
        self.monitorObj.startMonitoring()

    def startEngine(self):
        """
        Start the FirewallEngine.

        Working:
            Spin two process, one for core firewall engine
            and other for monitoring services.

        Args:
            None

        Raises:
            None

        Returns:
            None
        """
        processes = []

        firewallProcess = multiprocessing.Process(target=self.startFirewall)
        monitorProcess = multiprocessing.Process(target=self.startMonitor)

        firewallProcess.start()
        monitorProcess.start()

        processes.append(firewallProcess)
        processes.append(monitorProcess)

        self.logger.log("Integrations: " + str(self.integrations),
                        logtype="info")

        for process in processes:
            process.join()
Exemplo n.º 4
0
class TestFirewallMonitor(unittest.TestCase):
    """
    Test class for FirewallMonitor.
    """

    def setUp(self):
        """
        Setup test class for FirewallMonitor.
        """

        # Setup firewall_monitor object
        self.firewall_obj = FirewallMonitor(interface='XYZ',
                                            debug=False)

    @patch('securetea.lib.firewall.firewall_monitor.utils')
    def test_check_services(self, mock_utils):
        """
        Test check_services.
        """
        # If error is returned
        mock_utils.excecute_command.return_value = (b'', 'Error')
        self.firewall_obj.check_services()
        self.assertEqual([], self.firewall_obj.services_list)

        # If output is returned
        mock_utils.excecute_command.return_value = (
                            """ [ + ]  acpid\n
                                [ - ]  alsa-utils\n
                                [ - ]  anacron\n
                                [ + ]  apparmor\n
                                [ + ]  apport\n
                                [ + ]  atd\n
                                [ + ]  avahi-daemon\n
                                [ + ]  bluetooth\n
                            """, b'')

        dummy_services_list = ['acpid',
                               'apparmor',
                               'apport',
                               'atd',
                               'avahi-daemon',
                               'bluetooth']

        self.firewall_obj.check_services()
        self.assertEqual(self.firewall_obj.services_list,
                         dummy_services_list)

    @patch('securetea.lib.firewall.firewall_monitor.utils')
    def test_check_process(self, mock_utils):
        """
        Test check_process.
        """
        # If error is returned
        mock_utils.excecute_command.return_value = (b'', 'Error')
        self.firewall_obj.check_process()
        self.assertEqual([], self.firewall_obj.process_list)

        # If output is returned
        mock_utils.excecute_command.return_value = (
                    """
                    UID        PID  PPID  C STIME TTY          TIME CMD
                    root         1     0  0 14:59 ?        00:00:03 /sbin/init splash
                    root         2     0  0 14:59 ?        00:00:00 [kthreadd]
                    root         4     2  0 14:59 ?        00:00:00 [kworker/0:0H]
                    root         5     2  0 14:59 ?        00:00:00 [kworker/u8:0]
                    root         6     2  0 14:59 ?        00:00:00 [mm_percpu_wq]
                    root         7     2  0 14:59 ?        00:00:00 [ksoftirqd/0]
                    root         8     2  0 14:59 ?        00:00:00 [rcu_sched]
                    root         9     2  0 14:59 ?        00:00:00 [rcu_bh]
                    """, b'')

        dummy_process_list = [{'14:59': 'init'},
                              {'14:59': 'kthreadd'},
                              {'14:59': '0:0H'},
                              {'14:59': 'u8:0'},
                              {'14:59': 'mm_percpu_wq'},
                              {'14:59': '0'},
                              {'14:59': 'rcu_sched'},
                              {'14:59': 'rcu_bh'}]

        self.firewall_obj.check_process()
        self.assertEqual(self.firewall_obj.process_list,
                         dummy_process_list)

    @patch('securetea.lib.firewall.firewall_monitor.utils')
    def test_check_open_ports(self, mock_utils):
        """
        Test check_open_ports.
        """
        # If error is returned
        mock_utils.excecute_command.return_value = (b'', 'Error')
        self.firewall_obj.check_open_ports()
        self.assertEqual(self.firewall_obj.open_ports, [])

        # If output is returned
        mock_utils.excecute_command.return_value = (
                    """
                    unix  2      [ ACC ]     STREAM     LISTENING     35521    random1
                    unix  2      [ ACC ]     STREAM     LISTENING     33829    random2
                    """, b'')

        dummy_ports_list = ['35521', '33829']
        self.firewall_obj.check_open_ports()
        self.assertEqual(self.firewall_obj.open_ports,
                         dummy_ports_list)

    @patch('securetea.lib.firewall.firewall_monitor.psutil')
    def test_network_usage(self, mock_psutil):
        """
        Test network_usage.
        """
        mock_psutil.net_io_counters.return_value = """
                               'XYZ': snetio(bytes_sent=53363,
                                             bytes_recv=53363,
                                             packets_sent=604,
                                             packets_recv=604,
                                             errin=0,
                                             errout=0,
                                             dropin=0,
                                             dropout=0)
                                                   """
        self.firewall_obj.network_usage()
        bytes_sent = 53363
        bytes_recv = 53363

        self.assertEqual(self.firewall_obj.network_data['bytes_sent'],
                         bytes_sent)
        self.assertEqual(self.firewall_obj.network_data['bytes_recv'],
                         bytes_recv)

        # Test if IndexError is raised or not
        self.firewall_obj.interface = "XYZ-XYZ"

        with self.assertRaises(IndexError):
            self.firewall_obj.network_usage()