示例#1
0
def test_watchlist_update_invalid_object(cbcsdk_mock):
    """Testing Watchlist.update() raising InvalidObjectError when Watchlist ID is missing."""
    watchlist = Watchlist(cbcsdk_mock.api,
                          model_unique_id=None,
                          initial_data=None)
    with pytest.raises(InvalidObjectError):
        watchlist.update(nonexistant_key="This is ignored")
示例#2
0
def test_watchlist_delete(cbcsdk_mock):
    """Testing Watchlist.delete()."""
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}", WATCHLIST_GET_SPECIFIC_RESP)
    cbcsdk_mock.mock_request("DELETE", f"/threathunter/watchlistmgr/v3/orgs/test/watchlists/{id}", None)
    watchlist = Watchlist(cbcsdk_mock.api, model_unique_id="watchlistId")
    watchlist.delete()
示例#3
0
def test_watchlist_enable_tags(cbcsdk_mock):
    """Testing Watchlist.enable_tags()."""
    api = cbcsdk_mock.api
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}", WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(api, model_unique_id="watchlistId")
    cbcsdk_mock.mock_request("PUT", f"/threathunter/watchlistmgr/v3/orgs/test/watchlists/{id}/tag", {"tag": True})
    watchlist.enable_tags()
示例#4
0
def test_disable_alerts(cbcsdk_mock):
    """Testing Watchlist.disable_alerts()."""
    api = cbcsdk_mock.api
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}", WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(api, model_unique_id="watchlistId")
    cbcsdk_mock.mock_request("DELETE", f"/threathunter/watchlistmgr/v3/orgs/test/watchlists/{id}/alert", None)
    watchlist.disable_alerts()
示例#5
0
def test_watchlist_update_api_error(cbcsdk_mock):
    """Testing Watchlist.update() raising ApiError when passing in "report_ids" with empty list."""
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}", WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(cbcsdk_mock.api, model_unique_id="watchlistId", initial_data=None)
    cbcsdk_mock.mock_request("PUT", f"/threathunter/watchlistmgr/v3/orgs/test/watchlists/{id}",
                             WATCHLIST_GET_SPECIFIC_RESP)
    with pytest.raises(ApiError):
        watchlist.update(report_ids=[])
示例#6
0
def test_watchlist_update(cbcsdk_mock):
    """Testing Watchlist.update()."""
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}", WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(cbcsdk_mock.api, model_unique_id="watchlistId", initial_data=None)
    assert "description" in watchlist._info
    assert "nonexistant_key" not in watchlist._info
    assert watchlist._info["description"] == "Existing description for the watchlist."
    cbcsdk_mock.mock_request("PUT", f"/threathunter/watchlistmgr/v3/orgs/test/watchlists/{id}",
                             WATCHLIST_GET_SPECIFIC_RESP)
    watchlist.update(description="My New Description", nonexistant_key="This Is Ignored")
    assert watchlist._info["description"] == "My New Description"
示例#7
0
def test_watchlist_save(cbcsdk_mock):
    """Testing Watchlist.save()."""
    api = cbcsdk_mock.api
    id = "watchlistId"
    cbcsdk_mock.mock_request("POST", "/threathunter/watchlistmgr/v3/orgs/test/watchlists", WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(api, model_unique_id="watchlistId", initial_data=CREATE_WATCHLIST_DATA)
    watchlist.validate()
    watchlist.save()

    # if Watchlist response is missing a required field per enterprise_edr.models.Watchlist, raise InvalidObjectError
    cbcsdk_mock.mock_request("GET", f"/threathunter/watchlistmgr/v2/watchlist/{id}",
                             WATCHLIST_GET_SPECIFIC_MISSING_FIELDS_RESP)
    watchlist = api.select(Watchlist, "watchlistId")
    with pytest.raises(InvalidObjectError):
        watchlist.validate()
    with pytest.raises(InvalidObjectError):
        watchlist.save()
示例#8
0
def test_watchlist_init(cbcsdk_mock):
    """Testing Watchlist.__init__()."""
    id = "watchlistId"
    cbcsdk_mock.mock_request("GET",
                             f"/threathunter/watchlistmgr/v2/watchlist/{id}",
                             WATCHLIST_GET_SPECIFIC_RESP)
    watchlist = Watchlist(cbcsdk_mock.api,
                          model_unique_id="watchlistId",
                          initial_data=None)
    assert watchlist._model_unique_id == "watchlistId"
示例#9
0
def test_watchlist_update_id(cbcsdk_mock):
    """Testing Watchlist.update()."""
    id = "watchlistId2"
    id2 = "watchlistId"
    cbcsdk_mock.mock_request("GET",
                             f"/threathunter/watchlistmgr/v2/watchlist/{id}",
                             WATCHLIST_GET_SPECIFIC_RESP_2)
    watchlist = Watchlist(cbcsdk_mock.api,
                          model_unique_id="watchlistId2",
                          initial_data=None)
    assert "description" in watchlist._info
    assert "nonexistant_key" not in watchlist._info
    cbcsdk_mock.mock_request("PATCH",
                             "/threathunter/watchlistmgr/v2/watchlist",
                             WATCHLIST_GET_SPECIFIC_RESP)
    watchlist.id = id2
    result_repr = watchlist.__repr__()
    assert 'id watchlistId' in result_repr
    assert '(*)' in result_repr
    watchlist._update_object()
示例#10
0
def test_watchlist_disable_tags_no_id(cbcsdk_mock):
    """Testing Watchlist.disable_tags() raising InvalidObjectError when ID is missing."""
    api = cbcsdk_mock.api
    watchlist = Watchlist(api, model_unique_id=None)
    with pytest.raises(InvalidObjectError):
        watchlist.disable_tags()
示例#11
0
def test_watchlist_delete_no_id(cbcsdk_mock):
    """Testing Watchlist.delete() raising InvalidObjectError when ID is missing."""
    watchlist = Watchlist(cbcsdk_mock.api, model_unique_id=None)
    with pytest.raises(InvalidObjectError):
        watchlist.delete()
示例#12
0
def test_watchlist_classifier_empty(cbcsdk_mock):
    """Testing Watchlist.classifier_ when "classifier" is not in self._info."""
    watchlist = Watchlist(cbcsdk_mock.api)
    assert "classifier" not in watchlist._info
    assert watchlist.classifier_ is None
示例#13
0
def test_watchlist_classifier(cbcsdk_mock):
    """Testing Watchlist.classifier_ property."""
    watchlist = Watchlist(cbcsdk_mock.api, model_unique_id="watchlistId", initial_data=WATCHLIST_GET_SPECIFIC_RESP)
    assert watchlist.classifier_ == ("feed_id", "feed_id_associated")
def enterprise_edr():
    """
    Enterprise EDR operations, using research from TAU.

    1. Find Processes with Indicators of Compromise (IOC's) matching Egregor ransomware, then
    2. Combine observed Process hashes with TAU research into Reports, finally
    3. Add the Reports to a new Watchlist.
    """
    print(f"\n{BOLD}****************************************************\n"
          " 3. Carbon Black Cloud Enterprise EDR Watchlist API \n"
          f"****************************************************{UNBOLD}\n")
    logging.info("Building Egregor ransomware Reports and Watchlist from IOCs")
    egregor_query = "filemod_count:[10000 TO *] filemod_name:recover-files.txt (modload_name:rundll32.exe "\
                    "OR modload_name:regsvr32.exe)"
    print(
        "Using Enterprise EDR to create Threat Reports and a Watchlist, based on Egregor Ransomware IOCs: "
        f"\n{egregor_query}\n")

    # Find Enterprise EDR Processes that match Egregor ransomware behavior
    egregor_ransomware_processes = enterprise_edr_api.select(Process).where(
        egregor_query)

    # Extract the Process hashes
    process_hashes = set()
    print("Finding Process hashes that matched Egregor IOC query.\n")
    for process in egregor_ransomware_processes:
        process_hashes.add(process.process_md5)
        process_hashes.add(process.process_sha256)

    # Create an Enterprise EDR Report with the found Process hashes
    ransomware_hashes_report = create_eedr_report(
        title="Egregor Ransomware MD5/SHA256 Hashes",
        description="Process hashes suggesting Egregor ransomware behavior",
        severity=10,
        iocs={
            "id": 1,
            "match_type": "equality",
            "field": "process_hash",
            "values": list(process_hashes)
        })
    # Save the Report as a Watchlist Report (vs. a Feed Report)
    ransomware_hashes_report.save_watchlist()

    egregor_query = (
        "filemod_count:[10000 TO *] filemod_name:recover-files.txt "
        "(modload_name:rundll32.exe OR modload_name:regsvr32.exe)")

    # Continuously monitor for any Processes that exhibit Egregor ransomware behavior
    ransomware_query_report = create_eedr_report(
        title="Egregor Ransomware Query",
        description="IOCs suggesting ransomware behavior",
        severity=10,
        iocs={
            "id": 1,
            "match_type": "query",
            "values": [egregor_query]
        })

    # Save the Report as a Watchlist Report (vs. a Feed Report)
    ransomware_query_report.save_watchlist()

    print("Creating an Engregor ransomware Watchlist.\n")
    # Create a new Watchlist to track ransomware Process hashes
    wldata = {
        "name": "CBCSDK-Test",
        "description": "Egregor Ransomware Watchlist",
        "create_timestamp": time.time(),
        "last_update_timestamp": time.time(),
        "id": 1
    }
    ransomware_watchlist = Watchlist(enterprise_edr_api, initial_data=wldata)
    # Save the new Watchlist
    ransomware_watchlist.save()

    # Add the Reports to the Watchlist
    logging.info(f"Adding Reports to Watchlist {ransomware_watchlist.id}")
    print(
        "Adding Egregor ransomware SHA256/MD5 hashes Report and Query Report to Watchlist.\n"
    )
    ransomware_watchlist.update(
        report_ids=[ransomware_hashes_report.id, ransomware_query_report.id])
    return ransomware_watchlist.id