def do_command(self):
     client = QRadarAdvisorClient(qradar_host=self.system_host,
                                  qradar_token=self.system_token,
                                  advisor_app_id=self.opts_dict["app_id"],
                                  cafile=False,
                                  log=logging)
     resp = client.offense_insights(self.opts_dict["offense"])
     print("Status: {}\n Content: {}".format(str(resp), resp.content))
 def do_command(self):
     client = QRadarAdvisorClient(qradar_host=self.system_host,
                                  qradar_token=self.system_token,
                                  advisor_app_id=self.opts_dict["app_id"],
                                  cafile=False,
                                  log=logging)
     resp = client.quick_search(self.opts_dict["search"])
     print(str(resp))
Beispiel #3
0
	def do_command(self):
		client = QRadarAdvisorClient(qradar_host=self.system_host,
									 qradar_token=self.system_token,
									 advisor_app_id=self.opts_dict["app_id"],
									 cafile=False, log=logging,
									 opts={}, function_opts=self.opts_dict)
		client.get_csrf_token()

		print("The XSRF_TOKEN is {}".format(client.http_info.xsrf_token))
 def do_command(self):
     client = QRadarAdvisorClient(qradar_host=self.system_host,
                                  qradar_token=self.system_token,
                                  advisor_app_id=self.opts_dict["app_id"],
                                  cafile=False,
                                  log=logging,
                                  opts={},
                                  function_opts=self.opts_dict)
     resp = client.offense_insights(self.opts_dict["offense"])
     print("Return: {}".format(str(resp)))
Beispiel #5
0
    def test_full_search_by_id(self, mocked_get_search_result,
                               mocked_get_session, mocked_update_session):

        #
        # First verify that if there is no CSRF token, the full_search
        # function will call get_csrf_token to get one
        #
        mocked_cookies = Mock()
        # Use this to mock the member variables
        mocked_session = Mock(cookies=mocked_cookies)
        mocked_get_session.return_value = mocked_session

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=QRADAR_VERIFY,
                                     log=logging)
        #
        # when a QRadarAdvisorClient is instantiated, its http_info shall
        # has no csrf token
        #
        assert not client.http_info.xsrf_token

        try:
            mocked_session.get.return_value = _generate_response({}, 400)
            client.full_search_by_id(123456)
            assert False
        except CsrfTokenError:
            #
            # because the CSRF token is None, full_search has to call get_csrf_token
            # to get it. Since we returned 400 above, the full_search call
            # shall throw this exception
            #
            assert True

        #
        # Now put a CSRF token
        #
        client.http_info.xsrf_token = CSRF_TOKEN
        ret_cookies = {"XSRF-TOKEN": CSRF_TOKEN}
        mocked_cookies.get_dict.return_value = ret_cookies

        #
        # This time full_search will call the full search endpoint
        #

        stix_json = {"type": "bundles"}
        mocked_get_search_result.return_value = stix_json

        search_id = 1234

        ret = client.full_search_by_id(search_id)
        mocked_get_search_result.assert_called_with(search_id)

        assert ret == stix_json
Beispiel #6
0
    def do_command(self):
        client = QRadarAdvisorClient(qradar_host=self.system_host,
                                     qradar_token=self.system_token,
                                     advisor_app_id=self.opts_dict["app_id"],
                                     cafile=False,
                                     log=logging)
        offense_id = self.opts_dict["offense_id"]
        restart_if_existed = self.opts_dict.get("restart_if_exist",
                                                "False") == "True"

        stix_json = client.offense_analysis(
            offense_id=offense_id, restart_if_existed=restart_if_existed)

        print(json.dumps(stix_json))
    def _qradar_advisor_quick_search_function(self, event, *args, **kwargs):
        """Function:
        Perform a QRadar Advisor quick search for an indicator.
        The indicator is given as qradar_advisor_search_value in the input.
        The QRadar Advisor reply is in json format.
        This function forwards the QRadar Advisor reply to Resilient server, so
        that user can process it in post-process script. """
        try:
            # Get the function parameters:
            qradar_advisor_search_value = kwargs.get(
                "qradar_advisor_search_value")  # text

            log = logging.getLogger(__name__)
            log.info("qradar_advisor_search_value: %s",
                     qradar_advisor_search_value)

            qradar_verify_cert = True
            if "verify_cert" in self.options and self.options[
                    "verify_cert"] == "false":
                qradar_verify_cert = False

            yield StatusMessage("starting...")
            client = QRadarAdvisorClient(
                qradar_host=self.options["qradar_host"],
                qradar_token=self.options["qradar_advisor_token"],
                advisor_app_id=self.options["qradar_advisor_app_id"],
                cafile=qradar_verify_cert,
                log=log,
                opts=self.opts,
                function_opts=self.options)

            ret_json = client.quick_search(qradar_advisor_search_value)

            yield StatusMessage("done...")

            log.debug("Return json is:{}".format(json.dumps(ret_json)))

            results = ret_json

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            log.error(str(e))
            yield FunctionError(str(e))
Beispiel #8
0
    def do_command(self):
        client = QRadarAdvisorClient(qradar_host=self.system_host,
                                     qradar_token=self.system_token,
                                     advisor_app_id=self.opts_dict["app_id"],
                                     cafile=False,
                                     log=logging)
        search_value = self.opts_dict["search"]
        try:
            search_id = int(search_value)
            #
            #   It is a serach id.
            #   For example: -i 1102 -s 2
            #
            resp = client.full_search_by_id(search_id)
        except ValueError as e:
            #
            # It is not a search_id. Try the full search from start
            # For example: -i 1102 -s user:jsmith
            #
            resp = client.full_search(self.opts_dict["search"])

        print(str(resp))
Beispiel #9
0
def selftest_function(opts):
    """
    Placeholder for selftest function. An example use would be to test package api connectivity.
    Suggested return values are be unimplemented, success, or failure.
    """
    qradar_verify_cert = True
    options = opts.get("fn_qradar_advisor", {})
    if "verify_cert" in options and options["verify_cert"] == "false":
        qradar_verify_cert = False

    try:
        qraw_client = QRadarAdvisorClient(qradar_host=options["qradar_host"],
                                          qradar_token=options["qradar_advisor_token"],
                                          advisor_app_id=options["qradar_advisor_app_id"],
                                          cafile=qradar_verify_cert, log=log,
                                          opts=opts, function_opts=options)
        r = qraw_client.test_connectivity()
        if r.status_code == 200:
            return {"state": "success", "status_code": r.status_code}
        else:
            return {"state": "failure", "status_code": r.status_code}

    except Exception as e:
        return {"state": "failure", "status_code": str(e)}
Beispiel #10
0
    def test_set_methods(self):
        stage = "stage1"
        timeout = 3600
        period = 10

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=False,
                                     log=logging)
        client.set_full_search_stage(stage)
        assert client.full_search_stage == stage

        client.set_full_search_timeout(timeout)
        assert client.full_search_timeout == timeout

        client.set_full_search_period(period)
        assert client.full_search_period == period
Beispiel #11
0
    def test_get_csrf_token(self, mocked_get_session, mocked_update_session):

        mocked_cookies = Mock()
        # Use this to mock the member variables
        mocked_session = Mock(cookies=mocked_cookies)
        mocked_get_session.return_value = mocked_session

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=QRADAR_VERIFY,
                                     log=logging)

        mocked_session.get.return_value = _generate_response({}, 200)
        ret_cookies = {"XSRF-TOKEN": CSRF_TOKEN}
        mocked_cookies.get_dict.return_value = ret_cookies

        client.get_csrf_token()

        #
        # Assert that QRadarAdvisorClient is calling the /about endpoint to get CSRF token
        #
        url = QRADAR_API_BASE_URL + "/about"
        mocked_session.get.assert_called_with(url=url, verify=QRADAR_VERIFY)
        #
        # Assert that QRadarAdvisorClient is using the cookies (ret_cookies here)
        # returned from the mocked session to update the HttpInfo.
        #
        mocked_update_session.assert_called_with(ret_cookies)

        #
        # Verify error handling. Simulate that the /about endpoint returns 400
        #
        mocked_session.get.return_value = _generate_response({}, 400)
        try:
            client.get_csrf_token()
            assert False
        except CsrfTokenError:
            assert True
Beispiel #12
0
    def test_offense_analysis(self, mocked_get_search_result,
                              mocked_perform_search, mocked_get_session):

        #
        # First verify that if there is no CSRF token, the full_search
        # function will call get_csrf_token to get one
        #
        mocked_cookies = Mock()
        # Use this to mock the member variables
        mocked_session = Mock(cookies=mocked_cookies)
        mocked_get_session.return_value = mocked_session

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=QRADAR_VERIFY,
                                     log=logging)
        #
        # when a QRadarAdvisorClient is instantiated, its http_info shall
        # has no csrf token
        #
        assert not client.http_info.xsrf_token

        try:
            mocked_session.get.return_value = _generate_response({}, 400)
            client.offense_analysis(123456)
            assert False
        except CsrfTokenError:
            #
            # because the CSRF token is None, full_search has to call get_csrf_token
            # to get it. Since we returned 400 above, the full_search call
            # shall throw this exception
            #
            assert True

        #
        # Now put a CSRF token
        #
        client.http_info.xsrf_token = CSRF_TOKEN
        ret_cookies = {"XSRF-TOKEN": CSRF_TOKEN}
        mocked_cookies.get_dict.return_value = ret_cookies

        #
        # This time offense_analysis shall call the QRadarOffenseAnalysis
        #

        stix_json = {"type": "bundles"}

        mocked_get_search_result.return_value = stix_json
        mocked_perform_search.return_value = stix_json

        offense_id = 12345

        ret = client.offense_analysis(offense_id, restart_if_existed=False)

        assert ret == stix_json
        # because we set restart_if_existed=False, verify we call get_search_result
        # directly
        mocked_get_search_result.assert_called_with(offense_id)

        ret = client.offense_analysis(offense_id, restart_if_existed=True)

        assert ret == stix_json
        # because we set restart_if_existed=True, verify we call perform_search
        # to start a new analysis
        mocked_perform_search.assert_called_with(offense_id)
Beispiel #13
0
    def test_offense_insights(self, mocked_get_session, mocked_update_session):
        #
        # First verify that if there is no CSRF token, the full_search
        # function will call get_csrf_token to get one
        #
        mocked_cookies = Mock()
        # Use this to mock the member variables
        mocked_session = Mock(cookies=mocked_cookies)
        mocked_get_session.return_value = mocked_session

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=QRADAR_VERIFY,
                                     log=logging)
        #
        # when a QRadarAdvisorClient is instantiated, its http_info shall
        # has no csrf token
        #
        assert not client.http_info.xsrf_token

        try:
            mocked_session.get.return_value = _generate_response({}, 400)
            client.offense_insights(12345678)
            assert False
        except CsrfTokenError:
            #
            # because the CSRF token is None, full_search has to call get_csrf_token
            # to get it. Since we returned 400 above, the full_search call
            # shall throw this exception
            #
            assert True

        #
        # Now put a CSRF token
        #
        client.http_info.xsrf_token = CSRF_TOKEN
        ret_cookies = {"XSRF-TOKEN": CSRF_TOKEN}
        mocked_cookies.get_dict.return_value = ret_cookies

        offense_id = 12345

        url = QRADAR_API_BASE_URL + "/offense/" + str(offense_id) + "/insights"
        ret_json = {"insights": "Sample insights from Watson"}

        mocked_session.get.return_value = _generate_response(ret_json, 200)

        ret = client.offense_insights(offense_id)

        assert ret == ret_json

        #
        # Now test non 200 status_code
        #
        try:
            mocked_session.get.return_value = _generate_response(ret_json, 403)
            client.offense_insights(offense_id)
            assert False
        except OffenseInsightsError:
            assert True

        #
        # Test exception
        #
        try:
            mocked_session.get.side_effect = Exception("Some error exception")
            client.offense_insights(offense_id)
            assert False
        except OffenseInsightsError:
            assert True
Beispiel #14
0
    def test_quick_search(self, mocked_get_session, mocked_update_session):
        #
        # First verify that if there is no CSRF token, the full_search
        # function will call get_csrf_token to get one
        #
        mocked_cookies = Mock()
        # Use this to mock the member variables
        mocked_session = Mock(cookies=mocked_cookies)
        mocked_get_session.return_value = mocked_session

        client = QRadarAdvisorClient(qradar_host=QRADAR_HOST,
                                     advisor_app_id=QRADAR_APP_ID,
                                     qradar_token=QRADAR_TOKEN,
                                     cafile=QRADAR_VERIFY,
                                     log=logging)
        #
        # when a QRadarAdvisorClient is instantiated, its http_info shall
        # has no csrf token
        #
        assert not client.http_info.xsrf_token

        try:
            mocked_session.get.return_value = _generate_response({}, 400)
            client.quick_search("Not matter here")
            assert False
        except CsrfTokenError:
            #
            # because the CSRF token is None, full_search has to call get_csrf_token
            # to get it. Since we returned 400 above, the full_search call
            # shall throw this exception
            #
            assert True

        #
        # Now put a CSRF token
        #
        client.http_info.xsrf_token = CSRF_TOKEN
        ret_cookies = {"XSRF-TOKEN": CSRF_TOKEN}
        mocked_cookies.get_dict.return_value = ret_cookies

        url = QRADAR_API_BASE_URL + "/search/quick"

        search_value = "user:jsmith"

        search_dict = {"indicator": search_value}
        dict_str = json.dumps(search_dict)
        quick_search_result = {
            "suspicious_observables": [],
            "other_observables": []
        }

        mocked_session.post.return_value = _generate_response(
            quick_search_result, 200)

        ret = client.quick_search(search_value)

        assert ret == quick_search_result
        mocked_session.post.assert_called_with(url=url,
                                               data=dict_str,
                                               verify=QRADAR_VERIFY)

        #
        # Verify status_code other than 200 shall result in exception
        #
        mocked_session.post.return_value = _generate_response(
            quick_search_result, 422)
        try:
            client.quick_search(search_value)
            assert False
        except QuickSearchError:
            assert True

        #
        # Verify exception of post call
        #
        mocked_session.post.side_effect = Exception("Some error exception")
        try:
            client.quick_search(search_value)
            assert False
        except QuickSearchError:
            assert True
    def _qradar_advisor_offense_analysis_function(self, event, *args, **kwargs):
        """Function:
        This function performs two tasks:
        1. call the QRadar Advisor REST API to retrieve insights for a given QRadar offense
        2. call the QRadar Advisor REST API to perform analysis on the QRadar offense
        The input is qradar_offense_id in the input.
        The reply from QRadar Advisor analysis is in stix format. This function then
        1. extract the observables from the stix objects
        2. generate a html representation for the stix
        The return to Resilient server includes the above two, together with the raw replies for
        offense insights and offense analysis."""
        try:
            # Get the function parameters:
            qradar_offense_id = kwargs.get("qradar_offense_id")  # text
            qradar_advisor_result_stage = self.get_select_param(kwargs.get("qradar_advisor_result_stage"))  # select, values: "stage1", "stage2", "stage3"
            qradar_analysis_restart_if_existed = kwargs.get("qradar_analysis_restart_if_existed")  # boolean

            log = logging.getLogger(__name__)
            log.info("qradar_offense_id: %s", qradar_offense_id)
            log.info("qradar_advisor_result_stage: %s", qradar_advisor_result_stage)
            log.info("qradar_analysis_restart_if_existed: %s", qradar_analysis_restart_if_existed)

            qradar_verify_cert = True
            if "verify_cert" in self.options and self.options["verify_cert"] == "false":
                qradar_verify_cert = False

            yield StatusMessage("starting...")

            if qradar_analysis_restart_if_existed:
                # User wants restart a new analysis. Warn him/her it could take some time
                yield StatusMessage("Restarting a new analysis. It could take up to 15 minutes...")

            offense_analysis_timeout = int(self.options.get("offense_analysis_timeout", 1200))
            offense_analysis_period = int(self.options.get("offense_analysis_period", 5))

            log.debug("Using timeout: {}".format(str(offense_analysis_timeout)))
            log.debug("Using period: {}".format(str(offense_analysis_period)))

            client = QRadarAdvisorClient(qradar_host=self.options["qradar_host"],
                                         qradar_token=self.options["qradar_advisor_token"],
                                         advisor_app_id=self.options["qradar_advisor_app_id"],
                                         cafile=qradar_verify_cert,
                                         log=log)
            stix_json = client.offense_analysis(offense_id=qradar_offense_id,
                                                restart_if_existed=qradar_analysis_restart_if_existed,
                                                return_stage=qradar_advisor_result_stage,
                                                timeout=offense_analysis_timeout,
                                                period=offense_analysis_period)
            #
            # extract list of observables from this stix bundle
            #
            observables = stix_utils.get_observables(stix_json=stix_json,
                                                     log=log)
            #
            # generate a folder-tree like structure in html for this stix bundle
            #
            html_str = stix_tree.get_html(stix_json, log)

            #
            # get the insights for this offense
            #
            insights = client.offense_insights(offense_id=qradar_offense_id)

            yield StatusMessage("done...")
            yield StatusMessage("Returning {} observables".format(str(len(observables))))

            results = {
                "observables": observables,
                "note": html_str,
                "insights": insights,       # Return the raw insights dict
                "stix": stix_json           # Return the raw stix2 dict
            }

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            log.error(str(e))
            yield FunctionError(str(e))
    def _qradar_advisor_full_search_function(self, event, *args, **kwargs):
        """Function: Perform a QRadar Advisor full search on an indicator.
        The indicator is given as the qradar_advisor_search_value of the input.
        Another input is qradar_advisor_result_stage. This can be "stage1", "stage2", or "stage3".
        The return from QRadar Advisor is a report in stix format.
        Then this function calls util funtions from lib to
        1. extract observables from objects
        2. generate a html representation of the stix objects
        3. generate a summary
        All of the above 3 will be returned to Resilient server, together with the raw stix
        """
        try:
            # Get the function parameters:
            qradar_advisor_search_value = kwargs.get(
                "qradar_advisor_search_value")  # text
            qradar_advisor_result_stage = self.get_select_param(
                kwargs.get("qradar_advisor_result_stage")
            )  # select, values: "stage1", "stage2", "stage3"

            log = logging.getLogger(__name__)
            log.info("qradar_advisor_search_value: %s",
                     qradar_advisor_search_value)
            log.info("qradar_advisor_result_stage: %s",
                     qradar_advisor_result_stage)

            qradar_verify_cert = True
            if "verify_cert" in self.options and self.options[
                    "verify_cert"] == "false":
                qradar_verify_cert = False

            yield StatusMessage("starting...")

            # Warn the user
            yield StatusMessage(
                "Watson Search with Local Context could take up to 15 minutes..."
            )

            stix_json = None

            client = QRadarAdvisorClient(
                qradar_host=self.options["qradar_host"],
                qradar_token=self.options["qradar_advisor_token"],
                advisor_app_id=self.options["qradar_advisor_app_id"],
                cafile=qradar_verify_cert,
                log=log)

            full_search_timeout = self.options.get("full_search_timeout", 1200)
            full_search_period = self.options.get("full_search_period", 5)

            log.debug("Using timeout: {}".format(str(full_search_timeout)))
            log.debug("Using period: {}".format(str(full_search_period)))

            client.full_search_timeout = int(full_search_timeout)
            client.full_search_period = int(full_search_period)

            client.set_full_search_stage(qradar_advisor_result_stage)

            stix_json = client.full_search(qradar_advisor_search_value)

            #
            # extract list of observables from this stix bundle
            #
            observables = stix_utils.get_observables(stix_json=stix_json,
                                                     log=log)
            #
            # generate a folder-tree like structure in html for this stix bundle
            #
            html_str = stix_tree.get_html(stix_json, log)

            yield StatusMessage("Returning {} observables".format(
                str(len(observables))))

            #
            # no insights
            #
            summary = "Watson Search with Local Context of indicator {} returns {} observables.".format(
                qradar_advisor_search_value, str(len(observables)))
            if len(observables) == 1:
                summary = "Watson Search with Local Context of indicator {} returns {} observable.".format(
                    qradar_advisor_search_value, str(len(observables)))

            results = {
                "observables": observables,
                "note": html_str,
                "summary": summary,
                "stix": stix_json
            }

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception as e:
            log.error(e.message)
            yield FunctionError(e.message)