Luminar_IOCs_and_leaked_credentials

This connector allows integration of intelligence-based IOC data and customer-related leaked records identified by Luminar.

Data Enrichment & Threat Intelligence · Luminar IOCs & leaked credentials · Feed

Details

IDLuminar_IOCs_and_leaked_credentials
ProviderCognyte
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Cognyte is a global leader in security analytics software that empowers governments and enterprises with Actionable
Intelligence for a safer world. Our open software fuses, analyzes and visualizes disparate data sets at scale to help
security organizations find the needles in the haystacks. Over 1,000 government and enterprise customers in more than
100 countries rely on Cognyte’s solutions to accelerate security investigations and connect the dots to successfully
identify, neutralize, and prevent threats to national security, business continuity and cyber security.

Luminar is an asset-based cybersecurity intelligence platform that empowers enterprise organizations to build and
maintain a proactive threat intelligence operation that enables to anticipate and mitigate cyber threats, reduce risk
and enhance security resilience. Luminar enables security teams to define a customized, dynamic monitoring plan to
uncover malicious activity in its earliest stages on all layers of the Web.

This connector allows integration of intelligence-based IOC data and customer-related leaked records identified by Luminar.

Configure Luminar IOCs & leaked credentials in Cortex

Parameter Description Required
Luminar Base URL Luminar Base URL True
Luminar API Account ID Luminar API Account ID True
Luminar API Client ID Luminar API Client ID True
Luminar API Client Secret Luminar API Secret True
Trust any certificate (not secure) Trust any certificate (not secure) False
Use system proxy settings Use system proxy settings False
Fetch indicators Fetch indicators False
Indicator Reputation Indicators from this integration instance will be marked with this reputation. False
Source Reliability Reliability of the source providing the intelligence data. True
Feed Expiration Policy Feed Expiration Policy False
Feed Fetch Interval Feed Fetch Interval False
Tags Supports CSV values. False
Traffic Light Protocol Color The Traffic Light Protocol (TLP) designation to apply to indicators fetched from the feed False
Bypass exclusion list When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

luminar-get-indicators


Gets Luminar Indicators

Base Command

luminar-get-indicators

Input

Argument Name Description Required
limit The maximum number of indicators to return. Default is 50. Optional

Context Output

There is no context output for this command.

Command example

!luminar-get-indicators limit="3"

Context Example

{
    "Luminar": {
        "Indicators": [
            {
                "Indicator Type": "File",
                "Indicator Value": "a35866ff36a7ec0a226b8f814f3642185742020e",
                "Malware Family": "SlayerRAT v0.4",
                "rawJSON": {
                    "created": "2016-02-15T00:00:00.000Z",
                    "created_by_ref": "identity--cd3843c0-8119-4ac0-9409-cec757123a6a",
                    "id": "indicator--88369314-3515-4c5c-a3e3-dba75e4ae964",
                    "indicator_types": [
                        "malicious-activity"
                    ],
                    "modified": "2016-02-15T00:00:00.000Z",
                    "name": "SlayerRAT v0.4",
                    "pattern": "[file:hashes.'SHA-1' = 'a35866ff36a7ec0a226b8f814f3642185742020e']",
                    "pattern_type": "stix",
                    "spec_version": "2.1",
                    "type": "indicator",
                    "valid_from": "2016-02-15T00:00:00.000Z"
                }
            },
            {
                "Indicator Type": "Domain",
                "Indicator Value": "xbodyyellow.top",
                "Malware Family": "Locky",
                "rawJSON": {
                    "created": "2016-02-22T00:00:00.000Z",
                    "created_by_ref": "identity--cd3843c0-8119-4ac0-9409-cec757123a6a",
                    "id": "indicator--0240fda0-1b77-4bde-86d8-eeb27203e4d7",
                    "indicator_types": [
                        "malicious-activity"
                    ],
                    "modified": "2016-02-22T00:00:00.000Z",
                    "name": "Locky",
                    "pattern": "[domain-name:value = 'xbodyyellow.top']",
                    "pattern_type": "stix",
                    "spec_version": "2.1",
                    "type": "indicator",
                    "valid_from": "2016-02-22T00:00:00.000Z"
                }
            },
            {
                "Indicator Type": "Email",
                "Indicator Value": "javamaker@inbox.ru",
                "Malware Family": "OilRig",
                "rawJSON": {
                    "created": "2016-10-10T00:00:00.000Z",
                    "created_by_ref": "identity--cd3843c0-8119-4ac0-9409-cec757123a6a",
                    "id": "indicator--a1ee47e7-fe49-4fae-8c20-7a14452c5da7",
                    "indicator_types": [
                        "malicious-activity"
                    ],
                    "modified": "2016-10-10T00:00:00.000Z",
                    "name": "OilRig",
                    "pattern": "[email-addr:value = 'javamaker@inbox.ru']",
                    "pattern_type": "stix",
                    "spec_version": "2.1",
                    "type": "indicator",
                    "valid_from": "2016-10-10T00:00:00.000Z"
                }
            }
        ]
    }
}

Human Readable Output

Indicators from Luminar

Indicator Type Indicator Value Malware Family
File a35866ff36a7ec0a226b8f814f3642185742020e SlayerRAT v0.4
Domain xbodyyellow.top Locky
Email javamaker@inbox.ru OilRig

luminar-get-leaked-records


Gets Luminar Leaked Records

Base Command

luminar-get-leaked-records

Input

Argument Name Description Required
limit The maximum number of leaked records to return. Default is 50. Optional

Context Output

There is no context output for this command.

Command example

!luminar-get-leaked-records limit="3"

Context Example

{
    "Luminar": {
        "Leaked_Credentials": [
            {
                "Credentials": "######",
                "Indicator Type": "Account",
                "Indicator Value": "a@a.com",
                "rawJSON": {
                    "account_login": "a@a.com",
                    "credential": "######",
                    "display_name": "a@a.com",
                    "id": "user-account--e4af982e-4673-4795-94d6-17b5ef96f8ae",
                    "spec_version": "2.1",
                    "type": "user-account"
                }
            },
            {
                "Credentials": "######",
                "Indicator Type": "Account",
                "Indicator Value": "b@b.com",
                "rawJSON": {
                    "account_login": "b@b.com",
                    "credential": "######",
                    "display_name": "b@b.com",
                    "id": "user-account--b8fc71bf-3542-4fcb-a0c7-70dc5e7366e8",
                    "spec_version": "2.1",
                    "type": "user-account"
                }
            },
            {
                "Credentials": "######",
                "Indicator Type": "Account",
                "Indicator Value": "c@c.com",
                "rawJSON": {
                    "account_login": "c@c.com",
                    "credential": "######",
                    "display_name": "c@c.com",
                    "id": "user-account--885ee892-320c-4e62-8161-a999d2df086a",
                    "spec_version": "2.1",
                    "type": "user-account"
                }
            }
        ]
    }
}

Human Readable Output

Leaked Credentials from Luminar

Indicator Type Indicator Value Credentials
Account a@a.com ######
Account b@b.com ######
Account c@c.com ######

luminar-reset-fetch-indicators


WARNING: This command will reset your fetch history.

Base Command

luminar-reset-fetch-indicators

Input

There are no input arguments for this command.

Context Output

There is no context output for this command.

Command example

!luminar-reset-fetch-indicators

Human Readable Output

Fetch history deleted successfully

Configuration parameters

  • luminar_base_url — Luminar Base URL (required)
  • luminar_account_id — Luminar API Account ID (required)
  • luminar_client_id — Luminar API Client ID (required)
  • luminar_client_secret — Luminar API Client Secret (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • feed — Fetch indicators
  • feedReputation — Indicator Reputation
  • feedReliability — Source Reliability (required)
  • feedExpirationPolicy
  • feedExpirationInterval
  • feedFetchInterval — Feed Fetch Interval
  • feedTags — Tags
  • tlp_color — Traffic Light Protocol Color
  • feedBypassExclusionList — Bypass exclusion list
  • feedIncremental — Incremental Feed

Commands (3)

  • luminar-get-indicators

    Gets Luminar Indicators

  • luminar-get-leaked-records

    Gets Luminar Leaked Records

  • luminar-reset-fetch-indicators

    This command will reset your fetch history.

import json

import pytest
from CognyteLuminar import (
    Client,
    cognyte_luminar_get_indicators,
    cognyte_luminar_get_leaked_records,
    enrich_incident_items,
    enrich_malware_items,
    fetch_indicators_command,
    generic_item_finder,
    module_test,
    reset_last_run,
)

client = Client(
    base_url="http://test.com",
    account_id="abcd1234",
    client_id="cognyte",
    client_secret="test",
    verify=False,
    proxy=False,
    tags=["TT1", "TT2"],
    tlp_color="RED",
)
generic_expected_output = {
    "created": "2016-02-01T00:00:00.000Z",
    "created_by_ref": "identity--262928b4-f329-4436-9e81-6f35f69d8a85",
    "id": "indicator--f0680d81-7ce7-4a04-8315-0d38f792b908",
    "indicator_types": ["malicious-activity"],
    "modified": "2016-02-01T00:00:00.000Z",
    "name": "Imminent Monitor 4.1",
    "pattern": "[file:hashes.MD5 = '9dd8c0ff4fc84287e5b766563240f983']",
    "pattern_type": "stix",
    "spec_version": "2.1",
    "type": "indicator",
    "valid_from": "2016-02-01T00:00:00.000Z",
}
enrich_malware_output = {
    "value": "Ukraine Power Grid",
    "occurred": "01/04/2016, " + "00:00:00",
    "type": "Malware",
    "rawJSON": {
        "type": "malware",
        "spec_version": "2.1",
        "id": "malware--0913cc2e-56a1-4c00-aafb-e3ce7a8d8940",
        "created": "2016-01-04T00:00:00.000Z",
        "modified": "2016-01-04T00:00:00.000Z",
        "malwareTypes": ["trojan"],
        "is_family": False,
        "name": "Ukraine " + "Power " + "Grid",
    },
    "fields": {
        "STIX Is Malware Family": False,
        "tags": ["malicious-activity"],
        "stixid": "malware--0913cc2e-56a1-4c00-aafb-e3ce7a8d8940",
        "STIX Malware Types": ["trojan"],
        "malware_types": ["trojan"],
    },
}

enrich_incident_output = {
    "type": "incident",
    "spec_version": "2.1",
    "id": "incident--9907916e-f213-4c08-bd91-6c2bf109e509",
    "created": "2021-02-02T00:00:00.000Z",
    "modified": "2021-02-02T00:00:00.000Z",
    "name": "Master Breach Comp",
    "created_by_ref": "identity--b276f696-62b2-4b5b-b8df-cda64e955399",
}


def load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


INDICATOR_LIST = load_json("test_data/indicator_list.json")
child_record = load_json("test_data/child.json")
lumanar_data = load_json("test_data/luminar_api_result.json")
indicator_list_output = load_json("test_data/indicator_list_record.json")
leaked_record_output = load_json("test_data/leaked_record_list.json")
user_account_record = load_json("test_data/luminar_user_account.json")


def test_test_module(mocker):
    mocker.patch.object(client, "fetch_access_token", autospec=True)
    response = module_test(client)
    assert response == "ok"


def test_cognyte_luminar_get_indicators(mocker):
    mocker.patch.object(client, "get_luminar_indicators_list", side_effect=[INDICATOR_LIST])
    args = {"limit": 3}
    response = cognyte_luminar_get_indicators(client, args)
    assert len(response.outputs) == 3
    assert len(response.raw_response) == 3
    assert response.outputs_prefix == "Luminar.Indicators"


def test_cognyte_luminar_get_indicators_zero_limit(mocker):
    mocker.patch.object(client, "get_luminar_indicators_list", side_effect=[INDICATOR_LIST])
    args = {"limit": 0}
    response = cognyte_luminar_get_indicators(client, args)
    assert response.readable_output == "No Indicators Found."


def test_cognyte_luminar_get_indicators_without_limit(mocker):
    mocker.patch.object(client, "get_luminar_indicators_list", side_effect=[INDICATOR_LIST])
    args = {}
    response = cognyte_luminar_get_indicators(client, args)
    assert len(response.outputs) == 50
    assert len(response.raw_response) == 50
    assert response.outputs_prefix == "Luminar.Indicators"


def test_cognyte_luminar_get_leaked_records(mocker):
    mocker.patch.object(client, "get_luminar_leaked_credentials_list", side_effect=[INDICATOR_LIST])
    args = {"limit": 3}
    response = cognyte_luminar_get_leaked_records(client, args)

    assert len(response.outputs) == 3
    assert len(response.raw_response) == 3
    assert response.outputs_prefix == "Luminar.Leaked_Credentials"


def test_cognyte_luminar_get_leaked_records_without_limit(mocker):
    mocker.patch.object(client, "get_luminar_leaked_credentials_list", side_effect=[INDICATOR_LIST])
    args = {}
    response = cognyte_luminar_get_leaked_records(client, args)

    assert len(response.outputs) == 50
    assert len(response.raw_response) == 50
    assert response.outputs_prefix == "Luminar.Leaked_Credentials"


def test_cognyte_luminar_get_leaked_records_zero_limit(mocker):
    mocker.patch.object(client, "get_luminar_leaked_credentials_list", side_effect=[INDICATOR_LIST])
    args = {"limit": 0}
    response = cognyte_luminar_get_leaked_records(client, args)
    assert response.readable_output == "No Leaked Records Found."


def test_reset_last_run():
    response = reset_last_run()
    assert response.readable_output == "Fetch history deleted successfully"


def test_fetch_indicators_command(mocker):
    mocker.patch.object(client, "fetch_luminar_indicators", side_effect=[INDICATOR_LIST])
    response = fetch_indicators_command(client)
    assert str(response) == str(True)


@pytest.mark.parametrize("expected_optput", [(generic_expected_output)])
def test_generic_item_finder(expected_optput):
    response = generic_item_finder(INDICATOR_LIST, "indicator--f0680d81-7ce7-4a04-8315-0d38f792b908")
    result = {}
    for i in response:
        result.update(i)
    assert result == expected_optput


@pytest.mark.parametrize("expected_optput", [(enrich_malware_output)])
def test_enrich_malware_items(expected_optput):
    malware = (
        {
            "type": "malware",
            "spec_version": "2.1",
            "id": "malware--0913cc2e-56a1-4c00-aafb-e3ce7a8d8940",
            "created": "2016-01-04T00:00:00.000Z",
            "modified": "2016-01-04T00:00:00.000Z",
            "malwareTypes": ["trojan"],
            "is_family": False,
        },
    )
    indicator = [ele for ele in INDICATOR_LIST if ele["type"] == "indicator"]
    parent, child = enrich_malware_items(malware[0], indicator, ["TT1", "TT2"], "RED")
    assert parent == expected_optput


@pytest.mark.parametrize("expected_optput", [(enrich_incident_output)])
def test_enrich_incident_items(expected_optput):
    user_account_list = [ele for ele in INDICATOR_LIST if ele["type"] == "user-account"]
    incident = {
        "type": "incident",
        "spec_version": "2.1",
        "id": "incident--9907916e-f213-4c08-bd91-6c2bf109e509",
        "created": "2021-02-02T00:00:00.000Z",
        "modified": "2021-02-02T00:00:00.000Z",
        "name": "Master Breach Comp",
        "created_by_ref": "identity--b276f696-62b2-4b5b-b8df-cda64e955399",
    }
    parent, child = enrich_incident_items(incident, user_account_list, ["TT1", "TT2"], "RED")
    assert parent == expected_optput


def test_fetch_access_token(requests_mock):
    req_url = f"{client._base_url}/realm/{client.luminar_account_id}/token"
    req_headers = {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"}
    requests_mock.post(req_url, headers=req_headers, json={"access_token": "12345"})

    response = client.fetch_access_token()
    assert response == "12345"


def test_get_last_run(mocker):
    mocker.patch.object(client, "get_last_run", side_effect=[""])
    response = client.get_last_run()
    assert response == ""


def test_fetch_luminar_api_feeds(requests_mock):
    post_req_url = f"{client._base_url}/realm/{client.luminar_account_id}/token"
    get_req_url = f"{client._base_url}/stix"
    post_req_headers = {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"}
    requests_mock.post(post_req_url, headers=post_req_headers, json={"access_token": "12345"})
    access_token = client.fetch_access_token()
    get_req_headers = {"Authorization": f"Bearer {access_token}"}
    requests_mock.get(get_req_url, headers=get_req_headers, json=lumanar_data)
    response = client.fetch_luminar_api_feeds()
    response_list = []
    for i in response:
        response_list = i
        break
    assert response_list == lumanar_data["objects"]


def gen_indicator_list(Indicator):
    yield Indicator


def test_get_luminar_indicators_list(mocker, requests_mock):
    post_req_url = f"{client._base_url}/realm/{client.luminar_account_id}/token"
    get_req_url = f"{client._base_url}/stix"
    post_req_headers = {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"}
    requests_mock.post(post_req_url, headers=post_req_headers, json={"access_token": "12345"})
    access_token = client.fetch_access_token()
    get_req_headers = {"Authorization": f"Bearer {access_token}"}
    requests_mock.get(get_req_url, headers=get_req_headers, json=lumanar_data)
    response = client.fetch_luminar_api_feeds()
    response_list = []
    for i in response:
        response_list.append(i)
        break
    gen_response = gen_indicator_list(response_list)
    mocker.patch.object(client, "fetch_luminar_api_feeds", side_effect=gen_response)
    response = client.get_luminar_indicators_list()
    assert response == indicator_list_output


def test_luminar_leaked_credentials_list(mocker, requests_mock):
    post_req_url = f"{client._base_url}/realm/{client.luminar_account_id}/token"
    get_req_url = f"{client._base_url}/stix"
    post_req_headers = {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"}
    requests_mock.post(post_req_url, headers=post_req_headers, json={"access_token": "12345"})
    access_token = client.fetch_access_token()
    get_req_headers = {"Authorization": f"Bearer {access_token}"}
    requests_mock.get(get_req_url, headers=get_req_headers, json=user_account_record)
    response = client.fetch_luminar_api_feeds()
    response_list = []
    for i in response:
        response_list.append(i)
        break
    gen_response = gen_indicator_list(response_list)
    mocker.patch.object(client, "fetch_luminar_api_feeds", side_effect=gen_response)
    response = client.get_luminar_leaked_credentials_list()
    assert response == leaked_record_output