Beispiel #1
0
class TaxiiLogger(BaseLogger):
    def __init__(self, data_dir, work_dir, config='glastopf.cfg'):
        config = os.path.join(work_dir, config)
        BaseLogger.__init__(self, config)
        self.options = {'enabled': self.config.getboolean('taxii', 'enabled')}
        self.host = self.config.get('taxii', 'host')
        self.port = self.config.getint('taxii', 'port')
        self.inbox_path = self.config.get('taxii', 'inbox_path')
        self.use_https = self.config.getboolean('taxii', 'use_https')
        self.client = HttpClient()
        self.client.setProxy('noproxy')

        auth_credentials = {
            'username': self.config.get('taxii', 'auth_basic_username'),
            'password': self.config.get('taxii', 'auth_basic_password'),
            'key_file': self.config.get('taxii', 'auth_certificate_keyfile'),
            'cert_file': self.config.get('taxii', 'auth_certificate_certfile')
        }
        self.client.setAuthCredentials(auth_credentials)

        if self.config.getboolean('taxii', 'use_auth_basic'):
            self.client.setAuthType(tc.HttpClient.AUTH_BASIC)
        elif self.config.getboolean('taxii', 'use_auth_certificate'):
            self.client.setAuthType(tc.HttpClient.AUTH_CERT)
        elif self.config.getboolean(
                'taxii', 'use_auth_basic') and self.config.getboolean(
                    'taxii', 'use_auth_certificate'):
            self.client.setAuthType(tc.HttpClient.AUTH_CERT_BASIC)
        else:
            self.client.setAuthType(tc.HttpClient.AUTH_NONE)

        self.stix_transformer = StixTransformer(self.config, data_dir)

    def insert(self, event):
        # converts from conpot log format to STIX compatible xml
        stix_package = self.stix_transformer.transform(event)

        # wrapping the stix message in a TAXII envelope
        bytestream = bytes(bytearray(stix_package, encoding='utf-8'))
        content_block = ContentBlock(libtaxii.CB_STIX_XML_10, bytestream)

        inbox_message = InboxMessage(message_id=generate_message_id(),
                                     content_blocks=[content_block])
        inbox_xml = inbox_message.to_xml()

        # the actual call to the TAXII web service
        response = self.client.callTaxiiService2(self.host, self.inbox_path,
                                                 libtaxii.VID_TAXII_XML_11,
                                                 inbox_xml, self.port)
        response_message = libtaxii.get_message_from_http_response(
            response, '0')

        if response_message.status_type != libtaxii.messages.ST_SUCCESS:
            logger.error(
                'Error while transmitting message to TAXII server: {0}'.format(
                    response_message.status_detail))
            return False
        else:
            return True
Beispiel #2
0
class TaxiiLogger(BaseLogger):
    def __init__(self, data_dir, configFile='glastopf.cfg'):
        if isinstance(configFile, ConfigParser):
            config = configFile
        else:
            config = ConfigParser()
            config.read(configFile)
        self.options = {'enabled': config.getboolean('taxii', 'enabled')}
        self.host = config.get('taxii', 'host')
        self.port = config.getint('taxii', 'port')
        self.inbox_path = config.get('taxii', 'inbox_path')
        self.use_https = config.getboolean('taxii', 'use_https')
        self.client = HttpClient()
        self.client.setProxy('noproxy')

        auth_credentials = {'username': config.get('taxii', 'auth_basic_username'),
                            'password': config.get('taxii', 'auth_basic_password'),
                            'key_file': config.get('taxii', 'auth_certificate_keyfile'),
                            'cert_file': config.get('taxii', 'auth_certificate_certfile')}
        self.client.setAuthCredentials(auth_credentials)

        if config.getboolean('taxii', 'use_auth_basic'):
            self.client.setAuthType(tc.HttpClient.AUTH_BASIC)
        elif config.getboolean('taxii', 'use_auth_certificate'):
            self.client.setAuthType(tc.HttpClient.AUTH_CERT)
        elif config.getboolean('taxii', 'use_auth_basic') and config.getboolean('taxii', 'use_auth_certificate'):
            self.client.setAuthType(tc.HttpClient.AUTH_CERT_BASIC)
        else:
            self.client.setAuthType(tc.HttpClient.AUTH_NONE)

        self.stix_transformer = StixTransformer(config, data_dir)

    def insert(self, event):
        # converts from conpot log format to STIX compatible xml
        stix_package = self.stix_transformer.transform(event)

        # wrapping the stix message in a TAXII envelope
        content_block = ContentBlock(libtaxii.CB_STIX_XML_10, stix_package)

        inbox_message = InboxMessage(message_id=generate_message_id(), content_blocks=[content_block])
        inbox_xml = inbox_message.to_xml()

        # the actual call to the TAXII web service
        response = self.client.callTaxiiService2(self.host, self.inbox_path, libtaxii.VID_TAXII_XML_10, inbox_xml, self.port)
        response_message = libtaxii.get_message_from_http_response(response, '0')

        if response_message.status_type != libtaxii.messages.ST_SUCCESS:
            logger.error('Error while transmitting message to TAXII server: {0}'.format(response_message.status_detail))
            return False
        else:
            return True
Beispiel #3
0
class Test_Stix(unittest.TestCase):
    def setUp(self):
        self.config = ConfigParser()
        self.config.add_section('taxii')
        self.config.set('taxii', 'enabled', "True")
        self.config.set('taxii', 'include_contact_info', "True")
        self.config.set('taxii', 'contact_name', 'James Bond')
        self.config.set('taxii', 'contact_email', '[email protected]')
        self.config.set('taxii', 'host', 'taxiitest.mitre.org')
        self.config.set('taxii', 'port', '80')
        self.config.set('taxii', 'inbox_path', '/services/inbox/default/')
        self.config.set('taxii', 'use_auth_basic', 'False')
        self.config.set('taxii', 'auth_basic_username', 'your_username')
        self.config.set('taxii', 'auth_basic_password', 'your_password')
        self.config.set('taxii', 'use_auth_certificate', 'False')
        self.config.set('taxii', 'auth_certificate_keyfile', 'keyfile_oath')
        self.config.set('taxii', 'auth_certificate_certfile', 'certfile_path')
        self.config.set('taxii', 'use_https', 'True')

        self.tmpdir = tempfile.mkdtemp()
        self.files_dir = os.path.join(self.tmpdir, 'files')
        os.mkdir(self.files_dir)
        self.stix_transformer = StixTransformer(self.config, self.tmpdir)
        self.xml_validator = STIXValidator(None, True, False)

    def tearDown(self):
        if os.path.isdir(self.tmpdir):
            shutil.rmtree(self.tmpdir)

    def test_stix_transform(self):
        """
        Objective: Test if the expected XML is generated from a "unknown" attack event.
        """

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content,
                                              None,
                                              server_version="",
                                              sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)

        (isvalid, validation_error,
         best_practice_warnings) = self.xml_validator.validate(
             StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(
            isvalid,
            'Error while parsing STIX xml: {0}'.format(validation_error))
        self.assertTrue(
            '<HTTPSessionObj:User_Agent>test</HTTPSessionObj:User_Agent>' in
            stix_package_xml)
        self.assertTrue(
            '<HTTPSessionObj:HTTP_Method datatype="string">GET</HTTPSessionObj:HTTP_Method>'
            in stix_package_xml)
        self.assertTrue('<HTTPSessionObj:Value>/test</HTTPSessionObj:Value>' in
                        stix_package_xml)
        self.assertTrue(
            '<HTTPSessionObj:Version>HTTP/1.0</HTTPSessionObj:Version>' in
            stix_package_xml)

    def test_stix_transform_invalid_header(self):
        """
        Objective: Test if we can generate valid XML from a HTTP request with a invalid header item.
        """

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nXUser-XAgent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content,
                                              None,
                                              server_version="",
                                              sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)

        (isvalid, validation_error,
         best_practice_warnings) = self.xml_validator.validate(
             StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(
            isvalid,
            'Error while parsing STIX xml: {0}'.format(validation_error))
        #TODO: Parse XML and check content of header, request_line, etc.

    def test_stix_transform_event_with_rfidata(self):
        """
        Objective: Test if the expected XML is generated from a "unknown" attack event.
        """

        rfi_data = """<?php echo "<script>alert("test");</script>";?>"""
        rfi_md5 = hashlib.md5(rfi_data).hexdigest()
        with open(os.path.join(self.files_dir, rfi_md5), 'w') as rfi_file:
            rfi_file.writelines(rfi_data)

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        test_event.matched_pattern = 'rfi'
        test_event.file_name = rfi_md5
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content,
                                              None,
                                              server_version="",
                                              sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)
        (isvalid, validation_error,
         best_practice_warnings) = self.xml_validator.validate(
             StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(
            isvalid,
            'Error while parsing STIX xml: {0}'.format(validation_error))
        self.assertTrue(
            '<cyboxCommon:Simple_Hash_Value>0e209064ee6949f6e57b3d77d5b1f92c</cyboxCommon:Simple_Hash_Value>'
            in stix_package_xml)
        self.assertTrue(
            '<cyboxCommon:Simple_Hash_Value>11a2a92d391f10821dbb90f1f7e6ae0f2374231e0ccd611665c95d6d7a3bb43c</cyboxCommon:Simple_Hash_Value>'
            in stix_package_xml)
        self.assertTrue(
            '<ArtifactObj:Raw_Artifact datatype="string"><![CDATA[PD9waHAgZWNobyAiPHNjcmlwdD5hbGVydCgidGVzdCIpOzwvc2NyaXB0PiI7Pz4=]]></ArtifactObj:Raw_Artifact>'
            in stix_package_xml)

    def test_taxii_connectivity(self):
        """
        Objective: Test if we can send a message to mitre's test TAXII server.
        """
        self.config.set('taxii', 'use_https', 'False')
        config_file = tempfile.mkstemp()[1]
        with open(config_file, 'w') as f:
            self.config.write(f)
        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content,
                                              None,
                                              server_version="",
                                              sys_version="")

        taxiiLogger = TaxiiLogger(self.tmpdir, os.getcwd(), config_file)
        taxii_result = taxiiLogger.insert(test_event)
        # TaxiiLogger returns false if the message could not be delivered
        self.assertTrue(taxii_result)
        f.close()  #clean the tempfile

    def test_taxii_connectivity_https(self):
        """
        Objective: Test if we can send a message to mitre's test TAXII server using https.
        """
        self.config.set('taxii', 'use_https', 'True')
        config_file = tempfile.mkstemp()[1]
        with open(config_file, 'w') as f:
            self.config.write(f)
        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content,
                                              None,
                                              server_version="",
                                              sys_version="")

        taxiiLogger = TaxiiLogger(self.tmpdir, os.getcwd(), config_file)
        taxii_result = taxiiLogger.insert(test_event)
        # TaxiiLogger returns false if the message could not be delivered
        self.assertTrue(taxii_result)
        f.close()  #clean the tempfile
Beispiel #4
0
class Test_Stix(unittest.TestCase):

    def setUp(self):
        self.config = ConfigParser()
        self.config.add_section('taxii')
        self.config.set('taxii', 'enabled', "True")
        self.config.set('taxii', 'include_contact_info', "True")
        self.config.set('taxii', 'contact_name', 'James Bond')
        self.config.set('taxii', 'contact_email', '[email protected]')
        self.config.set('taxii', 'host', 'taxiitest.mitre.org')
        self.config.set('taxii', 'port', '80')
        self.config.set('taxii', 'inbox_path', '/services/inbox/default/')
        self.config.set('taxii', 'use_auth_basic', 'False')
        self.config.set('taxii', 'auth_basic_username', 'your_username')
        self.config.set('taxii', 'auth_basic_password', 'your_password')
        self.config.set('taxii', 'use_auth_certificate', 'False')
        self.config.set('taxii', 'auth_certificate_keyfile', 'keyfile_oath')
        self.config.set('taxii', 'auth_certificate_certfile', 'certfile_path')
        self.config.set('taxii', 'use_https', 'True')

        self.tmpdir = tempfile.mkdtemp()
        self.files_dir = os.path.join(self.tmpdir, 'files')
        os.mkdir(self.files_dir)
        self.stix_transformer = StixTransformer(self.config, self.tmpdir)
        self.xml_validator = STIXValidator(None, True, False)

    def tearDown(self):
        if os.path.isdir(self.tmpdir):
            shutil.rmtree(self.tmpdir)

    def test_stix_transform(self):
        """
        Objective: Test if the expected XML is generated from a "unknown" attack event.
        """

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content, None, server_version="", sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)

        (isvalid, validation_error, best_practice_warnings) = self.xml_validator.validate(StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(isvalid, 'Error while parsing STIX xml: {0}'.format(validation_error))
        self.assertTrue('<HTTPSessionObj:User_Agent>test</HTTPSessionObj:User_Agent>' in stix_package_xml)
        self.assertTrue('<HTTPSessionObj:HTTP_Method datatype="string">GET</HTTPSessionObj:HTTP_Method>' in stix_package_xml)
        self.assertTrue('<HTTPSessionObj:Value>/test</HTTPSessionObj:Value>' in stix_package_xml)
        self.assertTrue('<HTTPSessionObj:Version>HTTP/1.0</HTTPSessionObj:Version>' in stix_package_xml)

    def test_stix_transform_invalid_header(self):
        """
        Objective: Test if we can generate valid XML from a HTTP request with a invalid header item.
        """

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nXUser-XAgent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content, None, server_version="", sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)

        (isvalid, validation_error, best_practice_warnings) = self.xml_validator.validate(StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(isvalid, 'Error while parsing STIX xml: {0}'.format(validation_error))
        #TODO: Parse XML and check content of header, request_line, etc.

    def test_stix_transform_event_with_rfidata(self):
        """
        Objective: Test if the expected XML is generated from a "unknown" attack event.
        """

        rfi_data = """<?php echo "<script>alert("test");</script>";?>"""
        rfi_md5 = hashlib.md5(rfi_data).hexdigest()
        with open(os.path.join(self.files_dir, rfi_md5), 'w') as rfi_file:
            rfi_file.writelines(rfi_data)

        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        test_event.matched_pattern = 'rfi'
        test_event.file_name = rfi_md5
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content, None, server_version="", sys_version="")
        stix_package_xml = self.stix_transformer.transform(test_event)
        (isvalid, validation_error, best_practice_warnings) = self.xml_validator.validate(StringIO(stix_package_xml.encode('utf-8')))
        self.assertTrue(isvalid, 'Error while parsing STIX xml: {0}'.format(validation_error))
        self.assertTrue('<cyboxCommon:Simple_Hash_Value>0e209064ee6949f6e57b3d77d5b1f92c</cyboxCommon:Simple_Hash_Value>' in stix_package_xml)
        self.assertTrue('<cyboxCommon:Simple_Hash_Value>11a2a92d391f10821dbb90f1f7e6ae0f2374231e0ccd611665c95d6d7a3bb43c</cyboxCommon:Simple_Hash_Value>' in stix_package_xml)
        self.assertTrue('<ArtifactObj:Raw_Artifact datatype="string"><![CDATA[PD9waHAgZWNobyAiPHNjcmlwdD5hbGVydCgidGVzdCIpOzwvc2NyaXB0PiI7Pz4=]]></ArtifactObj:Raw_Artifact>' in stix_package_xml)

    def test_taxii_connectivity(self):
        """
        Objective: Test if we can send a message to mitre's test TAXII server.
        """
        self.config.set('taxii', 'use_https', 'False')
        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content, None, server_version="", sys_version="")

        taxiiLogger = TaxiiLogger(self.tmpdir, self.config)
        taxii_result = taxiiLogger.insert(test_event)
        # TaxiiLogger returns false if the message could not be delivered
        self.assertTrue(taxii_result)

    def test_taxii_connectivity_https(self):
        """
        Objective: Test if we can send a message to mitre's test TAXII server using https.
        """
        self.config.set('taxii', 'use_https', 'True')
        test_event = AttackEvent()
        test_event.source_addr = ('1.2.3.4', 43811)
        http_request_content = """GET /test HTTP/1.0\r\nUser-Agent: test\r\n\r\n"""
        test_event.http_request = HTTPHandler(http_request_content, None, server_version="", sys_version="")

        taxiiLogger = TaxiiLogger(self.tmpdir, self.config)
        taxii_result = taxiiLogger.insert(test_event)
        # TaxiiLogger returns false if the message could not be delivered
        self.assertTrue(taxii_result)